硬件平台: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)