uboot移植第三天——代码分析(3)

本文详细解析了U-Boot启动过程中的重定位机制,包括为何需要重定位、重定位的具体实现过程及其代码分析。无论开发板采用何种启动方式,重定位都是确保代码能正确执行的关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

uboot中start.S相关代码分析

重定位

——即把falsh中的代码复制到ram(sdram)中,本开发板复制到sdram中。
不管我们开发板是以什么方式启动(nor/nand)启动,都需要进行重定位
因为:
当nor启动时,因为nor的特性,只能读不能写,因此需要从定位,
当nand启动时,nand启动只把前4k代码复制到片内内存,uboot打印4k,因此需要重定位。相应继续执行4K以后的代码,就必须重定位,然后跳到重定位后的地址执行。

代码分析

relocate:               /* relocate U-Boot to RAM       */
    adr r0, _start      /* r0 <- current position of code   */
    ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */
    cmp     r0, r1                  /* don't reloc during debug         */
    beq     stack_setup

    ldr r2, _armboot_start
    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

/*这段代码是在start.S最开头*/
.globl _start
_start: b       reset

解析:
1、ADR伪指令— 小范围的地址读取
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄
存器中。
在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通
常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一
条指令实现,则产生错误,编译失败。

  1. adr r0, _start的意思其实很简单,就是将_start(这个是代码最开始执行的)的地址赋值给r0.但是具体实现的方式就有点复杂了,对于用adr指令实现的话,说明_start这个地址,相对当前PC的偏移,应该是很小的,意思就是向前一段后者向后一段去找,肯定能找到_start这个标号地址的,此处,自己通过看代码也可以看到_start,就是在当前指令的前面,距离很近,编译后,对应汇编代码,也可以猜得出,应该是上面所说的,用sub来实现,即当前PC减去某个值,得到_start的值(在从Nor Flash启动时,对应的代码,也是在Nor Flash中,对应的物理地址是0x0,如果直接从链接地址运行时,该值就是链接地址),此时是0x0。
  2. cmp r0, r1 因此r0不等r1,beq不成立,所以不跳到stack_setup执行。
  3. ldr r2, _armboot_start //_armboot_start这个标号中的值_start赋给r2,实际就是链接地址
    ldr r3, _bss_start //根据链接脚本可知这是代码段的结束地址,bss段的起始地址
    sub r2, r3, r2 /计算出uboot的大小 /
    add r2, r0, r2 /重定位的结束地址 /
  4. 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
    这就是循环的进行代码得复制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值