init/ 内核启动机制与原理详解
源码路径:
rk3588/kernel-6.1/init/
内核版本:Linux 6.1(RK3588 / ARM64)
文档目录:linuxDoc/init/
init/ 负责内核从 架构入口进入 C 环境之后,到 用户态 PID 1(init/systemd/busybox) 运行之前的总控逻辑。体量集中在 main.c(约 1800+ 行),其余文件处理根挂载、initramfs、初始任务与版本信息。
目录
一、子系统职责
| 职责 | 主要实现 |
|---|---|
| 早期单线程初始化总控 | start_kernel() |
| 创建 init 线程与 kthreadd | rest_init() |
| SMP 就绪后驱动与子系统 initcall | do_basic_setup() → do_initcalls() |
| 内置 initramfs 解包 | initramfs.c |
| 真实根文件系统挂载 | do_mounts.c → prepare_namespace() |
| 执行用户态 init | kernel_init() → run_init_process() |
释放 __init 段、只读内核 |
free_initmem()、mark_readonly() |
| 0 号任务静态模板 | init_task.c |
不在 init/:setup_arch()、设备树解析、时钟/电源驱动主体 → arch/、drivers/。
二、启动阶段划分
2.1 start_kernel(仍多为 __init,关中断早期)
- 架构:
setup_arch、build_all_zonelists、page_alloc_init、mm_init - 参数:
parse_early_param、parse_args(init=等) - 调度/RCU/IRQ/时间:
sched_init、init_IRQ、time_init、hrtimers_init - 开中断后:
console_init、fork_init、vfs_caches_init、cgroup_init… - 结尾:
arch_call_rest_init()→rest_init()(不再返回)
详见 01。
2.2 rest_init + kernel_init
user_mode_thread(kernel_init):将来 exec 成用户态,目标 pid 1kernel_thread(kthreadd):内核线程工厂- boot 线程:
schedule_preempt_disabled()→cpu_idle kernel_init:kernel_init_freeable()→ 释放 init 内存 → 按序尝试 exec init
详见 02。
2.3 initcall 与挂根
do_pre_smp_initcalls:linker 段__initcall_start..__initcall0_startdo_initcalls:pure → core → … → late(七级)wait_for_initramfs()→console_on_rootfs()→prepare_namespace()或早期 initramfs 脚本
三、与相邻子系统边界
| 子系统 | 与 init 的衔接点 |
|---|---|
| arch/arm64 | setup_arch 填充 memblock、cmdline、SMP 信息;start_kernel 之前由 head.S 进入 |
| mm | mm_init、page_alloc_init;RK defer_free_memblock 在 smp_init 后由 main.c 拉起 |
| sched | sched_init 在 start_kernel;完整 SMP 调度在 sched_init_smp(kernel_init_freeable) |
| drivers | 大量 device_initcall / module_init 映射到 initcall device 级 |
| VFS | vfs_caches_init(早期+晚期)、prepare_namespace 挂根 |
| certs | integrity_load_keys() 在 kernel_init_freeable 末尾 |
四、RK3588 平台说明
| 特性 | 位置 | 作用 |
|---|---|---|
| 长命令行分段打印 | main.c + CONFIG_ARCH_ROCKCHIP |
避免单次 printk 截断 bootargs |
| Thunder Boot 延迟 memblock | main.c + mm/memblock.c |
后台线程释放大块内存给 buddy,缩短关键路径 |
| initrd 硬件解压等待 | initramfs.c |
与快启、HW decompress 驱动配合 |
产品常见启动参数:root=PARTUUID=...、rootwait、init=/sbin/init、ro/rw。
详见 07。
五、总结
init/ 是 “内核活起来” 的调度中心:不实现具体设备驱动,但决定 何时 跑 initcall、何时 等设备 probe、何时 挂根并 exec 用户态。RK3588 定制点少而关键,主要影响 启动日志 与 内存交给伙伴分配器的时机。
正在加载留言…