历史上的今天
今天是:2026年03月20日(星期五)
2023年03月20日 | ARM启动中的分散加载
2023-03-20 来源:zhihu
分散加载作用:
可以将代码放入不同的存储空间。
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-Data
RAM Size = ZI-Data + RW-Data
RW-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-CODE
RW-DATA
RW,包含RW-DATA与 RW-CODE(DATA)
ZI(BSS)
ENTRY,包含ENTRY之外的段。
通过使用特殊模块选择器模式.ANY可以将输入段分配给执行区,而无需考虑其父模块。可以使用一个或多个.ANY模式以任意分配方式填充运行时域。在大多数情况下,使用单个.ANY等效于使用*模块选择器。
下一篇:NXP单片机怎样选型方法
史海拾趣
|
本帖最后由 paulhyde 于 2014-9-15 09:00 编辑 http://v.youku.com/v_show/id_XMTA3NTQ3Njky.html … 查看全部问答> |
|
刚好身边有两个号码需要充值,一个联通,一个移动。 直接登录联通网站,输入号码后,就可以直接充值,基本操作需要(算上仔细检查的时间)5分钟吧! 登录移动网站,也许是移动业务太多的缘故,一下子迷失在里面,经过几番周折,进了充值页面,跳 ...… 查看全部问答> |
|
在用户手册上没有针对User Leds的一些定义, 只有一个LED的ADS工程,但是编译好以后将bin下载到板子上运行,User Leds似乎没反应,所以我判断工程有问题. 现在想自己编写代码操作User Leds,大家是怎么做的?… 查看全部问答> |
|
*((volatile unsigned *)i)=0xEA000000+0x1FFE; *((volatile unsigned *)i)=0xEA000000+0x1FFE; 上面的这段代码一直看不懂是什么意思: 在启动文件里面,将中断的地址映射到了_ISR_STARTADDRESS为起始地址处。 在C语言的主程序里面也是将中断服务程序定义到了_ISR_STARTADDRESS处。如 #define ...… 查看全部问答> |
|
我想问问大家,我用jtag烧录好bootloader后,然后串口更新应用程序,但是应用程序就是不能运行,全部用的是例程里面的程序,也不知道为什么就不是不运行。应用程序起始地址为0x00001000,网上说bl.sct 这个文件也要配置,这个我不知道,我没改过, ...… 查看全部问答> |
|
详细可联系 QQ:348075293 手机:13732189922 [local]1[/local]参考价550(包含仿真器、串口转接、串口扩展,如不需这些配件,价格可议)… 查看全部问答> |
|
新年的假期结束了,大家开始回到工作岗位或者回到学校,又要回到往常的忙碌的工作和生活中了。在春节期间,咱们都忙着吃吃喝喝玩玩,现在得振作起来了,打到节后综合症。我们版块也要活跃起来,新年新气象,咱们一起来学习430,开展新一轮的活动, ...… 查看全部问答> |




