u-boot-2014.10移植第10天----深入分析代码(五)

硬件平台:tq2440

开发环境:Ubuntu-3.11

u-boot版本:2014.10

本文允许转载,请注明出处:http://blog.csdn.net/fulinus


b   relocate_code 

ENTRY(relocate_code)
    ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */  //r1为u-boot.lds文件中__image_copy_start的地址。
    subs    r4, r0, r1      /* r4 <- relocation offset */  //r0 = gd->reloc_off , r4 = r0 - r1
    beq relocate_done       /* skip relocation */
    ldr r2, =__image_copy_end   /* r2 <- SRC &__image_copy_end */


copy_loop:

    ldmia   r1!, {r10-r11}      /* copy from source address [r1]    */      //r1中放在u-boot代码的起始位置__image_copy_star,将r1地址中的8个字节拷贝到r10和r11寄存器中,r1自加8(?不确定)
    stmia   r0!, {r10-r11}      /* copy to   target address [r0]    */     //r0中放在要拷贝到那里去的目的地址,即r0 = gd->reloc_of,将r10和r11寄存器中的值,放在r0地址中的8个字节。

    cmp r1, r2          /* until source end address [r2]    */ //比较r1和r2的值,r2也就是要拷贝代码的结束地址__image_copy_end
    blo copy_loop //如果r1小于r2跳转


    /*
     * fix .rel.dyn relocations
     */
    ldr r2, =__rel_dyn_start    /* r2 <- SRC &__rel_dyn_start */
    ldr r3, =__rel_dyn_end  /* r3 <- SRC &__rel_dyn_end */

http://blog.csdn.net/skyflying2012/article/details/37660265,按照这篇博文中的说法,这里拷贝一些和地址有关系的内容。毕竟重定位了,有些依赖绝对地址的值在这里据需要修改,但是不是在rel.dyn段中修改,而是将值加上偏移量,即加上relocation offset的值,并把它按照原先的顺序放到重定位的rel.dynl段中。
fixloop:

    ldmia   r2!, {r0-r1}        /* (r0,r1) <- (SRC location,fixup) */   //__rel_dyn_start起始的值拷贝到r0和r1寄存器中。
    and r1, r1, #0xff  //r1和0xFF相与运算,下面会用来判断是否等于0x17,上面说的博文中说“网上查阅资料,这里对于rel.dyn段中每一个rel section(8个字节)第二个4字节,0x17,是一种label的类型R_ARM_RELATIVE

80eba944:       80e9d40c        rschi   sp, r9, ip, lsl #8
80eba948:       00000017        andeq   r0, r0, r7, lsl r0

80ebc18c:       80eaa54c        rschi   sl, sl, ip, asr #10
80ebc190:       00000017        andeq   r0, r0, r7, lsl r0
    cmp r1, #23         /* relative fixup? */
    bne fixnext //不相等就跳,说明这不是一个与地址相关的内容所以就不用拷贝。


    /* relative fix: increase location by offset */
    add r0, r0, r4   //上面 /* r4 <- relocation offset */  //r0 = gd->reloc_off , r4 = r0 - r1,这四条语句就是在将内存中表示的地址加上重定位的偏移量,再将这个地址中的值(估计是另一个地址)也加上重定位的偏移量
    ldr r1, [r0]  获取地址中的值
    add r1, r1, r4 //值再加上偏移量。
    str r1, [r0] 保存到重定位的rel.dyn段中去。
fixnext:
    cmp r2, r3 //小于就说明没有修改完,接着修改
    blo fixloop


relocate_done:


#ifdef __XSCALE__
    /*
     * On xscale, icache must be invalidated and write buffers drained,
     * even with cache disabled - 4.2.7 of xscale core developer's manual
     */
    mcr p15, 0, r0, c7, c7, 0   /* invalidate icache */
    mcr p15, 0, r0, c7, c10, 4  /* drain write buffer */
#endif


    /* ARMv4- don't know bx lr but the assembler fails to see that */

//记得前面lr的值已经加上了偏移量,所以这里就跳到了重定位的地方去执行了。

#ifdef __ARM_ARCH_4__
    mov        pc, lr
#else
    bx    
#endif


ENDPROC(relocate_code)

你可能感兴趣的:(移植,ARM,u-boot,arm汇编,2014.10)