[U-Boot] armv8 relocation questions
fenghua at phytium.com.cn
fenghua at phytium.com.cn
Sat May 17 05:53:33 CEST 2014
>
> hi Darwin,
> It's a little late.
>> I'm hoping someone can help answer these questions about armv8 relocation.
>>
>> The CONFIG_SYS_TEXT_BASE seems to be be usually setup to a decent amount of alignment. For the purposes of this discussion, let's say it would normally be 0x88000000 and all is well. The relocation address moves to near the end of memory, to say, 0xfffa8000. So far so good.
>>
>> Now let's say I want to shift the image a bit so that I can add a small 32-byte header required by a previous bootloader. So I set CONFIG_SYS_TEXT_BASE to 0x88000020, and the relocated address is still 0xfffa8000 and the relocated vectors should be at 0xfffa9000. The image crashes so after some debugging, I find that the code appears to be relocated fine, but some sections have symbols that are not relocated properly. The vectors try to relocate to 0xfffa8fe0 and rodata.str1.1 printf format strings are also 0x20 off. There are likely other offset sections with issues as well.
>>
>> The relocation offset is 0x77fa7fe0 due to the calculations in arch/arm/lib/board.c. Simplifying, they look like this:
>>
>> addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
>>
>> /* round down to next 4 kB limit */
>> addr &= ~(4096 - 1);
>> debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
>>
>> /*
>> * reserve memory for U-Boot code, data & bss
>> * round down to next 4 kB limit
>> */
>> addr -= gd->mon_len;
>> addr &= ~(4096 - 1);
>>
>> addr += 0x20; // hack to adjust relocaddr to aligned address...
>>
>> <snip>
>>
>> gd->relocaddr = addr;
>> gd->start_addr_sp = addr_sp;
>> gd->reloc_off = addr - _TEXT_BASE;
>> debug("relocation Offset is: %08lx\n", gd->reloc_off);
>>
>>
>> Since _TEXT_BASE is 0x88000020 and addr is 0xfffa8000, the reloc_off is a number like 0x77fa7fe0.
>>
>> Now if I add 0x20 to 'addr' above just before the <snip>, relocaddr becomes 0x77fa8000 and the relocation works perfectly and no more crashes happen.
>>
>> So my question - is the CONFIG_SYS_TEXT_BASE alignment requirement related to to any assumptions in the linker itself about image base alignment, specifically referring to creation of the rela.dyn sections and their use for image relocation?
>>
>> A related question is if CONFIG_SYS_TEXT_BASE needs to be at a specific alignment. The maximum alignment in the armv8 code base is ".align 11" which I believe means 0x800 or 2048.
>>
>> Note that an armv7 target appears to relocate properly with smaller offsets such as 0x20.
>>
>> Thanks.
>>
>>
> I traced the problem you described and found it is caused by 'adrp' instruction. 'adrp' instruction produces 4kb aligned address of a label. So, if CONFIG_SYS_TEXT_BASE is not 4kb aligned the address produced by 'adrp' and following 'add' instruction will be incorrect.
> For example, if CONFIG_SYS_TEXT_BASE = 0x20 then address of '_start' is 0x20 and address of '_end_ofs' is 0x30, where u-boot access variable '_end_ofs' gcc generate code as following:
> adrp x0, ...
> add x0, x0, 0x30
>
> We noticed that 0x30 is added to 'x0' to produce the address of '_end_ofs'. So when CONFIG_SYS_TEXT_BASE=0x20 and relocated destination address is not 0x****020 register x0 contain incorrect address of '_end_ofs'.
>
> David.
>
>
Another point, if the relocated address is not shifted with the same offset with CONFIG_SYS_TEXT_BASE all the alignment in u-boot maybe lost, for example the interrupt vector table. So, this issue is not only related with aarch64.
David
More information about the U-Boot
mailing list