6410uboot有一段代码用于重定位代码:
adr r0, _start
cmp r0, r6
beq clear_bss /* skip relocation */
mov r1, r6 /* r1 <- scratch for copy_loop */
ldr r3, _bss_start_ofs
add r2, r0, r3 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r9-r10} /* copy from source address [r0] */
stmia r1!, {r9-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end address [r2] */
blo copy_loop
s3c6410启动分为三个阶段,即bl0,bl1,bl2,bl0会根据不同的启动方式将bl1运行所需的镜像拷贝到steppingstone里,然后从steppingstone开始运行bl1,在bl1中会对时钟,内存,调试口等进行初始化,并在bl1最后将bl2镜像拷贝到ram运行。
这段代码需要按不同的启动方式来分析:
第一种为网上讲得比较多的nand 启动方式,这种方式下6410会把用于nand启动的uboot镜像拷贝到地址00000000开始的steppingstone里,并从00000000开始运行,即这个时候_start为00000000,考虑到运行速度等原因,所以uboot会把本身在运行的用于nand启动的uboot镜像重新拷贝到ram里运行,在运行到nand启动最后,它会将uboot的bl2拷贝到内存里,然后再跳到拷贝的起始地址运行,这时会再次进到到start.s里运行,而这时的_start地址就应该为RAM地址,所以就不需要再去重定位了,接下来就会去为 c语言代码运行准备栈空间;
第二种为6410中datasheet里讲的irom启动方式,这种方式下bl0运行时会把用于bl1启动的镜像拷贝到0c000000开始的steppingstone里,然后从这个地址开始运行,mmc启动就属于IROM启动方式,这时的_start应该就为0xc000000,所以也需要进行代码重定位,然后也会将bl2的代码拷贝到内存里,然后再运行。
对这代码我是这样理解的, 不知道是不是正确,如果高手看到了感觉有问题,请帮我指出来,谢谢。