微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM 的分散加载

ARM 的分散加载

时间:11-09 来源:互联网 点击:
对于刚学习ARM的人来说,如果分析它的启动代码,往往不明白下面几个变量的含义:|Image$$RO$$Limit|、|Image$$RW$$Base|、|Image$$ZI$$Base|。

首先申明我使用的调试软件为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参数,这样当编译时

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top