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

Wolfgang Denk
2010-09-16T11:29:20Z

Dear Albert ARIBAUD,

In message <4C91F659.7020607@free.fr> you wrote:
>
> 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,

You misread that. We actually make no attempts that the code can be
run from any arbitrary address. On contrary - we explicitly link it
for a fixed address map, which is defined by the location of the reset
vector, which is the one and only defined entry point into U-Boot.

[I'm giving the generic, architecture independent view of U-Boot
here. Actual implementations for some processors may behave
differently, but this is nothing you should build on.]

> 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.

The only reasonable use cases for such a szenario that I am aware of
would be best implemented in hardware, by being able to toggle between
two banks of flash memory, selecting one or the other as boot device.
Then you can even use the same U-Boot binary images, which is a good
thing in such setups. [eventualkly you want to store the environment
somewhere else, say in some storage device on the backplane, so all
instances of U-Boot refer to the same data.]

> (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)

I do not understand this what you mean by that, or what the problem
might be. It is trivial to arrange the code such that no significant
gaps remain. This requires just a little tuning of the linker
script.

> 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.

Again, please keep in mind that (1) this depends on the linker script,
and (2) that before relocation to RAM _all_ access to global variables
is extremely limited as we have only a read-only data segment and no
BSS segment at all.

> 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

I don't understand what you mean. Are you aware of the restrictions
of the execution environment before relocation to RAM?

> 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.

If any drivers do such things, and if these drivers are used before
relocation to RAM, these are serious bugs that must be fixed.

If you are aware of such bugs please post this information, so people
can start working on fixes.

> 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

This is, and has always been, the case.

> 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.

Hm... I don;t see global variables being used in timer_init() in
"arch/arm/cpu/arm926ejs/orion5x/timer.c" - which exact code are you
referring to?

> 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.

It seems you really minunderstand the excution environment before
relocation. Ther eis also no steck there, and of course no "globals
space allocated below the stack", because we don't even have the RAM
initialized yet.

> 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?

Please read the code, and the README. Please pay special attention to
section "Initial Stack, Global Data:".

In short: the pointer to the global data is passed in a register,
which we reserve for this purpose.

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
"... freedom ... is a worship word..."
"It is our worship word too."
-- Cloud William and Kirk, "The Omega Glory", stardate unknown