一、文件分析流程
1、第一部分:Section Cross References
主要是各個源文件生成的模塊之間相互引用的關系。
stm32f10x.o(STACK) refers (Special) to stkheap2.o(.text) for __use_two_region_memory
比如上面這句話,stm32f10x.o是stm32f10x.s生成的目標文件模塊,(STACK)是文件內定義的一個段,鏈接器把它視為一個Section,輸入節。它引用了模塊stkheap2.o輸入節(.text)里面的一個全局符號__use_two_region_memory(可能是一個函數或變量)。這個(Special)不知道是什么含義。
剩下的基本都是這用的意思。
stm32f10x_vector.o(.text) refers to __main.o(!!!main) for __main
__main.o(!!!main) refers to kernel.o(.text) for __rt_entry
kernel.o(.text) refers to usertask.o(.text) for main
上面這幾個對於程序意義比較重大用戶在啟動代碼中調用了__main.o模塊中的__main函數,__main又調用了kernel.o中的__rt_entry函數,最后kernel.o又調用了用戶定義的main主函數。
2、第二部分:Removing Unused input sections from the image.
就是將庫中沒有用到的函數從可執行映像中刪除掉,減小程序的體積。
Removing os_mbox.o(.text), (1094 bytes).
Removing os_mutex.o(.text), (1744 bytes).
Removing os_sem.o(.text), (1016 bytes).
3、第三部分:Image Symbol Table
Local Symbols
符號表里的局部符號。
../../angel/boardlib.s 0x00000000 Number 0 boardinit1.o ABSOLUTE
../../angel/handlers.s 0x00000000 Number 0 __scatter_copy.o ABSOLUTE
../../angel/kernel.s 0x00000000 Number 0 kernel.o ABSOLUTE
../../angel/rt.s 0x00000000 Number 0 rt_raise.o ABSOLUTE
../../angel/scatter.s 0x00000000 Number 0 __scatter.o ABSOLUTE
../../angel/startup.s 0x00000000 Number 0 __main.o ABSOLUTE
../../angel/sys.s 0x00000000 Number 0 sys_exit.o ABSOLUTE
../../angel/sysapp.c 0x00000000 Number 0 sys_wrch.o ABSOLUTE
../../armsys.c 0x00000000 Number 0 _get_argv.o ABSOLUTE
../../division_7m.s 0x00000000 Number 0 rtudiv10.o ABSOLUTE
../../fpinit.s 0x00000000 Number 0 fpinit.o ABSOLUTE
../../heapalloc.c 0x00000000 Number 0 hrguard.o ABSOLUTE
../../printf.c 0x00000000 Number 0 _printf_outstr_char.o ABSOLUTE
../../signal.c 0x00000000 Number 0 defsig_exit.o ABSOLUTE
../../stdlib.c 0x00000000 Number 0 exit.o ABSOLUTE
../../stkheap.s 0x00000000 Number 0 heapext.o ABSOLUTE
以上是一些系統內部的局部符號,還有用戶的一些局部符號
4、第四部分:Global Symbols
全局符號
_terminate_user_alloc - Undefined Weak Reference
_terminateio - Undefined Weak Reference
__Vectors 0x08000000 Data 4 stm32f10x_vector.o(RESET)
__main 0x08000131 Thumb Code 8 __main.o(!!!main)
__scatterload 0x08000139 Thumb Code 0 __scatter.o(!!!scatter)
__scatterload_rt2 0x08000139 Thumb Code 44 __scatter.o(!!!scatter)
這些是一些系統的全局符號
Font8x16 0x08001a82 Data 2048 tft018.o(.constdata)
Font8x8 0x08002282 Data 2056 tft018.o(.constdata)
codeGB_16 0x08002a8a Data 770 tft018.o(.constdata)
Region$$Table$$Base 0x08002dc0 Number 0 anon$$obj.o(Region$$Table)
Region$$Table$$Limit 0x08002de0 Number 0 anon$$obj.o(Region$$Table)
后面這兩個符號我認為很重要,在運行庫代碼將可執行映像從加載視圖轉變為可執行視圖的過程中起到了關鍵作用。Number是指它並不占據程序空間,而只是一個具有一定數值的符號,類似於程序中用define和EQU定義的。所以這里,我先放下map文件的分析,先通過仿真調試,看這兩個數值在程序中怎么用。



執行完成后,程序就會進入BL.W __rt_entry處進行庫的初始化工作。
經過這么一分析,現在我對於程序的加載映像和執行映像有了較深的理解:程序的RO_Code加上RO_Data總共是0x2dc0這么大,地址范圍0x0800,0000到0x8000,2dbf。然后在0x0800,2dc0-2dcf共16個字節放了RW加載映像地址(0x0800,2de0)、執行映像地址(0x2000,0000)、RW長度(0x20)和將該段數據從加載映像復制到執行映像的函數地址。在0x0800,2dd0-2ddf共16個字節放了ZI加載映像地址(0x0800,2e00)、執行映像地址(0x2000,0020)、ZI長度(0x480)和建立ZI、HEAP和STACK執行映像的函數地址。
在上面的第二個階段,將ZI清零階段,程序的ZI長度實際上只有0x20,而庫代碼留出了0x60的長度。因此數據區的頂端為0x2000,00a0-1。接下來從0x2000,00a0開始為堆的起始地址,堆長度加上程序棧長度為0x2000,04a0,這就是堆棧頂端,也是__initial_SP的初始值。
程序進入_rt_entry后,還要對heapstack進行處理,但我沒有看到有什么用的變化。從中對庫留出的ZI數據區進行了一些處理,我暫時也看不明白。好了,調試就到這里,回到map文件分析的正途。
5、第五部分:
Memory Map of the image
//映像的內存分布
Image Entry point : 0x080000ed
//程序的入口點:這里應該是RESET_Handler的地址
Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00002e00, Max: 0x00020000, ABSOLUTE)
//程序的加載映像地址和長度,2e00=2dc0(代碼和常數)+0x20(Region Table是RW的加載和執行地址、ZI與HEAPSTACK的執行地址)+0x20(已經初始化的數據)。
Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00002de0, Max: 0x00020000, ABSOLUTE) //這段RO區域的加載映像和執行映像一致。
Base Addr Size Type Attr Idx E Section Name Object
0x08000000 0x000000ec Data RO 3 RESET stm32f10x.o
0x080000ec 0x00000008 Code RO 191 * !!!main __main.o(c_w.l)
Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x000004a0, Max: 0x00005000, ABSOLUTE) //RW數據區 ZI數據區 Heap和Stack數據區。
Base Addr Size Type Attr Idx E Section Name Object
0x20000000 0x00000001 Data RW 100 .data tft018.o
x20000040 0x00000060 Zero RW 212 .bss libspace.o(c_w.l)
0x200000a0 0x00000000 Zero RW 2 HEAP stm32f10x.o
0x200000a0 0x00000400 Zero RW 1 STACK stm32f10x.o
6、第六部分:Image component sizes
這是指出各個模塊的輸入節的大小
Code (inc. data) RO Data RW Data ZI Data Debug Object Name
972 58 0 10 32 2416 can.o
824 168 0 15 0 1791 candemo.o
928 88 0 0 0 4529 stm32_init.o
52 18 236 0 1024 2700 stm32f10x.o
1836 32 4874 1 0 8076 tft018.o
最后給出總長度:這個11744應該=0x2dc0,1184應該0x4a0。11776應該是=0x2e00。
Total RO Size (Code + RO Data) 11744 ( 11.47kB)
Total RW Size (RW Data + ZI Data) 1184 ( 1.16kB)
Total ROM Size (Code + RO Data + RW Data) 11776 ( 11.50kB)
二、總結
感覺經過這么分析一遍,對於嵌入式系統程序的靜態結構和動態執行流程的了解又深入了一些,當然也還是有些問題並沒有了解透徹:留待以后慢慢解決吧。