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

Albert ARIBAUD
2010-09-16T10:50:01Z

Le 16/09/2010 07:09, Heiko Schocher a ?crit :
> Hello Albert,
>
> Albert ARIBAUD wrote:
>> Le 11/08/2010 20:16, Heiko Schocher a ?crit :
>>
>>> diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
>>> index 54519b0..88c6427 100644
>>> --- a/arch/arm/lib/board.c
>>> +++ b/arch/arm/lib/board.c
>>
>>> +init_fnc_t *init_sequence[] = {
>>
>> Tested this code tonight, and I noticed that if the image is run from
>> another location than the one it was linked for, then access to
>> init_sequence is not made at the right location. To get correct access
>> regardless of the image location, init_sequence has to be defined const.
>
> Hmm.. at this place code is not relocated! So it should be executed
> on the right address. Don;t know, if this would be the only problem,
> if you run this code from another address ...

Well, the main goal of -fPIC is that the code should be able to run from
anywhere, so it should be able to run from anywhere in FLASH. Besides,
that can be useful for designs where two (possibly differently built)
images of u-boot are located in FLASH and some mechanism allows booting
from either.

(I personally have another motive for having at least the _f part of
u-boot able to run fully PIC, as I want to implement direct-to-u-boot
resetting on targets that have a reset vector rather far away from the
end of the addressable space but too near to fit u-boot in, e.g. the
orion5x which resets as 0xffff0000: 64 KB is too small for u-boot. I
have submitted a patch for this then withdrawn it because of the
relocation patches; however for this conversation, we can keep this
point aside)

As for what would or would not work, ATM it boils down to 'access to
const variables will be position-independent, access to others will
not'. Non-initialized as well as initialized-but-not-const globals are
always accessed at their link location before and after relocation, and
thus will work only if you're running the image at its linked location.

This means that non-const data obviously can't work when the image is
linked to FLASH; and they can even wreak havoc if the image linked for
RAM and relocated near, but not exactly at, its linked location. The
fact that it did not break so far in u-boot without reloc (and yes,
several drivers do access globals during in-FLASH board init) is due to
the fact that DRAM is already initialized when drivers access these
globals at their linked location; this breaks when the image is linked
for a location in FLASH.

Of course solving the init data issue (by making them const) will not
solve the issue of rw data. For this one I see two solutions:

1) forbid using such data in drivers during _f phase if that is
possible. For instance, in the timer.c driver of orion5x, the timer_init
code accesses two writable variables because it wants to have a first
reference for rollover detection; this can obviously be postponed to the
_r init phase.

2) in case where the _f phase *has* to store data in globals, then this
data should go to the globals space allocated below the stack, where gd
also resides, and be later copied to usual globals if reqired.

BTW, the comments in board.c say that the _f init functions receive a
pointer to gd; actually they dont, they're int (*) (void). Were the
comments always out-of-sync with the code, or was there a removal of the
gd argument for some reason?

Amicalement,
--
Albert.