* [U-Boot] armv8 relocation questions
@ 2014-05-13 21:38 Darwin Rambo
2014-05-16 13:47 ` fenghua at phytium.com.cn
0 siblings, 1 reply; 24+ messages in thread
From: Darwin Rambo @ 2014-05-13 21:38 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-13 21:38 [U-Boot] armv8 relocation questions Darwin Rambo
@ 2014-05-16 13:47 ` fenghua at phytium.com.cn
2014-05-16 16:23 ` Darwin Rambo
2014-05-17 3:53 ` fenghua at phytium.com.cn
0 siblings, 2 replies; 24+ messages in thread
From: fenghua at phytium.com.cn @ 2014-05-16 13:47 UTC (permalink / raw)
To: u-boot
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.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 13:47 ` fenghua at phytium.com.cn
@ 2014-05-16 16:23 ` Darwin Rambo
2014-05-16 20:28 ` Wolfgang Denk
2014-05-22 14:19 ` fenghua at phytium.com.cn
2014-05-17 3:53 ` fenghua at phytium.com.cn
1 sibling, 2 replies; 24+ messages in thread
From: Darwin Rambo @ 2014-05-16 16:23 UTC (permalink / raw)
To: u-boot
On 14-05-16 06:47 AM, fenghua at 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.
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 16:23 ` Darwin Rambo
@ 2014-05-16 20:28 ` Wolfgang Denk
2014-05-16 21:15 ` Tom Rini
2014-05-16 21:24 ` Darwin Rambo
2014-05-22 14:19 ` fenghua at phytium.com.cn
1 sibling, 2 replies; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-16 20:28 UTC (permalink / raw)
To: u-boot
Dear Darwin,
In message <53763B78.6030801@broadcom.com> you wrote:
>
> 3. 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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"UNIX was not designed to stop you from doing stupid things, because
that would also stop you from doing clever things." - Doug Gwyn
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 20:28 ` Wolfgang Denk
@ 2014-05-16 21:15 ` Tom Rini
2014-05-16 22:26 ` Jeroen Hofstee
2014-05-16 21:24 ` Darwin Rambo
1 sibling, 1 reply; 24+ messages in thread
From: Tom Rini @ 2014-05-16 21:15 UTC (permalink / raw)
To: u-boot
On Fri, May 16, 2014 at 10:28:25PM +0200, Wolfgang Denk wrote:
> Dear Darwin,
>
> In message <53763B78.6030801@broadcom.com> you wrote:
> >
> > 3. 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.
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140516/55ccfcc7/attachment.pgp>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 20:28 ` Wolfgang Denk
2014-05-16 21:15 ` Tom Rini
@ 2014-05-16 21:24 ` Darwin Rambo
2014-05-16 21:52 ` Tom Rini
1 sibling, 1 reply; 24+ messages in thread
From: Darwin Rambo @ 2014-05-16 21:24 UTC (permalink / raw)
To: u-boot
On 14-05-16 01:28 PM, Wolfgang Denk wrote:
> Dear Darwin,
>
> In message <53763B78.6030801@broadcom.com> you wrote:
>>
>> 3. 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
>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 21:24 ` Darwin Rambo
@ 2014-05-16 21:52 ` Tom Rini
0 siblings, 0 replies; 24+ messages in thread
From: Tom Rini @ 2014-05-16 21:52 UTC (permalink / raw)
To: u-boot
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:
> >>
> >>3. 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.
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140516/e7e4b73d/attachment.pgp>
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 21:15 ` Tom Rini
@ 2014-05-16 22:26 ` Jeroen Hofstee
2014-05-17 2:13 ` fenghua at phytium.com.cn
0 siblings, 1 reply; 24+ messages in thread
From: Jeroen Hofstee @ 2014-05-16 22:26 UTC (permalink / raw)
To: u-boot
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:
> > >
> > > 3. 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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 22:26 ` Jeroen Hofstee
@ 2014-05-17 2:13 ` fenghua at phytium.com.cn
2014-05-17 16:53 ` Wolfgang Denk
0 siblings, 1 reply; 24+ messages in thread
From: fenghua at phytium.com.cn @ 2014-05-17 2:13 UTC (permalink / raw)
To: u-boot
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:
>>>>
>>>> 3. 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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 13:47 ` fenghua at phytium.com.cn
2014-05-16 16:23 ` Darwin Rambo
@ 2014-05-17 3:53 ` fenghua at phytium.com.cn
1 sibling, 0 replies; 24+ messages in thread
From: fenghua at phytium.com.cn @ 2014-05-17 3:53 UTC (permalink / raw)
To: u-boot
>
> 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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-17 2:13 ` fenghua at phytium.com.cn
@ 2014-05-17 16:53 ` Wolfgang Denk
2014-05-18 12:37 ` Jeroen Hofstee
0 siblings, 1 reply; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-17 16:53 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
All women should know how to take care of children. Most of them will
have a husband some day. - Franklin P. Jones
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-17 16:53 ` Wolfgang Denk
@ 2014-05-18 12:37 ` Jeroen Hofstee
2014-05-18 19:51 ` Wolfgang Denk
0 siblings, 1 reply; 24+ messages in thread
From: Jeroen Hofstee @ 2014-05-18 12:37 UTC (permalink / raw)
To: u-boot
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-1-229511/ARM.Reference_Manual.pdf
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-18 12:37 ` Jeroen Hofstee
@ 2014-05-18 19:51 ` Wolfgang Denk
2014-05-19 7:37 ` Jeroen Hofstee
0 siblings, 1 reply; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-18 19:51 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Any excuse will serve a tyrant." - Aesop
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-18 19:51 ` Wolfgang Denk
@ 2014-05-19 7:37 ` Jeroen Hofstee
2014-05-19 12:33 ` Wolfgang Denk
0 siblings, 1 reply; 24+ messages in thread
From: Jeroen Hofstee @ 2014-05-19 7:37 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-19 7:37 ` Jeroen Hofstee
@ 2014-05-19 12:33 ` Wolfgang Denk
2014-05-19 18:10 ` Jeroen Hofstee
0 siblings, 1 reply; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-19 12:33 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Lispers are among the best grads of the Sweep-It-Under-Someone-
Else's-Carpet School of Simulated Simplicity. [Was that sufficiently
incendiary? :-)] - Larry Wall in <1992Jan10.201804.11926@netlabs.com
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-19 12:33 ` Wolfgang Denk
@ 2014-05-19 18:10 ` Jeroen Hofstee
2014-05-19 18:30 ` Wolfgang Denk
0 siblings, 1 reply; 24+ messages in thread
From: Jeroen Hofstee @ 2014-05-19 18:10 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-19 18:10 ` Jeroen Hofstee
@ 2014-05-19 18:30 ` Wolfgang Denk
2014-05-19 20:42 ` Jeroen Hofstee
0 siblings, 1 reply; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-19 18:30 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Intel told us the Pentium would have "RISK" features...
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-19 18:30 ` Wolfgang Denk
@ 2014-05-19 20:42 ` Jeroen Hofstee
2014-05-19 21:05 ` Wolfgang Denk
0 siblings, 1 reply; 24+ messages in thread
From: Jeroen Hofstee @ 2014-05-19 20:42 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-19 20:42 ` Jeroen Hofstee
@ 2014-05-19 21:05 ` Wolfgang Denk
2014-05-20 17:42 ` Jeroen Hofstee
0 siblings, 1 reply; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-19 21:05 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I'd rather be led to hell than managed to heaven.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-19 21:05 ` Wolfgang Denk
@ 2014-05-20 17:42 ` Jeroen Hofstee
0 siblings, 0 replies; 24+ messages in thread
From: Jeroen Hofstee @ 2014-05-20 17:42 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-16 16:23 ` Darwin Rambo
2014-05-16 20:28 ` Wolfgang Denk
@ 2014-05-22 14:19 ` fenghua at phytium.com.cn
2014-05-23 6:51 ` Wolfgang Denk
1 sibling, 1 reply; 24+ messages in thread
From: fenghua at phytium.com.cn @ 2014-05-22 14:19 UTC (permalink / raw)
To: u-boot
> On 14-05-16 06:47 AM, fenghua at 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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-22 14:19 ` fenghua at phytium.com.cn
@ 2014-05-23 6:51 ` Wolfgang Denk
2014-05-26 13:11 ` fenghua at phytium.com.cn
0 siblings, 1 reply; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-23 6:51 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If the hours are long enough and the pay is short enough, someone
will say it's women's work.
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-23 6:51 ` Wolfgang Denk
@ 2014-05-26 13:11 ` fenghua at phytium.com.cn
2014-05-26 14:38 ` Wolfgang Denk
0 siblings, 1 reply; 24+ messages in thread
From: fenghua at phytium.com.cn @ 2014-05-26 13:11 UTC (permalink / raw)
To: u-boot
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
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] armv8 relocation questions
2014-05-26 13:11 ` fenghua at phytium.com.cn
@ 2014-05-26 14:38 ` Wolfgang Denk
0 siblings, 0 replies; 24+ messages in thread
From: Wolfgang Denk @ 2014-05-26 14:38 UTC (permalink / raw)
To: u-boot
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
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
You don't have to stay up nights to succeed; you have to stay awake
days.
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2014-05-26 14:38 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-13 21:38 [U-Boot] armv8 relocation questions Darwin Rambo
2014-05-16 13:47 ` fenghua at phytium.com.cn
2014-05-16 16:23 ` Darwin Rambo
2014-05-16 20:28 ` Wolfgang Denk
2014-05-16 21:15 ` Tom Rini
2014-05-16 22:26 ` Jeroen Hofstee
2014-05-17 2:13 ` fenghua at phytium.com.cn
2014-05-17 16:53 ` Wolfgang Denk
2014-05-18 12:37 ` Jeroen Hofstee
2014-05-18 19:51 ` Wolfgang Denk
2014-05-19 7:37 ` Jeroen Hofstee
2014-05-19 12:33 ` Wolfgang Denk
2014-05-19 18:10 ` Jeroen Hofstee
2014-05-19 18:30 ` Wolfgang Denk
2014-05-19 20:42 ` Jeroen Hofstee
2014-05-19 21:05 ` Wolfgang Denk
2014-05-20 17:42 ` Jeroen Hofstee
2014-05-16 21:24 ` Darwin Rambo
2014-05-16 21:52 ` Tom Rini
2014-05-22 14:19 ` fenghua at phytium.com.cn
2014-05-23 6:51 ` Wolfgang Denk
2014-05-26 13:11 ` fenghua at phytium.com.cn
2014-05-26 14:38 ` Wolfgang Denk
2014-05-17 3:53 ` fenghua at phytium.com.cn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).