ARM 的分散加载
首先申明我使用的调试软件为ADS1.2,当我们把程序编写好以后,就要进行编译和链接了,在ADS1.2中选择MAKE按钮,会出现一个Errors and Warnings的对话框,在该栏中显示编译和链接的结果,如果没有错误,在文件的最后应该能看到Image component sizes,后面紧跟的依次是Code,RO Data,RW Data,ZI Data,Debug各个项目的字节数,最后会有他们的一个统计数据:
Code 163632,RO Data 20939,RW Data 53,ZI Data 17028
Tatal RO size (Code+ RO Data) 184571 (180.25kB)
Tatal RW size(RW Data+ ZI Data) 17081(16.68 kB)
Tatal ROM size(Code+ RO Data+ RW Data) 184624(180.30 kB)
后面的字节数是根据用户不同的程序而来的,下面就以上面的数据为例来介绍那几个变量的计算。
在ADS的Debug Settings中有一栏是Linker/ARM Linker,在output选项中有一个RO base选项,下面应该有一个地址,我这里是0x0c100000,后面的RW base地址是0x0c200000,然后在Options选项中有Image entry point,是一个初始程序的入口地址,我这里是0x0c100000。
有了上面这些信息我们就可以完全知道这几个变量是怎么来的了:
|Image$$RO$$Base| = Image entry point = 0x0c100000;表示程序代码存放的起始地址
|Image$$RO$$Limit|=程序代码起始地址+代码长度+1=0x0c100000+Tatal RO size+1
= 0x0c100000 + 184571 + 1 = 0x0c100000 +0x2D0FB + 1
= 0x0c12d0fc
|Image$$RW$$Base| = 0x0c200000;由RW base地址指定
|Image$$RW$$Limit| =|Image$$RW$$Base|+ RW Data 53 = 0x0c200000+0x37(4的倍数,0到55,共56个单元)
=0x0c200037
|Image$$ZI$$Base| = |Image$$RW$$Limit| + 1 =0x0c200038
|Image$$ZI$$Limit| = |Image$$ZI$$Base| + ZI Data 17028
=0x0c200038 + 0x4284
=0x0c2042bc
也可以由此计算:
|Image$$ZI$$Limit| = |Image$$RW$$Base| +TatalRWsize(RWData+ZIData) 17081
=0x0c200000+0x42b9+3(要满足4的倍数)
=0x0c2042bc
原文地址http://blog.csdn.net/yyt7529/archive/2009/06/05/4245604.aspx
简单应用时可以不写.scf文件。而在"Output"页中选择"Simple".然后填写"RO Base"和"RW Base"的起始地址。在"Lay Out"页中,填写Object/Symble: Startup.o, Section: Start.编写启动文件:Startup.s.
在"Option"页里的"Image Entry Point"填入起始地址。
--------------------------------------------------------------------------------
Scatter-Load Description File的结构:
".scf"文件中的"+RW"对应".s"源文件中的"READWRITE".
".scf"文件中的"+ZI"对应".s"源文件中的"NOINIT".
".scf"文件中的"+RO"对应".s"源文件中的"READONLY".
在".s"源文件中有:
AREA area_name CODE/DATA,READONLY/NOINIT/READWRITE
END
".scf"的例子
内容 注解
ROM_LOAD 0x80000000
{ ;Name of Load Region, Start Address for Load Region and Maximum size of Load Region(省略了)
ROM_EXEC 0x80000000 0x20000
{;片外存储区,从0x80000000开始,最多0x20000字节。
Startup.o(Vector,+First);Startup模块的Vector段放在最前面。注1
*(+RO);其他所有模块中的所有代码和只读的数据放在这里。
}
IRAM 0x40000000 0x00004000
{;片内RAM区,从0x40000000开始,最多0x4000字节
Startup.o(MyStacks,+first);指定Startup.o中MyStacks放在最前面。
Startup.o(+RW,+ZI);Startup.o中的其他+RW/+ZI段。注1
os_cpu_a.o(+RW,+ZI)
}
STACKS 0x40004000 UNINIT
{;片内16K RAM的顶端,存放不需要被"C library"初始化的段。
Stack.o(+ZI)注2
}
ERAM 0x80040000
{
*(+RW,+ZI)
}
HEAP +0 UNINIT
{;"+0"表示接着上一段"ERAM"的结尾,继续安排存储区。
Heap.o(+ZI)注3
}
}
下面是在scf文件中引用过的源文件示意:"Startup.s"
code 32
area Vectors,CODE,READONLY
entry
...
end注1:在"Startup.o"里面会生成名为"Vectors"的段,段的属性为"READONLY"
"Stack.s"
area Stacks, DATA, NOINIT
export StackUsr
StackUsr SPACE 1
end注2:在"Stack.o"里面会生成名为"Stacks"的段,段的属性为"NOINIT",该属性对应scf文件中的"+ZI".该段不需要初始化或者可以被初始化为"0".
"Heap.s"
area Heap,DATA,NOINIT
export bottom_of_heap
bottom_of_heap SPACE 1
end注3: "Heap.o"里面名为"Heap"的段。
在Scatter文件中最好每一个Region都加一个Maximum参数,这样当编译时如果实际使用的空间大于Maximum Size,会有Error:16220E: Excution region xxx size (xxx bytes) exceeds limit (xx bytes)。如果地址有重复,会有Error: 16221E: Excution region xxx overlaps with excution region xxx。前一个Region的首地址+ Maximum >在Scatter文件中最好每一个Region都加一个Maximum参数,这样当编译时
ARM分散加 相关文章:
- ARM的分散加载文件(scatter)介绍(11-09)
- ARM分散加载文件(11-09)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)