S3C2440启动可以从Nor flash 或者Nand flash 启动,从Nor启动可以直接在Nor(0地址开始)运行,NAND 启动会先将前4K代码copy到片上的SRAM,然后从0地址开始运行。
不管哪种启动方式,最终都需要将代码拷贝到SDRAM中去,因为一般完整的boot loader都比较大,片上SRAM是放不下的。
实现步骤:
1. 必要的初始化
1) 关看狗
2) 初始化SDRAM
在此过程中很有可能会用到LDR指令,注意,如果编译时链接地址设置位SDRAM的地址,也就是copy到SDRAM中运行的起始地址,那么这里就不能使用LDR,而要用adr(l).
这里说下LDR 和ADR的区别:
LDR: 与连接地址相关的绝对地址,比如链接起始地址位0x30000000, 那么用LDR 读到的地址就是0x3xxxxxxx的,而这个时候运行的代码实际上是在片上SRAM或者NOR,都是0地址开始的4K范围内,用LDR已读就读到千里之外去了。注意这里用LDR后,虽然编译后反汇编看到的是PC 偏移,但是这个PC实际上是与链接地址相关的
300000 5c: e59f0054 ldr r0, [pc, #84]
ADR(L): ADR 就加载运行地址相关的地址,也就是基于当前运行位置的偏移地址,比如 ADR R0, lable, 这个时候读到的label 的地址就是基于当前运行位置PC偏移后的地址,而不与链接地址相关,如下,它会被转换成ADD指令来读取。
3000004c: e28f201c add r2, pc, #28
2. copy 代码到SDRAM
3. 跳转到SDRAM执行
如果链接地址是从0开始,那么跳转时,只需要加上实际SDRAM运行的起始地址,然后赋值给PC指针即可。
ldr sp, =0x31000000
ldr r1, main_ofs
ldr r0, =_start
add lr, r0, r1
add lr, lr, #0x30000000
mov r0, #0
mov pc, lr
main_ofs:
.long main - _start