ARM启动中的分散加载

2023-11-01 5浏览
百检网是一家专业的第三方检测平台,汇聚众多拥有权威资质的第三方检测机构为你提供一站式的检测服务,做检测就上百检网。百检网让检测从此检测,一份报告全国通用,专业值得信赖。
分散加载作用:

可以将代码放入不同的存储空间。

5个G的计算机,电子专业书籍分享。

链接:https://pan.baidu.com/s/1y8BnUlGmiJMujLlTyrhznA

提取码:j9na

1.基本概念

了解分散加载文件之前,**需要了解Code、RO-Data、RW-Data、ZI-Data。

Code:程序代码

RO-Data:程序中定义的常量以及const型数据

RW-Data:已经初始化的静态变量,变量有初始值

ZI-Data:没有初始化的静态变量,变量没有初始值

#define num 10 /*RO-Data*/

char const flage = 5; /*RO-Data*/

char str[] = "str"; /*RW-Data*/

char a; /*ZI-Data*/

下图为keil的map文件

ROM(Flash)Size = Code + RO-Data + RW-DataRAM Size = ZI-Data + RW-DataRW-Data既占ROM,又占RAM原因:(RW-Data与ZI-Data存储不同原因)ZI段数据:程序只需要根据编译器分配给ZI段的基地址以及大小,将对应的RAM全部初始化为0即可。RW段数据:**编译器需要将RW段数据的所有初始值保存在ROM中,程序在执行时,再将ROM中保存的数据搬到RAM中。因此,RW段数据两者都占用空间,并且大小相同。ZI段与RW段数据初始化

在执行main()函数之前,程序会执行__main()函数。该函数只要包括_main()与_rt_entry()函数

_main():完成代码与数据的拷贝,将ZI段数据清零。

将代码拷贝到映射的空间运行。比如:将代码拷贝到RAM中运行

数据拷贝:完成ZI段数据清零与RW段数据赋值

_rt_entry():将堆、栈等初始化。之后该函数会跳转到main()函数

2.分散加载文件介绍

该文件用来描述链接器生成映像文件时需要的信息。该可以指定生成映像文件时Code、RO-Data、RW-DATA、ZI-DATA数据的存放地址。

2.1分散加载文件语法

分散加载文件由一个加载时域与多个运行时域构成。基本结构如下图:

2.1.1加载时域语法:

load_region_name(base_address|("+"offset))[attribute_list][max_size] {

execution_region_description+

}

load_region_name:该加载时域的名字

base_address:该加载时域的起始地址。有两种书写方式:base_address:表示该加载时域中的对象在连接时的起始地址,地址必须字节对齐+offset:表示本加载时域的中的对象在连接时的起始地址是前一个加载时域的结束地址后偏移offset字节处。若该加载时域为**个加载时域,则其起始地址为offset。offset数值必须能够被4整除。

attribute_list:指定该加载时域内容的属性。一般为ABSOLUTE。ABSOLUTE:**地址;PI:与位置无关;RELOC:可重定位;OVERLAY:覆盖;NOCOMPRESS:不能压缩;

max_size:该加载时域的*大尺寸。若该加载时域的实际尺寸超出了max_size,连接器将会报错。

execution_region_description:运行时域。+表示可以有一个或多个运行时域。

2.1.2运行时域语法:

exec_region_name(base_address|"+"offset)[attribute_list][max_size|" "length]) {

input_section_description*

}

exec_region_name:该运行时域的名字

base_address:同加载时域

attribute_list:指本运行时域的内容属性ABSOLUTE:**地址;PI:与位置无关;RELOC:可重定位;OVERLAY:覆盖;FIXED:固定地址。ALIGNalignment:将执行区的对齐约束从4增加到alignment。alignment的值必须为2的正数幂。若执行区有base_address,则它需要与alignment对齐。若执行区有offset,则链接器将计算的区基址与alignment边界对齐。EMPTY:将执行区中保留一个给定长度的空白内存块,一般提供给堆或栈使用。ZEROPAD:零初始化的段作为零填充块写入ELF文件。因此,运行时不需要使用零进行填充。PADVALUE:定义任何填充的值。NOCOMPRESS:不能进行压缩。UNINIT:未初始化的数据。

max_size:同加载时域。

length:若指定的长度为负值,则将base_address作为区的结束地址。通常与EMPTY一起使用,用来表示内存中变小的堆栈。

input_section_description:指定输入段的内容。

2.1.3输入段描述:

module_select_pattern [ "(" input_section_selector ( "," input_section_selector )* ")" ]

("+" input_section_attr | input_section_pattern | input_symbol_pattern)

module_select_pattern :文件过滤器。支持使用通配符"*“与”?"。字符匹配时,不区分大小写。

   *:表示零个或多个字符。   ?:表示单个字符。

input_section_attr :属性选择器与输入段属性相匹配。每个input_section_attr前都会有+号。紧靠+号前的逗号都可以省略。若要指定一个模式以匹配输入段名称,则名称前面需要有+号。选择器不区分大小写。可以识别以下选择器。RO-CODE(CODE)RO-DATA(CONST)RO,包含RO-DATA与RO-CODE(TEXT)RW-CODERW-DATARW,包含RW-DATA与RW-CODE(DATA)ZI(BSS)ENTRY,包含ENTRY之外的段。通过使用特殊模块选择器模式.ANY可以将输入段分配给执行区,而无需考虑其父模块。可以使用一个或多个.ANY模式以任意分配方式填充运行时域。在大多数情况下,使用单个.ANY等效于使用*模块选择器。


百检网秉承“客户至上,服务为先,精诚合作,以人为本”的经营理念,始终站在用户的角度解决问题,为客户提供“一站购物式”的新奇检测体验,打开网站,像挑选商品一样简单,方便。打破行业信息壁垒,建构消费和检测机构之间高效的沟通平台