We can produce the Linux kernel image files in different formats. Besides the intended use case, the hardware architecture, and the boot loader used on the system influence the kernel image we use. In this tutorial, we’ll look at the various kernel images available.
2. Understanding the Kernel
The kernel is the first component loaded into the memory upon boot up. It then remains in the memory throughout the computer’s use.
The kernel is the core of the Linux system. It provides a user interface that allows us to interact with the operating system. This bridges the applications with the underlying hardware: handling tasks such as process management, memory management, device drivers, and system security.
Additionally, it manages the system resources, provides essential services, and enables communication between software and hardware. It controls the system’s memory, processes, and hardware.
Under some scenarios, we may need to generate and construct custom kernel images. This can occur due to the following reasons:
- Firstly, when the pre-compiled kernels provided by our operating system distribution lack the specific features, optimizations, or hardware support required.
- Secondly, if we need to add or modify kernel modules, such as device drivers or filesystems.
- Thirdly, when we’re in development or debugging, we must assemble the kernel from the source code.
- Finally, when we need to compile a custom kernel tailored to meet the requirements of embedded systems with a unique hardware platform or specific conditions. This allows us to optimize the kernel for the hardware as we strip out unnecessary features and reduce the kernel size to fit within the limited resources of the embedded device.
When we compile a custom kernel, we can produce it into one of the following kernel images: vmlinux, vmlinuz, vmlinux.bin, zimage, and bzimage. A kernel image is a file with the binary representation of the kernel code and other components.
Kernel image formats differ based on compression, architecture, and specific use cases. Let’s look at the various Linux kernel images we have.
The original, uncompressed Linux kernel image is called vmlinux. vmlinux is the kernel in a uncompressed and non-bootable form. It’s the intermediate step to producing vmlinuz. It has debugging symbols included along with the complete and unmodified kernel code.
In most cases, vmlinux is used to develop kernels, debug, and analyze them. The vmlinux image should be bootable before being loaded to an operating system kernel. To make it bootable, we add a multi-boot header, boot sector, and set up routines.
The “vm” preceding the Linux stands for virtual memory. In Linux, we can use a portion of the hard disk space as virtual memory, hence the name “vm”.
vmlinuz is a compressed Linux kernel image file for booting the Linux operating system. When we compress the vmlinux file we create vmlinuz. The compression uses the gzip algorithm, resulting in a smaller file size than the uncompressed vmlinux.
The resulting file contains the kernel’s essential components. Compression reduces file size, optimizing boot efficiency and memory usage during boot.
When we’re booting the system, the boot loader reads the vmlinuz file from the boot device and decompresses it into memory. The decompressed kernel image is run from the memory.
The vmlinux.bin file is an uncompressed binary image generated during Linux kernel source code compilation. It includes the entire compiled kernel code, with debug symbols and additional information for debugging and analysis.
The vmlinux.bin image file is not directly executable and is too big for practical use. As a result, developers use it to understand and analyze the Linux kernel behavior.
vmlinux.bin offers increased flexibility, allowing for customizations tailored to specific requirements.
zimage refers to a distinct compressed kernel image file format. It’s designed for X86-based systems. It addresses the limitations of older bootloaders that couldn’t handle sizeable compressed kernel images.
We compress zimage using a compression algorithm called LZ77. The LZ77 compression algorithm optimizes speed and perfectly balances compression ratio and decompression performance. LZ77 compression creates a smaller image file than bzimage.
We must note that the zimage format is typical of the x86 architecture and other architectures may not support it.
bzimage refers to a compressed kernel image file used by the Linux bootloader to load and initialize the kernel during the system boot. The bootloader reads the bzimage file from the boot device and decompresses it into memory. It then transfers control to the decompressed kernel image, which continues the boot process.
The bzimage file is the by-product of compiling the Linux kernel source code, which includes the kernel’s core functionality, device drivers, and other vital elements. When we compile the kernel, it generates vmlinux. However, vmlinux is too big to fit into the finite memory available during boot (the first 640KB of RAM). As a result, we compress the vmlinux file into a smaller size (often compressed below 512KB) using the gzip utility, creating the bzimage image file.
The compression process significantly reduces the kernel image size, making the boot process easier. The “bz” in bzimage stands for “big zipped” because we compress the kernel image using the gzip compression algorithm.
Let’s look at some of the components present in the bzimage file. First, we have the boot loader header, which contains information the boot loader requires to load and execute the kernel. This header provides details like the kernel version, the size of the compressed kernel, the offset of the compressed kernel, and the location of the initial RAM disk (initrd) if present.
The initrd is a temporary root file system loaded into memory during the boot process before the actual root file system is mounted.
Then, we have the bzimage file containing the compressed kernel image. This image includes all the necessary code and data to initialize the kernel and start the operating system. It consists of the kernel’s entry point, initialization routines, device drivers, file systems, etc.
In this article, we saw the kernel image formats that provide us with different options for deploying and booting the Linux kernel. vmlinux is the uncompressed kernel code, vmlinuz, and vmlinux.bin are compressed versions for booting. zimage is an older compressed format, and bzImage is an improved version.
Lastly, choosing the right kernel image format depends on a variety of factors, such as the use case, the hardware architecture, boot loader compatibility, and compression/optimization requirements.