[U-Boot] [PATCH v2 3/3] image: Allow images to indicate they're loadable at any address

Nicolas Pitre
2011-11-08T00:35:38Z

On Tue, 8 Nov 2011, Wolfgang Denk wrote:

> Dear Nicolas Pitre,
>
> In message <alpine.LFD.2.02.1111071736280.3307@xanadu.home> you wrote:
> >
> > > 1) zImages are are relocatable. They should be loaded and started at
> > > offsets between 32 KiB and 128 MiB in system RAM.
> > >
> > > 2) Raw images (without the preloader) have to be started at a fixed
> > > address, virt_to_phys(PAGE_OFFSET + TEXT_OFFSET), which usually is
> > > at an offset of 32 KiB in system RAM (with very few exzceptions).
> > >
> > > Both sitations can be handled perfectly find with offset addresses in
> > > the images.
> >
> > No. Please, we're trying to remove _all_ hardcoded addresses from the
> > kernel boot process, absolute or relative. ...
>
> I understand you are referring here to zImages only. Correct?

Correct. Anything else is not relocatable.

> Or will raw images (without the preloader) be fully relocatable, too?

No.

> > ... This is why zImage can be
> > loaded at practically any address. If uImage insists on having a
> > relative offset encoded into it, this is slightly better than the
> > absolute address but not by much. Having the ability to use the _same_
> > uImage file and load it at _different_ addresses as specified by an
> > argument to the load command is highly desirable...
>
> Why is it so important to load it at specific (different) addresses
> when it can be started from any address?

The kernel code can be started from any address. We want the _code_ to
be that way.

However a particular board may or may not load the kernel at any
address. This is a machine specific restriction, not a kernel
restriction.

> Maybe this is a key point. I simply fail to understand this.

Let me repeat again. We want one single kernel image binary that ARM
distributions can use for all their target machines. It is therefore
necessary that uImage be free of any hardcoded load address (absolute or
relative). If a particular board require a particular load address for
the kernel, this must be encoded in its own u-Boot environment and not
in the distributed uImage. Failing that, uImage simply cannot be used
as a distribution format for the kernel because any address/offset
enforced by the uImage format is going to be incompatible with the needs
of a particular machine somewhere.

> > We don't want any hardcoded architecture specific address anymore.
> > This is being removed from the kernel as we speak. If I cannot use a
>
> Also for raw images?

No. The requirements on raw images are unchanged. you can use them if
you wish, but generic ARM distributions can't use that if they want to
target more than one SOC. Therefore raw images are not interesting by
the use case at hand.

> > totally generic way to not specify a load address (using -1 for example)
> > with mkimage soon, I'll be forced to remove the uImage makefile target
> > from Linux as it will simply be broken otherwise.
>
> Interesting argument. Because you are fully flexible and can use any
> address you cannot accept a make target that wraps your fully
> relocatable image to load it on a specific address. Now that makes
> sense to me.
>
> Or do I smell attempted extortion?

What do you not understand in the fact that such a specific address
makes the resulting image not universal? I'm telling you that I need to
produce a kernel image that doesn't carry with it any machine specific
load address so that same image can be installed unmodified on any
machine.

Instead, you insist on making that image less useful by attaching to it
some restrictions on its load address at build time rather than applying
those restrictions only at load time and only on machines where that
matters.

For the last time, we don't want any address encoded in the kernel
image for the simple fact that we don't know at build time what machine
the kernel will be used on, and therefore what address to use. This is
why zImage was made totally relocatable and totally position
independent so it can figure out at run time what address to use.
Figuring out the address to use at "make uImage" time only works for a
kernel that will boot on a single specific machine.

> > This allows to boot such image on only one specific architecture if
> > uImage must contain architecture specific addresses, be that absolute or
> > relative. Granted, a relative offset is less problematic than an
> > absolute address, but it is a problem nevertheless. Such architecture
>
> Please explain _why_ you consider it a problem. Describe use cases
> where it doesn't work.

That has been explained a few times already.

> > specific information must live with the boot loader (ideally as a
> > script) and not embodied into an image that could otherwise be totally
> > generic.
>
> Must it? I don't see the need. I don't even see the benefit.

Why do I care having this conversation with you then? Please tell me.

> > > With Stephen's new approach, we could only use the zImage approach,
> > > and we have to add additional configuration information to the boot
> > > loader.
> >
> > Absolutely! That is where that configuration information must be. The
> > bootloader is not generic since it must initialize a very specific piece
> > of hardware. It therefore makes sense to associate the per architecture
> > details such as the best kernel load address with the bootloader, not in
> > the image itself.
>
> Hm... if that is true, then it means we will have fully relocatable
> raw images?

It is already the case, more or less. The raw image _must_ be loaded at
TEXT_OFFSET from start of RAM, regardless of where that RAM is. So if
all you care about is raw image kernels, then having a relative a load
address for uImage makes perfect sense.

The role of the zImage code is to figure out at run time about its
position in RAM, deduce where the RAM starts, relocate itself if it is
in the way of the decompressed kernel, and decompress the actual kernel
in its final location (RAM start + TEXT_OFFSET) without having to
relocate the bigger decompressed data. Unless it is in the way of the
decompressed kernel, this code can be executed in place and doesn't need
to be relocated to any particular address.

> > OTOH, the kernel must become as generic as possible. Using DT plays a
> > big role in this. But not having a load address/offset encoded in the
> > image is also part of this. Think of what mess a Linux distribution for
> > ARM would otherwise have to carry when it must know that configuration
> > information for each device it intends to support. Having a single
> > kernel binary for as many ARM devices as possible is what we're aiming
> > for, and currently u-Boot is one of the obstacles.
>
> Please explain which exact problems you see if Linux on ARM would by
> default wrap the zImage into a relative uImage with load address =
> entry point address at 32 KiB offset from start of system RAM?

It will always have to relocate itself away from there as this is
typically where the decompressed kernel must be placed.

Knowing that, most people are already attempting to load their uImage
elsewhere, say at an offset of 16Mb FROM START of RAM. Or maybe they
have a ramdisk at that address so they load the kernel at an offset of
32MB. Or any such restriction that is particular to a specific
machine/setup.

But u-Boot will then ignore the wish of the user and relocate the image
content to 32KB after start of RAM, causing one copy. Now zImage knows
it must not overwrite itself with decompressed data, so it will move
itself away i.e. a second copy. Bot those copies are totally useless
and could be avoided if only u-Boot would stop ignoring the user's wish
to load and run zImage from the address indicated by the provided
argument to the load command.

This is a rigid restriction that a well intended bootloader would not
impose all the time if the user wishes to do otherwise. You might not
be concerned by use cases where we want images to be executed right
where they've been loaded irrespective of what that might be, but that
doesn't make that any less of a valid use case. And Stephen's patches
are providing just that.

Nicolas