Why using a uImage instead of a zImage

2020-03-23 06:08发布

问题:

I'am trying to learn the difference between a zImage and a uImage.

In my understanding uImage is got by running mkimage on the Image and as a result it adds a U-Boot wrapper (i don't know what it contains exactly) that contains a header plus the load address and entry point and maybe "extra informations" that i don't know.

In the other hand the zImage is the compressed Image, it doesn't contain the load address and entry point(what i think, correct me if i'am wrong) but also U-Boot can load it using bootz.

  • In this case why using a uImage instead of a zImage?

  • I'am curious to learn what are the formats of a zImage and a uImage could you please suggest some references ?

回答1:

In my understanding uImage is got by running mkimage on the Image

Your understanding is only partly correct.
A uImage can contain any type of file, and is not restricted to the Linux Image file. In fact it not likely to be the (uncompressed) Image file (since that is not a conventional make option).

In the other hand the zImage is the compressed Image, it doesn't contain the load address and entry point(what i think, correct me if i'am [sic] wrong)

You're incorrect, the zImage does contain the kernel's load address and entry point. The load address is needed in order to decompress the kernel Image to the proper RAM address. The kernel's entry point is needed to execute it after it has been decompressed.
When building the Image and zImage for ARM, the Makefiles use

ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)

which should translate to the start of physical memory + 0x8000.

The zImage itself (i.e. the self-extraction program) is PIC, position independent code. The zImage can be loaded anywhere in RAM, and executed at its first address, i.e. its entry point is its load address.

In this case why using a uImage instead of a zImage?

For older versions of U-Boot, there was no choice since the bootz command may not have been available for Linux kernels.
Nowadays it may be a subjective choice.

Note that there has been some resentment in the Linux kernel community towards the support of U-Boot in the kernel. IOW if some people had their way, I get the impression that you would not be able to build a uImage from the mainline source.

I'am [sic] curious to learn what are the formats of a zImage and a uImage could you please suggest some references ?

The layout of the zImage is essentially given by its linker specification.
For ARM see arch/arm/boot/compressed/vmlinux.lds.S.
Note that _magic_start contains a meaningless load address. This is also mentioned in Section 5 of Vincent Sanders' Booting ARM Linux

The zImage has a magic number and some useful information near its beginning.

Table 2. Useful fields in zImage head code
Offset into zImage  Value       Description
    0x24        0x016F2818      Magic number used to identify this is an ARM Linux zImage
    0x28        start address   The address the zImage starts at
    0x2C        end address     The address the zImage ends at

The start and end offsets can be used to determine the length of the compressed image (size = end - start).  
 ...  
The start address is usually 0 as the zImage code is position independent.

Note however that the ARM booting requirements have been superseded by Russel King's Documentation/arm/Booting

The layout of a uImage is simply the U-Boot header plus the image file, whatever that may be.

(Hopefully nothing I wrote contradicts what Tom Rini wrote.)



回答2:

This is not quite right. While the "legacy" u-boot header that is used to make what is typically called a uImage can be anything, including the Image found under arch/arm/boot/Image, it is most often the zImage file. This is because historically there was no support for directly booting a zImage in U-Boot and because a zImage provides no checksum on the data a uImage has a crc32 of the contents available.

The zImage file is a stand-alone executable. The legacy "uImage" format is not formally documented in U-Boot but could be understood by reading the code. In most cases, rather than using a "uImage" you would want to use a FIT image today, which has a number of docs in the doc/uImage.FIT directory in the U-Boot sources.