diff mbox

arm: Allow u-boot to run from offset base address

Message ID 1400105145-6628-1-git-send-email-drambo@broadcom.com
State New
Headers show

Commit Message

Darwin Rambo May 14, 2014, 10:05 p.m. UTC
If an earlier loader stage requires an image header and a specific
offset, then u-boot's base address (CONFIG_SYS_TEXT_BASE) may be
advanced beyond an aligned address. In this case the relocation
will not be done correctly for some sections such as vectors and rodata
string tables, which will show an incorrect offset after the symbols
are fixed up. Advance the relocation address by the image offset so that
the gd->reloc_off used will result in relocating these sections to their
correct addresses.

This change is done under CONFIG_ARM64 conditional compilation
because it has only been tested there and may not be appropriate
for other architectures.

Signed-off-by: Darwin Rambo <drambo@broadcom.com>
Reviewed-by: Steve Rae <srae@broadcom.com>
---

 arch/arm/lib/board.c |   13 +++++++++++++
 common/board_f.c     |   10 ++++++++++
 2 files changed, 23 insertions(+)

Comments

Jeroen Hofstee May 14, 2014, 10:41 p.m. UTC | #1
Hello Darwin,

On wo, 2014-05-14 at 15:05 -0700, Darwin Rambo wrote:

> +#ifdef CONFIG_ARM64
> +	/*
> +	 * Fix relocation if u-boot is not on an aligned address.
> +	 */
> +	{
> +		int offset = CONFIG_SYS_TEXT_BASE % 4096;
> +		if (offset) {
> +			addr += offset;
> +			debug("Relocation Addr bumped to 0x%08lx\n", addr);
> +		}
> +	}
> +#endif
> +

Do you really want to check a define at runtime? Placement is typically
at the end of RAM and allocation goes down, not up as in this patch.
Aren't you overlapping memory here?

>  
>  static int setup_reloc(void)
>  {
> +#ifdef CONFIG_ARM64
> +	/*
> +	 * Fix relocation if u-boot is not on an aligned address.
> +	 */
> +	int offset = CONFIG_SYS_TEXT_BASE % 4096;
> +	if (offset) {
> +		gd->relocaddr += offset;
> +		debug("Relocation Addr bumped to 0x%08lx\n", gd->relocaddr);
> +	}
> +#endif
>  	gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
>  	memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
>  

This is a generic file, hell breaks loose if you start using arch /
board / pre bootloader specific workarounds here afaiac.

lucky for you, I am not a u-boot maintainer, but this looks at least a
bit weird, glancing at it.

Regards,
Jeroen
Wolfgang Denk May 15, 2014, 4:26 a.m. UTC | #2
Dear Darwin Rambo,

In message <1400105145-6628-1-git-send-email-drambo@broadcom.com> you wrote:
> If an earlier loader stage requires an image header and a specific
> offset, then u-boot's base address (CONFIG_SYS_TEXT_BASE) may be
> advanced beyond an aligned address. In this case the relocation

Sorry, I cannot parse that.  CONFIG_SYS_TEXT_BASE is a compile time
constant, it cannot be "advanced" by a loader.  Do you mean that some
loader loads U-Boot to an incorrect address?  Well, in this case the
loader should be fixed, or?

> This change is done under CONFIG_ARM64 conditional compilation
> because it has only been tested there and may not be appropriate
> for other architectures.

In any case, any such changes (if there should be agreement that they
are actually useful) should be done in an architecture-neutral way.
Implementing it for one specific architecture only is wrong.

Best regards,

Wolfgang Denk
Darwin Rambo May 15, 2014, 2:16 p.m. UTC | #3
On 14-05-14 09:26 PM, Wolfgang Denk wrote:
> Dear Darwin Rambo,
>
> In message <1400105145-6628-1-git-send-email-drambo@broadcom.com> you wrote:
>> If an earlier loader stage requires an image header and a specific
>> offset, then u-boot's base address (CONFIG_SYS_TEXT_BASE) may be
>> advanced beyond an aligned address. In this case the relocation
> Sorry, I cannot parse that.  CONFIG_SYS_TEXT_BASE is a compile time
> constant, it cannot be "advanced" by a loader.  Do you mean that some
> loader loads U-Boot to an incorrect address?  Well, in this case the
> loader should be fixed, or?

Thank you for your comments.
  
I mean that the loader loads u-boot to it's correct address, which is
offset by a small amount because of a previous header requiring alignment.
Here's an example. u-boot is compiled to run at 0x88000020 because we want
to put a small header in front of the image, which starts at 0x88000000 and
needs to be aligned for its own reasons. Now for arm64, I believe that u-boot
cannot normally be positioned at any alignment less than 0x800 hex. So
u-boot would normally run at addresses like 0x88000000, 0x88000800, 0x88001000, etc.
And in these cases the relocation works fine. But if we want to position u-boot
at a smaller offset than 0x800, the symbol relocation breaks for arm64. It
turns out that there is a trivial fix so that u-boot can run at smaller offset
addresses, which I have provided here, is tested, and solves our problem nicely,
but only for arm64 right now.

>
>> This change is done under CONFIG_ARM64 conditional compilation
>> because it has only been tested there and may not be appropriate
>> for other architectures.
> In any case, any such changes (if there should be agreement that they
> are actually useful) should be done in an architecture-neutral way.
> Implementing it for one specific architecture only is wrong.

Yes, I agree, but I am not sure if this is a arm64-only problem or not.
Armv7 doesn't show this problem, and I can't test other architectures
for their alignment issues. So I thought that I would at least show the
fix for arm64 so we can decide if and how to proceed. Any suggestions you
can provide on how to proceed would be appreciated. And if the fix is
not suitable for upstreaming, then we should know it.

Is there a way to have architecture specific hooks like this called from
the generic common/board_f.c? The fix is also in arch/arm/lib/board.c but it
sounds like that file might be disappearing.

Also there might be a generic fix possible that works for all architectures
(by removing the ifdef CONFIG_ARM64), but I don't have the resources to test
them. Maybe it would be best to decide if we want to support this feature or
not first. Thanks!

Regards,
Darwin

>
> Best regards,
>
> Wolfgang Denk
>
Darwin Rambo May 15, 2014, 2:21 p.m. UTC | #4
On 14-05-14 03:41 PM, Jeroen Hofstee wrote:
> Hello Darwin,
>
> On wo, 2014-05-14 at 15:05 -0700, Darwin Rambo wrote:
>
>> +#ifdef CONFIG_ARM64
>> +	/*
>> +	 * Fix relocation if u-boot is not on an aligned address.
>> +	 */
>> +	{
>> +		int offset = CONFIG_SYS_TEXT_BASE % 4096;
>> +		if (offset) {
>> +			addr += offset;
>> +			debug("Relocation Addr bumped to 0x%08lx\n", addr);
>> +		}
>> +	}
>> +#endif
>> +
> Do you really want to check a define at runtime? Placement is typically
> at the end of RAM and allocation goes down, not up as in this patch.
> Aren't you overlapping memory here?

Yes, I wanted the runtime check since the adjustment to the relocation
address is also done at runtime.

There is no overlap here. The reason is that the original masking operation
to mask to a 4K boundary removed the small offset and backed up too far. So
adding the lost offset is guaranteed to not overlap, and furthermore, correct
the relocation offset so that arm64 images can run at smaller alignments than
we normally use. This might even be a generic fix but can't be tested easily
by me.

>
>>   
>>   static int setup_reloc(void)
>>   {
>> +#ifdef CONFIG_ARM64
>> +	/*
>> +	 * Fix relocation if u-boot is not on an aligned address.
>> +	 */
>> +	int offset = CONFIG_SYS_TEXT_BASE % 4096;
>> +	if (offset) {
>> +		gd->relocaddr += offset;
>> +		debug("Relocation Addr bumped to 0x%08lx\n", gd->relocaddr);
>> +	}
>> +#endif
>>   	gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
>>   	memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
>>   
> This is a generic file, hell breaks loose if you start using arch /
> board / pre bootloader specific workarounds here afaiac.

I don't disagree with this statement. Please see my other comments to
Wolfgang on this topic.

>
> lucky for you, I am not a u-boot maintainer, but this looks at least a
> bit weird, glancing at it.
>
> Regards,
> Jeroen
>
Thanks for your comments Jeroen. They are appreciated.
Darwin
Wolfgang Denk May 15, 2014, 3:16 p.m. UTC | #5
Dear Darwin,

In message <5374CC3B.7000504@broadcom.com> you wrote:
> 
> I mean that the loader loads u-boot to it's correct address, which is
> offset by a small amount because of a previous header requiring alignment.
> Here's an example. u-boot is compiled to run at 0x88000020 because we want
> to put a small header in front of the image, which starts at 0x88000000 and
> needs to be aligned for its own reasons. Now for arm64, I believe that u-boot
> cannot normally be positioned at any alignment less than 0x800 hex. So

I thing you have some misunderstanding of the meaning of the start
address of the image versus the entry point address.  These are not
related.  You can add any headers or padding you like to the image,
and put the entry point at an arbitrary address.

The restrictions we usually face are due to the bootmodes of the SoC,
which may start from a fixed reset address (whwere we then must make
sure that this is also the entry point address in the image), or where
the ROM boot loader may have specific requirements.

If you add some custom image header, you can also start at some random
entry point addres.. Just adapt your linker script as needed.

> And in these cases the relocation works fine. But if we want to position u-boot
> at a smaller offset than 0x800, the symbol relocation breaks for arm64. It
> turns out that there is a trivial fix so that u-boot can run at smaller offset
> addresses, which I have provided here, is tested, and solves our problem nicely,
> but only for arm64 right now.

No, your patch is highly dubious actually.  Note that the entry point
address which we are talking about is where code execution starts
_before_ relocation.  Relocation is a totally different topic.  The
address where we relocate to gets computed at runtime, and does not
depend on CONFIG_SYS_TEXT_BASE at all.  Also, as had been pointed out
before, memory allocation happens top down, so any adjustments you
want to make must be to lower addresses, never upward.

> Yes, I agree, but I am not sure if this is a arm64-only problem or not.

Unfortunaltely you don't explain what you really want to do. We have
the same task (loading the U-Boot image and starting it) in many,
nmany configurations either when a ROM boot loader performs the
loading, or where the SPL does it.  This is a well understood
procedure, and it has no such problem as you claim to have.

I suspect you have bugs elsewhere in your port, may it be the linker
script or your implementation of a special image header or whatever.

> can provide on how to proceed would be appreciated. And if the fix is
> not suitable for upstreaming, then we should know it.

Please understand that this is not a question of suitable for
upstreaming or not, it is a matter of correct or not.  I am pretty
much convinced that your modifcation cannot be right.

> Also there might be a generic fix possible that works for all architectures
> (by removing the ifdef CONFIG_ARM64), but I don't have the resources to test
> them. Maybe it would be best to decide if we want to support this feature or
> not first. Thanks!

Please define "this feature" in an exact way, and why you think it
would cause any problems.

Best regards,

Wolfgang Denk
Wolfgang Denk May 15, 2014, 3:21 p.m. UTC | #6
Dear Darwin,

In message <5374CD55.3010703@broadcom.com> you wrote:
> 
> > Do you really want to check a define at runtime? Placement is typically
> > at the end of RAM and allocation goes down, not up as in this patch.
> > Aren't you overlapping memory here?
> 
> Yes, I wanted the runtime check since the adjustment to the relocation
> address is also done at runtime.

This makes no sense to me.  CONFIG_SYS_TEXT_BASE is a compile time
constant.  So the result of all this is always known at compile time,
too.  I feel you misunderstand that CONFIG_SYS_TEXT_BASE is just the
start address of the text segment.  If you want to offset this by a
specific amount, you can just define this as needed.

> There is no overlap here. The reason is that the original masking operation
> to mask to a 4K boundary removed the small offset and backed up too far. So
> adding the lost offset is guaranteed to not overlap, and furthermore, correct
> the relocation offset so that arm64 images can run at smaller alignments than
> we normally use. This might even be a generic fix but can't be tested easily
> by me.

Argh... This is black magic depending on specific properties of your
process (which you don;t really explain).  Sorry, but this is a full
NAK for code that is build on sand like this.

Best regards,

Wolfgang Denk
Darwin Rambo May 15, 2014, 4:07 p.m. UTC | #7
On 14-05-15 08:21 AM, Wolfgang Denk wrote:
> Dear Darwin,
>
> In message <5374CD55.3010703@broadcom.com> you wrote:
>>> Do you really want to check a define at runtime? Placement is typically
>>> at the end of RAM and allocation goes down, not up as in this patch.
>>> Aren't you overlapping memory here?
>> Yes, I wanted the runtime check since the adjustment to the relocation
>> address is also done at runtime.
> This makes no sense to me.  CONFIG_SYS_TEXT_BASE is a compile time
> constant.  So the result of all this is always known at compile time,
> too.  I feel you misunderstand that CONFIG_SYS_TEXT_BASE is just the
> start address of the text segment.  If you want to offset this by a
> specific amount, you can just define this as needed.

May I respectfully ask that you please bear with me a just a bit longer so
I can try to explain things better?

CONFIG_SYS_TEXT_BASE is also used by the relocation calculations at runtime
to determine the relocation offset, which is also used for the symbol fixup
logic. It is known at compile time, but is used at runtime by the stock
u-boot code to determine the relocation offset. I am doing nothing more than
existing code in this regard.

If I set it to 0x88000020, then the code crashes because the symbol fixup
depends on the relocation offset which is now wrong. The reason is that the
relocation offset calculated in the code doesn't account for this offset.
If we adjust the relocation address, then the relocation offset is now
correct and the symbol fixups work perfectly.

Here's an example:
CONFIG_SYS_TEXT_BASE = 0x88000020
relocated address = 0xfffa8000   (This 4K alignment assumption breaks the relocation)
relocation offset = 0x77fa7fe0   (This is now wrong and the relocation breaks)

My patch does the following:
CONFIG_SYS_TEXT_BASE = 0x88000020
relocated address = 0xfffa8020
relocation offset = 0x77fa8000   (symbol fixups now work)

So this patch just gives us a way to run u-boot at text sections with
smaller alignments. In the past I never really understood why
CONFIG_SYS_TEXT_BASE had to be on specific alignments like XXXXX000 for
our architecture and the symbol fixup issue helps to explain this.

I know this is not the normal use case but it does fix the crash in the
symbol relocation with arm64 and allows u-boot to be more flexible in
it's text alignment requirements.

Thanks.

Best regards,
Darwin

>
>> There is no overlap here. The reason is that the original masking operation
>> to mask to a 4K boundary removed the small offset and backed up too far. So
>> adding the lost offset is guaranteed to not overlap, and furthermore, correct
>> the relocation offset so that arm64 images can run at smaller alignments than
>> we normally use. This might even be a generic fix but can't be tested easily
>> by me.
> Argh... This is black magic depending on specific properties of your
> process (which you don;t really explain).  Sorry, but this is a full
> NAK for code that is build on sand like this.
>
> Best regards,
>
> Wolfgang Denk
>
Wolfgang Denk May 15, 2014, 7:19 p.m. UTC | #8
Dear Darwin,

In message <5374E64B.1060104@broadcom.com> you wrote:
> 
> > This makes no sense to me.  CONFIG_SYS_TEXT_BASE is a compile time
> > constant.  So the result of all this is always known at compile time,
> > too.  I feel you misunderstand that CONFIG_SYS_TEXT_BASE is just the
> > start address of the text segment.  If you want to offset this by a
> > specific amount, you can just define this as needed.
> 
> May I respectfully ask that you please bear with me a just a bit longer so
> I can try to explain things better?
> 
> CONFIG_SYS_TEXT_BASE is also used by the relocation calculations at runtime
> to determine the relocation offset, which is also used for the symbol fixup
> logic. It is known at compile time, but is used at runtime by the stock
> u-boot code to determine the relocation offset. I am doing nothing more than
> existing code in this regard.

Let's have a look at your proposed code:

>> +		int offset = CONFIG_SYS_TEXT_BASE % 4096;
>> +		if (offset) {
>> +			addr += offset;
>> +			debug("Relocation Addr bumped to 0x%08lx\n", addr);
>> +		}

> If I set it to 0x88000020, then the code crashes because the symbol fixup
> depends on the relocation offset which is now wrong. The reason is that the
> relocation offset calculated in the code doesn't account for this offset.
> If we adjust the relocation address, then the relocation offset is now
> correct and the symbol fixups work perfectly.

First, please keep in mind that you cannot set CONFIG_SYS_TEXT_BASE in
arbitrary ways, at least not without adjusting your linker script
accordingly; also you may have limitations due to the way how the code
gets loaded / booted.  

_If_ your code is correct, then the target address computed for the
relocation is completely irrelevant.

> Here's an example:
> CONFIG_SYS_TEXT_BASE = 0x88000020
> relocated address = 0xfffa8000   (This 4K alignment assumption breaks the relocation)
> relocation offset = 0x77fa7fe0   (This is now wrong and the relocation breaks)
> 
> My patch does the following:
> CONFIG_SYS_TEXT_BASE = 0x88000020
> relocated address = 0xfffa8020
> relocation offset = 0x77fa8000   (symbol fixups now work)

You are mixing up copying code to another address range and relocating
symbols.

> So this patch just gives us a way to run u-boot at text sections with
> smaller alignments. In the past I never really understood why
> CONFIG_SYS_TEXT_BASE had to be on specific alignments like XXXXX000 for
> our architecture and the symbol fixup issue helps to explain this.

In many cases there is no strict reason.  When storing the images in
NOR flash or other block oriented storage it is usually convenient to
align them to sector boundaaries.  In systems where you have a MMU on,
it may be useful / convenient / necessary to have it aligned to page
boundaries.  But al this is totally irrelevant here.  Consider the
address arbitrarily chosen, it does not matter.

Also, moving the relocation address around by arbitrary amounts (that
are big enough not to cause alignment issues, say anything that is a
multiple of the cache line size) does not change anything.

If there are problems, these are somewhere in your implementation, and
not in the generic code.

> I know this is not the normal use case but it does fix the crash in the
> symbol relocation with arm64 and allows u-boot to be more flexible in
> it's text alignment requirements.

You ask for a "flexibility" that actually is already there; it's just
conveniend when debugging etc. to have "nice" addresses.  If there is
something not working, it's in your code.

Setting CONFIG_SYS_TEXT_BASE to something like 0x88000020 is extremly
fishy.  If you want to add some header data to your image, you should
not shift the text segment, but rather include your header in the
start of the text segment.  Or keep it completely separate, without
messing with CONFIG_SYS_TEXT_BASE.  


Best regards,

Wolfgang Denk
Albert ARIBAUD May 26, 2014, 9:50 a.m. UTC | #9
Hi Wolfgang, Darwin,

On Thu, 15 May 2014 21:19:57 +0200, Wolfgang Denk <wd@denx.de> wrote:

> Setting CONFIG_SYS_TEXT_BASE to something like 0x88000020 is extremly
> fishy.  If you want to add some header data to your image, you should
> not shift the text segment, but rather include your header in the
> start of the text segment.  Or keep it completely separate, without
> messing with CONFIG_SYS_TEXT_BASE.  

Back to the origin of the discussion and patch:

Darwin, can you describe the actual technical difficulty which caused
you to you write and submitting this patch?

> Best regards,
> 
> Wolfgang Denk

Amicalement,
Darwin Rambo May 26, 2014, 4:11 p.m. UTC | #10
Hi Albert,

The previous stage bootloader (which I had no control over) wanted it's 
header to be aligned to a 512 byte MMC block boundary, presumably since 
this allowed DMA operations without copy/shifting. At the same time, I 
didn't want to hack a header into start.S because I didn't want to carry 
another downstream patch. So I investigated if I could shift u-boot's 
base address as a feature that would allow an aligned header to be used 
without the start.S patch.

I know that a custom header patch to start.S would work, and that a 
header plus padding will also work. But I found out that you can align 
the base on certain smaller offsets if you keep the relocation offset at 
nice boundaries like 0x1000 and if the relocation offset is a multiple 
of the maximum alignment requirements of the image.

The original patch I submitted didn't handle an end condition properly, 
was ARM64-specific (wasn't tested on other architectures), and because 
the patch was NAK'd, I didn't bother to submit a v2 patch and consider 
the idea to be dead. I'm happy to abandon the patch. I hope this helps.

Best regards,
Darwin

On 14-05-26 02:50 AM, Albert ARIBAUD wrote:
> Hi Wolfgang, Darwin,
>
> On Thu, 15 May 2014 21:19:57 +0200, Wolfgang Denk <wd@denx.de> wrote:
>
>> Setting CONFIG_SYS_TEXT_BASE to something like 0x88000020 is extremly
>> fishy.  If you want to add some header data to your image, you should
>> not shift the text segment, but rather include your header in the
>> start of the text segment.  Or keep it completely separate, without
>> messing with CONFIG_SYS_TEXT_BASE.
>
> Back to the origin of the discussion and patch:
>
> Darwin, can you describe the actual technical difficulty which caused
> you to you write and submitting this patch?
>
>> Best regards,
>>
>> Wolfgang Denk
>
> Amicalement,
>
Albert ARIBAUD June 2, 2014, 7:26 a.m. UTC | #11
Hi Darwin,

On Mon, 26 May 2014 09:11:35 -0700, Darwin Rambo <drambo@broadcom.com>
wrote:

> Hi Albert,
> 
> The previous stage bootloader (which I had no control over) wanted it's 
> header to be aligned to a 512 byte MMC block boundary, presumably since 
> this allowed DMA operations without copy/shifting. At the same time, I 
> didn't want to hack a header into start.S because I didn't want to carry 
> another downstream patch. So I investigated if I could shift u-boot's 
> base address as a feature that would allow an aligned header to be used 
> without the start.S patch.
> 
> I know that a custom header patch to start.S would work, and that a 
> header plus padding will also work. But I found out that you can align 
> the base on certain smaller offsets if you keep the relocation offset at 
> nice boundaries like 0x1000 and if the relocation offset is a multiple 
> of the maximum alignment requirements of the image.
> 
> The original patch I submitted didn't handle an end condition properly, 
> was ARM64-specific (wasn't tested on other architectures), and because 
> the patch was NAK'd, I didn't bother to submit a v2 patch and consider 
> the idea to be dead. I'm happy to abandon the patch. I hope this helps.

Thanks.

If I understand correctly, your target has a requirement for storing
the image on a 512-byte boundary. But how does this affect the loading
of the image into RAM, where the requirement is only that the vectors
table be 32-bytes aligned? I mean, if you store the image in MMC at
offset 0x200 (thus satisfying the 512-byte boundary requirement) and
load it to, say, offset 0x10020 in RAM, how is it a problem for
your target?

If my example above inadequately represents the issue, then can you
please provide a similar but adequate example, a failure case scenario,
so that I can hve a correct understanding of the problem?

> Best regards,
> Darwin

Amicalement,
Darwin Rambo June 3, 2014, 12:37 a.m. UTC | #12
On 14-06-02 12:26 AM, Albert ARIBAUD wrote:
> Hi Darwin,
>
> On Mon, 26 May 2014 09:11:35 -0700, Darwin Rambo <drambo@broadcom.com>
> wrote:
>
>> Hi Albert,
>>
>> The previous stage bootloader (which I had no control over) wanted it's
>> header to be aligned to a 512 byte MMC block boundary, presumably since
>> this allowed DMA operations without copy/shifting. At the same time, I
>> didn't want to hack a header into start.S because I didn't want to carry
>> another downstream patch. So I investigated if I could shift u-boot's
>> base address as a feature that would allow an aligned header to be used
>> without the start.S patch.
>>
>> I know that a custom header patch to start.S would work, and that a
>> header plus padding will also work. But I found out that you can align
>> the base on certain smaller offsets if you keep the relocation offset at
>> nice boundaries like 0x1000 and if the relocation offset is a multiple
>> of the maximum alignment requirements of the image.
>>
>> The original patch I submitted didn't handle an end condition properly,
>> was ARM64-specific (wasn't tested on other architectures), and because
>> the patch was NAK'd, I didn't bother to submit a v2 patch and consider
>> the idea to be dead. I'm happy to abandon the patch. I hope this helps.
>
> Thanks.
>
> If I understand correctly, your target has a requirement for storing
> the image on a 512-byte boundary. But how does this affect the loading
> of the image into RAM, where the requirement is only that the vectors
> table be 32-bytes aligned? I mean, if you store the image in MMC at
> offset 0x200 (thus satisfying the 512-byte boundary requirement) and
> load it to, say, offset 0x10020 in RAM, how is it a problem for
> your target?
>
> If my example above inadequately represents the issue, then can you
> please provide a similar but adequate example, a failure case scenario,
> so that I can hve a correct understanding of the problem?

Hi Albert,

The constraints I have that I can't change, are that
- the 32 byte header is postprocessed and prepended to the image after 
the build is complete
- the header is at a 512 byte alignment in MMC
- the header and image are copied to SDRAM to an alignment like 
0x88000000. Thus the u-boot image is linked at and starts at 0x88000020.
- the vectors need to be 0x800 aligned for armv8 (.align 11 directive)

So the failure case is that when the relocation happens, it relocates to 
a 0x1000 alignment, say something like 0xffffa000. The relocation offset 
is not a multiple of 0x1000 (0xffffa000 - 0x88000020) and the relocation 
fails. Adjusting the relocation offset to a multiple of 0x1000 (by 
making the relocation address end in 0xNNNNN020) fixes the issues and 
allows u-boot to relocate and run from this address without failing. I 
hope this helps explain it a bit better.

Best regards,
Darwin

>
>> Best regards,
>> Darwin
>
> Amicalement,
>
Albert ARIBAUD June 9, 2014, 10:23 a.m. UTC | #13
Hi Darwin,

On Mon, 2 Jun 2014 17:37:25 -0700, Darwin Rambo <drambo@broadcom.com>
wrote:

> 
> 
> On 14-06-02 12:26 AM, Albert ARIBAUD wrote:
> > Hi Darwin,
> >
> > On Mon, 26 May 2014 09:11:35 -0700, Darwin Rambo <drambo@broadcom.com>
> > wrote:
> >
> >> Hi Albert,
> >>
> >> The previous stage bootloader (which I had no control over) wanted it's
> >> header to be aligned to a 512 byte MMC block boundary, presumably since
> >> this allowed DMA operations without copy/shifting. At the same time, I
> >> didn't want to hack a header into start.S because I didn't want to carry
> >> another downstream patch. So I investigated if I could shift u-boot's
> >> base address as a feature that would allow an aligned header to be used
> >> without the start.S patch.
> >>
> >> I know that a custom header patch to start.S would work, and that a
> >> header plus padding will also work. But I found out that you can align
> >> the base on certain smaller offsets if you keep the relocation offset at
> >> nice boundaries like 0x1000 and if the relocation offset is a multiple
> >> of the maximum alignment requirements of the image.
> >>
> >> The original patch I submitted didn't handle an end condition properly,
> >> was ARM64-specific (wasn't tested on other architectures), and because
> >> the patch was NAK'd, I didn't bother to submit a v2 patch and consider
> >> the idea to be dead. I'm happy to abandon the patch. I hope this helps.
> >
> > Thanks.
> >
> > If I understand correctly, your target has a requirement for storing
> > the image on a 512-byte boundary. But how does this affect the loading
> > of the image into RAM, where the requirement is only that the vectors
> > table be 32-bytes aligned? I mean, if you store the image in MMC at
> > offset 0x200 (thus satisfying the 512-byte boundary requirement) and
> > load it to, say, offset 0x10020 in RAM, how is it a problem for
> > your target?
> >
> > If my example above inadequately represents the issue, then can you
> > please provide a similar but adequate example, a failure case scenario,
> > so that I can hve a correct understanding of the problem?
> 
> Hi Albert,
> 
> The constraints I have that I can't change, are that
> - the 32 byte header is postprocessed and prepended to the image after 
> the build is complete
> - the header is at a 512 byte alignment in MMC
> - the header and image are copied to SDRAM to an alignment like 
> 0x88000000. Thus the u-boot image is linked at and starts at 0x88000020.
> - the vectors need to be 0x800 aligned for armv8 (.align 11 directive)

So far, so good -- I understand that the link-time location of the
vectors table is incorrect.

> So the failure case is that when the relocation happens, it relocates to 
> a 0x1000 alignment, say something like 0xffffa000. The relocation offset 
> is not a multiple of 0x1000 (0xffffa000 - 0x88000020) and the relocation 
> fails.

What does "relocation fails" mean exactly, i.e., where and how exactly
does the relocation code behave differently from expected? I'm asking
because I don't understand why the relocation offset should be a
multiple of 0x1000.

> Adjusting the relocation offset to a multiple of 0x1000 (by 
> making the relocation address end in 0xNNNNN020) fixes the issues and 
> allows u-boot to relocate and run from this address without failing. I 
> hope this helps explain it a bit better.

I do understand, however, that if the relocation offset must indeed be a
multiple of 0x1000, then obviously the vectors table will end up as
misaligned as it was before relocation.

Also, personally I would like it if the vectors table was always
aligned as it should, and there are at least three other boards which
require a prefix/header before their vectors table, as Masahiro (cc:)
indicated recently, so that makes the problem a generic one: how to
properly integrate a header in-image (as opposed to an out-of-image
one, which is just a matter of doing a 'cat', so to speak.

Therefore I'd like a generic solution to this, where the header is
prepended *and* aligned properly without breaking the start symbol
alignment constraints. This /might/ be possible by cleverly adding
a '.header' or '.signature' section to the linker script, possibly
doing a two-stage link; but this should not require the source code to
contain ad hoc relocation tricks.

Let me tinker with it in the next few days; I'll try and come up with a
clean and generic solution to this "in-code header" question.

Thanks again for your explanation!

> Best regards,
> Darwin

Amicalement,
Steve Rae June 9, 2014, 8:45 p.m. UTC | #14
On 14-06-09 03:23 AM, Albert ARIBAUD wrote:
> Hi Darwin,
>
> On Mon, 2 Jun 2014 17:37:25 -0700, Darwin Rambo <drambo@broadcom.com>
> wrote:
>
>>
>>
>> On 14-06-02 12:26 AM, Albert ARIBAUD wrote:
>>> Hi Darwin,
>>>
>>> On Mon, 26 May 2014 09:11:35 -0700, Darwin Rambo <drambo@broadcom.com>
>>> wrote:
>>>
>>>> Hi Albert,
>>>>
>>>> The previous stage bootloader (which I had no control over) wanted it's
>>>> header to be aligned to a 512 byte MMC block boundary, presumably since
>>>> this allowed DMA operations without copy/shifting. At the same time, I
>>>> didn't want to hack a header into start.S because I didn't want to carry
>>>> another downstream patch. So I investigated if I could shift u-boot's
>>>> base address as a feature that would allow an aligned header to be used
>>>> without the start.S patch.
>>>>
>>>> I know that a custom header patch to start.S would work, and that a
>>>> header plus padding will also work. But I found out that you can align
>>>> the base on certain smaller offsets if you keep the relocation offset at
>>>> nice boundaries like 0x1000 and if the relocation offset is a multiple
>>>> of the maximum alignment requirements of the image.
>>>>
>>>> The original patch I submitted didn't handle an end condition properly,
>>>> was ARM64-specific (wasn't tested on other architectures), and because
>>>> the patch was NAK'd, I didn't bother to submit a v2 patch and consider
>>>> the idea to be dead. I'm happy to abandon the patch. I hope this helps.
>>>
>>> Thanks.
>>>
>>> If I understand correctly, your target has a requirement for storing
>>> the image on a 512-byte boundary. But how does this affect the loading
>>> of the image into RAM, where the requirement is only that the vectors
>>> table be 32-bytes aligned? I mean, if you store the image in MMC at
>>> offset 0x200 (thus satisfying the 512-byte boundary requirement) and
>>> load it to, say, offset 0x10020 in RAM, how is it a problem for
>>> your target?
>>>
>>> If my example above inadequately represents the issue, then can you
>>> please provide a similar but adequate example, a failure case scenario,
>>> so that I can hve a correct understanding of the problem?
>>
>> Hi Albert,
>>
>> The constraints I have that I can't change, are that
>> - the 32 byte header is postprocessed and prepended to the image after
>> the build is complete
>> - the header is at a 512 byte alignment in MMC
>> - the header and image are copied to SDRAM to an alignment like
>> 0x88000000. Thus the u-boot image is linked at and starts at 0x88000020.
>> - the vectors need to be 0x800 aligned for armv8 (.align 11 directive)
>
> So far, so good -- I understand that the link-time location of the
> vectors table is incorrect.
>
>> So the failure case is that when the relocation happens, it relocates to
>> a 0x1000 alignment, say something like 0xffffa000. The relocation offset
>> is not a multiple of 0x1000 (0xffffa000 - 0x88000020) and the relocation
>> fails.
>
> What does "relocation fails" mean exactly, i.e., where and how exactly
> does the relocation code behave differently from expected? I'm asking
> because I don't understand why the relocation offset should be a
> multiple of 0x1000.
>
>> Adjusting the relocation offset to a multiple of 0x1000 (by
>> making the relocation address end in 0xNNNNN020) fixes the issues and
>> allows u-boot to relocate and run from this address without failing. I
>> hope this helps explain it a bit better.
>
> I do understand, however, that if the relocation offset must indeed be a
> multiple of 0x1000, then obviously the vectors table will end up as
> misaligned as it was before relocation.
>
> Also, personally I would like it if the vectors table was always
> aligned as it should, and there are at least three other boards which
> require a prefix/header before their vectors table, as Masahiro (cc:)
> indicated recently, so that makes the problem a generic one: how to
> properly integrate a header in-image (as opposed to an out-of-image
> one, which is just a matter of doing a 'cat', so to speak.
>
> Therefore I'd like a generic solution to this, where the header is
> prepended *and* aligned properly without breaking the start symbol
> alignment constraints. This /might/ be possible by cleverly adding
> a '.header' or '.signature' section to the linker script, possibly
> doing a two-stage link; but this should not require the source code to
> contain ad hoc relocation tricks.
>
> Let me tinker with it in the next few days; I'll try and come up with a
> clean and generic solution to this "in-code header" question.
>
> Thanks again for your explanation!
>
>> Best regards,
>> Darwin
>
> Amicalement,
>

Perhaps an oversimplified example of the current code would help to 
explain this better:

scenario #1:
CONFIG_SYS_TEXT_BASE		0x88000000
vectors:	.align 11	/* exception vectors need to be on a 0x800 byte 
boundary */
compile/linker produces (before relocation):
_start	symbol is at		0x88000000
vectors	symbol is at		0x88000800
the relocation offset is:	0x77f9b000
therefore, after relocation:
_start	symbol is at		0xfff9b000 (0x88000000+0xfff9b000)
vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)

scenario #2:
CONFIG_SYS_TEXT_BASE		0x88000020
vectors:	.align 11	/* exception vectors need to be on a 0x800 byte 
boundary */
compiler/linker produces (before relocation):
_start	symbol is at		0x88000020
vectors	symbol is at		0x88000800
the relocation offset is:	0x77f9afe0
therefore, after relocation:
_start	symbol is at		0xfff9b000 (0x88000020+0x77f9afe0)
vectors	symbol is at		0xfff9b7e0 (0x88000800+0x77f9afe0)

Note that in scenario #2, after relocation, the vectors are not on a 
0x800 byte boundary anymore.

Thanks, Steve
Jeroen Hofstee June 9, 2014, 8:56 p.m. UTC | #15
On ma, 2014-06-09 at 13:45 -0700, Steve Rae wrote:
> 
[snip]
> Note that in scenario #2, after relocation, the vectors are not on a 
> 0x800 byte boundary anymore.
> 

As long as the compiler emits adrp instructions, which it already does
at -O0, it is not only limited to vectors. No code works as expected
after relocation.

Regards,
Jeroen
Albert ARIBAUD June 10, 2014, 5:16 a.m. UTC | #16
Hi Steve,

(sorry for the duplicate)

On Mon, 9 Jun 2014 13:45:50 -0700, Steve Rae <srae@broadcom.com> wrote:

> 
> 
> On 14-06-09 03:23 AM, Albert ARIBAUD wrote:
> > Hi Darwin,
> >
> > On Mon, 2 Jun 2014 17:37:25 -0700, Darwin Rambo <drambo@broadcom.com>
> > wrote:
> >
> >>
> >>
> >> On 14-06-02 12:26 AM, Albert ARIBAUD wrote:
> >>> Hi Darwin,
> >>>
> >>> On Mon, 26 May 2014 09:11:35 -0700, Darwin Rambo <drambo@broadcom.com>
> >>> wrote:
> >>>
> >>>> Hi Albert,
> >>>>
> >>>> The previous stage bootloader (which I had no control over) wanted it's
> >>>> header to be aligned to a 512 byte MMC block boundary, presumably since
> >>>> this allowed DMA operations without copy/shifting. At the same time, I
> >>>> didn't want to hack a header into start.S because I didn't want to carry
> >>>> another downstream patch. So I investigated if I could shift u-boot's
> >>>> base address as a feature that would allow an aligned header to be used
> >>>> without the start.S patch.
> >>>>
> >>>> I know that a custom header patch to start.S would work, and that a
> >>>> header plus padding will also work. But I found out that you can align
> >>>> the base on certain smaller offsets if you keep the relocation offset at
> >>>> nice boundaries like 0x1000 and if the relocation offset is a multiple
> >>>> of the maximum alignment requirements of the image.
> >>>>
> >>>> The original patch I submitted didn't handle an end condition properly,
> >>>> was ARM64-specific (wasn't tested on other architectures), and because
> >>>> the patch was NAK'd, I didn't bother to submit a v2 patch and consider
> >>>> the idea to be dead. I'm happy to abandon the patch. I hope this helps.
> >>>
> >>> Thanks.
> >>>
> >>> If I understand correctly, your target has a requirement for storing
> >>> the image on a 512-byte boundary. But how does this affect the loading
> >>> of the image into RAM, where the requirement is only that the vectors
> >>> table be 32-bytes aligned? I mean, if you store the image in MMC at
> >>> offset 0x200 (thus satisfying the 512-byte boundary requirement) and
> >>> load it to, say, offset 0x10020 in RAM, how is it a problem for
> >>> your target?
> >>>
> >>> If my example above inadequately represents the issue, then can you
> >>> please provide a similar but adequate example, a failure case scenario,
> >>> so that I can hve a correct understanding of the problem?
> >>
> >> Hi Albert,
> >>
> >> The constraints I have that I can't change, are that
> >> - the 32 byte header is postprocessed and prepended to the image after
> >> the build is complete
> >> - the header is at a 512 byte alignment in MMC
> >> - the header and image are copied to SDRAM to an alignment like
> >> 0x88000000. Thus the u-boot image is linked at and starts at 0x88000020.
> >> - the vectors need to be 0x800 aligned for armv8 (.align 11 directive)
> >
> > So far, so good -- I understand that the link-time location of the
> > vectors table is incorrect.
> >
> >> So the failure case is that when the relocation happens, it relocates to
> >> a 0x1000 alignment, say something like 0xffffa000. The relocation offset
> >> is not a multiple of 0x1000 (0xffffa000 - 0x88000020) and the relocation
> >> fails.
> >
> > What does "relocation fails" mean exactly, i.e., where and how exactly
> > does the relocation code behave differently from expected? I'm asking
> > because I don't understand why the relocation offset should be a
> > multiple of 0x1000.
> >
> >> Adjusting the relocation offset to a multiple of 0x1000 (by
> >> making the relocation address end in 0xNNNNN020) fixes the issues and
> >> allows u-boot to relocate and run from this address without failing. I
> >> hope this helps explain it a bit better.
> >
> > I do understand, however, that if the relocation offset must indeed be a
> > multiple of 0x1000, then obviously the vectors table will end up as
> > misaligned as it was before relocation.
> >
> > Also, personally I would like it if the vectors table was always
> > aligned as it should, and there are at least three other boards which
> > require a prefix/header before their vectors table, as Masahiro (cc:)
> > indicated recently, so that makes the problem a generic one: how to
> > properly integrate a header in-image (as opposed to an out-of-image
> > one, which is just a matter of doing a 'cat', so to speak.
> >
> > Therefore I'd like a generic solution to this, where the header is
> > prepended *and* aligned properly without breaking the start symbol
> > alignment constraints. This /might/ be possible by cleverly adding
> > a '.header' or '.signature' section to the linker script, possibly
> > doing a two-stage link; but this should not require the source code to
> > contain ad hoc relocation tricks.
> >
> > Let me tinker with it in the next few days; I'll try and come up with a
> > clean and generic solution to this "in-code header" question.
> >
> > Thanks again for your explanation!
> >
> >> Best regards,
> >> Darwin
> >
> > Amicalement,
> >
> 
> Perhaps an oversimplified example of the current code would help to 
> explain this better:
> 
> scenario #1:
> CONFIG_SYS_TEXT_BASE		0x88000000
> vectors:	.align 11	/* exception vectors need to be on a 0x800 byte 
> boundary */
> compile/linker produces (before relocation):
> _start	symbol is at		0x88000000
> vectors	symbol is at		0x88000800
> the relocation offset is:	0x77f9b000
> therefore, after relocation:
> _start	symbol is at		0xfff9b000 (0x88000000+0xfff9b000)
> vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)
> 
> scenario #2:
> CONFIG_SYS_TEXT_BASE		0x88000020
> vectors:	.align 11	/* exception vectors need to be on a 0x800 byte 
> boundary */
> compiler/linker produces (before relocation):
> _start	symbol is at		0x88000020
> vectors	symbol is at		0x88000800
> the relocation offset is:	0x77f9afe0
> therefore, after relocation:
> _start	symbol is at		0xfff9b000 (0x88000020+0x77f9afe0)
> vectors	symbol is at		0xfff9b7e0 (0x88000800+0x77f9afe0)
> 
> Note that in scenario #2, after relocation, the vectors are not on a 
> 0x800 byte boundary anymore.

Ok, so technically relocation works as it was told to, just was given
"garbage in", with an image with an unaligned base and _start symbol
(and an aligned vectors symbol); relocation worked as expected, and
aligned base and start, thus not aligning vectors.

Now, on to understanding why the CONFIG_SYS_TEXT_BASE is not aligned.

Can you provide details from the case where the actual issue has
arisen, or even better yet, provide a source tree and build command
line, that I could reproduce the build here?

> Thanks, Steve

Amicalement,
Steve Rae June 10, 2014, 5:56 p.m. UTC | #17
On 14-06-09 10:16 PM, Albert ARIBAUD wrote:
> Hi Steve,
>
> (sorry for the duplicate)
>
> On Mon, 9 Jun 2014 13:45:50 -0700, Steve Rae <srae@broadcom.com> wrote:
>
>>
>>
>> On 14-06-09 03:23 AM, Albert ARIBAUD wrote:
>>> Hi Darwin,
>>>
>>> On Mon, 2 Jun 2014 17:37:25 -0700, Darwin Rambo <drambo@broadcom.com>
>>> wrote:
>>>
>>>>
>>>>
>>>> On 14-06-02 12:26 AM, Albert ARIBAUD wrote:
>>>>> Hi Darwin,
>>>>>
>>>>> On Mon, 26 May 2014 09:11:35 -0700, Darwin Rambo <drambo@broadcom.com>
>>>>> wrote:
>>>>>
>>>>>> Hi Albert,
>>>>>>
>>>>>> The previous stage bootloader (which I had no control over) wanted it's
>>>>>> header to be aligned to a 512 byte MMC block boundary, presumably since
>>>>>> this allowed DMA operations without copy/shifting. At the same time, I
>>>>>> didn't want to hack a header into start.S because I didn't want to carry
>>>>>> another downstream patch. So I investigated if I could shift u-boot's
>>>>>> base address as a feature that would allow an aligned header to be used
>>>>>> without the start.S patch.
>>>>>>
>>>>>> I know that a custom header patch to start.S would work, and that a
>>>>>> header plus padding will also work. But I found out that you can align
>>>>>> the base on certain smaller offsets if you keep the relocation offset at
>>>>>> nice boundaries like 0x1000 and if the relocation offset is a multiple
>>>>>> of the maximum alignment requirements of the image.
>>>>>>
>>>>>> The original patch I submitted didn't handle an end condition properly,
>>>>>> was ARM64-specific (wasn't tested on other architectures), and because
>>>>>> the patch was NAK'd, I didn't bother to submit a v2 patch and consider
>>>>>> the idea to be dead. I'm happy to abandon the patch. I hope this helps.
>>>>>
>>>>> Thanks.
>>>>>
>>>>> If I understand correctly, your target has a requirement for storing
>>>>> the image on a 512-byte boundary. But how does this affect the loading
>>>>> of the image into RAM, where the requirement is only that the vectors
>>>>> table be 32-bytes aligned? I mean, if you store the image in MMC at
>>>>> offset 0x200 (thus satisfying the 512-byte boundary requirement) and
>>>>> load it to, say, offset 0x10020 in RAM, how is it a problem for
>>>>> your target?
>>>>>
>>>>> If my example above inadequately represents the issue, then can you
>>>>> please provide a similar but adequate example, a failure case scenario,
>>>>> so that I can hve a correct understanding of the problem?
>>>>
>>>> Hi Albert,
>>>>
>>>> The constraints I have that I can't change, are that
>>>> - the 32 byte header is postprocessed and prepended to the image after
>>>> the build is complete
>>>> - the header is at a 512 byte alignment in MMC
>>>> - the header and image are copied to SDRAM to an alignment like
>>>> 0x88000000. Thus the u-boot image is linked at and starts at 0x88000020.
>>>> - the vectors need to be 0x800 aligned for armv8 (.align 11 directive)
>>>
>>> So far, so good -- I understand that the link-time location of the
>>> vectors table is incorrect.
>>>
>>>> So the failure case is that when the relocation happens, it relocates to
>>>> a 0x1000 alignment, say something like 0xffffa000. The relocation offset
>>>> is not a multiple of 0x1000 (0xffffa000 - 0x88000020) and the relocation
>>>> fails.
>>>
>>> What does "relocation fails" mean exactly, i.e., where and how exactly
>>> does the relocation code behave differently from expected? I'm asking
>>> because I don't understand why the relocation offset should be a
>>> multiple of 0x1000.
>>>
>>>> Adjusting the relocation offset to a multiple of 0x1000 (by
>>>> making the relocation address end in 0xNNNNN020) fixes the issues and
>>>> allows u-boot to relocate and run from this address without failing. I
>>>> hope this helps explain it a bit better.
>>>
>>> I do understand, however, that if the relocation offset must indeed be a
>>> multiple of 0x1000, then obviously the vectors table will end up as
>>> misaligned as it was before relocation.
>>>
>>> Also, personally I would like it if the vectors table was always
>>> aligned as it should, and there are at least three other boards which
>>> require a prefix/header before their vectors table, as Masahiro (cc:)
>>> indicated recently, so that makes the problem a generic one: how to
>>> properly integrate a header in-image (as opposed to an out-of-image
>>> one, which is just a matter of doing a 'cat', so to speak.
>>>
>>> Therefore I'd like a generic solution to this, where the header is
>>> prepended *and* aligned properly without breaking the start symbol
>>> alignment constraints. This /might/ be possible by cleverly adding
>>> a '.header' or '.signature' section to the linker script, possibly
>>> doing a two-stage link; but this should not require the source code to
>>> contain ad hoc relocation tricks.
>>>
>>> Let me tinker with it in the next few days; I'll try and come up with a
>>> clean and generic solution to this "in-code header" question.
>>>
>>> Thanks again for your explanation!
>>>
>>>> Best regards,
>>>> Darwin
>>>
>>> Amicalement,
>>>
>>
>> Perhaps an oversimplified example of the current code would help to
>> explain this better:
>>
>> scenario #1:
>> CONFIG_SYS_TEXT_BASE		0x88000000
>> vectors:	.align 11	/* exception vectors need to be on a 0x800 byte
>> boundary */
>> compile/linker produces (before relocation):
>> _start	symbol is at		0x88000000
>> vectors	symbol is at		0x88000800
>> the relocation offset is:	0x77f9b000
>> therefore, after relocation:
>> _start	symbol is at		0xfff9b000 (0x88000000+0xfff9b000)
>> vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)
>>
>> scenario #2:
>> CONFIG_SYS_TEXT_BASE		0x88000020
>> vectors:	.align 11	/* exception vectors need to be on a 0x800 byte
>> boundary */
>> compiler/linker produces (before relocation):
>> _start	symbol is at		0x88000020
>> vectors	symbol is at		0x88000800
>> the relocation offset is:	0x77f9afe0
>> therefore, after relocation:
>> _start	symbol is at		0xfff9b000 (0x88000020+0x77f9afe0)
>> vectors	symbol is at		0xfff9b7e0 (0x88000800+0x77f9afe0)
>>
>> Note that in scenario #2, after relocation, the vectors are not on a
>> 0x800 byte boundary anymore.
>
> Ok, so technically relocation works as it was told to, just was given
> "garbage in", with an image with an unaligned base and _start symbol
> (and an aligned vectors symbol); relocation worked as expected, and
> aligned base and start, thus not aligning vectors.
>
> Now, on to understanding why the CONFIG_SYS_TEXT_BASE is not aligned.
>
> Can you provide details from the case where the actual issue has
> arisen, or even better yet, provide a source tree and build command
> line, that I could reproduce the build here?
>
>> Thanks, Steve
>
> Amicalement,
>

Albert et al.

There could be "many" reasons why the CONFIG_SYS_TEXT_BASE is not 
aligned on a 0x1000 byte boundary (Darwin has attempted to document his 
particular use-case...)

But we think that the solution to support this is relatively 
straightforward:
(1) after determining the "relocation address" (which will be on a 
0x1000 byte boundary),
(2) add "CONFIG_SYS_TEXT_BASE % 4096" to that "relocation address" 
(which effectively makes the "relocation offset" a multiple of 0x1000 
too...)
So, in the scenario #1, (CONFIG_SYS_TEXT_BASE % 4096) = 0, so this 
algorithm changes nothing.
And in scenario #2, (CONFIG_SYS_TEXT_BASE % 4096) = 0x20, therefore, we 
would now get the following:
the relocation offset is:	0x77f9b000
therefore, after relocation:
_start	symbol is at		0xfff9b020 (0x88000020+0x77f9b000)
vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)
Which results in everything being aligned properly before AND after 
relocation.
(3) HOWEVER, shifting the address UP may cause the end of the relocated 
code to run past the end of the available memory... So we could:
(3.1) always relocate DOWN by ((CONFIG_SYS_TEXT_BASE % 4096) - 4096), or
(3.2) add (CONFIG_SYS_TEXT_BASE % 4096) to the calculated "gd->mon_len" 
(which is the value used to determine the "relocation address"; this 
would guarantee that there is always enough space for the relocated code...)

Note: 3.1 would usually waste up to 4096 bytes; whereas 3.2 would only 
adjust when necessary; therefore, we prefer 3.2 ....

I trust that everyone will find this explanation acceptable...
If so, we can publish a [v2] patch.
Thanks, Steve
Wolfgang Denk June 10, 2014, 6:13 p.m. UTC | #18
Dear Steve,

In message <539746C4.9040004@broadcom.com> you wrote:
> 
> There could be "many" reasons why the CONFIG_SYS_TEXT_BASE is not 
> aligned on a 0x1000 byte boundary (Darwin has attempted to document his 
> particular use-case...)

We should be more precise here and ask for any _good_ reasons.

I can think of many good reasons to keep the text base aligned.  As
for the reasons to use an unaligned address that were brought up here,
I still think that it would have been better to use an aligned taxe
base and do the rest with a customized linker script.

> But we think that the solution to support this is relatively 
> straightforward:
> (1) after determining the "relocation address" (which will be on a 
> 0x1000 byte boundary),
> (2) add "CONFIG_SYS_TEXT_BASE % 4096" to that "relocation address" 
> (which effectively makes the "relocation offset" a multiple of 0x1000 
> too...)
> So, in the scenario #1, (CONFIG_SYS_TEXT_BASE % 4096) = 0, so this 
> algorithm changes nothing.
> And in scenario #2, (CONFIG_SYS_TEXT_BASE % 4096) = 0x20, therefore, we 
> would now get the following:
> the relocation offset is:	0x77f9b000
> therefore, after relocation:
> _start	symbol is at		0xfff9b020 (0x88000020+0x77f9b000)
> vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)

I still cannot understand why _start and CONFIG_SYS_TEXT_BASE would
have to be the same.  There is no such requirement.  What exactly
prevents you from assigning _start a location at offset 0x20 to the
start of the text segment, i. e. CONFIG_SYS_TEXT_BASE ?

Then everything should be still the same for you, and no voodoo coding
would be needed.

> (3) HOWEVER, shifting the address UP may cause the end of the relocated 
> code to run past the end of the available memory... So we could:

This problem is void if you just use a poperly aligned text base in
combination with a prope start.S resp. linker script to make sure
_start is where you want it.

> I trust that everyone will find this explanation acceptable...

No, I do not see a good reason to add such code.

Best regards,

Wolfgang Denk
Steve Rae June 10, 2014, 7:38 p.m. UTC | #19
On 14-06-10 11:13 AM, Wolfgang Denk wrote:
> Dear Steve,
>
> In message <539746C4.9040004@broadcom.com> you wrote:
>>
>> There could be "many" reasons why the CONFIG_SYS_TEXT_BASE is not
>> aligned on a 0x1000 byte boundary (Darwin has attempted to document his
>> particular use-case...)
>
> We should be more precise here and ask for any _good_ reasons.
>
> I can think of many good reasons to keep the text base aligned.  As
> for the reasons to use an unaligned address that were brought up here,
> I still think that it would have been better to use an aligned taxe
> base and do the rest with a customized linker script.
>
>> But we think that the solution to support this is relatively
>> straightforward:
>> (1) after determining the "relocation address" (which will be on a
>> 0x1000 byte boundary),
>> (2) add "CONFIG_SYS_TEXT_BASE % 4096" to that "relocation address"
>> (which effectively makes the "relocation offset" a multiple of 0x1000
>> too...)
>> So, in the scenario #1, (CONFIG_SYS_TEXT_BASE % 4096) = 0, so this
>> algorithm changes nothing.
>> And in scenario #2, (CONFIG_SYS_TEXT_BASE % 4096) = 0x20, therefore, we
>> would now get the following:
>> the relocation offset is:	0x77f9b000
>> therefore, after relocation:
>> _start	symbol is at		0xfff9b020 (0x88000020+0x77f9b000)
>> vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)
>
> I still cannot understand why _start and CONFIG_SYS_TEXT_BASE would
> have to be the same.  There is no such requirement.  What exactly
> prevents you from assigning _start a location at offset 0x20 to the
> start of the text segment, i. e. CONFIG_SYS_TEXT_BASE ?

Wolfgang et al.

I agree that they do not need to be the same...
So our issue is that basically "for every ARMv7 board in the company", 
we are currently maintaining our own modified/customized version of 
"arch/arm/cpu/armv7/start.S" in order to add the appropriate 32 byte 
header...
And we could choose to do it using other methods, but they all require 
us to maintain a customized version of linker scripts, or some other 
code, or ....
The request here is that with the addition of some relatively 
straightforward (upstreamed) code, then this can be handled 
automatically by a post-processing step and we would be able to use a 
pristine version of the upstreamed code...
Our desire is to get this into the beginnings of the "ARMv8" boards, so 
that we can avoid the maintenance issues we have with the current ARMv7 
boards.

We appreciate your consideration of this request.
Thanks, Steve

>
> Then everything should be still the same for you, and no voodoo coding
> would be needed.
>
>> (3) HOWEVER, shifting the address UP may cause the end of the relocated
>> code to run past the end of the available memory... So we could:
>
> This problem is void if you just use a poperly aligned text base in
> combination with a prope start.S resp. linker script to make sure
> _start is where you want it.
>
>> I trust that everyone will find this explanation acceptable...
>
> No, I do not see a good reason to add such code.
>
> Best regards,
>
> Wolfgang Denk
>
Wolfgang Denk June 10, 2014, 8:35 p.m. UTC | #20
Dear Steve,

In message <53975EC2.1080209@broadcom.com> you wrote:
> 
> > I still cannot understand why _start and CONFIG_SYS_TEXT_BASE would
> > have to be the same.  There is no such requirement.  What exactly
> > prevents you from assigning _start a location at offset 0x20 to the
> > start of the text segment, i. e. CONFIG_SYS_TEXT_BASE ?
> 
> Wolfgang et al.
> 
> I agree that they do not need to be the same...
> So our issue is that basically "for every ARMv7 board in the company", 
> we are currently maintaining our own modified/customized version of 
> "arch/arm/cpu/armv7/start.S" in order to add the appropriate 32 byte 
> header...

There should be more clever ways to implement this.  If nothing else
comes to mind, an #ifdef in "arch/arm/cpu/armv7/start.S" should be
sufficient to condistionally insert / adjust any offset that might be
needed for a specific board.

> And we could choose to do it using other methods, but they all require 
> us to maintain a customized version of linker scripts, or some other 
> code, or ....

... or a CONFIG setting in your board config file resp. your board's
defconfig.

> The request here is that with the addition of some relatively 
> straightforward (upstreamed) code, then this can be handled 
> automatically by a post-processing step and we would be able to use a 
> pristine version of the upstreamed code...

I'm sorry, but I disagree especially on the "straightforward" part.
Also, I see no reason to make the existing code unnecessarily complex,
and add more disadvantages (like increased meory footprint etc.) when
the same purpose can be implemented without adding any special code at
all.

> Our desire is to get this into the beginnings of the "ARMv8" boards, so 
> that we can avoid the maintenance issues we have with the current ARMv7 
> boards.
> 
> We appreciate your consideration of this request.

These are two different things: implementing a clean and easy way to
support a necessary feature is one thing; to do it in the suggested
way by adding code where none is needed is another thing.

I'm all for adding support for any features that are useful, even if
only for a single user, as long as they don't hurt other users.  All
I'm asking is to chose another way to implement this feature.  So far,
I did not see any arguments that my alternative proposals would cause
any problems to you?

Best regards,

Wolfgang Denk
Albert ARIBAUD June 10, 2014, 9:20 p.m. UTC | #21
Hi Steve,

On Tue, 10 Jun 2014 12:38:42 -0700, Steve Rae <srae@broadcom.com> wrote:

> 
> 
> On 14-06-10 11:13 AM, Wolfgang Denk wrote:
> > Dear Steve,
> >
> > In message <539746C4.9040004@broadcom.com> you wrote:
> >>
> >> There could be "many" reasons why the CONFIG_SYS_TEXT_BASE is not
> >> aligned on a 0x1000 byte boundary (Darwin has attempted to document his
> >> particular use-case...)
> >
> > We should be more precise here and ask for any _good_ reasons.
> >
> > I can think of many good reasons to keep the text base aligned.  As
> > for the reasons to use an unaligned address that were brought up here,
> > I still think that it would have been better to use an aligned taxe
> > base and do the rest with a customized linker script.
> >
> >> But we think that the solution to support this is relatively
> >> straightforward:
> >> (1) after determining the "relocation address" (which will be on a
> >> 0x1000 byte boundary),
> >> (2) add "CONFIG_SYS_TEXT_BASE % 4096" to that "relocation address"
> >> (which effectively makes the "relocation offset" a multiple of 0x1000
> >> too...)
> >> So, in the scenario #1, (CONFIG_SYS_TEXT_BASE % 4096) = 0, so this
> >> algorithm changes nothing.
> >> And in scenario #2, (CONFIG_SYS_TEXT_BASE % 4096) = 0x20, therefore, we
> >> would now get the following:
> >> the relocation offset is:	0x77f9b000
> >> therefore, after relocation:
> >> _start	symbol is at		0xfff9b020 (0x88000020+0x77f9b000)
> >> vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)
> >
> > I still cannot understand why _start and CONFIG_SYS_TEXT_BASE would
> > have to be the same.  There is no such requirement.  What exactly
> > prevents you from assigning _start a location at offset 0x20 to the
> > start of the text segment, i. e. CONFIG_SYS_TEXT_BASE ?
> 
> Wolfgang et al.
> 
> I agree that they do not need to be the same...
> So our issue is that basically "for every ARMv7 board in the company", 
> we are currently maintaining our own modified/customized version of 
> "arch/arm/cpu/armv7/start.S" in order to add the appropriate 32 byte 
> header...

That is not a good approach -- and I should know, as there are boards
out there which already insist on having a header (mind you, a simple
4-byte constant) in start.S, and I am already trying to tackle this
out of start.S.

Your 32-byte header should not be in start.S, it should be linked in
before start.o in the linker script. Then you would only have one
start.S file and as many headers as you require.

> And we could choose to do it using other methods, but they all require 
> us to maintain a customized version of linker scripts, or some other 
> code, or ....

Not necessarily. You'll need to configure your target, that's sure,
because I guess different targets will have different (values in
the bytes of their) headers, but you don't need to have different
start.S files.

> The request here is that with the addition of some relatively 
> straightforward (upstreamed) code, then this can be handled 
> automatically by a post-processing step and we would be able to use a 
> pristine version of the upstreamed code...
> Our desire is to get this into the beginnings of the "ARMv8" boards, so 
> that we can avoid the maintenance issues we have with the current ARMv7 
> boards.
>
> We appreciate your consideration of this request.
> Thanks, Steve

I (believe I) understand the problem, and I am discussing here because I
too want it solved. On the one hand I do agree with Wolfgang here:
 
> > No, I do not see a good reason to add such code.

... because I don't want to allow a feature that is designed to counter
a problem; but on the other hand I want the problem fixed. So Darwin,
in order to find a satisfactory solution, let me try to recap the
situation and then ask a few questions.

Recap:

1. A typical ARM binary image is linked to a base address, defined by
   preprocessor macro (aka U-Boot config option) CONFIG_SYS_TEXT_BASE.

2. A typical ARM target defines CONFIG_SYS_TEXT_BASE so that the image,
   and especially its exception vectors table, is properly aligned upon
   loading the image in RAM.

3. When the ARM image relocates itself, it does so to a destination
   address which is computed so that the image and its vectors table
   are still properly aligned after relocation.

4. Some targets require that the image stored in MMC be prepended with
   a 32-byte header (and aligned to a sector-related boundary).

5. For some targets (if not all) the header is not separate from the
   image, i.e., it will also be copied from MMC to RAM. Such headers
   must be prepended at the link stage or earlier, so that the
   link-time and run-time values of all image symbols are consistent.

6. However, because the header is put at the start of the image before
   the vectors table, the image is still properly aligned but th
   vectors tabled is not any more, both when the image is loaded from
   MMC to RAM, and when it is relocated.

7. This mis-alignment issue does not only affect the vectors table; it
   also affects any location addressed using adrp instructions (if I
   did correctly understand Jeroen, Cc:).

This is my understanding of the issue. If it is correct, then I
believe the following solves the issue without changing anything to
the current code:

Instead of prepending a 32-byte header to the image, prepend the header
then a block of 2048-32 bytes. This way, the MMC image base address
(the header address) is aligned, and the alignment of any address in
the image itself is preserved. 

If for some reason it is impossible to pad the header (such as, the
header is actually prepended by a closed-source tool which takes the
'raw' image in and spits the 'MMC image' out), then the raw image
should be prepended with 2048-32 bytes beforehand, so that the 32
header bytes make up a whole 2048-bytes block, and the image remains
aligned.   

However, I guess that you, Darwin and Steve, probably have thought of
this already and dismissed it for a reason. If so, please explain
what this reason is.

Amicalement,
Steve Rae June 11, 2014, 12:14 a.m. UTC | #22
On 14-06-10 02:20 PM, Albert ARIBAUD wrote:
> Hi Steve,
>
> On Tue, 10 Jun 2014 12:38:42 -0700, Steve Rae <srae@broadcom.com> wrote:
>
>>
>>
>> On 14-06-10 11:13 AM, Wolfgang Denk wrote:
>>> Dear Steve,
>>>
>>> In message <539746C4.9040004@broadcom.com> you wrote:
>>>>
>>>> There could be "many" reasons why the CONFIG_SYS_TEXT_BASE is not
>>>> aligned on a 0x1000 byte boundary (Darwin has attempted to document his
>>>> particular use-case...)
>>>
>>> We should be more precise here and ask for any _good_ reasons.
>>>
>>> I can think of many good reasons to keep the text base aligned.  As
>>> for the reasons to use an unaligned address that were brought up here,
>>> I still think that it would have been better to use an aligned taxe
>>> base and do the rest with a customized linker script.
>>>
>>>> But we think that the solution to support this is relatively
>>>> straightforward:
>>>> (1) after determining the "relocation address" (which will be on a
>>>> 0x1000 byte boundary),
>>>> (2) add "CONFIG_SYS_TEXT_BASE % 4096" to that "relocation address"
>>>> (which effectively makes the "relocation offset" a multiple of 0x1000
>>>> too...)
>>>> So, in the scenario #1, (CONFIG_SYS_TEXT_BASE % 4096) = 0, so this
>>>> algorithm changes nothing.
>>>> And in scenario #2, (CONFIG_SYS_TEXT_BASE % 4096) = 0x20, therefore, we
>>>> would now get the following:
>>>> the relocation offset is:	0x77f9b000
>>>> therefore, after relocation:
>>>> _start	symbol is at		0xfff9b020 (0x88000020+0x77f9b000)
>>>> vectors	symbol is at		0xfff9b800 (0x88000800+0x77f9b000)
>>>
>>> I still cannot understand why _start and CONFIG_SYS_TEXT_BASE would
>>> have to be the same.  There is no such requirement.  What exactly
>>> prevents you from assigning _start a location at offset 0x20 to the
>>> start of the text segment, i. e. CONFIG_SYS_TEXT_BASE ?
>>
>> Wolfgang et al.
>>
>> I agree that they do not need to be the same...
>> So our issue is that basically "for every ARMv7 board in the company",
>> we are currently maintaining our own modified/customized version of
>> "arch/arm/cpu/armv7/start.S" in order to add the appropriate 32 byte
>> header...
>
> That is not a good approach -- and I should know, as there are boards
> out there which already insist on having a header (mind you, a simple
> 4-byte constant) in start.S, and I am already trying to tackle this
> out of start.S.
>
> Your 32-byte header should not be in start.S, it should be linked in
> before start.o in the linker script. Then you would only have one
> start.S file and as many headers as you require.
>
>> And we could choose to do it using other methods, but they all require
>> us to maintain a customized version of linker scripts, or some other
>> code, or ....
>
> Not necessarily. You'll need to configure your target, that's sure,
> because I guess different targets will have different (values in
> the bytes of their) headers, but you don't need to have different
> start.S files.
>
>> The request here is that with the addition of some relatively
>> straightforward (upstreamed) code, then this can be handled
>> automatically by a post-processing step and we would be able to use a
>> pristine version of the upstreamed code...
>> Our desire is to get this into the beginnings of the "ARMv8" boards, so
>> that we can avoid the maintenance issues we have with the current ARMv7
>> boards.
>>
>> We appreciate your consideration of this request.
>> Thanks, Steve
>
> I (believe I) understand the problem, and I am discussing here because I
> too want it solved. On the one hand I do agree with Wolfgang here:
>
>>> No, I do not see a good reason to add such code.
>
> ... because I don't want to allow a feature that is designed to counter
> a problem; but on the other hand I want the problem fixed. So Darwin,
> in order to find a satisfactory solution, let me try to recap the
> situation and then ask a few questions.
>
> Recap:
>
> 1. A typical ARM binary image is linked to a base address, defined by
>     preprocessor macro (aka U-Boot config option) CONFIG_SYS_TEXT_BASE.

OK

>
> 2. A typical ARM target defines CONFIG_SYS_TEXT_BASE so that the image,
>     and especially its exception vectors table, is properly aligned upon
>     loading the image in RAM.

Nope, the vectors respect the .align directive independent of the 
CONFIG_SYS_TEXT_BASE setting.

>
> 3. When the ARM image relocates itself, it does so to a destination
>     address which is computed so that the image and its vectors table
>     are still properly aligned after relocation.

Almost: the computed destination address is aligned on a 0x1000 byte 
boundary, so if the CONFIG_SYS_TEXT_BASE is also a multiple of 0x1000 
bytes, then this statement is true.

>
> 4. Some targets require that the image stored in MMC be prepended with
>     a 32-byte header (and aligned to a sector-related boundary).

OK

>
> 5. For some targets (if not all) the header is not separate from the
>     image, i.e., it will also be copied from MMC to RAM. Such headers
>     must be prepended at the link stage or earlier, so that the
>     link-time and run-time values of all image symbols are consistent.

Yes - copied from MMC to RAM, but not really necessary to do this at 
"link stage or earlier" (we do it with a post-processing tool to prepend 
a header onto 'u-boot.bin')

>
> 6. However, because the header is put at the start of the image before
>     the vectors table, the image is still properly aligned but th
>     vectors tabled is not any more, both when the image is loaded from
>     MMC to RAM, and when it is relocated.

Because we set the CONFIG_SYS_TEXT_BASE to 0xXXXX0020, the image is 
properly aligned, if CONFIG_SYS_TEXT_BASE is 0xXXXX0000, then the 
"before" image would not be properly aligned....

>
> 7. This mis-alignment issue does not only affect the vectors table; it
>     also affects any location addressed using adrp instructions (if I
>     did correctly understand Jeroen, Cc:).

Agree - it affects all of the "align" directives, in the code and the 
linker script file, and all instructions which assume alignment....
>
> This is my understanding of the issue. If it is correct, then I
> believe the following solves the issue without changing anything to
> the current code:
>
> Instead of prepending a 32-byte header to the image, prepend the header
> then a block of 2048-32 bytes. This way, the MMC image base address
> (the header address) is aligned, and the alignment of any address in
> the image itself is preserved.

Yes - if the header is an exact multiple of 0x1000 (4096), it will work 
correctly without any code modifications... (not certain about 2048...)

>
> If for some reason it is impossible to pad the header (such as, the
> header is actually prepended by a closed-source tool which takes the
> 'raw' image in and spits the 'MMC image' out), then the raw image
> should be prepended with 2048-32 bytes beforehand, so that the 32
> header bytes make up a whole 2048-bytes block, and the image remains
> aligned.
>
> However, I guess that you, Darwin and Steve, probably have thought of
> this already and dismissed it for a reason. If so, please explain
> what this reason is.

We wanted to implement a forward looking solution that worked for any 
size of prepended header, and which removed the constraint for the 
CONFIG_SYS_TEXT_BASE to be an exact multiple of 0x1000 (4096).

However, since this solution does not look like it will succeed, in a 
parallel thread, we are pursuing an alternate proposal to conditionally 
reserve space for the header in u-boot.bin (which is "link stage or 
earlier"!!!), which would then be modified by a post-processing tool.
So please review that proposal.
Thanks, Steve

>
> Amicalement,
>
Wolfgang Denk June 11, 2014, 4:38 a.m. UTC | #23
Dear Albert,

In message <E1WuTT8-0007AF-9l@janus> you wrote:
> 
> 1. A typical ARM binary image is linked to a base address, defined by
>    preprocessor macro (aka U-Boot config option) CONFIG_SYS_TEXT_BASE.

We shoul specifically keep in mind here that the "base address" is
defined as the start address of the text segment, which may or may not
be the same as the entry point address _start.  In general, these are
not the same.

> 2. A typical ARM target defines CONFIG_SYS_TEXT_BASE so that the image,
>    and especially its exception vectors table, is properly aligned upon
>    loading the image in RAM.
> 
> 3. When the ARM image relocates itself, it does so to a destination
>    address which is computed so that the image and its vectors table
>    are still properly aligned after relocation.

These items are not ARM specific.

> 4. Some targets require that the image stored in MMC be prepended with
>    a 32-byte header (and aligned to a sector-related boundary).

Why would such headers have to be part of the text segment?

> 5. For some targets (if not all) the header is not separate from the
>    image, i.e., it will also be copied from MMC to RAM. Such headers
>    must be prepended at the link stage or earlier, so that the
>    link-time and run-time values of all image symbols are consistent.

If the headers are in their own segment, this should be trivial.

> 6. However, because the header is put at the start of the image before
>    the vectors table, the image is still properly aligned but th
>    vectors tabled is not any more, both when the image is loaded from
>    MMC to RAM, and when it is relocated.

This would be a bug, then.  If we have an alignment requirement for
the text segment, and we load other data (or code) in front of the
text segment, then the size of such additional data must be made such
that the text segment is still properly aligned.  Usually I would
expect that the heaer is in a separate segment, and the linker script
would take care of the required alignment for the text segment and
insert the necessary gap to keep it properly aligned.

> Instead of prepending a 32-byte header to the image, prepend the header
> then a block of 2048-32 bytes. This way, the MMC image base address
> (the header address) is aligned, and the alignment of any address in
> the image itself is preserved. 

Agreed. Or should .text be aligned on a 4 k boundary?


Best regards,

Wolfgang Denk
Wolfgang Denk June 11, 2014, 5:02 a.m. UTC | #24
Dear Steve,

In message <53979F6A.90607@broadcom.com> you wrote:
> 
> Yes - copied from MMC to RAM, but not really necessary to do this at 
> "link stage or earlier" (we do it with a post-processing tool to prepend 
> a header onto 'u-boot.bin')

What exactly is the fuction of this post-processing tool?  Does it
retrieve any data from the previously built image (like size
information), or could the header also be generated before the link
step, so we just include it there?

Also, can we not use the U-Boot build process to generate these 32
bytes of header data?

> > 6. However, because the header is put at the start of the image before
> >     the vectors table, the image is still properly aligned but th
> >     vectors tabled is not any more, both when the image is loaded from
> >     MMC to RAM, and when it is relocated.
> 
> Because we set the CONFIG_SYS_TEXT_BASE to 0xXXXX0020, the image is 
> properly aligned, if CONFIG_SYS_TEXT_BASE is 0xXXXX0000, then the 
> "before" image would not be properly aligned....

...unless your linker script properly aligns all segments.

> We wanted to implement a forward looking solution that worked for any 
> size of prepended header, and which removed the constraint for the 
> CONFIG_SYS_TEXT_BASE to be an exact multiple of 0x1000 (4096).

The generic approach is to use the linker to define the memory map of
the resulting image, i. e. to create proper alignment of segments
andproper placement of code such that specific address and alignment
requirements are met.

> However, since this solution does not look like it will succeed, in a 
> parallel thread, we are pursuing an alternate proposal to conditionally 
> reserve space for the header in u-boot.bin (which is "link stage or 
> earlier"!!!), which would then be modified by a post-processing tool.

Why would such post-processing be needed?  I think you should strive
to get rid of such an additional step, and try to get the header
generation either be done before linking, or even better as integral
part of the build process.

We are talking about 32 bytes of data here, so I speculate it should
not be too difficult to generate these, probably even without theuse
of a special external tool?  Can you explain the structure of this 32
byte header?

Best regards,

Wolfgang Denk
diff mbox

Patch

diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 9b473b5..df520cc 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -449,6 +449,19 @@  void board_init_f(ulong bootflag)
 	dram_init_banksize();
 	display_dram_config();	/* and display it */
 
+#ifdef CONFIG_ARM64
+	/*
+	 * Fix relocation if u-boot is not on an aligned address.
+	 */
+	{
+		int offset = CONFIG_SYS_TEXT_BASE % 4096;
+		if (offset) {
+			addr += offset;
+			debug("Relocation Addr bumped to 0x%08lx\n", addr);
+		}
+	}
+#endif
+
 	gd->relocaddr = addr;
 	gd->start_addr_sp = addr_sp;
 	gd->reloc_off = addr - (ulong)&_start;
diff --git a/common/board_f.c b/common/board_f.c
index 4ea4cb2..1035d6f 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -728,6 +728,16 @@  static int reloc_fdt(void)
 
 static int setup_reloc(void)
 {
+#ifdef CONFIG_ARM64
+	/*
+	 * Fix relocation if u-boot is not on an aligned address.
+	 */
+	int offset = CONFIG_SYS_TEXT_BASE % 4096;
+	if (offset) {
+		gd->relocaddr += offset;
+		debug("Relocation Addr bumped to 0x%08lx\n", gd->relocaddr);
+	}
+#endif
 	gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
 	memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));