开发板与平台:XSBASE 270-S、PXA270
裸机程序:image重定向
编译环境:ads 1.20
调试方法:直接用工具烧至片内norflash的0x0地址
一:分析
虽然片内的norflash可以运行代码,但是只读不可写(不方便写)的特性,还有速度也没有SDRAM的速度快,所以初始化完SDRAM后就可以把norflash的数据拷贝到SDRAM中运行。
使用ARMCC编译的程序包含了几个image相关的符号,这让我们重定向提供了方便。
代码使用的都是简单的ARM汇编语句,这里要注意的是搬运代码采用单个字节搬运,为了速度,读者可以使用多字节进行搬运。
从图1可以看出R0段的起始地址为0xa0000000就是SDRAM的起始地址。一开始image是处于norflash中,在还没跳到SDRAM运行前,我们应该ss使用位置无关代码进行处理,处理完毕后,使用LDR PC, LOOP语句就可以跳到SDRAM中运行代码。图2到图4是相关工程的配置。
图1:
图2:
图3:
图4:
二:程序代码
Boot.s:
IMPORT InitMem
IMPORT InitRam
AREA boot, CODE, READONLY
ENTRY
;初始化内存
BL InitMem
;搬运数据到内存
BL InitRam
;跳转到内存中运行
LDR PC, =LOOP ;位置无关指令
LOOP
B LOOP
END
Initram.s:
IMPORT |Image$$RO$$Base|
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$RW$$Limit|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
EXPORT InitRam
AREA InitRam, CODE, READONLY
ENTRY
;提取各段的符号地址
LDR R0, =|Image$$RO$$Base|
LDR R1, =|Image$$RO$$Limit|
LDR R2, =|Image$$RW$$Base|
LDR R3, =|Image$$RW$$Limit|
LDR R4, =|Image$$ZI$$Base|
LDR R5, =|Image$$ZI$$Limit|
;判断是否需要搬运CODE段
CMP R0, #0x0
BEQ JUDGE_DATA2
LDR R8, =0x0
MOVE_TEXT
CMP R0, R1
LDRCC R7, [R8], #0x4
STRCC R7, [R0], #0x4
BCC MOVE_TEXT
;判断是否需要搬运RW段
JUDGE_DATA1
CMP R1, R2
BEQ JUDGE_ZI
;CODE段起点在0x0,但是RW段可能设置在内存中
JUDGE_DATA2
CMP R2, R4
BEQ JUDGE_ZI
MOVE_DATA
CMP R2, R4
LDRCC R7, [R1], #0x4
STRCC R7, [R2], #0x4
BCC MOVE_DATA
;判断是否需要清空BSS段
JUDGE_ZI
CMP R4, R5
BEQ OUT
LDR R8, =0x0
MOVE_ZI
CMP R4, R5
STRCC R8, [R4], #0x4
BCC MOVE_ZI
OUT
MOV PC, LR
END