uboot relocation section .rel.dyn

来源:互联网 发布:网络电视央视直播 编辑:程序博客网 时间:2024/06/05 16:16

U-boot version: GIT clone tag v2016.01-rc1

ARM gcc: arm-none-eabi-gcc 5.2.1


Trying to port U-boot to STM32F10x MCU, found U-boot .rel.dyn section is interesting. And it includes .dynsym and .dynstr section.

Now just write down how it works.


First let's see the example C-code.

unsigned long clock_get(enum clock clck){u32 sysclk = 0;u32 shift = 0;/* Prescaler table lookups for clock computation */u8 ahb_psc_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};/*operations*/} 

注意ahb_psc_table[]数组,relocation的对象就是数据。

The assemble code is:

 80005ac:       5cd3            ldrb    r3, [r2, r3] 80005ae:       40d8            lsrs    r0, r3 80005b0:       e000            b.n     80005b4 <clock_get+0x84> 80005b2:       2000            movs    r0, #0 80005b4:       b004            add     sp, #16 80005b6:       bd70            pop     {r4, r5, r6, pc} 80005b8:       08014766        stmdaeq r1, {r1, r2, r5, r6, r8, r9, sl, lr} /*0x8014766 is the ahb_psc_table[] array.0x80005b8 is the index of the array.*/ 80005bc:       40023808        andmi   r3, r2, r8, lsl #16 80005c0:       40023804        andmi   r3, r2, r4, lsl #16 80005c4:       007a1200        rsbseq  r1, sl, r0, lsl #4 80005c8:       0801a7a6        stmdaeq r1, {r1, r2, r5, r7, r8, r9, sl, sp, pc}
可以看到ahb_psc_table[]数组的地址(0x8014766)被存放在函数尾部 0x080005b8的位置。


The ahb_psc_table[] is stored in .rodata section.

 8014764:       0000000f        andeq   r0, r0, pc                    /*0x8014766 start is ahb_psc_table[]={0,0,0,0,1,2,3,4,6,7,8,9}*/ 8014768:       00000000        andeq   r0, r0, r0 801476c:       02010000        andeq   r0, r1, #0 8014770:       07060403        streq   r0, [r6, -r3, lsl #8] 8014774:       00000908        andeq   r0, r0, r8, lsl #18

这里是ahb_psc_table[]数据的实际存储位置。


The rel.dyn section is:

Disassembly of section .rel.dyn:0801c3fc <__rel_dyn_end-0x48e0>: 801c3fc:       08000528        stmdaeq r0, {r3, r5, r8, sl} 801c400:       00000017        andeq   r0, r0, r7, lsl r0 801c404:       080005b8        stmdaeq r0, {r3, r4, r5, r7, r8, sl} /*0x80005b8 is the index of ahb_psc_table[]*/ 801c408:       00000017        andeq   r0, r0, r7, lsl r0 801c40c:       080005c8        stmdaeq r0, {r3, r6, r7, r8, sl}

the relocation table item 0x801c404 is the index of ahb_psc_table[] item. 

relocation表里存的是函数后面存放ahb_psc_table[]地址的单元的地址。



Then the question is how to use this relocation table. Let's check the code of arch/arm/lib/relocation.S(removed un-used code)

ENTRY(relocate_code)ldrr1, =__image_copy_start/* r1 <- SRC &__image_copy_start */subsr4, r0, r1/* r4 <- relocation offset */beqrelocate_done/* skip relocation */ldrr2, =__image_copy_end/* r2 <- SRC &__image_copy_end */copy_loop:ldmiar1!, {r10-r11}/* copy from source address [r1]    */stmiar0!, {r10-r11}/* copy to   target address [r0]    */cmpr1, r2/* until source end address [r2]    */blocopy_loop/* * fix .rel.dyn relocations */ldrr2, =__rel_dyn_start/* r2 <- SRC &__rel_dyn_start */ldrr3, =__rel_dyn_end/* r3 <- SRC &__rel_dyn_end */fixloop:ldmiar2!, {r0-r1}/* (r0,r1) <- (SRC location,fixup) */andr1, r1, #0xffcmpr1, #23/* relative fixup? */bnefixnext/* relative fix: increase location by offset */addr0, r0, r4             /*calculate 0x80005b8's RAM address*/ldrr1, [r0]               /*read 0x80005b8's content--ahb_psc_table[] address*/addr1, r1, r4             /*modify ahb_psc_table[] address to RAM(new address)*/strr1, [r0]               /*write back ahb_psc_table[]'s new address to 0x80005b8's RAM address*/fixnext:cmpr2, r3blofixlooprelocate_done:bxlrENDPROC(relocate_code)

Got it ? It looks complex.

其实relocation函数改变的是函数后面单元中存放的ahb_psc_table[]数组的地址。因为整个image被搬移到了新地址(relocation feature假设整个image都搬移了),所以函数后面单元中存放的ahb_psc_table[]数组的地址必须修改,不然就找不到正确的ahb_psc_table[]数组。


The idea is:

1. Each function has an index for each variable which is bigger than 4 bytes.

2. Put all variables' index into the relocation table. After copy the data section to the new address, the U-boot could easily modify the address of all variables.


Here should insert a picture to make it more clear.



But if you don't need relocation, how to disable it? Open arch/arm/config.mk file.

# needed for relocationLDFLAGS_u-boot += -pie   /*This is for link process*/
This is the first place.

ifneq ($(CONFIG_SPL_BUILD),y)# Check that only R_ARM_RELATIVE relocations are generated.ALL-y += checkarmreloc# The movt / movw can hardcode 16 bit parts of the addresses in the# instruction. Relocation is not supported for that case, so disable# such usage by requiring word relocations.PLATFORM_CPPFLAGS += $(call cc-option, -mword-relocations)endif
This is the second place and it is for gcc.

So disable these two places, you could disable the relocation feature. Attention, checkarmreloc need disable.



0 0
原创粉丝点击