[U-Boot] [PATCH 12/26] ARM: add relocation support

Albert ARIBAUD
2010-09-17T12:58:15Z

Le 17/09/2010 13:05, Wolfgang Denk a ?crit :
> Dear Albert ARIBAUD,
>
> In message<4C9307C4.40208@free.fr> you wrote:
>>
>> Things do change indeed, hence my attempt ? 1) making sure I detect the
>> change, 2) design things so that they are as resilient to change as
>> possible. One example of such a resilience is making sure the u-boot
>> code designed to run in FLASH can run *anywhere* in FLASH.
>
> As for 1), just follow the postings on this mailing list.

Check. :)

> As for 2), you need to implement the following features (none of which
> are supported yet, AFAICT):
>
> [This is based on the assumption that you want to use the very same
> binary image fom different addresses]
>
> - The code must be completely position-independent.

This is indeed what I am trying to achieve by suggesting qualifying
const init_sequence and any other constant data used by u-boot while
executing from FLASH.

> - You need a way to detect if you are running on a virgin CPU fresh
> out of reset or on a pre-initialized system.
> - You need to isolate parts in the initialization sequence that must
> not be repeated.
> - You must make sure such steps are not re-run on a pre-initialized
> system.

This is not required per se to 'start from any location'. It is required
to 'start in any state', which is another requirement -- also
commandable since it increases resilience to varying conditions. I think
the 'start from anywhere' requirement can be fulfilled without
fulfilling (yet) the 'start in any state' one.

> - You need to implement a way with the different behaviour in terms of
> resources.

This requirement sounds very general; can you be more precise on it?

>>>> As for what I am trying to do: ironically, I am trying to find a way
>>>> that the entry point of u-boot be at the reset vector location, just as
>>>> it should.
>>>
>>> There it is.
>>
>> Yes. And you are opposing this, which I do not understand since I'm
>> trying to make this SoC/board perform exactly as you specify while
>> maintaining balance with the hardware's constraints.
>
> I do not understand what you mean. Unless loaded by some other
> mechanism (like when booting from NAND flash etc.), the entry point
> to U-Boot *is* of course at the reset vector location - or how would
> the CPU be able to execute the code?

Yes, u-boot needs to be stored in FLASH so that at execution time the
_start symbol is mapped at the physical location of the reset vector.

But no, u-boot does not necessarily need to be linked so that the _start
symbol maps at the vector reset location; not, at least, if the startup
code is position-independent.

Now, for arm926ejs, it so happens that prior to Heiko's relocation
patches, u-boot's startup code *was* position-independent, and is not
any more, but that making init_sequence (and other data read during
startup) onst makes it p-i again.

>>> If you can live with the wasted 64 kB of empty space "behind" the
>>> reset vector, then it is not worse than counting the number of flash
>>> sectors needed for the image (which you have to do anyway to
>>> determine the TEXT_BASE). And moving a number of static,
>>> never-changing objects into that free area is no real rocket science
>>> either. Say, half an hour of efforts including basic testing.
>>
>> Precisely, I do not want to live with wasting 64 out of 512 KB of FLASH.
>
> OK, se put a few objects in that "hole" to fill it.

This is a bad approach, as I explain below.

>> Regarding counting the flash sectors for mapping u-boot to flash to
>> determine TEXT_BASE, I never had to, thanks to u-boot being (albeit
>> accidentally) able to run from anywhere in FLASH (I can't help seeing
>> irony in the fact that this ability was broken by adding a flag which is
>> supposed to allow running from anywhere).
>
> I lost you. If you put the U-Boot image at an arbitrary location in
> flash, the CPU will not start it because the CPU begins execution at
> the reset vector.

You're mistaking "putting the image anywhere in FLASH" and "putting
_start anywhere in FLASH".

>> As for the half-hour of effort, the half-hour part is an assumption
>> which would need supporting, and even if it is only half an hour, it is
>> half an hours for each person configuring u-boot for arm; a burden that
>
> No. Only for those who have a system with such a reset vector
> location,

That is, all people using orion5x for instance.

> and I seriously doubt that any of these changes to the
> linker script have to be board specific.

I did not say board-specific, I said config-specific.

> That means you just need to
> perform this task once to improve the platform-specific linker script,
> and it will automatically work for all other users of that
> architecture as well.

Only for a given u-boot configuration. Change it, and that changes the
image content, thus the mapping, and you've got to fix _start again.

>> This statement does not contradict the proposal that U-boot, despite
>> being linked for some address in FLASH, should be able to run, from
>> _start to relocation, at any FLASH location at least for architectures,
>> CPUs, SoCs or boards which trivially allow this. I do believe this
>> requirement is both reasonable and useful.
>
> If you know how to implement this in a clean way, then please go
> forward and do it. Patches are welcome. All I can say is that I don't
> know how to do that, but then, I'm not an ARM expert. Eventually it
> might be easier on ARM than on PowerPC, where we don't have this
> feature yet either.

I do know how to implement this indeed -- I actually have a working (and
thoroughly tested) implementation, but valid for the master branch,
without Heiko's patches; I am working on making it work with Heiko's
patches right now. I can send a patch set based on master to the list as
an RFC.

>> Anyway: there is a bottom line on which I think we agree now:
>>
>> 1) init_sequence is a constant array and should thus be qualified 'const';
>>
>> 2) any data accessed between _start and relocation should be const as well.
>
> I think you mean the right thing, but the wording is wrong again.
>
> You can fully access (read and write) data in the special "global
> data" or "initial data" structure.

In that respect I may indeed have expressed myself inadequately. When I
said that a driver's _f init function could pass data via 'globals space
allocated below the stack, I should have said 'above' -- but I had
clearly expressed that I was talking about the memory area where gd lives.

> You can perform read-accesses to
> any data in the text and/or data segments. You cannot write to data in
> the the text and/or data segments. You must not attempt to access any
> data in the bss segment because this does not even exist, so you're
> accessing random addresses.

I think none of this contradicts either of points 1) and 2) above. Or
does it?

> Best regards,
>
> Wolfgang Denk

Amicalement,
--
Albert.