Kahibaro
Discord Login Register

Kernel loading

Where kernel loading fits in the boot chain

By the time “kernel loading” happens, a lot of work has already been done:

  1. Firmware (BIOS/UEFI) runs hardware initialization and finds the boot device.
  2. The bootloader (typically GRUB2 on Linux) is started from that device.
  3. The bootloader selects which kernel to boot and loads it (and its initramfs) into memory.
  4. Control is transferred from the bootloader to the kernel’s entry point.

This chapter covers steps 3 and 4: how the kernel image and initramfs are found, loaded, verified, and started.

You will see GRUB2 and firmware concepts mentioned, but their detailed behavior is covered in their own chapter. Here, focus on what specifically happens around the Linux kernel image itself.

Kernel images and their formats

Linux kernels are built into “images” that the bootloader can load into memory. The exact file and format depend on platform and distribution.

Common kernel image files

On x86 systems, you will most often see:

On other architectures, names vary (e.g., Image, zImage, uImage), but the idea is the same: a self-contained binary that includes:

Compressed vs uncompressed

A modern Linux kernel is large, so it is shipped in compressed form:

This matters for:

What the bootloader does for kernel loading

Assuming GRUB2 (other bootloaders behave similarly), the kernel-loading role is:

  1. Locate the kernel image
    GRUB uses a configuration file (commonly /boot/grub/grub.cfg) that specifies:
   linux   /boot/vmlinuz-6.8.0-31-generic root=UUID=... ro quiet splash
   initrd  /boot/initrd.img-6.8.0-31-generic
  1. Load kernel and initramfs into memory
    • Reads the kernel file from disk into memory at addresses chosen by the bootloader.
    • Reads the initramfs file and places it in memory, then passes its location to the kernel through the boot protocol.
    • Applies any required relocation to avoid overlaps with firmware or itself.
  2. Pass boot parameters (kernel command line)
    The kernel command line (for example, root=... ro quiet) is passed as a string.
    It affects:
    • Which root filesystem to mount.
    • Boot mode flags (e.g., single, init=/bin/sh, nomodeset).
    • Debugging options and hardware quirks.
  3. Optionally verify signatures
    In secure boot scenarios:
    • GRUB or the firmware may verify a signature on the kernel image and/or initramfs before loading or executing.
    • If verification fails, boot is refused.
  4. Transfer control to the kernel
    The bootloader calls the kernel entry point defined in the x86 boot protocol (or the equivalent on other architectures), handing over CPU control, registers, memory maps, and parameters.

Once that jump happens, the bootloader is out of the picture; the kernel takes over.

The Linux boot protocol (x86 perspective)

On x86, the interaction between bootloader and kernel is defined by the Linux boot protocol. You usually never touch this directly, but it explains what has to be prepared before the kernel can start.

Key things the bootloader must supply:

Other architectures (ARM, RISC-V, etc.) have their own conventions, but the idea is similar: bootloader loads the kernel at a given address, sets up basic CPU state, and calls a known entry point with some structure describing memory and firmware data.

From kernel entry to fully running kernel

From the moment the bootloader jumps into the kernel, the process is fully controlled by the kernel code.

1. Decompression and relocation

Steps:

  1. The small decompressor stub at the start of the image runs.
  2. It uncompresses the main kernel binary into its final location in memory:
    • Ensures it does not overwrite the initramfs or firmware data.
    • Deals with high memory vs low memory constraints.
  3. Control is passed to the uncompressed kernel’s early entry point.

Possible failure points here:

2. Very early initialization (arch-specific)

This is still before init runs and before drivers are fully initialized:

If something goes wrong here, you see very early kernel panics or the system appears to “freeze” right after the “Loading Linux…” message.

3. Parsing the kernel command line

The kernel command line string provided by the bootloader is parsed to configure:

This affects later stages like root mounting and init selection, but the parsing itself is part of kernel loading and early boot.

4. Attaching the initramfs

If the bootloader provided an initramfs:

At this point, the initial root filesystem is populated from the initramfs, and the kernel expects to find an init process inside it (e.g., /init or /sbin/init).

The details of what the initramfs does are covered in the initramfs chapter; here, the important point is: loading and attaching initramfs is part of the kernel’s early loading/initialization work.

Kernel loading in BIOS vs UEFI environments

The high-level idea is identical, but some details change depending on firmware type.

BIOS-style boot

Typical chain:

  1. BIOS loads the first-stage bootloader from the MBR.
  2. Bootloader eventually loads the full GRUB2 and its modules.
  3. GRUB2:
    • Reads /boot/grub/grub.cfg from a filesystem it understands.
    • Loads /boot/vmlinuz- and /boot/initrd.img- into memory.
    • Switches CPU to protected/long mode if required.
    • Calls the kernel’s entry point per the x86 boot protocol.

The kernel does not care that BIOS was used; it only sees the final CPU state and parameter structures.

UEFI-style boot

Typical chain:

  1. UEFI firmware loads an EFI executable from the EFI System Partition, such as:
    • shimx64.efi (often signed, used for Secure Boot)
    • grubx64.efi (GRUB2 as an EFI application)
  2. GRUB2 (EFI version):
    • Runs as a UEFI application, using UEFI services to read disks.
    • Loads the kernel and initramfs into memory.
    • Prepares the boot parameters, including EFI-specific data (e.g., EFI system table pointer).
    • Jumps to the kernel.

Alternatively, some setups use:

From the kernel’s perspective:

Initramfs: how it is loaded (from the kernel’s side)

Although initramfs has its own chapter, a couple of kernel-loading-specific points matter:

Problems in loading/initramfs at this stage often show as:

Kernel parameters that influence loading and early boot

Some common kernel command-line parameters affect kernel loading directly or indirectly:

These are examples of how “kernel loading” is not just copying bytes into memory, but also configuring how and where the kernel will operate once it starts.

Troubleshooting issues in the kernel loading stage

Many boot problems appear just as (or shortly after) the kernel is being loaded. Common symptoms and where they likely occur:

Tools/approaches that are specifically useful here:

Deeper recovery or configuration steps are covered in the boot troubleshooting chapter, but these are the kernel-loading-specific angles.

Summary of the kernel loading sequence

Putting it all together, the high-level flow during kernel loading is:

  1. Bootloader loads the compressed kernel image into memory.
  2. Bootloader loads the initramfs image into memory (if configured).
  3. Bootloader passes:
    • Memory map
    • Firmware tables
    • Initramfs location and size
    • Kernel command line
    • CPU mode and entry point
  4. Bootloader jumps to the kernel entry point.
  5. Kernel decompressor unpacks the kernel into its final location.
  6. Kernel initializes early CPU and memory management.
  7. Kernel parses the command line and attaches/initramfs.
  8. Initial root filesystem (usually from initramfs) is ready, and the kernel proceeds to start the first userspace process.

Everything after that — init systems, services, and user login — sits on top of this kernel loading foundation.

Views: 23

Comments

Please login to add a comment.

Don't have an account? Register now!