参考tekkaman的u-boot-2009.11的移植,有两点迷惑,经过查阅资料,仔细思考,解决了疑惑;记录如下:
1,判断是SDRAM&NOR&NAND的启动方式:链接:
http://www.360doc.com/content/10/1118/09/4672432_70333375.shtml
判断是否是SDRAM启动的方法是采用如下代码实现
/***************** CHECK_CODE_POSITION ******************************************/
adr r0, _start /* r0 <- current position of code相对寻址,范围小,是实际运行时该标号的地址,若是NOR启动或NAND启动,则_start为0地址,若通过仿真器或者已经拷贝到SDRAM运行,那么_start为连接器设置的期望运行地址,即_TEXT_BASE */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM,此处加载的绝对地址,即连接器处理后的地址,也就是期望在SDRAM中运行的地址*/
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
/***************** CHECK_CODE_POSITION ******************************************/
若实际运行的地址,是链接器期望运行的地址,那么现在代码正在SDRAM中运行,否则便是NOR或则NAND启动。
2,判断是NOR&NAND启动
/***************** CHECK_BOOT_FLASH ******************************************/
ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* address of Internal SRAM 0x4000003C*/
mov r0, #0 /* r0 = 0 */
str r0, [r1]
mov r1, #0x3c /* address of men 0x0000003C*/
ldr r0, [r1]
cmp r0, #0
bne relocate /*norflash启动,则跳转到该标号*/
/* recovery */
ldr r0, =(0xdeadbeef) /*若是NAND启动,恢复0X4000003C处原来的值,接着执行NAND拷贝到SDRAM*/
ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
str r0, [r1]
/***************** CHECK_BOOT_FLASH ******************************************/
/***************** NAND_BOOT *************************************************/
详细解释参考上面的链接
3,NOR启动代码搬移到SDRAM
/***************** NOR_BOOT *************************************************/
relocate: /* relocate U-Boot to RAM */
/*********** CHECK_FOR_MAGIC_NUMBER***************/
ldr r1, =(0xdeadbeef)
cmp r0, r1
bne loop3
/*********** CHECK_FOR_MAGIC_NUMBER***************/
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
ldr r2, _armboot_start /******疑虑出自这里*******/
ldr r3, _bss_star
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
/***************** NOR_BOOT *************************************************/
疑惑主要源自对ldr以及adr命令的迷惑,简单讲adr加载的是代码在运行时的地址,ldr加载的是链接器链接后的绝对地址;前面有述;
start.S开始处有
.globl _armboot_start
_armboot_start:
.word _start
刚开始我认为运行时,_armboot_start的值与_start的值相同;其实不是,_armboot_start中的值存的是链接后_start的值,即使期望在SDRAM中的地址;因此在NOR&NAND启动时,执行下来,r0与r2的值不同;__bss_start的位置,是bss的start开始位置,同时也是text+rodata+data的结束位置,即代码段,只读数据和已初始化的可写的数据的最末尾的位置。NOR启动时,执行到copy_loop之前,r0=0,r2为text+rodata+data的结束位置。然后执行拷贝