加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Scatter文件编写

发布时间:2020-12-15 06:50:03 所属栏目:百科 来源:网络整理
导读:?一个映像文件中可以包含多个域(region),在加载和运行映像文件时,每个域可以有不同的地址。每个域可以包括多达3个输出段,每个输出段是由若干个具有相同属性的输入段组成。这样在生成映像文件时,ARM链接器就需要知道下述两个信息。 分组信息??? 决定各
?一个映像文件中可以包含多个域(region),在加载和运行映像文件时,每个域可以有不同的地址。每个域可以包括多达3个输出段,每个输出段是由若干个具有相同属性的输入段组成。这样在生成映像文件时,ARM链接器就需要知道下述两个信息。
  • 分组信息??? 决定各域中的输出段是由哪些输入段组织而成;
  • 定位信息??? 决定各域在存储空间中的起始地址。
??? 根据映像文件中地址映射的复杂程度,有两种方法来告诉ARM链接器这些相关的信息。对于映像文件中地址映射关系比较简单的情况,可以使用命令行选项;对于映像文件中地址映射关系比较复杂的情况,可以使用一个scatter配置文件。Scatter文件又称为分散加载文件,将重点讲解如何编写scatter文件。
1、Scatter文件结构
??? Scatter文件是一个文本文件,使用BNF语法来描述ARM链接器生成映像文件时所需要的信息。具体来说,在scatter文件中可以指定下列信息:
  • 各个加载时域的加载时起始地址、最大尺寸和属性;
  • 每个加载时域包含的输出段;
  • 各个输出段的运行时起始地址、最大尺寸、存储访问特性和属性;
  • 各个输出段中包含的输入段。
??? 一个Scatter文件包含若干个加载域,一个加载域包含若干个输出段,一个输出段由若干个具有相同属性的输入段组成,其结构如图1所示。
???????????????

?????????????? ??????????????????? 图1 Scatter文件结构示意图
??? ① 加载时域的描述
??? 加载时域包括名称、起始地址、属性、最大尺寸和一个运行时域的列表。使用BNF语法描述,加载时域的格式如下所示:

Load_name ???? base_designator??? ???? attribute ???? max_size
{
……
}

  • Load_name?? 运行时域名称,它除了唯一地标识一个运行时域外,还用来构成链接器生成的链接符号;
  • base_designator 用来表示本加载时域的起始地址,它可以有两种格式表示:起始地址或偏移量;?
  • attribute?? 本加载时域的属性,其可能的取值为下面之一,默认的取值为ABSOLUTE:
  • ??? PI ???????? 位置无关属性;
  • ??? RELOC ????? 重定位;
  • ??? ABSOLUTE ?? 绝对地址;?
  • max_size 最大尺寸,如果本加载时域的实际尺寸超过了该值,链接器将报告错误。默认的取值为0xFFFFFFFF。
??? ② 输出段的描述
??? 输出段包括名称、起始地址、属性、最大尺寸和一个输入段的集合。使用BNF语法描述,输出段的格式如下所示:

output_name ??? base_designator ??? attribute?? ??? max_size
{
……
}

  • output_name 输出段的名称,它用来唯一地标识一个输出段,还用来构成链接器生成的链接符号。
  • base_designator 用来表示本输出段的起始地址,它可以有两种格式:起始地址值或偏移量。
  • attribute?? 表示本输出段的属性,其可能的取值如下所示:
  • ????PI????????? 位置无关属性
  • ??? RELOC?????? 重定位
  • ??? ABSOLUTE??? 绝对地址
  • ??? FIXED?????? 固定地址
  • ??? UNINIT ???? 未初始化的数据
  • max_size??? 指定本输出段的最大尺寸。
??? ③ 输入段的描述
??? 输入段里描述了一个文本字符串的模式,匹配该模式的输入段都将被包含在当前域中。模式中可以使用匹配符,符号"*"代表零个或者多个字符,符号"?"代表单个字符。进行匹配时,所有字符是大小写无关的。
??? 下面介绍一些使用scatter文件配置映像文件地址映射模式的例子。在本例中,映像文件包括一个加载时域和3个连续的输出段,这种模式适合于那些将其他程序加载到RAM中的程序,如操作系统的引导程序和Angel等。
??? 例子??? 一个简单的scatter文件?

Load_1?? 0x4000???????????? ;定义加载时域的名称为Load_1,起始地址为0x4000
{
???????? ER_RO??? + 0???? ;输出段名ER_RO,地址偏移量0,所以起始地址为0x4000
???? ???? { *( + RO) }?????? ;通配符*,包含了所有的RO属性的输入段,它们被连续放置
???????? ER_RW??? + 0???? ;输出段名称ER_RW,起始地址为前一个输出段的结束地址加偏移量0
???? ???? { *( +? RW) }????? ;本输出段包含所有的RW属性的输入段,它们被连续放置
ER_ZI 0x5000?????? ;输出段名称ER_ZI,起始地址为0x5000
???? ???? { *( +? ZI) }????? ;本输出段包含了所有的ZI属性的输入段,它们被连续放置
}

??? 按照例 scatter文件的描述,ARM链接器会生成相应的映像文件地址映射关系,如图2所示。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />??????????????????

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
???????????????????????? 图2 程序运行时地址映射关系
?
2、固定时域
??? 任何一个映像文件都需要指定一个初始入口点(initial entry point),它是影响文件运行时的入口点。初始入口点必须位于一个固定域中,所谓固定域是指该域的加载时地址和运行时地址是相同的。如果初始入口点不是位于一个固定域中,ARM链接器在链接时会产生下面的错误信息。
??? L6203E:Entry point (0x0000 0000) lies within non-root region 32 bit RAM
??? 使用scatter文件时,可以有下面两种方法来设置固定域。
?
??? ① 设置输出段地址
??? 第1种方法是设定一个加载域中第1个输出段的运行地址,使其和该加载域的加载地址相同。这样该输出段就是一个固定域。
??? 例1就使用这种方法确定固定域。其中,加载域LR_1的起始地址为0x8000,输出段ER_RO的起始地址指定为0x8000,与加载域LR_1的起始地址相同,因此,输出段ER_RO是一个固定域,并且是映像文件的初始入口点。
??? 例1 指定固定域

LR_1 0x08000??????????????? ;加载域LR_1的起始地址为0x8000
{
???? ER_RO 0x08000????????? ;输出段ER_RO的起始地址为0x8000
???? {
*( +? RO)????????? ;包含了所有的RO数据,包含初始入口点
???? }
???? ;其他部分内容
}

??? ② 设置输出段属性
??? 第2种方法通过将某个输出段的属性设置成FIXED。
??? 例2指定固定域

LR_1 0x8000???????????????? ;加载时域LR_1的起始地址为0x8000
{
???? ER_RO??? 0x8000
???? {
???????? *( +? RO)????????? ;除了init.o之外的其他RO数据
???? }
???? ER_INIT 0x9000 FIXED?? ;设置输出段属性为FIXED,确定固定域
???? {
???? init.o( +? RO)???????? ;本输出段包含了init.o,包含映像文件的初始入口点
???? }
???? ;其他部分内容
}

?
3、一个实际系统的例子
??? 在一个嵌入式设备中,为了保持好的性价比,通常在系统中存在多种存储器。在一个实际的ARM开发板中,可能包括片内Flash、RAM和片外Flash、RAM。在本例中,我们假设用ARM芯片构造了一个嵌入式系统,包含了8KB片内Flash存储器、16KB片内RAM存储器、起始地址为0x80000000的片外Flash和起始地址为0x81000000的片外RAM,其地址空间分配关系如图3所示。
??? 在这样的ARM系统中,我们编写了程序,并且按照例3中的分散加载文件对映象文件的地址进行分配。分配后的地址映像关系如图4所示。
??? ??

?

???????? 图3 ARM系统中的地址空间??????? ??????????????? ?图4 地址映像关系
??? 从图4中可以看出:可执行代码都放在片外Flash中,并且Vectors向量表放在片外Flash的起始地址上;Startup目标文件的数据放置在片内RAM中,堆栈放在片内RAM的顶端;其他数据放置在片外RAM中,堆空间紧跟其后。
??? 例3 片外Flash启动程序的scatter文件

ROM_LOAD ?0x80000000???????????????? ;定义加载区名称ROM_LOAD,起始地址0x80000000
{
?? ? ROM_EXE? 0x80000000????????????? ;定义执行代码空间,起始地址与加载域地址相同
??? {
??????? Startup.o (vectors,? +First)???? ;首先放置Startup.o文件的向量表vectors
??????? * ( +RO)?????????????? ;后面地址空间放置其他RO属性代码
}?
?
???? IRAM ?0x40000000???????????????????? ;定义数据空间
??? {?? Startup.o ( +RW,+ZI) ? }
?
STACKS? 0x40004000? UNINIT?????????? ;定义堆栈空间
??? {??? stack.o ( +ZI)??? }
?
??? ERAM? 0x81000000???????????????????? ;定义数据空间
??? {?? * ( +RW,+ZI)????? }???????????? ;剩下未指定空间的所有数据
???
??? HEAP + 0? UNINIT???????????????????? ;定义堆空间
??? {???? heap.o ( +ZI)??? }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读