main之前初始化流程

新一發表於2017-10-28

 

main之前初始化流程

本文分別介紹Keil呼叫的ARMCC以及ARM-NONE-EABI-GCC兩個編譯器在main之前的操作:

Keil MDK啟動檔案

總結一下MDK的啟動流程: 
1.系統初始化,包括中斷向量表的重新對映 
2.載入RW段(.data段初始化) 
3.載入ZI段(.bss段初始化) 
4.初始化使用者堆疊 
5.初始化Microlib 
6.呼叫main函式 
microlib 是預設 C 庫的備選庫。 它旨在與需要裝入到極少量記憶體中的深層嵌入式應用程式配合使用。 這些應用程式不在作業系統中執行。 
microlib 進行了高度優化以使程式碼變得很小。 它的功能比預設 C 庫少,並且根本不具備某些 ISO C 特性。 某些庫函式的執行速度也比較慢,例如,memcpy()。 
下圖是Keil呼叫ARMCC的載入到執行的變化檢視: 
這裡寫圖片描述 
對於RO與RW段 
Loadregion_nameBase表示region_name區域的裝載地址 
“Imageregion_nameBase”表示region_name區域的執行地址 
“Imageregion_nameLength”表示region_name區域的長度(單位:位元組) 
對於ZI段 
“Imageregion_nameZIBase”表示region_name區域的執行地址 
“Imageregion_nameZILength”表示region_name區域的長度(單位:位元組)

 ARM-NONE-EABI-GCC的crt0啟動流程

利用arm-none-eabi-gcc編譯器生成ELF檔案,將ELF檔案通過objdump反彙編可以找出main之前的初始化函式_mainCRTStartup。
下圖為ARM7V-M平臺下_mainCRTStartup的大致流程:

這裡寫圖片描述

下面看一下ELF檔案中各段的分佈: 
這裡寫圖片描述 
由上圖可知.text後直接跟.data段,但.data段的地址為RAM的實際地址。

 小結:

arm-none-eabi-gcc不像armcc有將全域性變數的值儲存在flash中,所以沒有像scatter_load函式這樣從flash中載入全域性變數到ram中,arm-none-eabi-gcc只能靠載入器將.data段直接載入到ram中。

相關文章