uboot移植之重定位

参考文章:https://blog.csdn.net/skyflying2012/article/details/37660265

重定位的代码量不多,如下:

.globl    relocate_code
relocate_code:
    mov    r4, r0    /* save addr_sp */  
    mov    r5, r1    /* save addr of gd */ 
    mov    r6, r2    /* save addr of destination */  //r6->重定位目标地址

    /* Set up the stack                            */
stack_setup:
    mov    sp, r4  //设置栈,与重定位无关

    adr    r0, _start  //根据 当前pc的值 和 _start与当前PC的偏移量 得到_start的绝对地址,存入r0.由于uboot的链接地址是0,这里的_start为0.
    cmp    r0, r6    //比较 当前代码段的起始地址 和 重定位目标地址是否一样,如果一样就只清除bss段(这是重定位后每次上电都要进行的),不一样就进行重定位
    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

#ifndef CONFIG_SPL_BUILD
    /*
     * fix .rel.dyn relocations
     */
    ldr    r0, _TEXT_BASE        /* r0 <- Text base */
    sub    r9, r6, r0        /* r9 <- relocation offset */
    ldr    r10, _dynsym_start_ofs    /* r10 <- sym table ofs */
    add    r10, r10, r0        /* r10 <- sym table in FLASH */
    ldr    r2, _rel_dyn_start_ofs    /* r2 <- rel dyn start ofs */
    add    r2, r2, r0        /* r2 <- rel dyn start in FLASH */
    ldr    r3, _rel_dyn_end_ofs    /* r3 <- rel dyn end ofs */
    add    r3, r3, r0        /* r3 <- rel dyn end in FLASH */
fixloop:
    ldr    r0, [r2]        /* r0 <- location to fix up, IN FLASH! */
    add    r0, r0, r9        /* r0 <- location to fix up in RAM */
    ldr    r1, [r2, #4]
    and    r7, r1, #0xff
    cmp    r7, #23            /* relative fixup? */
    beq    fixrel
    cmp    r7, #2            /* absolute fixup? */
    beq    fixabs
    /* ignore unknown type of fixup */
    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]
    add    r1, r1, r9
fixnext:
    str    r1, [r0]
    add    r2, r2, #8        /* each rel.dyn entry is 8 bytes */
    cmp    r2, r3
    blo    fixloop
#endif

 

uboot移植之重定位

上一篇:TRUNK&VLAN&STP攻防


下一篇:noip模拟测试19