> On 14-05-16 06:47 AM, feng...@phytium.com.cn wrote: >> >> 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'. > Thank you David. I agree that the adrp will cause problems if the string > sections and label used are not relocated to correct boundaries. The adrp > used before the relocation works because the symbols are on aligned > boundaries. > > I think I have a way to explain this problem better now. > > 1. Working generic code: > CONFIG_SYS_TEXT_BASE = 0x88000000 > unrelocated vectors = 0x888001000 > relocation address = 0xfffa8000 = 0xfffa8000 - 0x88000000 > relocation offset = 77fa8000 > relocated vectors = 0xfffa9000 (0x800 alignment, but pushed to fffa9000 > because of code after 0xfffa8800) > > Now in this case, the .align directive for the vectors section wants the > vectors sitting at 0x800 alignment, which they are. > When the symbols are relocated, the vectors are now at 0xfffa9000 which is > aligned properly. > > 2. Failing offset case: > CONFIG_SYS_TEXT_BASE = 0x88000020 > unrelocated vectors = 0x888001000 (respecting .align 11 directive) > relocation address = 0xfffa8000 > relocation offset = 77fa7fe0 = 0xfffa8000 - 0x88000020 > relocated vectors = 0xfffa8fe0 (BAD ALIGNMENT) > Now the relocated rodata.str1.1 string tables are not aligned, which I > believe breaks > the adrp instruction. The strings are offset by 0x20 and the printf fails. > > 3. Fixed offset case: > CONFIG_SYS_TEXT_BASE = 0x88000020 > unrelocated vectors = 0x888001000 (respecting .align 11 directive) > relocation address = 0xfffa8020 > relocation offset = 77fa8000 = 0xfffa8020 - 0x88000020 > relocated vectors = 0xfffa9000 (GOOD ALIGNMENT, respects .align 11 after > relocation) > > So in this fixed offset case, the adrp label is aligned to a 4K page size. > > > General comments: > > Any section in the image that requires a particular alignment must have that > alignment respected after relocation. You cannot relocate to an arbitrary > address if it breaks the maximum image alignment requirement after relocation. > > If the vectors want an 0x800 alignment, and the relocation puts them on a > 0x1000 boundary, then that will work fine. > If the string section wants a 0x1000 alignment and are relocated to a 0x1000 > boundary, that also works. > > But if for some reason, the hardware ever required a 0x2000 (.align 13) > alignment, then the generic code's 0x1000 (.align 12) relocation alignment > would not work because the alignment after relocation would not respect the > .align 13 directive. We just haven't run into this issue yet and may never do > so, but it is important to understand the limitations of relocation relative > to image alignment requirements. The current hardcoded 4096 (0x1000) image > relocation alignment just happens to work and looks nice, that's all, but not > by consideration of image alignment. > > And if any text base alignment is less than the image's maximum alignment > requirement, the load will fail, and then we likely scratch our heads and set > the CONFIG_SYS_TEXT_BASE alignment higher until it works.
Whatever CONFIG_SYS_TEXT_BASE is the alignment will be ok if the relocated address satisfy the align requirement. So CONFIG_SYS_TEXT_BASE could be any value(compiler maybe require the text base aligned with 0x20), just make relocated address has the same offset. David
_______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot