s3c2440启动方式
1. 从nand flash 启动
1.1
上电后将nand flash中的前4KB数据复制到“Stepping Stone”;
1.2
CPU 执行“Stepping Stone”中的代码;
//通常的做法是将nand
flash中的代码拷贝至sdram;
2. 从nor
flash 启动
2.1 根据nor
flash的总线数据宽度,从第一条指令开始执行;
//通常的做法:是用这段程序将nor
flash中的代码拷贝至sdram;
启动代码核心分析
GET option.inc ;栈地址等常量定义
GET memcfg.inc ;SDRAM初始化相关
GET 2440addr.inc ;特殊功能寄存器USERMODE EQU 0x10 ;定义运行模式常量,即CPSR寄存器的模式控制位赋值
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~ ;定义各模式堆栈地址
;实现$HandleAddr宏
$HandlerLabel
sub sp,sp,#4 ; sp = sp -4
stmfd sp!,{r0} ; sp = sp -4, r0寄存器的值入栈
ldr r0,=$HandleAddr ; $HandleAddr是该宏的参数,将该值赋给r0
ldr r0,[r0] ; $HandleAddr相当于是一个函数指针,此时将该指针所指向函数入口地址赋值给r0
str r0,[sp,#4] ; ro入栈,即$HandleAddr
ldmfd sp!,{r0,pc} ; 出栈,恢复r0,将$HandleAddr赋值给pc
MEND;入口地址,定义一个init段
;初始化异常向量表
b ResetHandler; 0x00000000 为ResetHandler如上例:CPU上电时从0x0000000启动,此时ResetHandler被执行
;实现arm对中断的处理,IsrIRQ
IsrIRQ
sub sp,sp,#4 ;reserved for PC
stmfd sp!,{r8-r9} ;保存r8、r9ldr r9,=INTOFFSET ;中断偏移寄存器,当ENT0时,该值为0,随后32个外部中断源依次递增
ldr r9,[r9]
ldr r8,=HandleEINT0
add r8,r8,r9,lsl #2 ;r9左移2位、r8 = r8 + r9,
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc} ;跳转到中断服务函数LTORG
;ResetHandler 实现
;1. WTCON 关闭看门狗;
;2. INTMSK\INTSUBMSK 中断屏蔽;
;3. 系统时钟初始化
;4. 存储器初始化
adrl r0, SMRDATA ; SDRAM的13个特殊寄存器设置参数
ldmia r0,{r1-r13}
ldr r0,=BWSCON
stmia r0,{r1-r13};堆栈初始化
bl InitStacks
;在InitStacks中,初始化各模式堆栈例如
mrs r0,cpsr
bic r0,r0,#MODEMASK
orr r1,r0,#UNDEFMODE|NOINT
msr cpsr_cxsf,r1 ;UndefMode ,通过修改CPSR,将处理器切换到该模式
ldr sp,=UndefStack ; UndefStack=0x33FF_5C00;执行启动
ldr r0, =BWSCON
ldr r0, [r0]
ands r0, r0, #6 ;OM[1:0] != 0, NOR FLash boot
bne copy_proc_beg ;do not read nand flash
adr r0, ResetEntry ;OM[1:0] == 0, NAND FLash boot
cmp r0, #0 ;if use Multi-ice,
bne copy_proc_beg ;do not read nand flash for boot
;nop
;===========================================================
nand_boot_beg ;从nand 启动
bl RdNF2SDRAM ;该函数将代码从nand 拷贝到 内存
ldr pc, =copy_proc_beg;copy_pro_beg实现
;arm的可执行程序的映像文件,分为RO(代码段和只读数据段)、RW(可读/写数据段)和ZI 未初始化数据段
;根据link的设置,从0x00000000处跳转到SDRAM的0x30000000处
copy_proc_beg
adr r0, ResetEntry
ldr r2, BaseOfROM ;RO段的目标地址
cmp r0, r2
ldreq r0, TopOfROM
beq InitRam ;搬移RW
ldr r3, TopOfROM
0
ldmia r0!, {r4-r7} ;利用r4-r7,每次搬移16个字节
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0sub r2, r2, r3
sub r0, r0, r2InitRam
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0;初始化ZI段
mov r0, #0
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1;跳转到c函数
b Main ;