Deep Dive into the Linux Kernel Boot Process
This article walks through the Linux kernel boot sequence on ARM platforms, covering self‑decompression, early initialization checks, page‑table setup, and the start_kernel routine that brings up hardware, memory management, scheduling, and the first user process.
1. Linux kernel self‑decompression
After U‑Boot finishes, it executes the bootm command, which loads the kernel image into memory and calls do_bootm. If the kernel is compressed, the entry point is /kernel/arch/arm/boot/compressed/head.S, which invokes decompress_kernel(). The decompressor prints “Uncompressing Linux…done, booting the kernel” and then calls gunzip() (or unlz4(), bunzip2(), unlz()) to place the uncompressed kernel at its final location.
2. Kernel boot preparation stage
The linker script /kernel/arch/arm/kernel/vmlinux.lds shows that the kernel entry point is stext defined in /kernel/arch/arm/kernel/head.S. After decompression, execution jumps to stext, which performs the following steps:
ENTRY(stext)
setmodePSR_F_BIT | PSR_I_BIT, SVC_MODE @ disable IRQ/FIQ, enter SVC mode
mrc p15, 0, r9, c0, c0 @ read processor ID into r9
bl __lookup_processor_type @ r5 = procinfo, r9 = cpuid
mov r5, r10 @ check processor support
beq __error_p, error 'p'
bl __lookup_machine_type @ r5 = machinfo
mov r5, r8 @ check machine support
beq __error_a, error 'a'
bl __vet_atags @ validate ATAGS from U‑Boot
bl __create_page_tables @ build initial coarse page tables
ldrr13, __switch_data @ address to jump after setupThe actions correspond to:
Disabling IRQ/FIQ and switching to SVC mode.
Verifying the processor ID; aborting if unsupported.
Verifying the machine (board) ID; aborting if unsupported.
Checking that the ATAGS structure passed by U‑Boot is well‑formed.
Creating a temporary coarse page table for early memory management.
Jumping to __switch_data, which eventually calls __mmap_switched for final preparations.
During __mmap_switched the kernel copies the .data section, clears .bss, saves the processor ID, machine type, and ATAGS pointer, and then branches to start_kernel.
3. Linux kernel initialization stage
The initialization begins at start_kernel, the common entry point for all Linux platforms. It performs the remaining hardware‑specific setup and then launches the first user‑space process init, completing the boot.
3.1 Main work of start_kernel
start_kernelcarries out a series of subsystem initializations:
Architecture‑specific and generic configuration.
Memory management.
Process management.
Scheduler setup.
Network subsystem.
Virtual file system.
File system.
3.2 Key functions called from start_kernel
setup_arch(&command_line) – initializes architecture‑specific data, parses the kernel command line (originating from U‑Boot’s bootargs), and performs early memory subsystem setup.
setup_command_line, parse_early_param, parse_args – parse and store command‑line parameters such as:
console=ttySAC2,115200
root=/dev/mmcblk0p2 rw
init=/linuxrc
rootfstype=ext3sched_init – creates the runqueue and the idle task for the scheduler.
rest_init – launches two kernel threads ( kernel_init and kthreadd) via kernel_thread. kernel_init mounts the root filesystem, runs init_post, and finally executes the first user process init. If the init path from the command line is invalid, four fall‑back options are tried: /sbin/init, /etc/init, /bin/init, and /bin/sh. After that, schedule() starts the scheduler and cpu_idle() launches the idle task, finishing the kernel boot.
3.3 Visual overview
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.
