Detailed Explanation of the Linux Kernel Boot Process on Rockchip Platform

Detailed Explanation of the Linux Kernel Boot Process on Rockchip Platform

More content can be added to the Linux system knowledge base package (tutorials + videos + Q&A).

Back to school season “Linux Driver Comprehensive Course” promotion.

Detailed Explanation of the Linux Kernel Boot Process on Rockchip Platform

Table of Contents

  • 1. Linux Kernel Boot Process Flowchart
  • 2. Self-Extraction Phase
  • 3. Kernel Entry Point
  • 4. Assembly Phase
  • 5. C Function Phase
  • 6. Kernel Boot Scene
  • 7. Executing the First Application Init Program

Accumulation, sharing, and growth, allowing both yourself and others to gain something! 😄

1. Linux Kernel Boot Process Flowchart

Detailed Explanation of the Linux Kernel Boot Process on Rockchip Platform

  • Self-Extraction: The Bootloader loads the compressed kernel image, and the kernel self-extracts into memory.
  • Kernel Entry Point: Starts from assembly code (e.g., stext), initializing CPU and memory management.
  • Assembly Phase: Completes low-level hardware initialization, sets up stack, segmentation, and paging.
  • C Function Phase: Enters start_kernel(), initializing core kernel subsystems.
  • Kernel Boot Scene: Creates the first user process and mounts the root filesystem.
  • Executing Init Program: Starts the first user-space process init, completing system initialization.

2. Self-Extraction Phase

Kernel Image Format The Linux kernel is typically stored in a compressed format, such as Image.gz or Image.lz4, to reduce storage space. The kernel image for the ARM64 platform usually exists in the form of Image or compressed Image.gz.

Bootloader Loads Kernel The Bootloader (e.g., U-Boot) is responsible for loading the compressed kernel image into memory. U-Boot reads the header information of the kernel image to determine its size and loading address, and loads it into the specified memory location.

Self-Extraction Code The self-extraction code for the ARM64 kernel is typically located in arch/arm64/boot/compressed/head.S. This code is responsible for decompressing the kernel image to the specified memory location.

// arch/arm64/boot/compressed/head.S
ENTRY(_start)
// Set stack pointer
    ldr     x0,=boot_stack_end
    mov     sp, x0

// Call decompress function
    bl      decompress_kernel

// After decompression, jump to the entry of the decompressed kernel
    ldr     x0,=KERNEL_START
    br      x0
ENDPROC(_start)

Decompression Complete After decompression, control is transferred to the decompressed kernel code. At this point, the kernel image has been decompressed into memory and is ready for execution.

3. Kernel Entry Point

Entry Point The entry point of the decompressed kernel is stext, located in arch/arm64/kernel/head.S. This is the starting point for ARM64 kernel execution.

// arch/arm64/kernel/head.S
ENTRY(stext)
// Initialize CPU registers
    mov     x0, #0
    msr     spsel, x0

// Set up segmentation and paging
    bl      __create_page_tables

// Enable MMU
    bl      __enable_mmu

// Jump to C code
    b       start_kernel
ENDPROC(stext)

Environment Initialization At the entry point, the kernel sets up the basic environment, including:

  • Initializing CPU registers.
  • Setting up segmentation and paging mechanisms (ARM64 uses MMU for virtual memory management).
  • Enabling the Memory Management Unit (MMU).

4. Assembly Phase

Low-Level Initialization In the kernel’s assembly code, some low-level hardware initialization tasks are completed, including:

  • Setting up the stack pointer.
  • Initializing the Interrupt Descriptor Table (IDT) and Global Descriptor Table (GDT).
  • Detecting CPU features (e.g., FPU, NEON, etc.).
// arch/arm64/kernel/head.S
__create_page_tables:
// Create page tables
    ldr     x0,=init_pg_dir
    ldr     x1,=init_pg_end
    bl      __create_pgd_entry
    ret
ENDPROC(__create_page_tables)

__enable_mmu:
// Enable MMU
    mrs     x0, sctlr_el1
    orr     x0, x0, #SCTLR_EL1_M
    msr     sctlr_el1, x0
    isb
    ret
ENDPROC(__enable_mmu)

Jump to C Code The last part of the assembly code jumps to the C language entry function start_kernel().

5. C Function Phase

start_kernel() start_kernel() is the main entry function for kernel initialization, located in init/main.c. It is responsible for initializing the core subsystems of the kernel.

// init/main.c
asmlinkage __visible void __init start_kernel(void)
{
// Initialize memory management
setup_arch(&command_line);
mm_init();

// Initialize process management
sched_init();

// Initialize interrupt management
init_IRQ();

// Initialize device drivers
platform_devices_init();

// Initialize file system
vfs_caches_init();

// Call rest_init()
rest_init();
}

rest_init() At the end of start_kernel(), the rest_init() function is called to complete the kernel startup process.

// init/main.c
static void __init rest_init(void)
{
// Create the first user process
kernel_thread(kernel_init,NULL, CLONE_FS);

// Start the scheduler
cpu_startup_entry(CPUHP_ONLINE);
}

6. Kernel Boot Scene

Creating the First User Process In rest_init(), the kernel creates the first user-space process:

  • Calls the kernel_init() function to prepare for starting the user-space init program.
  • If initramfs is used, the kernel first mounts initramfs as a temporary root filesystem.
// init/main.c
static int __init kernel_init(void* unused)
{
// Mount the root filesystem
if(initramfs_in_use)
populate_rootfs();

// Mount the real root filesystem
mount_root();

// Start the user-space init program
run_init_process("/sbin/init");
return 0;
}

Mounting the Root Filesystem The kernel attempts to mount the real root filesystem (e.g., ext4, xfs, etc.) and switch to that filesystem.

7. Executing the First Application Init Program

Init Program Init is the first process in user space, with PID 1. Its main task is to start user-space services and manage system run levels.

Path of Init If the init= kernel parameter is specified, the kernel will attempt to execute the specified program. Otherwise, the kernel will try to find the following paths in order:

  • /sbin/init
  • /etc/init
  • /bin/init
  • /bin/sh

Systemd or SysV Init Modern Linux distributions typically use systemd or the traditional SysV init as the init program.

// init/main.c
static int run_init_process(const char* init_filename)
{
    argv_init[0] = init_filename;
return do_execve(getname_kernel(init_filename), argv_init, envp_init);
}

Leave a Comment