嵌入式软件开发之: 映像文件存储器映射调整
如果对输入段的排列顺序有特殊的要求,如特定的输入段必须是域中的第一个输入节,而包含校验和的输入段必须是最后一个输入段,可以使用FIRST和LAST标记执行区中的第一个和最后一个段。
FIRST或LAST伪属性必须放在属性列表的最后。
特殊的模块选择程序模式“.ANY”允许在不考虑其父模块的情况下,将输入段分配给执行域。使用一个或多个“.ANY”模式以任意分配方式填充执行域。在大多数情况下,使用单个“.ANY”相当于使用“*”模块选择属性。
在分散载入描述文件中不能使用两个“*”选择属性。但是,可以使用两个变形的选择程序,例如,*A和*B,也可以将.ANY选择属性与模块选择属性一起使用。*模块选择属性的优先级比.ANY高。如果删除了文件中包含*选择属性的部分,.ANY选择属性才能在链接时起作用。
在解析所有其他(非.ANY)输入段描述并且将输入段分配给最匹配的执行区之后,才解析使用.ANY模块选择程序模式的input_section_descriptions。如果有一个以上.ANY模式,则链接程序尽可能多地填充第一个.ANY,然后开始填充下一个.ANY。
每个未被分配的剩余输入段将被分配给具有以下特性的执行区:
· 最大的剩余空间(由max_size的值和已分配给该区的输入段的尺寸确定);
· 匹配.ANY的input_section_description;
· 与输入段的存储器属性相匹配的存储器访问属性(如果有);
· input_section_pattern。
13.4.3 Scatter文件典型用法
1.创建启动域
所谓启动域就是加载地址和执行地址相同的域。系统执行的初始入口点必须要在启动域中,否则链接器将报告以下错误。
Entry point (0x00000000) lies within non-root region ER_ROM
在Scatter文件中确定启动域可以使用下面两种方法。
① 使用ABSOLUTE设置执行区属性,并且对第一个执行区及其所在的加载区使用相同的地址。为确保执行域地址和加载域地址相同,可以将加载域的起始地址和执行域的起始地址设为相同的值或者将第一个执行域的地址偏移量设为0。
下面的例子,指定了一个启动域。
BOOT 0x0000 ;加载域的起始地址在0x0
{
EXER 0x0000 ;指定加载域和执行域的地址相同
{
* (+RO) ;必须将启动域包含在内
}
;其他执行域
}
② 使用FIXED执行域属性,确保指定域的载入地址和执行地址相同。
下面的例子显示了使用FIXED属性,将执行域的起始地址固定在ROM中。
BOOT 0x0000 ;加载域的起始地址在0x0
{
EXER 0x0000 ;指定加载域和执行域的地址相同
{
* (+RO) ;必须将启动域包含在内
}
EXER_INIT 0x8000 FIXED
{
init.o(+RO)
}
}
③ 如果使用分散加载,负责创建执行域的代码和数据不能将其自身复制到另一位置,因此启动域必须包含以下内容。
· _main.o和_scatter*.o:包含复制代码和数据的代码。
· Region$$Table和ZISection$$Table段:包含要复制代码和数据的地址。
· _dc*.o:执行代码压缩。
可以使用armlinker产生的InRoot$$Sections符号放置启动代码。因为这些代码被定义为只读属性,所有如果Scatter文件中包含了“* (+RO)”,则表示启动域中包含了这些代码。或者显式的使用InRoot$$Sections符号在Scatter文件中对以上代码进行配置。
下面的例子显示了如何在Scatter文件中使用InRoot$$Sections链接符号,放置启动域。
LOADREG 0x8000 ;
{
ROOT 0x8000
{
* (InRoot$$Sections) ;放置启动域
}
OTHER 0x100000
{
* (RO,+RW,+ZI)
}
;其他Scatter文件描述
}
存储器相关文章:存储器原理
评论