ARM启动中的分散加载

发布时间:2023-03-20  

分散加载作用:

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

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等效于使用*模块选择器。

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>