Understanding the Linux Kernel Startup Process
This article walks through the complete Linux kernel boot sequence, from the bootloader loading a compressed vmlinuz image and initramfs, through decompression and the start_kernel routine, to the creation of PID 0, 1, 2 and the init process that launches system services and the user interface.
This article explains the full Linux kernel boot flow, covering the bootloader, kernel image formats, decompression, core initialization functions, and the creation of the first user‑space process.
1. Basic Kernel Startup Flow
Bootloader → load kernel image → decompress kernel → kernel startup → call start_kernel → launch init process.
1.1 Bootloader
Loads the compressed kernel image (e.g., vmlinuz) from storage devices such as hard disks or USB drives.
If an initramfs or initrd is configured, it is loaded alongside the kernel to provide a temporary root filesystem.
1.2 Kernel Decompression
A small decompression stub embedded in the image runs after the image is in memory and expands the kernel to a pre‑allocated address.
Control is immediately transferred to the entry point of the decompressed kernel.
1.3 Kernel Startup (x86 example)
Architecture‑specific initialization (CPU mode, paging, memory map) prepares the hardware environment.
The kernel stack is created to support subsequent function calls.
The central routine start_kernel is invoked.
1.4 start_kernel Function
Defined in init/main.c; it is the first C function executed after the early assembly code.
Initializes console output, memory management, device drivers, interrupt handling, scheduler, and other core subsystems.
Creates the first user‑space process (the init process).
1.5 Launching the Init Process
The init process ( /sbin/init) performs system‑wide initialization, runs init scripts, and starts services.
2. Kernel Image Files and Compression
2.1 Why the Kernel Image Is Compressed
Reduces storage footprint, speeds up loading from disk, optimizes network transfer, and is supported by standard bootloaders.
2.2 vmlinux , vmlinuz and bzImage
vmlinux– the uncompressed ELF binary produced by the linker, containing the full kernel code and symbols. vmlinuz – vmlinux compressed with gzip. bzImage – a “big” image for x86 created with make bzImage, overcoming the address‑space limits of the older zImage format.
2.3 Kernel Loading Process
The bootloader reads its configuration (e.g., grub.cfg), loads vmlinuz and optional initrd into memory, passes kernel command‑line parameters, and jumps to the kernel entry point.
3. Detailed Decompression on x86
3.1 Key Source Files
arch/x86/boot/header.S– defines the entry point address. arch/x86/boot/compressed/head_64.S and arch/x86/boot/compressed/misc.c – set up the environment and implement the actual decompression algorithm. arch/x86/kernel/head_64.S – code executed after decompression to continue kernel startup.
3.2 Decompression Steps
Bootloader jumps to the kernel entry point.
CPU state and memory environment are initialized (e.g., startup_32 for 32‑bit or startup_64 for 64‑bit).
The decompression stub calls decompress_kernel, which selects the appropriate algorithm (gzip inflate, etc.) and expands the image.
After decompression, the code loads the address of start_kernel into a register and jumps to it, handing control to the full kernel.
4. Process Hierarchy After Kernel Startup
4.1 Kernel vs. User Processes
Kernel threads run in kernel space with full privileges and handle low‑level tasks such as I/O scheduling and interrupt processing.
User processes run in user space, interact with the kernel via system calls, and are limited by user‑space permissions.
4.2 PID 0, 1, 2
PID 0 – the swapper/idle process, created directly by the early assembly code; it runs when no other process is runnable.
PID 1 – the init process, created by kernel_thread(kernel_init,…) inside rest_init. It launches the first user‑space services.
PID 2 – the kthreadd process, also created in rest_init, and becomes the parent of all subsequent kernel threads.
4.3 rest_init and kernel_thread
static noinline void __ref rest_init(void) {
rcu_scheduler_starting();
pid = kernel_thread(kernel_init, NULL, CLONE_FS); // create PID 1
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); // create PID 2
} int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) {
return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
(unsigned long)fn, (unsigned long)arg,
NULL, NULL, 0);
}5. System Initialization by init
The init process reads the system’s initialization configuration (e.g., /etc/inittab, /etc/init.d scripts, or systemd unit files) and runs the corresponding scripts.
It mounts essential filesystems, configures networking, starts logging, and launches other core services.
On systems using systemd, the graphical target is started, which launches a display manager (GDM, LightDM, etc.) and then the user’s desktop environment.
6. Summary Flowchart
Power‑on → BIOS → Bootloader → load vmlinuz + initrd → decompress → start_kernel → create PID 0, 1, 2 → init process runs system scripts → services and UI start → system ready.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Linux Tech Enthusiast
Focused on sharing practical Linux technology content, covering Linux fundamentals, applications, tools, as well as databases, operating systems, network security, and other technical knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
