Andes 的分散聚合(SAG)机制

Facebook
Twitter
LinkedIn

在嵌入式系统设计中,通常使用不同的存储器,如 Flash、SRAM、SDRAM,并位于不同的物理地址空间,怎样更好地利用这些不同的存储器并让系统高效地运行呢?通常这需要复杂的 link script 来管理实现,而 Andes 提供了分散聚合 (SAG, Scattering-And-Gathering)机制,SAG 机制能够将加载和运行时存储器中的代码和数据描述在一个 SAG 格式的文本描述文件中,并通过 link generator tool 将SAG 文件转化为标准GNU 的link script 文件,以供链接时使用。采用Andes的分散聚合机制,不仅可以帮助工程师清晰的描述存储器的使用情况,更可以避免使用复杂的标准 linker 脚本语言 。本文详细介绍了 SAG 语法格式,并以实际工程为例,阐述 SAG 的使用方法和益处。

1. Andes ELF 的目标文件的构成
Andes 使用标准的 GNU link script 格式,Andes 的目标文件也遵行标准的
ELF(Executable and Linking Format)格式。
ELF 目标文件主要由 .text 段 .data 段 .bss 段,还有一些其它的段如:.debug .comment 段。

下面以一个简单的 link script 的例子作为说明:
  SECTIONS 是 link script 语法中的关键 command,它用来描述输出文件的内存布局。例如上例中就含.text, .data, .bss 三个部分。
  .=0x10000; 其中的.是 location counter(LC)。表示.text 段虚拟地址从
0x10000 开始的。
  AT 用来说明加载地址,AT(0)表示.text 段的加载地址是 0。{ *(.text) },这个表示输出文件的.text 段内容由所有输入文件()的.text 段组成。后面的一个. = 0x40000。如果没有这个赋值,那么 LC 应该等于 0x10000+sizeof(text 段),这里强制指定 LC=0x40000.表明后面的.data 段的虚拟地址从 0x40000 开始。
  LOADADDR 用来得到加载地址,此处.data 段的加载地址是 AT(LOADADDR (.text) + SIZEOF (.text)),它紧接着.text 段,.data 为所有输入目标文件的.data段构成。同理,.bss 段的虚拟地址是紧接着.data 段虚拟地址之后,而加载地址是紧接着.data 段加载地址之后的。.bss 段由所有输入目标文件的.bss 段组成。通常在实际使用中的link script 会更加的复杂,SAG 机制能够很好的简化link
script 的设计,那接下来将对 SAG 机制作介绍。

2. Andes SAG 语法
SAG 使用巴科斯范式(BNF notation)中的以下几种符号表示:

SAG 格式总览
SAG 语法格式由:load regions,execution regions,input sections 等几部分组成,如下图所示:

2.1 关于 LMA 和 VMA
一般在嵌入式系统中,程序存储和运行在不同的地址空间,LMA 表示的是程序装载地址,VMA 表示的是程序运行地址,LMA 不等于 VMA 时程序在加载后不可直接运行,程序运行前,要把程序的内容,拷贝到对应的内存地址处,才能正确地运行。

2.2 header 格式
当要使用用户自定义的 section 时,须要使用 USER_SECTIONS 这个关键字。

2.3 Load Region(加载区)
Load Region 格式为:
load_region_name 用来表示某个程序加载区的名称。
address 表示的是 LMA。
offset 表示的是偏移量,当此时是第一个 load region 时表示的是与 0 地址的偏移量,当表示的不是第一个 load region 时,表示的是与前一个 load region结尾处的偏移量。
load_attr 表示属性,现在可以设置为 ALIGN alignment, 如 ALIGN 0x4 max_size 表示该加载区域的最大值。
例子:
LOAD_ROM_1 0x0000 ALIGN 0x4 0x10000
在这个例子中 load_region_name 是:LOAD_ROM_1,LMA 是 0x0000,以 4-byte 对齐,
max_size 是 64k

2.4 Execution Region(执行区)
Execution Region 格式为:
exe_region_name 用于表示某个程序执行区的名称
address 表示的是 VMA。
offset 当表示的是第一个 execution region,表示的是与该加载区的偏移量,当表示的不是第一 execution region 时,offset 表示的是前一个 execution region结尾处的偏移量。
exe_attr 表示属性,如可以设置为 ALIGN alignment,如 ALIGN 0x4 max_size 表示该 execution region 的最大值。
例子:
EXEC_ROM_1 0x0000 ALIGN 0x4 0x8000
在这个例子中exe_region_name 是 EXEC_ROM_1,它的 VMA 是 0x0000, 以
4-byte 对齐,max_size 是 32k

2.5 Input Section(输入段)
Input Section 的描述格式为:
此处:
module_select_pattern 可以是目标文件名
input_attr 可以是KEEP,该属性可以保证该 section 在链接时不会被remove
掉,或者是 SORT,用于排序。例子如:
program1.o KEEP(+RO)
此时该 input section 将包含目标文件 program1.o 中所有的 read-only section,由于加了 KEEP,所以所添加的 section 在链接的时候不会被 gc-section删除掉。
input_section_selector 中最常用的是 input section_attr。 input section_attr 有以下几种:

input_section_selector 中另外一种用的是 input_section_pattern,它的表示方法是 input_section_pattern ::= (.text | .data|…)。

ADDR variable 用于得到该处的 VMA 赋给 variable。 LOADADDR variable 用于得到该处的 LMA 赋给 variable。 STACK “=” num 为 sp 准备一个初始值 num。
VAR 用于设定并初始化一个变量。如 VAR _ILM_BASE = 0x00600000。

2.6 Execution Overlay Region(overlay 的执行区)
当使用 overlay 功能时,需要设定 Execution Overlay Region,设定格式为:
它在后面加了个:OVERLAY 的关键字。
pagesize 后面表示 Overlay 的大小,当是 0 时,表示 software Overlay,其它的设置和前面的 execution region 相同。

2.7 Overlay Input Section(overlay 的输入段)
当使用 overlay 功能时,要设置 Overlay Input Section,它和前面的 Input Section 类似。

3. 例子
如下例子所示的效果是:
在一个系统中,从 0x0000 开始,大小为 0x2000 的是 ROM1, 从 0x4000
开始,大小为 0x8000 的是 ROM2,此时我们需要将目标文件 program1.o 的 RO和 RW,ZI data。 存放在 ROM1 中,将其它目标文件的 .text,RO,RW, ZI 存放在 ROM2 中。此时的 LMA 效果对应于下图的左侧。
同时需要将目标文件program1.o 中的RW, ZI 的运行地址设置在从0x10000开始的大小为 0x8000 的 DRAM 上,将其它目标文件的 RW,ZI 的运行地址设置在从 0x18000 开始,大小为 0x8000 的SRAM 上。此时的 VMA 效果对应于下图的右侧。

该例子中 program1.o 中的 RO 和其它目标文件中的.text, RO 的 LMA 和 VMA 是相等的,此时所有的 RW,ZI 的加载区域是分别在 ROM1 和 ROM2 上,但是运行地址是分别在 DRAM 和 SRAM 上,所以 RW,ZI 的 LMA 不等于 VMA,所以在程序使用到 RW, ZI 所代表的.data,.bss 段之前需要将它们从加载区复制到运行区,以达到所图中右侧所示的效果。

对应的 SAG 可以这样设计:
利用 SAG 机制,除了快速设计上列所示的系统中存储的分配机制,还可以快速的进行 overlay 程序的设计,overlay 程序主要是用于分时重复利用快速但存储空间有限的存储器。

4.将 SAG 文件转化成 linker script
在 AndeSight 或者 BSP package 中提供了叫做 nds_ldsag 的工具,该工具可以将 SAG 文件转化成标准的 GUN link script 文件。在 cygwin 下,执行方法如下,filename.ld 就是我们希望获得的link script 文件。
./nds_ldsag.exe filename.sag -o filename.ld

5.结语
Andes 提供的通俗、易用的 SAG 描述语言,可以帮助工程师根据系统中的存储设备的特点,对程序的加载与运行区域进行很方便的设计和描述,甚至可以快速的进行更为复杂的 overlay 程序的设计,然后通过自动化工具 nds_ldsag 将 SAG 描述文件转成标准 link 脚本供连接器使用,从而大大提高在 Andes core 平台上的软件开发效率。

参考文档:
1: BSP321 programming guide link generator
2: The GNU Linker Manual