ARM映像文件组成

引言

        ARM编译器将各种源文件(汇编文件、C语言程序文件、C++语言程序文件)编译生成ELF格式的目标文件(后缀为.o文件,以下将目标文件简称为.o文件),.o文件经过连接器,和C/C++运行时库一起编译生成ELF格式的映像文件(image,如常用的MKD使用 fromelf.exe生成的bin文件就是image),bin文件可以直接写入到flash中,实际上使用jlink下载的内容就是bin文件的内容(hex文件是包含地址信息的bin文件,可以理解为hex=地址信息+bin)。下文中也将映像文件称为bin文件或者image文件。编译流程如下图。

图片来源于《Introductiontothe  Armv8-M  Architecture  and its ProgrammersModel》

相关文档在后面有链接

1、ARM映像文件的组成

1.1 ARM映像文件的组成

ARM映像文件是一个层次性的结构,有如下三部分组成:域(region)、输出段(output section)、输入段(input section),三者有如下的关系:

  • 一个bin文件由一个或多个域组成

  • 一个域包含一个或多个输出段

  • 一个输出段包含一个或多个输入段

  • 各输入段包含了目标文件中的代码和数据

        输入段可以理解为我们写的代码具体包含哪些属性。输入段包含4类:代码、已经初始化的数据、未初始化的存储区域、内容初始化为0的区域,即(code+RW)、ZI、ZI,分别为RO段、RW段、ZI段。编译器根据输入段的属性,将这些输入段分组,组成不同的输出段以及域。

        一个输出段里面包含了一些列具有相同RO、RW、ZI属性的输入段。输出段的属性于其中包含的输入段的属性相同,在一个输出段内部,各个输入段是按照一定的规律排序的。

        一个域包含1到3个输出段,其中各输出段的属性各不相同。各输出段的排列顺序是由其属性决定的,RO属性排在最前面,其次RW,最后ZI段。一个域通常映射到一个物理储存器上,如flash、ram等。

        抛开上面较书面的表达,我们已keil为例。在mdk中,域的定义由分散链接文件(sct)决定,随便打开一个keil的sct文件,可以看到:

在sct中,定义了三个域,名字分别为LR_IROM1、ER_IROM1、RW_IRAM1,LR_IROM1是最终的bin文件,ER_IROM1是加载域,RW_IRAM1是执行域。keil生成的bin中,一般包含三个段:RO段(代码+只读数据)、RW段、ZI段。一个域至少包含上述三个段中的一个。

        对于一个C文件来说,可能包含代码、全局变量、只读数据、为0的数据、未初始化的数据。在编译的时候,会自动将各个段进行分类,例如led.c文件,会将代码部分放到RO段里面,全局变量放到RW段,未初始化的变量存放到ZI段。

        以下进行一些猜测:如果说我们有led1.c和led2.c两个文件,二者分别生成RO、RW、ZI,则可以理解为:led1.c和led2.c是输入段1.1.1和1.1.2,他们生成的RO、RW、ZI为输出段1.1和1.2,最终合并在域1中(实际上我们知道,这个域存放的地方是M4芯片内部的flash)。

1.2 ARM映像文件各组成部分的地址映射

        bin文件在储存系统(如内部flash)中的地址有两种:一种是bin文件位于储存器中时的地址,称为加载地址。一种时bin文件运行时的地址,称为运行地址。之所以分成两类,是因为在bin文件中,有些域是可以移动到新的储存区域,比如RW域中的数据在运行的时候会搬运到RAM中。

        如下图所示为例,flash的起始地址为0x0800 0000,依次存放RO、RW、ZI段,在运行的时候,ZI和RW会搬运到SRAM中。

        一个bin文件一般包含若干个域,一个域包含若干个输出段。ARM链接器在链接时需要知道如下信息才能正确的生成bin文件:

  • 分组信息 决定如何将各输入段组织成相应的输出段和域

  • 定位信息 决定各域在储存空间中的起始地址

    根据bin文件中地址映射的复杂程度,可以使用命令行选项的方式提供或者提供配置文件(如keil的sct文件)

2、ARM映像文件的入口点

2.1 ARM映像文件中的两类入口点

        bin文件有两类入口点:一种是映像文件运行时的入口点,称为初始入口点(initial entry point),另一种时普通的入口点(entry point)。

        初始入口点时bin文件运行时的入口点,每个bin只有唯一的初始入口点,保存在ELF头文件中。如果bin是被操作系统加载的,则OS正是用过跳转到该初始入口点处执行来加载该映像文件。

        普通入口点是在汇编中用ENTRY来定义的,在嵌入式系统中一个典型的用途就是将中断服务程序定义为普通入口点,防止在链接的时候将中断服务程序给删除了。在C库中,__main是入口点。在sct中,可以看到:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x10000000 0x0000F000  {    ; load region size_regionER_IROM1 0x10000000 0x0000F000  {  ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO)}RW_IRAM1 0x1FFFC000 0x00003000  {  ; RW data.ANY (+RW +ZI)}
}

其中REST就是初始入口点属性,将初始入口点放到ROM中,在start.s中可以看到如下的汇编写法:

这个就是初始入口点定义的代码部分。

        在一个bin文件中,只有一个初始入口点,普通入口点可以由多个,初始入口点可以是普通入口点,也可以不是。

2.2 定义初始入口点

初始入口点需要满足如下两个条件:

  • 初始入口点必须位于bin文件的运行时域内

  • 包含初始入口点的运行时域不能被覆盖,它的加载地址和运行地址必须相同(这种域称为固定域,root region)

可以使用链接选项-entry address来指定bin的初始入口点,address表示初始入口点的地址。

        如果bin被一个加载器加载再运行,如被引导程序或者OS加载,则bin文件必须包含一个初始入口点。比如,一个操作系统的映像文件被一个引导程序加载,这时程序跳转到该映像文件的初始入口点处开始执行,它覆盖了引导程序,称为系统中的操作系统。这种映像文件中通常包含了其它的普通入口点,这些入口点一般为异常中断处理程序的入口地址。

        当用户没有指定链接选项-entry指定链接地址,则按照如下规则决定映像文件的初始入口点:

  • 如果输入的目标文件中只有一个普通入口点,该普通入口点被链接器当作bin文件的初始入口点

  • 如果输入的目标文件没有普通入口点或者普通入口点多余一个,则链接器生成的bin文件不包含初始入口点,且产生警告。

2.3 普通入口点的用法

普通入口点一般用作两种用途:

  • 指定中断服务程序的入口,防止链接的时候删除中断服务器程序代码

  • 没有指定链接选项-entry address且输入的目标文件中只有一个普通入口点,则该普通入口点被当作初始入口点

3、输入段的排列顺序

链接器根据各输入段的属性来组织这些输入段,具有相同属性的输入段被放到域中一段连续的地址空间中,组成一个输出段。在输出段中,各输入段的起始地址与输出段的起始地址和该输出段中各输入段的排列顺序有关。

通常情况下,输出段中各输入段的排列顺序由如下几个因素决定:

  • 输入段的属性

  • 输入段的名称

  • 各输入段在连接命令行的输入段列表中的排列顺序

按照输入段的属性,排列顺序如下:

  • 只读的代码段(RO-code)

  • 只读的数据段(RO-data)

  • 可读写的代码段(RW-code)

  • 其它以及初始化的数据段(RW-data)

  • 未初始化的数据(ZI)

        对于相同属性的输入段,按照名称顺序来排序,输入段的名称区分大小写,按照ASCII码顺序进行排序。如果输入段的名称也相同,按照其在输入段列表中的顺序进行排序。也就是说,即使各输入段的属性和名称保持不变,若在编译时,各个输入段在列表中的排列属性不同,生成的映像文件也将不同。

        可以使用连接选项-first、-last改变输入段的排列顺序,也可以使用配置文件改变输入段的排列顺序。排序规则影响因素有三个:输入段属性、输入段名称、输入段在列表中的顺序。连接选项-first、-last只对输入段的名称和在列表中的顺序有效,无法改变因输入段的属性进行的排序规则。

        在各个输入端排好序之后,在最终确定各个输入段的起始地址之前,可以通过填充“补丁”使各个输入段满足地址对齐要求。

4、题外话

        本篇文章是博主在学习ARM体系的时候写的笔记性质的文章,先在CSDN上分享,用到的参考文档有:

  • 《Introductiontothe  Armv8-M  Architecture  and its ProgrammersModel》
  • 《ARM体系结构与编程》

相关文档已经上传到博主的仓库里面,链接:https://gitee.com/zichuanning520/htq_library

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

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

相关文章

如何解决香港服务器使用的常见问题

​  站长们在选择香港服务器租用时会考虑到它的各种性能以及稳定性,这是必须的。但是使用过程中还有些问题也不容忽视,比如:带宽资源是否短缺,是否存在安全漏洞,连接是否正常等这些问题也要考虑到。 香港服务器使用中…

数据库备份与恢复(实战mysqldump+bin-log)

一、为什么要进行数据库备份? 常见数据库备份的应用场景如下: 数据丢失应用场景: 人为操作失误造成某些数据被误操作 软件 BUG 造成部分数据或全部数据丢失 硬件故障造成数据库部分数据或全部数据丢失 安全漏洞被入侵数据恶意破坏 非数据丢…

Leetcode—2331.计算布尔二叉树的值【简单】

2023每日刷题(六) Leetcode—2331.计算布尔二叉树的值 递归实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ bool evaluateTree(struct TreeNod…

2.1.C++项目:网络版五子棋对战之前置知识

文章目录 一、Websocketpp(一)Websocket介绍(二)报文格式(三)Websocketpp介绍(四)Websocketpp使用1.websocketpp常用接口介绍2. http/websocket服务器 (五)Js…

动画制作软件 Animate 2024 mac中文版介绍说明(an2024) v24.0

Animate 2024 mac是一款动画制作软件,它能帮助用户轻松制作出各种精美的动画作品。 Animate 2024拥有强大而直观的设计工作流程,能够让用户自由地构建动画场景、绘制精美的图形,并轻松添加动态效果。无论是传统手绘风格还是骨骼动画&#xff…

【Lua语法】字符串

Lua语言中的字符串是不可变值。不能像在C语言中那样直接改变某个字符串中的某个字符,但是可以通过创建一个新字符串的方式来达到修改的目的 print(add2(1 , 2 ,15,3))a "no one"b string.gsub(a , "no" , "on1111")print(a) print…

第87步 时间序列建模实战:LSTM回归建模

基于WIN10的64位系统演示 一、写在前面 这一期,我们介绍大名鼎鼎的LSTM回归。 同样,这里使用这个数据: 《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal…

Compose Desktop 使用中的几个问题(分平台加载资源、编写Gradle 任务下载平台资源、桌面特有组件、鼠标键盘事件)

前言 在我之前的文章 Compose For Desktop 实践:使用 Compose-jb 做一个时间水印助手 中,我们使用 Compose For Desktop 写了一个用于读取照片 EXIF 中的拍摄日期参数并以文字水印的方式添加到照片上的桌面程序。 但是事实上,这个程序的名字…

从入门到进阶 之 ElasticSearch SpringData 继承篇

🌹 以上分享 从入门到进阶 之 ElasticSearch SpringData 继承篇,如有问题请指教写。🌹🌹 如你对技术也感兴趣,欢迎交流。🌹🌹🌹 如有需要,请👍点赞&#x1f…

PHP数据加密传输和存储问题

PHP数据加密的类型 md5(),sha1(),crypt() 双md5加密加盐

AAPCS:最新的ARM子程序调用规则

AAPCS是arm公司发布的ARM架构应用程序二进制(ABI)程序调用接口,该文档由多个版本,博主第一次ARM程序调用规则是在《ARM体系与结构编程》,但书中描述的是ATPCS,AAPCS是ATPCS的升级版。后面去ARM官网看到了AA…

自然语言处理基础——词表示

词表示 把自然语言中最基本的语言单元——词转换为机器能够理解的 词表示能完成以下两个能力 词相似度计算 词与词之间语义的关系 近义词&上位词 使用近义词或上位词表示的问题 遗漏差异 遗漏新的释义 带有主观性 数据吸收 需要大量人工构建 One-Hot Representation …

Kafka学习(最新版3.6.0)

文章目录 一、初识MQ1.1 什么是MQ1.2 同步和异步通讯1.1.1 同步通讯1.1.2 异步通讯 1.3 技术对比1.4 MQ的两种模式 二、初识Kafka2.1 Kafka的使用场景2.2 Kafka基本概念2.3 Topic与Partition 三、Kafka基本使用3.1 部署前的准备3.2 启动kafka服务器3.3 Kafka核心概念之Topic3.4…

059:mapboxGL监听键盘事件,通过eastTo控制左右旋转

第059个 点击查看专栏目录 本示例是介绍演示如何在vue+mapbox中监听键盘事件,通过eastTo控制左右旋转。 本例通过easeTo方法来加减一定数值的bearing角度,通过.addEventListener的方法来监听键盘的按键动作。这里一定要设置interactive: false, 否则展现不出来旋转效果。 直…

机械设备经营小程序商城的作用是什么

由于机械设备厂商品牌需要各地招商代理,因此在管理方面也需要工具进行高效管理。如今各个行业都在开展数字化转型解决行业所遇难题或通过线上销售解决传统三公里难题及品牌扩张难题、用户消费渠道少等难题,构建会员体系精细化管理,同时还需要…

MySQL 主从复制原理

文章目录 1.主从复制方式1.1 异步复制1.2 半同步复制1.3 全同步复制 2.主从复制原理3.主从复制时推还是拉?参考文献 主从复制是 MySQL 高可用(备份)和高性能(读写分离)的基础,有了这个基础,MySQ…

【Ascend C算子开发(入门)】——Ascend C编程模式与范式

Ascend C编程模型与范式 1.并行计算架构抽象 Ascend C编程开发的算子是运行在AI Core上的,所以我们需要了解一下AI Core的结构。AI Core主要包括计算单元、存储单元、搬运单元。 计算单元包括了三种计算资源:Scalar计算单元(执行标量计算&…

外骨骼机器人和人形机器人概览

前言:一点思考 外骨骼机器人和人形机器人都曾随着一些爆品的出现火热过一段时间,但总感觉当前技术条件还不成熟,真正能落地的应用场景不多。马斯克在擎天柱发布会上被问到人形机器人的落地与前景问题时并没有给出明确答案,只是用…

c++ pcl点云变换骨架枝干添加树叶源码实例

程序示例精选 c pcl点云变换骨架枝干添加树叶源码实例 如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助! 前言 这篇博客针对《c pcl点云变换骨架枝干添加树叶源码实例》编写代码,代码整洁,…

自然语言处理---Tr ansformer机制详解之Transformer结构

1 Encoder模块 1.1 Encoder模块的结构和作用 经典的Transformer结构中的Encoder模块包含6个Encoder Block.每个Encoder Block包含一个多头自注意力层,和一个前馈全连接层. 1.2 Encoder Block 在Transformer架构中,6个一模一样的Encoder …