以下启动代码是从《ARM嵌入式系统实验教程(一)》中提取出来的。
1 ; 启动文件,初始化C程序的运行环境,然后进入C程序代码。
2
3 IMPORT |Image$$RO$$Limit|
4 IMPORT |Image$$RW$$Base|
5 IMPORT |Image$$ZI$$Base|
6 IMPORT |Image$$ZI$$Limit|
7
8 IMPORT Main ; 声明C程序中的Main()函数
9
10 AREA Start,CODE,READONLY ; 声明代码段Start
11 ENTRY ; 标识程序入口
12 CODE32 ; 声明32位ARM指令
13
14 Reset LDR SP,=0x40003F00 ; 设置堆栈
15
16 ; 初始化C程序的运行环境
17 LDR R0,=|Image$$RO$$Limit|
18 LDR R1,=|Image$$RW$$Base|
19 LDR R3,=|Image$$ZI$$Base|
20
21 CMP R0,R1
22 BEQ LOOP1
23 LOOP0 CMP R1,R3
24 LDRCC R2,[R0],#4
25 STRCC R2,[R1],#4
26 BCC LOOP0
27
28 LOOP1 LDR R1,=|Image$$ZI$$Limit|
29 MOV R2,#0
30 LOOP2 CMP R3,R1
31 STRCC R2,[R3],#4
32 BCC LOOP2
33
34 B Main ; 跳转到C程序代码Main()函数
35
36 END
从ADS1.2的帮助文档可以看出以下几个symbol的定义应该是:
|Image$$RO$$Base|
表示RO输出段运行时起始地址,也可以说是程序代码存放的起始地址,由-ro-base这个参数指定;
|Image$$RO$$Limit|
表示RO输出段运行时存储区域界限,其值可通过|Image$$RO$$Base|+Code sizes+RO Data sizes+4计算得出;
|Image$$RW$$Base|
表示RW输出段运行时起始地址,记得是运行时的地址,而不一定是加载时的存放地址,因为RW输出段在加载时可能是在ROM中并紧跟着RO输出段存放的,当程序运行时才移动(在有些书中说是移动,个人觉得应该只是复制,希望大家能帮我解释一下,谢谢!)到RAM起始地址为|Image$$RW$$Base|的区域,由-rw-base这个参数指定;未指定的话,默认紧跟RO输出段,那么|Image$$RW$$Base|=|Image$$RO$$Limit|;
|Image$$RW$$Limit|
表示RW输出段运行时存储区域界限,其值可通过|Image$$RW$$Base|+RW Data sizes+4计算得出;
|Image$$ZI$$Base|
表示ZI输出段运行时起始地址,它是运行时在RAM中生成的,紧跟着RW输出段存放,其值和|Image$$RW$$Limit|一样;
|Image$$ZI$$Limit|
表示ZI输出段运行时存储区域界限,其值可通过|Image$$ZI$$Base|+ZI Data sizes+4计算得出。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;一个arm由RO,RW,ZI三个断组成 其中RO为代码段,RW是已经初始化的全局变量,ZI是未初始化的全局变量(对于GNU工具 对应的概念是TEXT ,DATA,BSS)bootloader
;bootloader要将RW段复制到ram中并将ZI段清零 编译器使用下列段来记录各段的起始和结束地址
; |Image$$RO$$Base| ; RO段起始地址 2
; |Image$$RO$$Limit| ; RO段结束地址加1 ,表示RO区末地址后面的地址,即RW数据源的起始地址
; |Image$$RW$$Base| ; RW段起始地址
; |Image$$RW$$Limit| ; RW段结束地址加1
; |Image$$ZI$$Base| ; ZI段起始地址
; |Image$$ZI$$Limit| ; ZI段结束地址加1
;IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
;IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
;IMPORT |Image$$ZI$$Base| ; Base and limit of area
;IMPORT |Image$$ZI$$Limit| ; to zero initialise
;IMPORT Main ; The main entry of mon program
;大总结!!!!!!!!!!!!!映像一开始总是存储在ROM/Flash里面的,其RO部分既可以在ROM/Flash里面执行,也可以转移到速度更快的RAM中执行;而RW和ZI这两部分是必须转移到可写的RAM里去。所谓应用程序执行环境的初始化,就是完成必要的从ROM到RAM的数据传输和内容清零。
;r0是RW区的load address
;r1是RW区的execution address
;当两者相等时就不用拷贝
;不相等时,程序先把ROM里|Image$$RO$$Limt|开始的RW初始数据拷贝到RAM里面|Image$$RW$$Base|开始的地址,当RAM这边的目标地址到达|Image$$ZI$$Base|后就表示RW区的结束和ZI区的开始,接下去就对这片ZI区进行清零操作,直到遇到结束地址|Image$$ZI$$Limit|