台州建网站公司,wordpress 用微信登陆,消防电气火灾监控系统网站开发,wordpress 插件 加速文章目录 加载域的结束地址并不是固件的结束地址#xff1f;ROM中执行域的描述RAM中执行域的描述问题分析 中断向量表在固件中的存储位置代码段在固件中的位置只读数据Regin$$Table RW Data段其中的内部机理 总结 MAP 文件分析可以参考之前的文章
程序代码在未运行时在存储器… 文章目录 加载域的结束地址并不是固件的结束地址ROM中执行域的描述RAM中执行域的描述问题分析 中断向量表在固件中的存储位置代码段在固件中的位置只读数据Regin$$Table RW Data段其中的内部机理 总结 MAP 文件分析可以参考之前的文章
程序代码在未运行时在存储器空间内称为加载域在运行时在存储器空间内称为运行域。
加载域的结束地址并不是固件的结束地址 在这里我们根据加载域的描述可以知道加载域的空间结束位置应该为0x080200000x000109780x08030978的位置。从下面的固件我们可以知道固件的实际结束位置应该是0x080305E8。这里的俩个位置并不一致是什么原因呢我们继续往下逐步分析。 ROM中执行域的描述 上图内容的最后一行结束地址为0x080304e00x200x08030500和第一行中的描述一致。 根据类型和属性可以知道这一部分的内容为代码段Code和只读数据段(RO Data) 起始的第一个段为只读数据段这个段的内容为中断向量表的数据。
这里我们根据上图计算下 代码段大小0x0802f754-0x08020188 0x000f5cc对应于十进制为62924 只读数据段大小0x08030500-0x0802f7540x1880xf34对应于十进制为3892 计算结果刚好和MAP文件中固件信息汇总处的结果一致
RAM中执行域的描述 根据类型和属性信息我们可以知道这一部分内容为RW Data和ZI Data 这里我们根据上图计算 RW Data大小0x478对应于十进制为1144 ZI Data0x49b00x2000-0x4780x6538对应于十进制为25912 Grand Totals - 显示映像文件的真实大小 ELF Image Totals - 可执行链接格式映像文件大小如果使用RW数据压缩来优化ROM大小则最终镜像的大小会发生变化 ROM Totals - 显示包含镜像所需的ROM的最小大小 上面的计算结果和真实映像文件的大小是对应的由于对RW数据进行了压缩导致实际的RW空间会比上面的计算值小。 知识点linker默认会将重复的RW数据压缩。
上图中最后一行0x200049b00x20000x200069b0刚好和栈顶地址一致
问题分析
至此我们基本知道了原因由于链接时会将重复的RW数据进行压缩所以实际的固件大小会小于加载数据的大小差值刚好为被压缩掉的RW数据空间的大小
中断向量表在固件中的存储位置
在MAP文件中我们可以知道 向量表的起始地址为0x08020000结束地址为0x08020188 对应于固件中的信息 首地址为栈顶地址 第二数据为复位函数的入口地址 后续内容依次为中断向量表中各个中断函数的入口地址。
代码段在固件中的位置
中断向量表的内容结束后便是代码段的内容 从MAP文件中可以看出0x08020188位置开始到0x0802f754位置结束存储的内容便为代码段的程序代码 如下图红框中的位置开始后续便为程序代码的数据 … 上图为代码段结束部分的位置
只读数据
代码段内容结束后紧跟着就是只读数据段 从下面的map文件可知0x0802f754到0x0803500之间存储的便是只读数据 这里我们去上图长框位置的CRC32Table的数据进行查看对应固件位置如下图所示 上图红框位置开始后续的数据和下面表中的数据是完全一致的。
Regin$$Table
之前的文章中有分析这个数据表往RAM空间加载数据依据的便是这个表提供的信息。
RW Data段
单纯从MAP文件看RW Data数据需要0x478字节的空间
在固件文件中从0x0803500一直到程序的结束存储的便是RW Data数据的内容共占0xE8字节的空间从上面的分析中可以知道实际生成固件中的RW Data是压缩过后的数据其中去掉了重复数据等程序运行时在RAM中再将数据展开这样有助于节省ROM空间。
其中的内部机理
对于没有赋初值或初始化为0的全局变量会等到程序运行时再在RAM中划分出一块区域并初始化为0这时你可能会纳闷程序代码中怎么知道变量在RAM中划分区域的位置呢答案是程序实际就是知道并且程序中每次需要访问变量的位置在程序代码中变量指向的空间就是RAM中对应的位置。你可能会感觉很神奇但结合之前的Regin$$Table分析你可能就会感到豁然了毕竟RAM中的空间分配早就在固件生成时都定义好了固件中也已经记录了这些信息。 那对于RW Data而言其实道理也是一样的只不过RW Data对应的数据是有初值的。这里我们只需将全部全局变量的值记录下来并去掉重复数据后存储到固件中在程序运行时在RAM中创建了对应的全局变量空间后将初值赋值给对应的变量即可。不过这好像还有个疑问运行时怎么知道将那个值赋值给哪个变量呢后续再继续探究下。
总结
固件各段在Flash中的存放顺序以及运行时加载到SRAM中的顺序如下