Map文件内容分为以下五段:
1)Section Cross References:模块、段(入口)交叉引用;(ASR编译生成的map文件没有输出该段信息)
2)Removing Unused input sections from the image:移除未使用的模块;
3)Image Symbol Table:映射符号表;
4)Memory Map of the image:内存(映射)分布;
5)Image component sizes:存储组成大小。
一些相关概念:
段(section) :描述映像文件的代码和数据块。
RO:Read-Only的缩写,包括RO-data(只读数据)和RO-code(代码)。
RW:Read-Write的缩写,主要是RW-data,RW-data由程序初始化初始值。
ZI:Zero-initialized的缩写,主要是ZI-data,由编译器初始化为0。
.text:与RO-code同义。
.constdata:与RO-data同义。
.bss: 与ZI-data同义。
.data:与RW-data同义
2.1Section Cross References
这里以stm32工程生成的map文件为例,如下图:
main模块(main.o) 中的main函数调用了sys.o里的Stm32_Clock_Init函数。从该段可以查阅各.o的关联。
2.2 Removing Unused input sections from the image
这里以3602项目的map文件为例:
从上面的信息可以得知总共有20797段未被调用,未被调用的大小为1104506(1M左右)字节。
2.3 Image Symbol Table
映射符号表,指明各个段所存储对应地址的表,分为两类Symbol,Local Symbols和Global Symbols。
Local Symbols:用static声明的全局变量,C文件中用static声明的函数,汇编文件中的标号地址(作用域限本文件)
Global Symbols:全局变量,C文件中函数,汇编文件中的标号地址(作用域全工程)
字段内容组成如下:
1)Symbol Name:符号名称
2)Value:存储对应的地址;
在stm32上会看到有0x0800xxxx、0x2000xxxx这样的地址。
0x0800xxxx指存储在FLASH里面的代码、变量等。
0x2000xxxx指存储在内存RAM中的变量Data等。
在ASR项目上FLASH和RAM的基地址的定义为
QSPI_BASE_ADDR 0x80040000
PSRAM_BASE_ADDR 0x7E000000
3)Ov Type:符号对应的类型
符号类型大概有几种:Number、Section、Thumb Code、Data等;
4)Size:存储大小
5)Object(Section):段目标
这里一般指所在模块(所在源文件)。
以3602项目的map文件为例:
2.4 Memory Map of the image
内存映射分布
以3602项目的map文件为例:
Image Entry point : 0x8001a000:指映射入口地址。程序执行的入口点。
Load Region DDR_RO (Base: 0x8001a000, Size: 0x00ec9bf8, Max: 0x02000000, ABSOLUTE):
指加载区域位于DDR_RO开始地址0x8001a000,大小有0x00ec9bf8,这块区域最大为0x02000000.
这里以STM32单片机为例加载域就是程序在Flash中的实际存储,而运行域是芯片上电后的运行状态,因为MCU没上电时RAM中没有数据,所以此时所有的东西(包括代码、变量、初始值等)都是存放在flash中的,当上电后又要把变量等复制到RAM中才能正常运行。
通过上面的框图可以看出,RW区也是要存储到ROM/Flash里面的。在执行映像之前,必须将已初始化的RW数据从ROM中复制到RAM中的执行地址并创建ZI Section(初始值为0的变量区),这样才算完成了MCU运行的准备。
2.5 Image component sizes
存储组成大小,主要就是对模块进行汇总存储大小信息。
以3602项目的map文件为例:
Code (inc. Data) :显示代码占用了多少字节。 在此映像中,有8477372字节的代码, 其中包括1034396字节的内联数据 (inc. data),包含文字常量池和短字符串,一般被忽略。按照理解这一部分应该是属于一些临时生成的碎片内容。
RO Data :只读段 一般常量const、“字符串”等;和代码段一样是存储在flash中;不加载到ram。
RW Data :已初始化的全局变量;这个是我们程序运行是要搬运到ram的段,且在程序开始执行时就进行rw段的搬运工作ZI Data :显示零初始化的数据占用了多少字节。
ZI Data :zi-data段是没有初始化,,不占flash存储,只需要在ram中开辟出空间,包含堆栈内容,局部变量是在栈中。
Debug :显示调试数据占用了多少字节,例如,调试输入节以及符号和字符串。
Grand Totals :显示映像的真实大小。
ELF Image Totals :ELF(Executable and Linking Format)可执行链接格式映像文件大小。
ROM Totals:显示包含映像所需的 ROM的最小大小。这不包括 ZI数据和存储在ROM 中的调试信息。
由上可知Total ROM Size (Code + RO Data + RW Data)也就是ROM flash 的大小。为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,Total RAM Size(RW Data + ZI Data)。