一、基本概念
什么是arm的映像文件,arm映像文件其实就是可执行文件,包括bin或hex两种格式,可以直接烧到rom里执行。映像文件一般由域组成,域最多由三
个输出段组成(RO,RW,ZI)组成,输出段又由输入段组成。在scatterfile中可以为每一个代码或数据区在装载和执行时指定不同的存储区域地
址,所谓域,指的就是整个bin映像文件所处在的区域,Scatlerloading的存储区块可以分成二种类型:装载域:当系统启动或加载时应用程序的
存放区。执行域:系统启动后,应用程序进行执行和数据访问的存储器区域,系统在实时运行时可以有一个或多个执行块。映像中所有的代码和数据都有一个装载地
址和运行地址(二者可能相同也可能不同,视具体情况而定)。在系统启动时,C函数库中的__main初始化代码会执行必要的复制及清零操作,使应用程序的
相应代码和数据段从装载状态转入执行状态。
我们输入的代码,一般有代码部分和数据部分,这就是所谓的输入段,经过编译后就变成了bin文件中ro段和rw段,还有所谓的zi段,这就是输出段。对于
加载域中的输出段,一般来说ro段后面紧跟着rw段,rw段后面紧跟着zi段。在运行域中这些输出段并不连续,但rw和zi一定是连着的。zi段和rw段
中的数据其实可以是rw属性。
二、基本语法
1.scatter文件语法
scatter文件是一个简单的文本文件,包含一些简单的语法。
ROM 0x0800_0000 0x00e0_0000 ;定义加载域
{
ROM 0x0800_0000 0x0040_0000 ;定义执行域,执行域首地址=加载域首地址
{
bootarm.obj (C$$code,+First)
*.obj (LEADING_PART,+First)
*plutommi.lib (+RO-CODE)
*lcmmi.lib (+RO-CODE)
*l4_classb.lib (+RO-CODE)
*mtkapp.lib (+RO-CODE)
*l1_classb.lib (+RO-CODE)
*email.lib (+RO-CODE)
*l4misc.lib (+RO-CODE)
...........
...........
}
................
...............
ROM3 +0x0 0x00400000
{
.ANY (+RO-CODE)
}
ROM4 +0x0 0x00400000
{
ANY (+RO-CODE)
}
ROM5 +0x0
{
ANY (+RO-DATA)
}
................
................
}
每个块由一个头标题开始定义,头中至少包含块的名字和起始地址,另外还有最大长度和其他一些属性选项。块定义的内容包括在紧接的一对花括号内,依赖于具体
的系统情况。一个加载块必须至少含有一个执行块;实践中通常有多个执行块。一个执行块必须至少含有一个代码或数据段;这些通常来自源文件或库函数等的目标
文件;通配符号*可以匹配指定属性项中所有没有在文件中定义的余下部分。注释部分使用分号作为开头,到当前行的行尾为止。
三、系统分析
一般而言,一个程序包括只读的代码段和可读写的数据段。在ARM的集成开发环境中,只读的代码段和常量被称作RO段(ReadOnly);可读写的全局变
量和静态变量被称作RW段(ReadWrite);RW段中要被初始化为零的变量被称为ZI段(ZeroInit)。对于嵌入式系统而言,程序映象都是存
储在Flash存储器等一些非易失性器件中的,而在运行时,程序中的RW段必须重新装载到可读写的RAM中。这就涉及到程序的加载时域和运行时域。简单来
说,程序的加载时域就是指程序烧入Flash中的状态,运行时域是指程序执行时的状态。对于比较简单的情况,可以在ADS集成开发环境的ARM
LINKER选项中指定RO BASE和RW
BASE,告知连接器RO和RW的连接基地址。对于复杂情况,如RO段被分成几部分并映射到存储空间的多个地方时,需要创建Scatterfile文本文
件,通知连接器把程序的某一部分连接在存储器的某个地址空间。需要指出的是,Scatterfile中的定义要按照系统重定向后的存储器分布情况进行。在
引导程序完成初始化的任务后,应该把主程序转移到RAM中去运行,以加快系统的运行速度。
下面我们来解析附件中的Scatterfile.
首先,6223平台的项目使用的是NORFlashROM(16M)+SDRAM(4M)+InternalRAM(48K),装载域全部在
FlashROM中,也就是整个bin的大小,最大不超过12M。而执行域则分散在FlashROM,SDRAM和InternalRAM中,其中
FlashROM中的第一个执行域是从地址0x08000000开始,最大为0x00400000,也就是4M,其中包括了bootarm.obj
(C$$code,+First)等目标文件,第二个执行域为从第一个执行域的末尾开始,最大为0x00400000,也是4M,而第三四五个执行域为剩
余的所有NORFlash空间,在FlashROM,SDRAM和InternalRAM中没有指定执行域的代码段在此处运行。而外部RAM,也就是
SDRAM中的执行域是从地址0x00008000开始到0x00400000的部分,共4M,包括了我们增加的第三方软件在内的部分读写数据段,堆栈和
将要被初始化为零的变量(也就是ZI段)。内部RAM,也就是InternalRAM则从地址0x40000000开始,最大为0xC000,也就是
48K,里面运行的是我们的3GP模块需要维护的一些数据段和一些bootloader等数据段。
当前项目软件运行时会感觉比以前项目软件运行速度要慢一些,此处不排除我们使用了GIF格式的动画代替BMP格式的图片带来的解析图片的时间变长,但可以
肯定的是,我们将3GP功能的一些数据段放到内部RAM中运行,肯定会减少系统空闲内存的使用,使系统需要更多地使用外部RAM,从而降低了系统运行的速
度。
因此,我们可以适当地更改Scatterfile,将一些不常使用的数据放到外部RAM中执行,可以大大地提高软件的速度,给用户一个更好的使用体验。
文章评论(0条评论)
登录后参与讨论