armlink使用介紹 過程 Image的結構

基本內容 在keil的help中都有, 不過經作者梳理後, 看起來更清晰些; 感謝!  (轉載記錄)

原文鏈接:https://blog.csdn.net/suxiang198/article/details/70786574 

查看原鏈接地址, 文檔結構更好; 


簡述
早前Keil被ARM收購,而目前比較主流的嵌入式系統的IC都是ARM架構的,因此許多嵌入式工程開發環境是Keil,一些比較複雜的情況下需要根據自己的需要劃分memory空間,因此對Keil中鏈接腳本的內容值得學習一番。下面的介紹都是基於ARM Compiler armlink v6.4 Release(2016.2.24更新版本)進行的。

armlink相關介紹
基本特性
Linker的功能就是將編譯生成的各個中間文件作爲輸入,產生鏈接後的可執行文件。
1. 支持多種格式的可執行文件輸出(比如binary, hex, axf等);
2. 可以鏈接A32, T32或A64代碼;
3. 自動選擇合適的C或C++庫進行鏈接;
4. 可以自定義將code和data放在memory map的對應位置,通過鏈接時輸入命令或者使用scatter file的形式進行;
5. RW data壓縮佔用最小的ROM size;
6. 優化未用的sections;
7. 在鏈接輸出文件中置入調試信息;
8. 產生靜態的調用圖,並列出stack的用量;
9. 輸出文件中置入symbol table;
10. 輸出文件中顯示code和data size;

link command
armlink options input-file-list 
1
輸入項    說明
options    Linker command-line options
input-file-list    A space-separated list of objects, libraries, or symbol definitions (symdefs) files
關於options輸入項,Keil列出了上百種,方便配置各項link參數。

link過程

* 從輸入文件解析符號;
* 從庫中抽取對象模塊,以滿足一些符號需求;
* 移除未使用到的sections;
* 將重複的共用的代碼,數據,調試sections進行優化;
* 將輸入sections進行分類,將相似屬性與名字的sections進行整合成爲連續的塊;
* 根據分組和提供的劃分信息組織對象放入memory區域;
* 分配地址給可重定位的值;
* 產生可執行image。

鏈接模式
鏈接模式(Linking Model)是因命令參數和memory map不同而使用的鏈接器的不同行爲模式。

鏈接模式    說明
Bare-metal    目標無關,可以使用自己的OS, memory map, app code創建image,一些有限制性的動態鏈接也支持。可以指定額外的選項
Bare-metal Position Independent Executables(PIE)    不需要指定地址,可以在任何適合的地址執行,所有對象和庫都必須是位置無關的
Partial linking    已經鏈接過的部分ELF文件作爲輸入,繼續進行鏈接
BPABI    支持類似DLL方式
Base Platform    爲BPABI的支持scatter-loading的擴展
Image的結構
ARM ELF image由sections, regions, segments組成。


ELF object file view(linker input)
從鏈接輸入文件的角度看,ELF object file可以是如下類型:

ELF object file    說明
可重定位文件    應當就是編譯後的文件,可以重定位
共享對象文件    包含了code和data的共享對象文件
Linker View
從鏈接器的角度看,有兩種類別的地址:

地址類別    說明
Load Address    Linker期望外部加載器之類的從ELF文件拷貝fragment的位置/地址, 可能和fragment實際執行的地址並不一樣
Execution Address    Linker期望fragment程序執行期間的實際地址
如果一個fragment是位置獨立的或可重定位的,那執行期間它的執行地址可以變化。

ELF image file view(linker output)
ELF image file view由程序segment和output sections組成:

組成部分    說明
Load region    一個Load region對應一個程序片段(program segment)
Execution region    包含了RO, RW, XO, ZI其中一個或以上的output sections
一個或多個execution regions組成一個Load region。

各個部分進一步說明
部分    說明
Input section    從鏈接輸入文件中解析出的獨立section,包含code(RO),初始化了的data(RW),未初始化但描述了一段memory(XO),在image能執行前必須設置爲0的部分,一般是在該output section給出描述,實際空間是在執行時分配的(ZI)
Output section    將有相同RO,RW,XO,ZI屬性的input sections組成起來,被linker整合爲連續的內存空間
Region    一個region可包含多達4個output sections,output sections在region中的位置爲XO–>RO–>RW–>ZI,一個region一般映射到物理memory設備(ROM,RAM,Peripheral),也可能通過scatter-loading改變output sections的順序
Program segment    一個程序片段對應一個load region(包含execution regions),程序片段包含text和data信息
注:XO memory只支持ARMv7-M和ARMv8-M架構。

image結構的加載時視圖以及運行時視圖


爲何之前提到的Load Address和Execution Address可能會不同呢,因爲在load(bootloader)時是將image regions放到系統的memory map,但是在程序執行時,memory中region的位置可能發生改變。
在執行image前,有時候可能需要將一些regions移到memory的可執行地址,並創建ZI output sections。例如RW data可能需要從其處於ROM的load address拷貝到處於RAM中的execution address。

視圖    說明
Load view    程序下載到memory,但程序尚未運行
Execution view    程序開始運行後
所以Load Address和Execution Address的不同就是因爲在程序啓動時,會有memory搬移的動作而導致地址發生變化。

常見image視圖示例
OS bootloader或桌面系統:

對應鏈接command:

armlink --cpu=8-A.32 --ro_base 0x8000
1
一般沒有特別通過armlink指定,regions中output sections的排序是XO–>RO–>RW–>ZI的,這裏只指定了ro_base,即RO地址指定了,RW,ZI會自動鏈接到其後面。
上面這裏沒有XO section,如果有的話,ro_base是指定的XO section的地址,RO,RW,ZI會連續接在其後面。

Embedded系統


對應的鏈接command:

armlink --cpu=8-A.32 --ro_base 0x0 --rw_base 0xA000
1
注意,如果有XO section的話,和上圖一樣的處理。另外,execution address和load address不同的話,搬移時原則是execution region不能和load region有重合。

更加複雜點的情況

對應的鏈接command:

armlink --cpu=8-A.32 --split --ro_base 0x8000 --rw_base 0xE000
1

————————————————
版權聲明:本文爲CSDN博主「suxiang198」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/suxiang198/article/details/70786574

 

 

發佈了0 篇原創文章 · 獲贊 4 · 訪問量 6223
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章