How Does the Linux Kernel Boot? A Deep Dive into Decompression and Initialization
This article explains the Linux kernel boot sequence, covering the decompression of a compressed kernel, the early startup code in head.S, the preparation steps performed by U-Boot, and the detailed initialization phases—including architecture setup, memory management, process creation, and the start_kernel routine.
Linux Kernel Self-Decompression Process
After U-Boot finishes system boot, it executes the command stored in the bootm environment variable, loading the Linux kernel into memory and calling the do_bootm function. If the kernel is uncompressed, it starts directly; if compressed, a decompression routine in the kernel header is invoked.
The source file for the compressed kernel entry point is /kernel/arch/arm/boot/compressed/head.S. It calls decompress_kernel(), prints “Uncompressing Linux...done, booting the kernel”, then uses gunzip() (or unlz4(), bunzip2(), unlz()) to place the kernel at the designated address and start it.
Linux Kernel Startup Preparation Phase
The kernel link script /kernel/arch/arm/kernel/vmlinux.lds shows that the entry function is stext (defined in /kernel/arch/arm/kernel/head.S). After decompression, the code jumps to stext to begin execution.
ENTRY(stext)
setmodePSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode and irqs disabled
mrcp15, 0, r9, c0, c0 @ obtain processor ID into r9
bl __lookup_processor_type @ returns procinfo in r5, cpuid in r9
mov r10, r5 @ invalid processor (r5=0?)
beq __error_p @ error 'p' if unsupported
bl __lookup_machine_type @ returns machinfo in r5
mov r8, r5 @ invalid machine (r5=0?)
beq __error_a @ error 'a' if unsupported
bl __vet_atags @ verify ATAGS format from U-Boot
bl __create_page_tables @ create initial page tables
ldrr13, __switch_data @ address to jump to after preparation(1) Disable IRQ/FIQ and switch to SVC mode via the setmode macro.
(2) Validate the processor ID; if unsupported, abort boot.
(3) Validate the machine code; if unsupported, abort boot.
(4) Verify the ATAGS format passed from U-Boot.
(5) Create a coarse page table used in early boot; a finer table will be rebuilt later.
(6) Jump to __switch_data, which calls __mmap_switched for final preparations.
1) Copy .data segment, clear .bss to set up C runtime environment.
2) Save processor ID, machine code, and ATAGS pointer.
3) Branch to start_kernel for kernel initialization. __switch_data:
.long __mmap_switched
...
__mmap_switched:
adrr3, __switch_data + 4
ldmiar3!, {r4, r5, r6, r7}
cmp r4, r5 @ Copy data segment if needed
ldrne fp, [r4], #4
strne fp, [r5], #4
bne 1b
mov fp, #0 @ Clear BSS
...
str r9, [r4] @ Save processor ID
str r1, [r5] @ Save machine type
str r2, [r6] @ Save ATAGS pointer
bic r4, r0, #CR_A @ Clear A bit
stmiar7, {r0, r4} @ Save control register values
b start_kernel
ENDPROC(__mmap_switched)Linux Kernel Initialization Phase
This phase starts with the start_kernel function, the entry point for all Linux platforms. It completes remaining hardware‑specific initialization, performs a series of kernel‑level setups, then launches the first user‑space process init, marking the end of kernel boot.
3.1 Main Work of start_kernel
start_kernelperforms several key initializations:
Architecture‑specific and generic configuration
Memory management setup
Process management setup
Scheduler initialization
Network subsystem initialization
Virtual file system setup
File system initialization
3.2 Key Functions in the start_kernel Flow
setup_arch(&command_line)
This architecture‑specific initialization handles processor parameter setup, early processing of the tagged list of boot parameters, and early memory subsystem initialization.
The command_line is the boot argument string passed from U‑Boot (environment variable bootargs). If empty, it defaults to the kernel’s built‑in command line defined by CONFIG_CMDLINE.
setup_command_line, parse_early_param, parse_args
These functions parse and store command‑line parameters. Example parsing result: console=ttySAC2,115200 – console device and baud rate root=/dev/mmcblk0p2 rw – root filesystem path init=/linuxrc – first user‑space process rootfstype=ext3 – filesystem type
sched_init
Initializes the scheduler, creates the run queue, and sets up the idle thread for the current task.
rest_init
Performs the final kernel startup steps:
1) Call kernel_thread to start two kernel threads: kernel_init and kthreadd.
kernel_init mounts the root filesystem and invokes init_post to run the first user process (init).
If the init path from command_line is invalid, fallback to /sbin/init, /etc/init, /bin/init, or /bin/sh.
2) Call schedule() to start the scheduler.
3) Call cpu_idle() to launch the idle process.These steps complete the Linux kernel boot process.
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.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional 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.
