Image vs zImage vs uImage - linux-kernel

What is the difference between them?
I know that u-boot needs a kernel in uImage format.
The system I use first boots from stage 1 loader and then it calls u-boot. I want to discard u-boot and directly boot from stage 1 loader. Which type of kernel image do I have to use?

What is the difference between them?
Image: the generic Linux kernel binary image file.
zImage: a compressed version of the Linux kernel image that is self-extracting.
uImage: an image file that has a U-Boot wrapper (installed by the mkimage utility) that includes the OS type and loader information.
A very common practice (e.g. the typical Linux kernel Makefile) is to use a zImage file. Since a zImage file is self-extracting (i.e. needs no external decompressors), the wrapper would indicate that this kernel is "not compressed" even though it actually is.
Note that the author/maintainer of U-Boot considers the (widespread) use of using a zImage inside a uImage questionable:
Actually it's pretty stupid to use a zImage inside an uImage. It is
much better to use normal (uncompressed) kernel image, compress it
using just gzip, and use this as poayload for mkimage. This way
U-Boot does the uncompresiong instead of including yet another
uncompressor with each kernel image.
(quoted from https://lists.yoctoproject.org/pipermail/yocto/2013-October/016778.html)
Which type of kernel image do I have to use?
You could choose whatever you want to program for.
For economy of storage, you should probably chose a compressed image over the uncompressed one.
Beware that executing the kernel (presumably the Linux kernel) involves more than just loading the kernel image into memory. Depending on the architecture (e.g. ARM) and the Linux kernel version (e.g. with or without DTB), there are registers and memory buffers that may have to be prepared for the kernel. In one instance there was also hardware initialization that U-Boot performed that had to be replicated.
ADDENDUM
I know that u-boot needs a kernel in uImage format.
That is accurate for all versions of U-Boot which only have the bootm command.
But more recent versions of U-Boot could also have the bootz command that can boot a zImage.

Related

RootFileSystem vs kernel updating

I know that they are two different things, but what is the difference between the actual Linux kernel and the rootFS file system especially in terms of location in memory and updates?
Regarding partitioning, why is it that the kernel and rootFS are nearly always on different partitions? Won't the kernel code be stored within the rootFS itself? So how are they on different partitions in memory?
Now regarding updating, I've been looking into an OTA update framework which claims to do a full kernel image update. It uses two separate partitions for rootFS. If there is a problem updating one rootFS partition, it can fall back to the working rootFS partition which makes sense. However, how is this actually updating the kernel tho? I don't understand.
I know that they are two different things, but what is the difference between the actual Linux kernel and the rootFS file system especially in terms of location in memory and updates?
Kernel is usually one image file (like zImage). In ARM systems kernel also needs device tree file, but let's avoid it for now. RootFS, in turn, is a file system that contains all files in your /, like binaries (init, bash), config files (/etc), user home directory, and so on. Sometimes RootFs contains kernel image file, sometimes it doesn't, depends on your particular system.
Regarding partitioning, why is it that the kernel and rootFS are nearly always on different partitions? Won't the kernel code be stored within the rootFS itself? So how are they on different partitions in memory?
The key to your questions is to think about bootloader (like U-Boot or GRUB). Once you understand how OS boot process works in bootloader, the answer will automatically reveal itself. As you mentioned, different partitioning schemes exist, which leads to difference in boot process. Actually, there is a lot of different boot schemes out there. Let's review some of them, and hopefully it'll explain what you want to know.
Kernel and rootfs on different partitions. In this case, bootloader usually reads kernel image to RAM, passing rootfs partition via kernel cmdline (via root= parameter). Then bootloader starts kernel execution, and kernel is mounting rootfs from partition specified in root= parameter.
Kernel image is located inside rootfs. In this case, bootloader ought to know where exactly kernel image is located (e.g. in /boot/zImage). Bootloader knows rootfs FS format (e.g. ext4), reads /boot/zImage from rootfs to RAM. Then execution continues as in previous item.
Kernel image and rootfs are passed via network (e.g. TFTP). In such case, sometimes, rootfs is being placed into RAM and mounted as ramdisk (from RAM). No persistent storage is used in such case, and any changes to rootfs will be lost after reboot. Another network case is when rootfs is mounted via NFS, then persistent storage on the server will be used (transparently viewed by the user).
Now regarding updating, I've been looking into an OTA update framework which claims to do a full kernel image update. It uses two separate partitions for rootFS. If there is a problem updating one rootFS partition, it can fall back to the working rootFS partition which makes sense. However, how is this actually updating the kernel tho? I don't understand.
In terms of updates, it's not that different which scheme to use,
(1) or (2). What are you talking about is called (at least in Android) A/B Seamless Updates, meaning that two partitions (A and B) are used for storing the same image (e.g. old rootfs and new rootfs). You need to understand that it's ok to update just rootfs without kernel. There is a rule in kernel development that reads like this: "We don't break userspace". Which means you can rely on different versions of kernel to run the same userspace, or you can rely on one kernel version to run different userspaces.
So it's more like architecture question: do you want to update kernel in your system at all? If yes, then you need to provide two different partitions for kernel and two partitions for rootfs. Or alternatively you can put kernel image and rootfs in the same partition (for example see Android boot image format), and provide second partition for updates.

LEDE: The uImage compress type not supported

I am trying to build kernel image in LEDE for Atmel at91 SAMA5D3 platforms and the compressed type is XZ. Once uImage is successfully, I transferred this image to my SD card and tried to boot up with it. However, the boot up is always failed with following message:
Booting uImage …
The uImage compress type not supported
SD/MMC: Failed to load image
I tried with some other’s image and that will work well so I am not sure if there is any kernel config I also need to enable or disable.
Could anyone help with this? Thanks!
The message seems to indicate that whatever boot program that you're using to load the Linux kernel does not have any decompression capability.
Therefore instead of expecting the boot program to perform the decompression, you need to build a kernel image that is self-decompressing, i.e. a zImage.
If you insist, you can wrap the zImage in a uImage header, but since the zImage is self-extracting the image needs to be marked as "uncompressed".
Note that the file type uImage is produced by the U-Boot utility mkimage, and this type of image is for the benefit of U-Boot.
Other boot programs may or may not recognize a uImage.
Boot programs for ARM are expected to support zImage.
Your post is sparse in terms of details.
If all you did was select XZ instead of the default gzip for the Kernel compression mode in the kernel's menuconfig, and did build a zImage, then the mkimage was used with incorrect arguments.
A zImage within a uImage must be marked as "uncompressed".

Using both multiboot and floppy with QEMU

I am trying to develop an operating system. I have finished the Barebones tutorial from OSDev but still have some issues with multiboot.
As I understand, when I create a multiboot image following the tutorial, I have an ELF format binary file. This ELF executable is loaded into memory by QEMU when I specify the -kernel option. So I have a single executable program in memory and it has an entry point. It has some functions and libraries alongside it. There is nothing else in the memory. There is also no floppy or disk image from which I can read or write sectors. This is mainly because I haven't specified anything to QEMU in that regard.
However, what I want to achieve is after QEMU loads my ELF executable, I want to have a disk or floppy architecture from which I can read or write sectors. I also want to load some user programs from it or maybe set up a file system on it. So far, what I'm think is this:
qemu-system-i386 -kernel myKernel.bin -fda myDisk.image
Or maybe, I should take my myKernel.bin file, pad it with zeros until it is aligned to 512 bytes, then append the rest of the disk image to it.
My question is how can I achieve this functionality with QEMU. I need to know whether a task like this is possible before diving into writing a disk driver. If not possible, I can take a different approach but these are the ideas I have right now. I have already looked into -initrd and it isn't quite what I want. I also don't want to have any files loaded into the RAM by QEMU. Instead, I want to manipulate the disk image myself. Any suggestions on how to do that?
You don't need both a floppy image and a multiboot kernel, unless you've written some kind of loader. The -kernel flag works similarly to grub and it's much faster than loading from virtual media. This is how many linux kernel and driver devs test their code rather than creating a virtual media image every time.

What is different between u-boot.bin and u-boot.img

I just compiled the U-Boot bootloader and I see a few file names in the u-boot program directory which are:
u-boot.bin
u-boot.img
u-boot.lds
u-boot.srec
Basically, I'm interested in the files with extensions .img and .bin. What is different between them?
Is u-boot.img for SD card and u-boot.bin for flashing to NAND ?
u-boot.bin is the binary compiled U-Boot bootloader.
u-boot.img contains u-boot.bin along with an additional header to be used by the boot ROM to determine how and where to load and execute U-Boot.
The way in which these files are deployed can depend upon the nature of your device, its boot ROM and where the files are loaded from.
Boot ROMs are generally provided by the SoC/CPU vendor. These days, many boot ROMs are capable of loading u-boot.img, reading the file's header, loading u-boot.bin into memory and finally executing it. Some boot ROMs are complex enough to load u-boot.bin directly or even the OS kernel. While others may load an intermediate bootloader (MLO/X-Loader) first which then takes responsibility for loading U-Boot as the secondary bootloader once external memory is initialized.
This image depicts the latter case as implemented by some TI OMAP processors:
This boot process is reduced by some devices by moving many of the X-Loader tasks into U-Boot and placing boot parameters (such as memory addresses) into the header of u-boot.img avoiding the need for an intermediate bootloader.
You will need to investigate the properties of your device to determine how you should go about deploying U-Boot.

What all necessary argument required to boot Linux kernel

I am new to linux kernel and Try to understand booting of Linux kernel from the point it loaded into RAM,I would like to know after Linux image loaded into RAM ,How control is passed to this image ,what all are necessary parameter needs to pass to kernel and can we pass control to linux image without passing any parameter,
I am looking into the UBOOT code with "bootm.c" but unable to understand where control is passed to Linux image,which function is responsible for it.
Is load_zimage() is responsible for passing the control/
Can anybody lead me to right direction or suggest some good tutorials on this particular part
of linux booting from x86 archetectiure.
I think it depends. Different kinds of CPU architecture, they use different ways to pass information to Linux Kernel. Of course, the Linux Kernel can boot up successfully without bootloader pass information to it, but it need to statically set up correctly in the Linux Kernel, such as root device name, console device, mem size, and also some parameters to enable/disable some features in Linux Kernel.
Why bootloader need to pass various information(parameters) to Linux Kernel, I think it's flexible consideration. Think about this case that it's possible to share one Linux Kernel on two board with same CPU but different peripheral modules.
Let me show some examples that UBoot passes information to Linux Kernel:
(1) For PowerPC cpu, nowadays they use DTB(Device Tree Blob) file to pass more information from UBoot to Linux Kernel. They consider UBoot and DTB as firmware, and in Linux Kernel, they adopt one open firmware(OF) infrastructure. You may know "bootm" command in UBoot, bootm can have three parameters, the first is uImage address, the secondary one is initrd address, and the third one is the dtb address.
(2) Earlier days, they use bootargs to pass information to Linux Kernel. Also you may know there is gd/bd structure in the UBoot, they also can pass information to Linux Kernel. But the information passed in this way is limited, not like DTB.
Hope the above information help you to understand your question.

Resources