u-boot之start.S小结
1、关于加载地址和运行地址
加载地址就是代码在FLASH上存储的地址,也叫加载域,或者存储地址,或者LMA(load address),就bin文件的存储地址
运行地址就是代码在RAM上运行时地址,也叫运行时域,或者VMA(virtual address),若在NOR flash中运行,这个运行应该和加载地址是一样的.
运行地址在连接文件u-boot.lds中指定,这个文件其实同时指定了加载地址,那就是默认和运行地址一样,除非用AT命令显式指定加载地址
另外运行地址也可以通过Ttext命令行指定,这就是为什么在u-boot.lds中指定的运行地址是0x0,而实际运行是偏移了0x33f80000,因为在makefile中通过:
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE)
翻译下就是arm-linux-ld –Ttext _TEXT_BASE,这句指定了运行地址。
2、关于重定位
重定位就代码拷贝,然后跳到拷贝的目的地址去继续运行,网上看了别人一段代码,为了支持nand flash启动,直接在start.S中添加了nand flash的拷贝代码,当时很迷惑,为什么这个start.S可以存在两段拷贝代码呢,一个是原来的,支持nor flash的,一个是新加的nand flash的,那么从nand flash启动的时候这两段是不是都执行到,而拷贝两次呢,仔细不对啊,原来的那段是拷贝Nor flash,不能操作nand flashj,后来发现是没看清楚代码布局,其实这个start.S nandflash启动时不会执行到原来的relocate那段,因为代码安排如下
…
Nand flash copy
…
Relocate(原来的nor flash copy)
…
stack_setup….
在nand flash copy的结尾会通过beq stack_setup跳过nor flash copy段。若是只需要从nand flash启动,则nor flash copy段可以删除
3、关于adr r0 _start
relocate: /* relocate U-Boot to RAM */
/* 这条指令就是将代码的当前地址,也就是运行地址赋给r0, 当在 nor flash中运行时,r0=0,_start=33f80000,而不是网上有人说的 r0=_start=0,因为_start是连接时就确定的,一直是33f80000,当从RAM(这里的RAM是指SDRAM,不包括从nand flash启动时那块石头SRAM)运行时,r0=33f80000. */
adr r0, _start
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
/*_armboot_start 存放的是_start的值 */
ldr r2, _armboot_start //r2=33f80000
ldr r3, _bss_start //
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
4,关于汇编代码调用c函数
在nand flash启动的u-boot复制有如下代码
@ copy U-Boot to RAM
ldr r0, =TEXT_BASE //复制的目的地址33f80000
mov r1, #0x0 //复制的源地址0x0
mov r2, #0x30000 //复制的大小
bl nand_read_ll //这里调用了c函数,r0-r2,分别是传给c函数的第1,2,3个参数
tst r0, #0x0 //从c函数返回,返回值也放在r0
beq ok_nand_read
写到这里我忽然又想到一个问题,既然从nand flash启动,原来的relocate那段代码跳过了,但是判读是不是调试状态也就没有了,那岂不是nand flash不支持调试,暂记下,以后再看。
5、u-boot执行流程,smdk2410
Start_code
--------设置处理器模式为super
--------关闭watchdog
--------屏蔽所有中断
bl cpu_init_crit
--------清除I/D cache 关闭MMU
--------lowlevel_init,配置SDRAM访问时序
Relocate
--------复制u-boot 到RAM
stack_setup
--------配置堆栈段
clear_bss
--------清楚bss段
ldr pc, _start_armboot---跳转到RAM去执行