一、文件分析流程

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. cocos2d-x + Lua接入iOS原生SDK的实现方案[转]

    相信很多朋友在使用cocos2d-x+lua开发游戏时都遇到过接入iOS原生SDK的问题,比如常见的接应用内支付SDK,广告SDK或是一些社交平台SDK等等,我也没少接过这类SDK.这篇文章主要是对我 ...

  2. vs2010中将c++控制台程序修改成windows应用程序

    报错:无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用 vs2010环境下将Win32控制台应用程序,改为Win32项目 直接将控制台的mian函数改成 _ ...

  3. ios异常(crash)输出

    最近突然想起友盟的sdk附带的一个功能:将闪退异常情况上报服务器,(stackflow,github)找了一些资料,自己写了一个demo,想起来好久没有写过blog了,顺便分享. 其实不止是ios,a ...

  4. python笔记一

    好奇,想一探究竟.安装就出点小问题,win7,64位,一直卡在这里不动了? 只好取消.第二天安装仍是如此. 于是下载Windows6.1-KB2999226-x64.msu,安装,仍卡顿不动: 于是找 ...

  5. 用odbc连接oracle问题

    如果用11g的客户端,然后通过odbc(远程连接)连接10g的oracle,会出现监听程序无法启动(ORA-12541: TNS: 无监听程序) 此时需要在客户端目录中D:\instantclient ...

  6. NSString和NSMutableString的创建及其一些常用方法

    NSString和NSMutableString都是对象类型,是NSObject的子类.NSString是不可变字符串,NSMutableString是可变字符串 一.NSString的创建 1.创建 ...

  7. Python之路【第十五篇】:Web框架

    Python之路[第十五篇]:Web框架   Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 1 2 3 4 5 6 ...

  8. mysql的从头到脚优化之服务器参数的调优

    一. 说到mysql的调优,有许多的点可以让我们去做,因此梳理下,一些调优的策略,今天只是总结下服务器参数的调优  其实说到,参数的调优,我的理解就是无非两点: 如果是Innodb的数据库,innod ...

  9. MySQL大数据分页的优化思路和索引延迟关联

    之前上次在部门的分享会上,听了关于MySQL大数据的分页,即怎样使用limit offset,N来进行大数据的分页,现在做一个记录: 首先我们知道,limit offset,N的时候,MySQL的查询 ...

  10. 8.4 H5知识点总结

    HTML简介 HyperText Markup Language 简称为HTML HyperText: 超文本 (文本 + 图片 + 视频 + 音频 + 链接) Markup Language: 标记 ...