理解启动代码(ADS)
;ORR R1,R0,#(MODUSR :OR: IRQBIT :OR: FIQBIT)
;MSR CPSR_cxsf,R1 ; ENTER USR MODE
;MOV sp,R2
;SUB R2,R2,#UsrStkSz
ORR R1,R0,#(MODSYS :OR: IRQBIT :OR: FIQBIT)
MSR CPSR_cxsf,R1 ; ENTER SYS MODE
MOV sp,R2 ;
三,初始化变量
编译完成之后,连接器会生成三个基本的段,分别是RO,RW,ZI,并会在image中顺序摆放.显然,RW,ZI在运行开始时并不位于指定的RW位置, 因此必须初始化
LDR R0,=|Image$$RO$$Limit|
LDR R1,=|Image$$RW$$Base|
LDR R2,=|Image$$ZI$$Base|
1
CMP R1,R2
LDRLO R3,[R0],#4
STRLO R3,[R1],#4
BLO %B1
MOV R3,#0
LDR R1,=|Image$$ZI$$Limit|
2
CMP R2,R1
STRLO R3,[R2],#4
BLO %B2
四,复制异常向量
由于代码于RAM运行时,有明显的速度优势,而且变量可以动态配置,因此可以通过remap将RAM映射到0,使得出现异常时ARM从RAM中取得向量.
IMPORT |Image$$RO$$Base|
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$RW$$Limit|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
COPY_VECT_TO_RAM
LDR R0,=|Image$$RO$$Base|
LDR R1,=SYSINIT
LDR R2,=0x200000 ; RAM START
0
CMP R0,R1
LDRLO R3,[R0],#4
STRLO R3,[R2],#4
BLO %B0
这段程序将SYSINIT之前的代码,也就是异常处理函数,全部复制到RAM中,这就意味着不能将RW设置为 0x200000,这样会使得向量被冲掉.
四,在RAM中运行
如果有必要,且代码足够小,可以将代码置于RAM中运行,由于RAM中本身没有代码,就需要将代码复制到RAM中:
COPY_BEGIN
LDR R0,=0x200000
LDR R1,=RESET ; =|Image$$RO$$Base|
CMP R1,R0 ;
BLO COPY_END ;
ADR R0,RESET
ADR R2,COPY_END
SUB R0,R2,R0
ADD R1,R1,R0
LDR R3,=|Image$$RO$$Limit|
3
CMP R1,R3
LDRLO R4,[R2],#4
STRLO R4,[R1],#4
BLO %B3
LDR PC,=COPY_END
COPY_END
程序首先取得RESET的连接地址,判断程序是否时是在RAM中运行,方法是与RAM起始地址比较,如果小于,那么就跳过代码复制.
在复制代码的时候需要注意,在这段程序结束之前的代码没有必要复制,因为这些代码都已经执行过了,所以,先取得COPY_END,作为复制起始地址,然后计算其相对RESET的偏移,然后以RO的值加上这个偏移,就是复制目的地的起始地址,然后开始复制.
五,开始主程序
以上步骤完成,就可以跳转到main运行
IMPORT Main
LDR PC,=Main
B .
六,器件初始化
主程序首先要进行器件的初始化,对S64而言,应该先初始化WDT,因为默认情况下,WDT是打开的,然后是各设备的时钟分配,最后应该 remap
启动代码AD 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)