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

Simon Glass
2011-11-08T01:10:51Z

Hi Nicolas,

On Mon, Nov 7, 2011 at 4:35 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> 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.

I will leave you to your discussion, but want to pick up on this point.

Can I assume that we have (or can have) a 'make uImage' target or
similar in the kernel which can pack together:

- a compressed kernel (not zImage, I mean something that U-Boot can
decompress), with a rel_offset of 32KB
- a DTB
- a ramdisk

and that with Stephen's patch (committed to U-Boot) today, we can, in
U-Boot, with a script, load this uImage to somewhere and have U-Boot
decompress the kernel and set the bits out nicely in RAM, no matter
where that RAM is? The kernel will start at 32KB, and the other bits
will be somewhere above that. Then U-Boot can enter the kernel at 32KB
and all will be well, yes?

Because it seems to me that this approach would work just as well as
the zImage approach (it is perhaps more 'pure' from a boot loader
point of view), and that the code in the kernel zImage header that
figures out where SDRAM is and decompresses the kernel to 32KB could
just as well be in U-Boot.

Then both groups get what they want.

Regards,
Simon

>
>> > 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
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>