U-Boot源码(u-boot-2012.04.01)分析start.S中重定位代码

U-Boot源码分析start.S中重定位代码

1. 将NOR Flash中的程序复制到SDRAM中

r0–addr_sp; r1–ip; r2–addr(33F41000);

relocate_code:

mov r4, r0  /* save addr_sp */
mov r5, r1  /* save addr of gd */
mov r6, r2  /* save addr of destination */

/* Set up the stack  */

stack_setup:

mov sp, r4

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

2. 把”基于0地址编译得到的地址”改为新地址

需要结合反汇编文件u-boot.dis

#ifndef CONFIG_SPL_BUILD
/*
 * fix .rel.dyn relocations
 */
ldr r0, _TEXT_BASE          // r0=0,代码基地址

sub r9, r6, r0              // r9 = r6-r0 = r2-r0 = 33F41000-0=33F41000 
ldr r10, _dynsym_start_ofs  // r10 = _dynsym_start_ofs = 00073608
add r10, r10, r0            // r10 = r10 + 0 = 00073608
ldr r2, _rel_dyn_start_ofs  // r2 = 0006b568
add r2, r2, r0              // r2 = r2 + 0 = 0006b568
ldr r3, _rel_dyn_end_ofs    // r3 = 00073608
add r3, r3, r0              // r3 = r3 + 0 = 00073608

fixloop:

ldr r0, [r2]    
    // 第1次循环. r0 = [0006b568] = 00000020    
add r0, r0, r9  
    // 第1次循环. r0 = r0 +r9 = 00000020 + 33F41000 = 33F41020
ldr r1, [r2, #4]
    // 第1次循环. r1 = [0006b568 + 4] = 00000017
and r7, r1, #0xff
    // 第1次循环. r7 = r1 & 0xff = 00000017
cmp r7, #23     
    // 第1次循环. r7 == 23(0x17)
beq fixrel
    // 跳转到fixrel
cmp r7, #2          
beq fixabs
b   fixnext

fixabs:

/* absolute fix: set location to (offset) symbol value */
mov r1, r1, LSR #4      /* r1 <- symbol index in .dynsym */
add r1, r10, r1     /* r1 <- address of symbol in table */
ldr r1, [r1, #4]        /* r1 <- symbol value */
add r1, r1, r9      /* r1 <- relocated sym addr */
b   fixnext

fixrel:

/* relative fix: increase location by offset */
ldr r1, [r0]
    // 第1次循环. r1 = [00000020] = 000001e0
add r1, r1, r9
    // 第1次循环. r1 = r1 + r9 = 000001e0 + 33F41000 = 33F411e0

fixnext:

str r1, [r0]
    // 第1次循环. [33F41020] = 33F411e0
add r2, r2, #8      /* each rel.dyn entry is 8 bytes */
    // 第1次循环. r2 = r2 + 8 = 0006b568 + 8 = 0006b570
cmp r2, r3
    // 第1次循环. 0006b570 与 00073608 比较
blo fixloop
    // 上面比较为假,再次跳转到fixloop
#endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值