armlink 第一章 鏡像結構

第一章 鏡像結構

注意:本文章只針對,裸機開發.至於SysV,BPABI,BP的鏈接模型請參考《armlink_user_guide》

1.1 重要的概念

1.1.1 鏡像的構成

編譯器將源文件編譯成中間文件。鏈接器將中間文件最終生成鏡像文件。

在中間文件中,邏輯最小單元稱爲section。鏈接器將所有中間文件的section收集起來,然後按照一定的規則,進行重新組織。將具有相同屬性的section,組織在一起,稱爲輸出section。相應的,中間文件的section稱爲輸入section。然後再將不同的輸出section組織在一起,起個名字叫做region。

他們之間的關係如下圖

在這裏插入圖片描述

下面分別介紹輸入section,輸出section,region和segment

  1. 輸入section:輸入section來自於中間文件。它含有代碼,初始化數據或者描述信息。描述信息用於表示未被初始化的段或者鏡像執行之前必須設置爲0的段。輸入section具有RO,RW,XO,ZI這樣的屬性。這些屬性被armlink用於組織成region或者輸出section

  2. 輸出section:輸出section其實是具有相同屬性的輸入section的集合,因此輸出section的屬性和輸入section的屬性相同。這些輸入section被連續的放置於內存中。

  3. region:一個region最多包含四個不同屬性的輸出section。默認情況下,在region中的輸出section根據屬性進行排序。XO輸出section總是第一個,接着是RO輸出section,然後是RW輸出section,最後是ZI輸出section。通常一個region被映射成一個物理內存設備,例如ROM,RAM。可以使用scatter改變輸出section的順序。

  4. segment:等同於region,之所以叫segment是因爲在arm elf標準中使用了這個術語。

注意:armlink的單個segment的最大值爲2GB

RO——read only

RW——read write

ZI——zero initialized

XO——execute only

1.1.2 鏡像的地址

在執行鏡像之前,可能必須要把部分region移動到它的執行地址處,或者創建ZI輸出section。例如,對於已經初始化的RW數據可能必須將其從ROM移動到RAM處。

這樣就會導致一個鏡像具有兩種不同的內存視圖:加載視圖,執行視圖

  1. 加載視圖:描述了鏡像執行之前的地址
  2. 執行視圖:描述了鏡像執行時的地址

當region的加載地址和執行地址一樣時,稱爲root region

下圖展示了這兩者的區別。

在這裏插入圖片描述

1.2 三種簡單的鏡像結構

爲了幫助理解上述概念,這裏介紹三種簡單鏡像。

1.2.1 類型1

類型1:一個加載region,三個執行region。如下圖所示:

在這裏插入圖片描述

爲了指定ro的地址,可以使用命令行選項–ro_base.命令如下:

armlink --ro_base 0x8000

注意:0x8000是默認地址,因此在這個例子中,也可以不用指定

加載視圖:這個唯一的加載region由RO和RW兩個輸出section組成。ZI輸出section在加載視圖中不存在,他是在執行之前創建的。

執行視圖:由三個連續的執行region組成,他們分別包含RO,RW和ZI輸出section。RO和RW的執行地址與加載地址一樣,因此無需做任何移動。但是,ZI執行region必須在運行時創建。

使用--ro_base address指定RO region的加載和執行地址。

使用--zi_base address指定ZI region的執行地址。

包含XO的加載視圖

如果一個鏡像包含XO section。那麼XO輸出section就被放置於--ro_base指定的位置處。RO和RW則連續排在其後

包含XO的執行視圖

如果一個鏡像包含XO section,那麼XO執行地址爲--ro_base指定的地址處,RO,RW和ZI緊隨其後

1.2.2 類型2

類型2:一個加載region,三個執行region。但是RW執行region的地址和RO的執行地址不連續。

如下圖:

在這裏插入圖片描述

使用下面的命令創建這種類型的鏡像:

armlink --ro_base 0x0 --rw_base 0xA000

加載視圖:一個加載region,包含RO和RW輸出section,且這兩者連續放置。

執行視圖:第一執行region包含RO輸出section。第二個執行region包含RW和ZI輸出section

第一個執行region和加載region地址相同,因此不需要移動。第二個執行regoin和加載region的地址不同,因此它需要進行搬運。ZI 執行region在運行時創建

使用--ro_base address指定RO輸出section加載和執行地址。

使用--rw_base address指定RW輸出section的執行地址。

使用--zi_base address指定ZI執行region的地址

含有XO region的加載視圖

如果一個鏡像含有XO section。那麼XO section被放置在--ro_base指定的地址處。RO和RW則緊隨其後

含有XO region的執行視圖

如果一個鏡像含有XO section。那麼XO section的執行region放置在--ro_base指定的地址處。RO則緊隨其後

如果使用了--xo_base address,那麼XO 執行region被放置在這個指定的地址處

1.2.3 類型3

類型3:該類型類似於類型2,但是跟類型2不同的是,類型3的加載視圖,被分隔成多個root region。如下圖:

在這裏插入圖片描述

使用下面的命令,生成這種類型的鏡像:

armlink --split --ro_base 0x8000  --rw_base 0xE000

加載視圖:第一個 加載region 包含 RO輸出section 。第二個 加載region 包含 RW輸出section。

執行視圖:第一個執行region包含RO 輸出section,第二個執行region包含RW輸出section。第三個執行region包含ZI輸出section。

RO和RW輸出section都是root region,因此不需要移動,只有ZI需要在運行時創建。

使用–split,將默認的單個加載region分隔開。

含有XO的加載視圖

如果一個鏡像含有XO section,則XO被放置在--ro_base 所在的地址處,RO和RW緊隨其後

含有XO的執行視圖

如果一個鏡像含有XO section,則放置在--ro_base 所指的地址處。

如果你指定了--split選項,XO和RO被放置在第一個加載regioin中,RW和ZI執行region放在第二個加載region中

如果你指定了--xo_base,XO的執行地址則是此處指定的地址。

本章完,下章,scatter文件語法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章