原创 KEIL MDK输出map文件分析01

2009-10-11 17:45 8820 7 8 分类: MCU/ 嵌入式

<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />20091011星期日16:13:12<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


 


标题:KEIL MDK输出map文件分析01


零、前言


前面写了一篇文章对__main函数的执行过程做了一个粗略的跟踪描叙,对一个烧录了程序的STM32开发板从启动复位到进入用户main函数的过程有了一个大概的了解,但是有很多问题感觉还是模模糊糊,因此,今天又把KEIL MDK编译、链接后生成的map文件简单分析一下,加深对链接器、嵌入式系统可执行映像特点的了解。、


一、文件分析流程


1、第一部分:Section Cross References


主要是各个源文件生成的模块之间相互引用的关系。


stm32f10x.o(STACK) refers (Special) to stkheap2.o(.text) for __use_two_region_memory


比如上面这句话,stm32f10x.ostm32f10x.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是指它并不占据程序空间,而只是一个具有一定数值的符号,类似于程序中用defineEQU定义的。所以这里,我先放下map文件的分析,先通过仿真调试,看这两个数值在程序中怎么用。


 


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> 点击看大图


 



果然,在刚开始执行程序时,R10R11的值就已经被赋值成了这两个值。


 


点击看大图


 


 很快就将0x08002dc00x08002dcf处的16个字节,4个双字加载到了R0-R3,我们可以分析一下里面的内容,R0就是程序加载视图的RW区的起始地址(0x08002de0),R1就是要输出的执行视图的RW区的地址(0x20000000),R2就是要复制的RW数据的个数,R3是复制函数 __scatterload_copy)的地址,类似于一个回调函数。接下来就要用了:0x0800011E 4718  BX  r3这条指令去执行复制工作。


点击看大图


接下来又将0x08002dd00x08002ddf处的16个字节,4个双字加载到了R0-R3,我们可以分析一下里面的内容,R0就是程序加载视图的RW区的起始地址(0x08002de0+0x20=0x08002e00),R1就是要输出的执行视图的RW区的地址(0x20000020),R2就是要复制的RW数据的个数,R3ZI区域建立函数(  __scatterload_zeroinit )的地址。



执行完成后,程序就会进入BL.W  __rt_entry处进行库的初始化工作。


OK,先写到这里,要去吃晚饭了!!!。


 

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2016-3-25 16:11

我靠!吃完饭不回来了?
相关推荐阅读
nthq2004 2010-05-08 20:04
USB自定义设备驱动02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  本来还想编写应用程序测试一下自定...
nthq2004 2010-05-07 21:35
USB自定义设备驱动01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、USB设备驱动入门1、学习目...
nthq2004 2010-05-04 21:01
智林开发板上实现自定义的USB HID设备
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />  一、自定义HID设备的相关概念1...
nthq2004 2010-05-01 21:58
U盘例程在智林开发板上的移植
 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 一、移植前的准备工作1、有哪些操...
nthq2004 2010-04-30 19:19
U盘实现流程跟踪分析02
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   二、追踪USB大容量设备的实现...
nthq2004 2010-04-27 21:51
U盘实现流程跟踪分析01
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />   一、追踪USB大容量设备的实现...
EE直播间
更多
我要评论
1
7
关闭 站长推荐上一条 /3 下一条