一、文件分析流程

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文件的分析,先通过仿真调试,看这两个数值在程序中怎么用。

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

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

接下来又将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/

KEIL MDK输出map文件分析的更多相关文章

  1. STM8S103 解决Rom空间不足 & Map文件分析

    STM8S103只有8KRom,很容易造成空间不足.对于空间不足,我们就要从map文件着手分析,究竟哪些函数占了多少空间,map文件分为几部分:Segments(总括了各个段所占的空间), Modul ...

  2. map文件分析

    1.MAP文件基本概念 段(section):描述映像文件的代码和数据块 RO:Read-Only的缩写,包括RO-data(只读数据)和RO-code(代码) RW:Read-Write的缩写,主要 ...

  3. 代码中函数、变量、常量 / bss段、data段、text段 /sct文件、.map文件的关系[实例分析arm代码(mdk)]

    函数代码://demo.c #include<stdio.h> #include<stdlib.h> , global2 = , global3 = ; void functi ...

  4. 如何定位Release 版本中程序崩溃的位置 ---利用map文件 拦截windows崩溃函数

    1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名 ...

  5. keil MDK启动文件分析---基于LPC2100系列(其实都是相通的)

    转用MDK有一段时间了,越来越觉得MDK的强大,因为我之前都是用ADS1.2开发产品,所以更能体会到MDK的强大与易用性.MDK编译出来的代码与ADS1.2相比,代码量减少了很多,我的一个工程用ADS ...

  6. stm32 map文件的分析

    相信有较大项目开发经验的朋友都曾遇到内存溢出的问题,那么大家都是如何分析这类问题的呢?大家遇到HardFault_Handler 有对map分析过吗? 首先讲述一下关于map在MDK-ARM中的配置. ...

  7. keil MDK中如何生成*.bin格式的文件

    在Realview MDK的集成开发环境中,默认情况下可以生成*.axf格式的调试文件和*.hex格式的可执行文件.虽然这两个格式的文件非常有利于ULINK2仿真器的下载和调试,但是ADS的用户更习惯 ...

  8. Keil MDK忽略警告:文件末尾空白行警告

    使用Keil MDK调试程序的时候,没有习惯在每个文件的末尾增加一个空白行,结果文件一多,编译时产生的警告就一大堆,排错都得用滚轮滚好久,就一个空白行还得出警告,烦死了,烦死了,烦死了!实在受不了了, ...

  9. loadrunner脚本中写入脚本输出log到外部文件,分析参数取值方式

    loadrunner脚本中写入脚本输出log到外部文件,分析参数取值方式 分类: 心得 loadrunner 我的测试 2012-04-01 12:52 2340人阅读 评论(0) 收藏 举报 脚本l ...

随机推荐

  1. 【MySQL】MySQL无基础学习和入门大纲

    一.安装 1.yum安装 2.分发包安装 3.配置文件 4.初始化数据库 二.启动 1.service mysqld start默认配置启动 2.mysqld_safe方式加载配置文件启动 3.mys ...

  2. 了解 JavaScript 应用程序中的内存泄漏

    简介 当处理 JavaScript 这样的脚本语言时,很容易忘记每个对象.类.字符串.数字和方法都需要分配和保留内存.语言和运行时的垃圾回收器隐藏了内存分配和释放的具体细节. 许多功能无需考虑内存管理 ...

  3. PIC32MZ tutorial -- Watchdog Timer

    Watchdog is a very necessary module for embedded system. Someone said that embedded system operates ...

  4. Java利用aspose-words将word文档转换成pdf(破解 无水印)

    首先下载aspose-words-15.8.0-jdk16.jar包 http://pan.baidu.com/s/1nvbJwnv 引入jar包,编写Java代码 package doc; impo ...

  5. CentOS和Ubuntu下安装配置Greenplum数据库集群(包括安装包和源码编译安装)

    首先说一下,无论是CentOS/RedHat还是Ubuntu都可以按源码方式.安装包方式编译安装. 1.   规划 192.168.4.93(h93)       1个主master  2个主segm ...

  6. KBMMW 4.90.00 发布

    kbmMW is a portable, highly scalable, high end application server andenterprise architecture integra ...

  7. 英语语法 It all started the summer before second grade when our moving van pulled into her neighborhood

    It all started the summer before second grade when our moving van pulled into herneighborhood It all ...

  8. eval()与jQuery.parseJSON()的差别以及常见的解析缺少分号的问题

    在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象 http://blog.163.com/wujicaiguai%40126/blog/static/1701715 ...

  9. ORACLE 分析函数整理汇总

    1. 聚合分析函数 SUM MIN MAX AVG COUNT 这类聚合类分析函数可以在窗口中分组

  10. sql ltrim rtrim

    sql中用LTRIM ( ),RTRIM ( ).分别截断首尾空格,返回字符表达式. 例1: DECLARE @string_to_trim varchar(60)SET @string_to_tri ...