STM32 MAP文件结合固件文件分析

文章目录

    • 加载域的结束地址并不是固件的结束地址?
      • ROM中执行域的描述
      • RAM中执行域的描述
      • 问题分析
    • 中断向量表在固件中的存储位置
    • 代码段在固件中的位置
    • 只读数据
      • Regin$$Table
    • RW Data段
      • 其中的内部机理
    • 总结

MAP 文件分析可以参考之前的文章

程序代码在未运行时在存储器空间内称为加载域,在运行时在存储器空间内称为运行域。

加载域的结束地址并不是固件的结束地址?

在这里插入图片描述
在这里我们根据加载域的描述可以知道加载域的空间结束位置应该为0x08020000+0x00010978=0x08030978的位置。从下面的固件我们可以知道固件的实际结束位置应该是0x080305E8。这里的俩个位置并不一致是什么原因呢?我们继续往下逐步分析。

在这里插入图片描述

ROM中执行域的描述

在这里插入图片描述

上图内容的最后一行:结束地址为0x080304e0+0x20=0x08030500,和第一行中的描述一致。
根据类型和属性可以知道这一部分的内容为代码段(Code)只读数据段(RO Data)
起始的第一个段为只读数据段,这个段的内容为中断向量表的数据。

这里我们根据上图计算下:
代码段大小:0x0802f754-0x08020188= 0x000f5cc对应于十进制为62924
只读数据段大小:0x08030500-0x0802f754+0x188=0xf34对应于十进制为3892
在这里插入图片描述
计算结果刚好和MAP文件中固件信息汇总处的结果一致

RAM中执行域的描述

在这里插入图片描述
根据类型和属性信息我们可以知道这一部分内容为RW DataZI Data
这里我们根据上图计算:
RW Data大小:0x478对应于十进制为1144
ZI Data:0x49b0+0x2000-0x478=0x6538对应于十进制为25912
在这里插入图片描述
Grand Totals - 显示映像文件的真实大小
ELF Image Totals - 可执行链接格式映像文件大小(如果使用RW数据压缩来优化ROM大小,则最终镜像的大小会发生变化)
ROM Totals - 显示包含镜像所需的ROM的最小大小
上面的计算结果和真实映像文件的大小是对应的,由于对RW数据进行了压缩,导致实际的RW空间会比上面的计算值小。
知识点:linker默认会将重复的RW数据压缩。

上图中最后一行0x200049b0+0x2000=0x200069b0刚好和栈顶地址一致:
在这里插入图片描述

问题分析

至此我们基本知道了原因,由于链接时会将重复的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中的顺序如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/839874.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git学习和使用指南简单篇

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

element-ui手机区号+手机号

需求场景 项目开发中对方要求手机号带上全球区号 需求分析 项目使用的是若依前端框架,element-ui的框架。尝试使用已经网上的组件vue-country-intl等发现不怎么适配element-ui的样式等。这还不是关键的,关键的是弹窗中使用这些组件发现区号的下拉展示框…

C++,LeetCode算法题的字符串输入处理

文章目录 24. 算法24.1. 二叉树输入处理,包括建树、打印树、释放树。24.2. 单链表输入处理,包括建链(头插、尾插)、打印链、释放链。24.3. 一维矩阵输入处理。24.4. 二维矩阵输入处理。24.5. 调用函数输入处理。 24. 算法 24.1. …

一文了解基于ITIL的运维管理体系框架

本文来自腾讯蓝鲸智云社区用户:CanWay ITIL(Information Technology Infrastructure Library)是全球最广泛使用的 IT 服务管理方法,旨在帮助组织充分利用其技术基础设施和云服务来实现增长和转型。优化IT运维,作为企业…

Docker 容器间通讯

1、虚拟ip/访问 同一网络 安装docker时,docker会默认创建一个内部的桥接网络docker0,每创建一个容器分配一个虚拟网卡,容器之间(包括宿主机)可以根据分配的ip互相访问(ps:其他主机(包括其他主机的容器)无法ping通docker容器ip无法访问&#…

安卓手机APP开发__蓝牙功能概述

安卓手机APP开发__蓝牙功能概述 目录 概述 基本内容 关键的类和接口 概述 安卓平台支持了蓝牙网络栈,它允许一个设备和其它的蓝牙设备进行无线的交换数据。 APP的框架…

【qt】标准项模型

标准项模型 一.使用标准型项模型1.应用场景2.界面拖放3.创建模型4.配套模型5.视图设置模型6.视图属性的设置 二.从文件中拿到数据1.文件对话框获取文件名2.创建文件对象并初始化3.打开文件对象4.创建文本流并初始化5.读取文本流6.关闭文件7.完整代码 三.为模型添加数据1.自定义…

pytorch在docker里面使用GPU

本博客主要介绍如何在容器里面使用pytorch进行推理,训练,同时用上GPU。 1. 前置条件,安装好docker。 2. 安装nvidia-container-toolkit 参考官方文档: Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.…

mysql实战——半同步复制搭建

一、搭建前准备 主库 192.168.1.78 从库 192.168.1.76 二、搭建 1、先搭建异步复制 MySQL实战——主从异步复制搭建(一主一从)-CSDN博客 2、在异步的基础上搭建半同步复制 主库 mysql>install plugin rpl_semi_sync_slave soname semisy…

ctfshow web入门 其他 web396--web412

web396 <?php error_reporting(0); if(isset($_GET[url])){$url parse_url($_GET[url]);shell_exec(echo .$url[host].> .$url[path]);}else{highlight_file(__FILE__); } shell_exec(echo .$url[host].> .$url[path]); 这个是将url的host写入path,也就是说我们的pa…

el-table-column两种方法处理特殊字段,插槽和函数

问题&#xff1a;后端返回的字段为数字 解决办法&#xff1a; {{ row[item.prop] 1 ? "启用" : "禁用" }} {{ row[item.prop] }} 最终果&#xff1a; 另外&#xff1a;如果多种状态时可用函数 {{ getStatus(row[item.prop]) }} {{ row[item.prop…

IO游戏设计思路

1、TCP ,UDP ,KCP ,QUIC TCP 协议最常用的协议 UDP协议非常规的协议&#xff0c;因为需要在线广播&#xff0c;貌似运营商会有一些影响 KCP 基于UDP的协议&#xff0c;GitHub - l42111996/java-Kcp: 基于java的netty实现的可靠udp网络库(kcp算法)&#xff0c;包含fec实现&am…

WEB攻防【2】——ASPX/.NET项目/DLL反编译/未授权访问/配置调试报错

ASP&#xff1a;windowsiisaspaccess .net&#xff1a;windowsiisaspxsqlserver IIS上的安全问题也会影响到 WEB漏洞&#xff1a;本身源码上的问题 服务漏洞&#xff1a;1、中间件 2、数据库 3、第三方软件 #知识点: 1、.NET:配置调试-信息泄绵 2、.NET:源码反编译-DLL…

【openlayers系统学习】3.5colormap详解(颜色映射)

五、colormap详解&#xff08;颜色映射&#xff09; ​colormap​ 包是一个很好的实用程序库&#xff0c;用于创建颜色图。该库已作为项目的依赖项添加&#xff08;1.7美化&#xff08;设置style&#xff09;&#xff09;。要导入它&#xff0c;请编辑 main.js​ 以包含以下行…

Flutter 中的 CupertinoActivityIndicator 小部件:全面指南

Flutter 中的 CupertinoActivityIndicator 小部件&#xff1a;全面指南 在Flutter中&#xff0c;CupertinoActivityIndicator是用于iOS风格的应用程序中的一个活动指示器小部件。它提供了一个简单的、具有动画效果的旋转轮&#xff0c;用来向用户表示应用程序正在处理某些任务…

【Numpy】深入解析numpy.mat()函数

numpy.mat()&#xff1a;深入探索NumPy中的矩阵类 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393; 博主简…

Spring Cloud 系列之Gateway:(9)初识网关

传送门 Spring Cloud Alibaba系列之nacos&#xff1a;(1)安装 Spring Cloud Alibaba系列之nacos&#xff1a;(2)单机模式支持mysql Spring Cloud Alibaba系列之nacos&#xff1a;(3)服务注册发现 Spring Cloud 系列之OpenFeign&#xff1a;(4)集成OpenFeign Spring Cloud …

使用霍尔效应传感或磁场传感技术的应用

随着支持技术的增强&#xff0c;使用霍尔效应传感或磁场传感技术的应用目前已变得有效。本技术文档介绍了霍尔效应技术&#xff0c;并对应用进行了回顾&#xff0c;特别是区分霍尔传感器 IC 的主要类型以及它们可以支持的各种传感行为。此外&#xff0c;它还探讨了一些使能技术…

Spring Cache基本使用

Spring 从 3.1 版本开始定义缓存抽象来统一不同的缓存技术&#xff1b;在应用层面与后端存储之间&#xff0c;提供了一层抽象&#xff0c;这层抽象目的在于封装各种可插拔的后端存储( ehcache, redis, guava)&#xff0c;最小化因为缓存给现有业务代码带来的侵入。 一、Spring…

linux 内核安装、切换版本,禁用内核更新

安装内核 版本5.15.0-105 sudo apt-get install linux-image-5.15.0-105-generic sudo apt-get install linux-headers-5.15.0-105-generic切换内核版本 #查看已安装内核版本 grep menuentry /boot/grub/grub.cfg sudo dpkg --get-selections |grep linux-image#修改文件/etc…