KEIL MDK輸出map文件分析


一、文件分析流程


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文件的分析,先通過仿真調試,看這兩個數值在程序中怎么用。

KEIL MDK輸出map文件分析 - Wornyong - 智能物聯,嵌入您我!
  果然,在剛開始執行程序時, R10 R11 的值就已經被賦值成了這兩個值。

KEIL MDK輸出map文件分析 - Wornyong - 智能物聯,嵌入您我!
  很快就將0x08002dc0到0x08002dcf處的16個字節,4個雙字加載到了R0-R3,我們可以分析一下里面的內容,R0就是程序加載視圖的RW區的起始地址(0x08002de0),R1就是要輸出的執行視圖的RW區的地址(0x20000000),R2就是要復制的RW數據的個數,R3是復制函數 ( __scatterload_copy)的地址,類似於一個回調函數。接下來就要用了:0x0800011E 4718  BX  r3這條指令去執行復制工作。

KEIL MDK輸出map文件分析 - Wornyong - 智能物聯,嵌入您我!
 接下來又將0x08002dd0到0x08002ddf處的16個字節,4個雙字加載到了R0-R3,我們可以分析一下里面的內容,R0就是程序加載視圖的RW區的起始地址(0x08002de0+0x20=0x08002e00),R1就是要輸出的執行視圖的RW區的地址(0x20000020),R2就是要復制的RW數據的個數,R3是ZI區域建立函數(  __scatterload_zeroinit )的地址。


執行完成后,程序就會進入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)


 


二、總結


感覺經過這么分析一遍,對於嵌入式系統程序的靜態結構和動態執行流程的了解又深入了一些,當然也還是有些問題並沒有了解透徹:留待以后慢慢解決吧。

http: // kmoving.blog.163.com/blog/static/20504919720129241952437/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM