[U-Boot] armv8 relocation questions

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.
Best Regards, Darwin Rambo

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.

On 14-05-16 06:47 AM, fenghua@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.
But since most people just use higher alignments naturally, this issues remain mostly hidden I think.
Best regards, Darwin
David.

Dear Darwin,
In message 53763B78.6030801@broadcom.com you wrote:
- Fixed offset case:
CONFIG_SYS_TEXT_BASE = 0x88000020
You completely fail to respond to my repeated statement that a CONFIG_SYS_TEXT_BASE like this is bogus.
I guess i give up on this.
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.
Who was it who asked why we had such unreasonable strict alignment requirements for the relocation address?
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
Is this a theoretical or a practical question? Where exactly do you have such a use case?
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.
Ummm... experience from 15 years of PPCBoot / U-Boot history don't count here, I guess?
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.
CONFIG_SYS_TEXT_BASE should always be reasonable aligned. There is no good reason to add arbitrary small offsets like you do. I've explained to you a feww times before that you should include your header into the text segment, and the problem would be just gone.
But since most people just use higher alignments naturally, this issues remain mostly hidden I think.
Not hidden, they don't exist. Non-random sig this time.
Best regards,
Wolfgang Denk

On Fri, May 16, 2014 at 10:28:25PM +0200, Wolfgang Denk wrote:
Dear Darwin,
In message 53763B78.6030801@broadcom.com you wrote:
- Fixed offset case:
CONFIG_SYS_TEXT_BASE = 0x88000020
You completely fail to respond to my repeated statement that a CONFIG_SYS_TEXT_BASE like this is bogus.
This. What the heck is going on? CONFIG_SYS_TEXT_BASE is where the text section ends up, and the rest of the binary that follows, until we relocate. If we're being loaded by something else, it needs to be placing us at the right spot. If there's some header on top of the image to be considered by the loader, adjust where THAT loads us. If we cannot, then you must change CONFIG_SYS_TEXT_BASE around. Pad things up a bit for proper alignment. It seems where somewhere around "Doctor, it hurts when I hit myself with a hammer!" and can't stop hammering our poor finger.

Hello Tom,
On vr, 2014-05-16 at 17:15 -0400, Tom Rini wrote:
On Fri, May 16, 2014 at 10:28:25PM +0200, Wolfgang Denk wrote:
Dear Darwin,
In message 53763B78.6030801@broadcom.com you wrote:
- Fixed offset case:
CONFIG_SYS_TEXT_BASE = 0x88000020
You completely fail to respond to my repeated statement that a CONFIG_SYS_TEXT_BASE like this is bogus.
This. What the heck is going on? CONFIG_SYS_TEXT_BASE is where the text section ends up, and the rest of the binary that follows, until we relocate. If we're being loaded by something else, it needs to be placing us at the right spot. If there's some header on top of the image to be considered by the loader, adjust where THAT loads us. If we cannot, then you must change CONFIG_SYS_TEXT_BASE around. Pad things up a bit for proper alignment. It seems where somewhere around "Doctor, it hurts when I hit myself with a hammer!" and can't stop hammering our poor finger.
Not really I guess, I read it as "Doctor, it hurts when I hit myself with a hammer!" But morphine prevents it to hurt, so everybody should use morphine.
But a bit more serious, as far as understood it u-boot is loaded to the CONFIG_SYS_TEXT_BASE being set, but not aligned to the requirements of adrp (which assumes 4k). Did someone find a decent description of adrp and how it should be relocated? Is adrp always required or an optimization?
And yes, obviously obeying alignment requirements before and after relocating obviously helps, but I am also curious how Darwin gets away with this by adding an offset (in the wrong direction) and if this would always work (given the former is fixed).
And yes, I don't know a single thing about arm64 so perhaps above sounds completely stupid...
Regards, Jeroen

Hi Jeroen,
Hello Tom,
On vr, 2014-05-16 at 17:15 -0400, Tom Rini wrote:
On Fri, May 16, 2014 at 10:28:25PM +0200, Wolfgang Denk wrote:
Dear Darwin,
In message 53763B78.6030801@broadcom.com you wrote:
- Fixed offset case:
CONFIG_SYS_TEXT_BASE = 0x88000020
You completely fail to respond to my repeated statement that a CONFIG_SYS_TEXT_BASE like this is bogus.
This. What the heck is going on? CONFIG_SYS_TEXT_BASE is where the text section ends up, and the rest of the binary that follows, until we relocate. If we're being loaded by something else, it needs to be placing us at the right spot. If there's some header on top of the image to be considered by the loader, adjust where THAT loads us. If we cannot, then you must change CONFIG_SYS_TEXT_BASE around. Pad things up a bit for proper alignment. It seems where somewhere around "Doctor, it hurts when I hit myself with a hammer!" and can't stop hammering our poor finger.
Not really I guess, I read it as "Doctor, it hurts when I hit myself with a hammer!" But morphine prevents it to hurt, so everybody should use morphine.
But a bit more serious, as far as understood it u-boot is loaded to the CONFIG_SYS_TEXT_BASE being set, but not aligned to the requirements of adrp (which assumes 4k). Did someone find a decent description of adrp and how it should be relocated? Is adrp always required or an optimization?
We can not make gcc-aarch64 do not use adrp instruction when constructing address of label. So, I think the 4kb alignment would be a requirement or restriction. Gcc did not declare it explicitly due to in normal world memory are allocated with page aligned. If u-boot for aarch64 want to be compiled at address not 4kb aligned the relocated address should also be shifted with the same offset.
David

Dear fenghua,
In message B9A956AA-4ED7-488D-B496-90111AA45A5A@phytium.com.cn you wrote:
We can not make gcc-aarch64 do not use adrp instruction when constructing address of label.
So, I think the 4kb alignment would be a requirement or restriction. Gcc did not declare it explicitly due to in normal world memory are allocated with page aligned. If u-boot for aarch64 want to be compiled at address not 4kb aligned the relocated address should also be shifted with the same offset.
Sorry, I don't understand anything here. At which exact place is there any such 4 k alignment restriction? When we relocate U-Boot, we just process a list of addresses. Even if the start of the image is aligned to a 4 k boundary, there are a zillion of other addresses that are not, and these can be relocated just fine.
So why exactly would there be such a restriction on the start address of the image? Note especially, that the start address of the image is just where the text segment starts - it is not necessarily the entry point address where code execution begines.
Best regards,
Wolfgang Denk

Hello Wolfgang,
On za, 2014-05-17 at 18:53 +0200, Wolfgang Denk wrote:
Dear fenghua,
In message B9A956AA-4ED7-488D-B496-90111AA45A5A@phytium.com.cn you wrote:
We can not make gcc-aarch64 do not use adrp instruction when constructing address of label.
So, I think the 4kb alignment would be a requirement or restriction. Gcc did not declare it explicitly due to in normal world memory are allocated with page aligned. If u-boot for aarch64 want to be compiled at address not 4kb aligned the relocated address should also be shifted with the same offset.
Sorry, I don't understand anything here. At which exact place is there any such 4 k alignment restriction? When we relocate U-Boot, we just process a list of addresses. Even if the start of the image is aligned to a 4 k boundary, there are a zillion of other addresses that are not, and these can be relocated just fine.
The following document [1] mentions:
"ADRP Xd, label Address of Page: sign extends a 21-bit offset, shifts it left by 12 and adds it to the value of the PC with its bottom 12 bits cleared, writing the result to register Xd. This computes the base address of the 4KiB aligned memory region containing label, and is designed to be used in conjunction with a load, store or ADD instruction which supplies the bottom 12 bits of the label’s address. This permits position- independent addressing of any location within ±4GiB of the PC using two instructions, providing that dynamic relocation is done with a minimum granularity of 4KiB (i.e. the bottom 12 bits of the label’s address are unaffected by the relocation). The term “page” is short-hand for the 4KiB relocation granule, and is not necessarily related to the virtual memory page size."
And apparently gcc choose to use it as such. Since the instructions in question are relative to the most significant bits of the pc it does not need fixups, so it is not included in the "list of addresses" you mention. The compiler does create the 4k requirement though by using the instruction the way it does.
Regards, Jeroen
[1] http://www.element14.com/community/servlet/JiveServlet/previewBody/41836-102...

Dear Jeroen,
In message 1400416665.2394.20.camel@yellow you wrote:
So, I think the 4kb alignment would be a requirement or restriction. Gcc did not declare it explicitly due to in normal world memory are allocated with page aligned. If u-boot for aarch64 want to be compiled at address not 4kb aligned the relocated address should also be shifted with the same offset.
Sorry, I don't understand anything here. At which exact place is there any such 4 k alignment restriction? When we relocate U-Boot, we just process a list of addresses. Even if the start of the image is aligned to a 4 k boundary, there are a zillion of other addresses that are not, and these can be relocated just fine.
The following document [1] mentions:
"ADRP Xd, label
...
And apparently gcc choose to use it as such. Since the instructions in
Where exactly does it chose to do so? I cannot understand why that should be a problem for _start, but not for any of the other symbols we're relocating?
question are relative to the most significant bits of the pc it does not need fixups, so it is not included in the "list of addresses" you mention. The compiler does create the 4k requirement though by using the instruction the way it does.
Sorry, I cannot follow. where exactly does this happen, and why there, and not anywhere else?
Best regards,
Wolfgang Denk

Hello Wolfgang.
On zo, 2014-05-18 at 21:51 +0200, Wolfgang Denk wrote:
In message 1400416665.2394.20.camel@yellow you wrote:
So, I think the 4kb alignment would be a requirement or restriction. Gcc did not declare it explicitly due to in normal world memory are allocated with page aligned. If u-boot for aarch64 want to be compiled at address not 4kb aligned the relocated address should also be shifted with the same offset.
Sorry, I don't understand anything here. At which exact place is there any such 4 k alignment restriction? When we relocate U-Boot, we just process a list of addresses. Even if the start of the image is aligned to a 4 k boundary, there are a zillion of other addresses that are not, and these can be relocated just fine.
The following document [1] mentions:
"ADRP Xd, label
...
And apparently gcc choose to use it as such. Since the instructions in
Where exactly does it chose to do so?
In the code emitter which decide to use the following instructions to look up a label, as mentioned by David [1]. Since it only uses _part of_ the pc, it introduces the need to have the relocation offset be a multiple of 4k.
adrp x0, ... add x0, x0, 0x30
I cannot understand why that should be a problem for _start, but not for any of the other symbols we're relocating?
It is not a problem of _start. Any label / symbol which is looked up with only the adrp + compile time offset will be incorrect if the relocation offset is not n * 4k. It just that moving _start around makes the relocation offset not obey this requirement.
question are relative to the most significant bits of the pc it does not need fixups, so it is not included in the "list of addresses" you mention. The compiler does create the 4k requirement though by using the instruction the way it does.
Sorry, I cannot follow. where exactly does this happen, and why there, and not anywhere else?
In any code emitted which uses above pattern. And above code works fine if text is 4k natural aligned before and after relocation. It also works fine when the same offset is used before and after relocation.
Regards, Jeroen
[1] http://lists.denx.de/pipermail/u-boot/2014-May/179713.html

Dear Jeroen,
In message 1400485047.1998.17.camel@yellow you wrote:
"ADRP Xd, label
...
And apparently gcc choose to use it as such. Since the instructions in
Where exactly does it chose to do so?
In the code emitter which decide to use the following instructions to look up a label, as mentioned by David [1]. Since it only uses _part of_ the pc, it introduces the need to have the relocation offset be a multiple of 4k.
adrp x0, ... add x0, x0, 0x30
No. I mean: to which exact lines of U-Boot C source code will be translated into that?
I mean, from what has been discussed here that would be the relocation loop, right? And there this should not happen, as we deal with random addresses. So I wonder if this is either a coding error in the armv8 related assembler code, or a compiler bug, or something else?
I cannot understand why that should be a problem for _start, but not for any of the other symbols we're relocating?
It is not a problem of _start. Any label / symbol which is looked up with only the adrp + compile time offset will be incorrect if the relocation offset is not n * 4k. It just that moving _start around makes the relocation offset not obey this requirement.
Well, in this case relocation can never work correctly, so we're back at my question above: bad assembly code of the armv8 port, or a compiler bug?
Sorry, I cannot follow. where exactly does this happen, and why there, and not anywhere else?
In any code emitted which uses above pattern. And above code works fine if text is 4k natural aligned before and after relocation. It also works fine when the same offset is used before and after relocation.
The question is - where does such code get emitted? Is it generated from C code, or manually created assembly?
I would like to see the exact source code reference into U-Boot code...
Best regards,
Wolfgang Denk

Hello Wolfgang,
On ma, 2014-05-19 at 14:33 +0200, Wolfgang Denk wrote:
Dear Jeroen,
In message 1400485047.1998.17.camel@yellow you wrote:
"ADRP Xd, label
...
And apparently gcc choose to use it as such. Since the instructions in
Where exactly does it chose to do so?
In the code emitter which decide to use the following instructions to look up a label, as mentioned by David [1]. Since it only uses _part of_ the pc, it introduces the need to have the relocation offset be a multiple of 4k.
adrp x0, ... add x0, x0, 0x30
No. I mean: to which exact lines of U-Boot C source code will be translated into that?
I mean, from what has been discussed here that would be the relocation loop, right? And there this should not happen, as we deal with random addresses. So I wonder if this is either a coding error in the armv8 related assembler code, or a compiler bug, or something else?
mm, forget about U-Boot for a second and please consider the following, complicated, program:
#include <stdio.h>
int main(int c, char *argv[]) { puts("Hello World"); return 0; }
compiled with `aarch64-linux-gnu-gcc -g -Wall hello.c` results in:
int main(int c, char *argv[]) { 400590: a9be7bfd stp x29, x30, [sp,#-32]! 400594: 910003fd mov x29, sp 400598: b90013a0 str w0, [x29,#16] 40059c: f9000fa1 str x1, [x29,#24] puts("Hello World"); 4005a0: 90000000 adrp x0, 400000 <_init-0x3b8> 4005a4: 91194000 add x0, x0, #0x650 4005a8: 97ffff9e bl 400420 puts@plt return 0; 4005ac: 52800000 mov w0, #0x0 // #0 } 4005b0: a8c27bfd ldp x29, x30, [sp],#32 4005b4: d65f03c0 ret
Notice the adrp and hardcoded offset to load the location of the argument. The 90000000 decodes to adrp x0, 0, the value of the program counter with its lower 12bits cleared -> which is the 400000 when not being relocated. Then the harcoded 650 offset is added to point to:
Contents of section .rodata: 400648 01000200 00000000 48656c6c 6f20576f ........Hello Wo 400658 726c6400 00000000 rld.....
---- Now suppose the code is moved 0x20 up, then the adrp will still return 400000, the constant #0x650 it still added, but Hello World is now at 400670 and it won't work.
If 0x1000 (4k) is added, the adrp sets 401000, the fixed 650 is added again and properly points to the repositioned "Hello World". This will work for any multiple of 4k.
I cannot understand why that should be a problem for _start, but not for any of the other symbols we're relocating?
It is not a problem of _start. Any label / symbol which is looked up with only the adrp + compile time offset will be incorrect if the relocation offset is not n * 4k. It just that moving _start around makes the relocation offset not obey this requirement.
Well, in this case relocation can never work correctly, so we're back at my question above: bad assembly code of the armv8 port, or a compiler bug?
Relocation will work fine, as long as (relocation_offset % 4096) == 0. Note that this is only about the offset, the label / symbol itself can be aligned to anything, since the hardcoded "add" will take care of that part.
The question is - where does such code get emitted? Is it generated from C code, or manually created assembly?
It is generated, there are no literal adrp instructions in U-boot. As far as I understand it, it is a compiler feature..
Regards, Jeroen

Dear Jeroen Hofstee,
In message 1400523005.1985.33.camel@yellow you wrote:
mm, forget about U-Boot for a second and please consider the following, complicated, program:
I think we should NOT forget U-Boot, which comes with it's own, specifically tuned set of compiler options and linker scripts.
#include <stdio.h>
int main(int c, char *argv[]) { puts("Hello World"); return 0; }
compiled with `aarch64-linux-gnu-gcc -g -Wall hello.c` results in:
I have no idea how the tool chain was configured here, and what the linker script might look like.
int main(int c, char *argv[]) { 400590: a9be7bfd stp x29, x30, [sp,#-32]! 400594: 910003fd mov x29, sp 400598: b90013a0 str w0, [x29,#16] 40059c: f9000fa1 str x1, [x29,#24] puts("Hello World"); 4005a0: 90000000 adrp x0, 400000 <_init-0x3b8> 4005a4: 91194000 add x0, x0, #0x650 4005a8: 97ffff9e bl 400420 puts@plt return 0; 4005ac: 52800000 mov w0, #0x0 // #0 } 4005b0: a8c27bfd ldp x29, x30, [sp],#32 4005b4: d65f03c0 ret
Notice the adrp and hardcoded offset to load the location of the argument. The 90000000 decodes to adrp x0, 0, the value of the program counter with its lower 12bits cleared -> which is the 400000 when not being relocated. Then the harcoded 650 offset is added to point to:
Contents of section .rodata: 400648 01000200 00000000 48656c6c 6f20576f ........Hello Wo 400658 726c6400 00000000 rld.....
Maybe. This is with some (unknown here) specific set of compiler options and linker statements. This does not mean that the same or silimar code will be generated for U-Boot, or - if it really is - that this has to be like that. Eventually the tool chain needs some tweaking flags to tell it that we intend to relocate the image later?
The question is - where does such code get emitted? Is it generated from C code, or manually created assembly?
It is generated, there are no literal adrp instructions in U-boot. As far as I understand it, it is a compiler feature..
That depends on specific compiler options / linker settings, eventually?
Best regards,
Wolfgang Denk

Hello Wolfgang,
On ma, 2014-05-19 at 20:30 +0200, Wolfgang Denk wrote:
Dear Jeroen Hofstee,
In message 1400523005.1985.33.camel@yellow you wrote:
mm, forget about U-Boot for a second and please consider the following, complicated, program:
I think we should NOT forget U-Boot, which comes with it's own, specifically tuned set of compiler options and linker scripts.
well it mentioned for a second...
compiled with `aarch64-linux-gnu-gcc -g -Wall hello.c` results in:
I have no idea how the tool chain was configured here, and what the linker script might look like.
for what it is worth: aarch64-linux-gnu-gcc (Ubuntu/Linaro 4.8.1-10ubuntu7) 4.8.1 with its default linker script.
Maybe. This is with some (unknown here) specific set of compiler options and linker statements. This does not mean that the same or silimar code will be generated for U-Boot,
Could be, but the vexpress_aemv8a shows the same pattern. It has around 1688 of adrp instructions.
or - if it really is - that this has to be like that. Eventually the tool chain needs some tweaking flags to tell it that we intend to relocate the image later?
I wondered about that. I could not find such a flag, nor did David think it exists.. [1]
The question is - where does such code get emitted? Is it generated from C code, or manually created assembly?
It is generated, there are no literal adrp instructions in U-boot. As far as I understand it, it is a compiler feature..
That depends on specific compiler options / linker settings, eventually?
Perhaps eventually. But for now it seems that also U-boot is forced to keep the relocation offset a multiple of 4k.
Regards, Jeroen
[1] http://lists.denx.de/pipermail/u-boot/2014-May/179741.html

Dear Jeroen,
In message 1400532143.1985.57.camel@yellow you wrote:
I have no idea how the tool chain was configured here, and what the linker script might look like.
for what it is worth: aarch64-linux-gnu-gcc (Ubuntu/Linaro 4.8.1-10ubuntu7) 4.8.1 with its default linker script.
OK, now I know where it's coming from; did you look into this?
Maybe. This is with some (unknown here) specific set of compiler options and linker statements. This does not mean that the same or silimar code will be generated for U-Boot,
Could be, but the vexpress_aemv8a shows the same pattern. It has around 1688 of adrp instructions.
Probably with the same / similar compiler options?
I wondered about that. I could not find such a flag, nor did David think it exists.. [1]
You mean this statement:
We can not make gcc-aarch64 do not use adrp instruction when constructing address of label.
?
David, can you definitely confirm that there are no compiler / linker flags for relocatable code that might influence code generation / use of adrp here?
That depends on specific compiler options / linker settings, eventually?
Perhaps eventually. But for now it seems that also U-boot is forced to keep the relocation offset a multiple of 4k.
For aarch64, you mean? Because the tool chain and/or our current understanding how it generates code requires it, right?
Best regards,
Wolfgang Denk

Hello Wolfgang,
On ma, 2014-05-19 at 23:05 +0200, Wolfgang Denk wrote:
Dear Jeroen,
In message 1400532143.1985.57.camel@yellow you wrote:
I have no idea how the tool chain was configured here, and what the linker script might look like.
for what it is worth: aarch64-linux-gnu-gcc (Ubuntu/Linaro 4.8.1-10ubuntu7) 4.8.1 with its default linker script.
OK, now I know where it's coming from; did you look into this?
peeked, but didn't see anything special about it.
Maybe. This is with some (unknown here) specific set of compiler options and linker statements. This does not mean that the same or silimar code will be generated for U-Boot,
Could be, but the vexpress_aemv8a shows the same pattern. It has around 1688 of adrp instructions.
Probably with the same / similar compiler options?
I wondered about that. I could not find such a flag, nor did David think it exists.. [1]
You mean this statement:
We can not make gcc-aarch64 do not use adrp instruction when constructing address of label.
?
Yes, I _think_ the architecture _could_ use the full pc, it is just bigger and slower, and I seems like the compiler folks just did not implemented it at all.
Perhaps eventually. But for now it seems that also U-boot is forced to keep the relocation offset a multiple of 4k.
For aarch64, you mean? Because the tool chain and/or our current understanding how it generates code requires it, right?
Right, only for aarch64 and current tools (but my guess it that it will stay around). ARM32 does not have such a requirement, since it uses the complete pc. Don't know about other architectures.
That said, _if_ placing start at a not 4k align / page aligned is acceptable for u-boot it might be smarter to always align the relocation offset instead of aligning the destination address itself, since alignment is always preserved in that case as long as it is smaller then 4k (and down, instead of up as in the original patch).
Regards, Jeroen

On 14-05-16 01:28 PM, Wolfgang Denk wrote:
Dear Darwin,
In message 53763B78.6030801@broadcom.com you wrote:
- Fixed offset case:
CONFIG_SYS_TEXT_BASE = 0x88000020
You completely fail to respond to my repeated statement that a CONFIG_SYS_TEXT_BASE like this is bogus.
I want to set it this way to avoid carrying a downstream patch in start.S if the header is added by a post processing step. I understand that I can put a custom header inside start.S but wanted a different solution that keeps the code with less patches.
I guess i give up on this.
I'm sorry we couldn't converge on this.
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.
Who was it who asked why we had such unreasonable strict alignment requirements for the relocation address?
The relocation address isn't unreasonably strict. I am happy with the 0x1000 alignment. What was breaking was the relocation offset which needs to have an alignment equal to or greater than the section alignments inside the image so that the symbols get relocated correctly.
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
Is this a theoretical or a practical question? Where exactly do you have such a use case?
This is a theoretical statement, just to try to demonstrate that the 4K page alignment is itself subject to future breakage if new hardware has alignment requirements that are greater than 4K. For example, if some new architecture had to have vectors on a 0x2000 alignment, and we put them on a 0x1000 alignment after relocation, the vector table would be corrupted.
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.
Ummm... experience from 15 years of PPCBoot / U-Boot history don't count here, I guess?
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.
CONFIG_SYS_TEXT_BASE should always be reasonable aligned. There is no good reason to add arbitrary small offsets like you do. I've explained to you a feww times before that you should include your header into the text segment, and the problem would be just gone.
I agree that is a solution, but I didn't want to carry a downstream patch when the issue with relocation and alignment is understood and fixable. I thought it might be an interesting discussion, I guess we certainly got that. :) Thanks again.
Best regards, Darwin
But since most people just use higher alignments naturally, this issues remain mostly hidden I think.
Not hidden, they don't exist. Non-random sig this time.
Best regards,
Wolfgang Denk

On Fri, May 16, 2014 at 02:24:47PM -0700, Darwin Rambo wrote:
On 14-05-16 01:28 PM, Wolfgang Denk wrote:
Dear Darwin,
In message 53763B78.6030801@broadcom.com you wrote:
- Fixed offset case:
CONFIG_SYS_TEXT_BASE = 0x88000020
You completely fail to respond to my repeated statement that a CONFIG_SYS_TEXT_BASE like this is bogus.
I want to set it this way to avoid carrying a downstream patch in start.S if the header is added by a post processing step. I understand that I can put a custom header inside start.S but wanted a different solution that keeps the code with less patches.
Then you need to either pad your header out a page worth I suspect based on skimming the rest of these threads or fix what's loading your tagged u-boot to load to 0x87ffffc0.

On 14-05-16 06:47 AM, fenghua@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.
- 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.
- 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.
- 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

Dear David,
In message 0579E649-F359-415B-A8ED-E1D4267F8A24@phytium.com.cn you wrote:
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.
There is a point which has not been answered yet, wnd which I really would like to understand. maybe you could be so kind and try to explain it to me?
I wonder if the use of the "ardp" instruction by the compiler can be influenced or maybe even prevent for specific code parts, for example by specific compiler options? For example, there is a number of PIC/PIE-related compiler options - would these have any influence here?
I wonder how "adrp" would work in any code that is supposed to be position-independent?
Best regards,
Wolfgang Denk

hi Wolfgang, I am will glad to share my understanding.
Dear David,
In message 0579E649-F359-415B-A8ED-E1D4267F8A24@phytium.com.cn you wrote:
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.
There is a point which has not been answered yet, wnd which I really would like to understand. maybe you could be so kind and try to explain it to me?
I wonder if the use of the "ardp" instruction by the compiler can be influenced or maybe even prevent for specific code parts, for example by specific compiler options? For example, there is a number of PIC/PIE-related compiler options - would these have any influence here?
I did not find any options that can prevent the use of adrp.
I wonder how "adrp" would work in any code that is supposed to be position-independent?
In my understanding, with adrp the program is still relocatable except that the text base should be 4KB aligned or the relocated address has the same offset with text base. Darwin want CONFIG_SYS_TEXT_BASE to be not 4KB aligned, so the relocated address should be offsetted in the same manner.
Position-independent code is usually page aligned, so gcc-aarch64 implicitly apply the restriction of text base.
Actually, u-boot for aarch64 apply another align requirement that is interrupt vector. The interrupt vector should be 2KB aligned. So, even without adrp CONFIG_SYS_TEXT_BASE should be 2KB aligned yet or relocated with the same offset, otherwise bug exist.
Best regards, David

Dear David,
In message CBDD3537-16F3-41C8-9929-6C30F56C36DF@phytium.com.cn you wrote:
I am will glad to share my understanding.
Thanks.
I wonder how "adrp" would work in any code that is supposed to be position-independent?
In my understanding, with adrp the program is still relocatable except that the text base should be 4KB aligned or the relocated address has the same offset with text base. Darwin want CONFIG_SYS_TEXT_BASE to be not 4KB aligned, so the relocated address should be offsetted in the same manner.
We should be careful here to use precise terms. CONFIG_SYS_TEXT_BASE is just the start address of the text segment, and if I understand correctly, it is NOT required that this is in any way aligned to a 4 KB boundary - we have to keep in mind here that the start of the text segment is not the same as the start address of the code; it can be the same, but often it is not - often other blocks of date preceed the actual program code (things like HRCW [hard reset configuration word], or strings with ID information etc., exception vector tables and/or code, etc.).
Position-independent code is usually page aligned, so gcc-aarch64 implicitly apply the restriction of text base.
Actually, u-boot for aarch64 apply another align requirement that is interrupt vector. The interrupt vector should be 2KB aligned. So, even without adrp CONFIG_SYS_TEXT_BASE should be 2KB aligned yet or relocated with the same offset, otherwise bug exist.
CONFIG_SYS_TEXT_BASE is just one number here, and it cannot be considered alone. We must also include into our considerations the linker script, because this is where actually alignments are enforced.
I think we do not need to add specific code to deal with these alignment requireents. It should be sufficient to implement these in the aarch64 linker script. This also applies for the alignment of the exception vector table.
Best regards,
Wolfgang Denk

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
participants (5)
-
Darwin Rambo
-
fenghua@phytium.com.cn
-
Jeroen Hofstee
-
Tom Rini
-
Wolfgang Denk