Linux 内核文件 rest_init 函数:流程与总结

start_kernel(void) 调用 rest_init (void),

函数原型 static noinline void __init_refok rest_init (void)

rest_init 开始

├─▶ rcu_scheduler_starting() ── RCU 调度功能激活

├─▶ smpboot_thread_init() ── smpboot 框架初始化

├─▶ kernel_thread(init) ── 创建 PID 1 (init 进程)

├─▶ numa_default_policy() ── 设置 NUMA 策略

├─▶ kernel_thread(kthreadd) ── 创建 PID 2 (kthreadd)

├─▶ 保存 kthreadd_task ── 供后续使用

├─▶ complete(&kthreadd_done) ── 通知完成

├─▶ init_idle_bootup_task() ── 当前线程 → idle 线程

├─▶ schedule_preempt_disabled() ── 首次调度,让出 CPU

└─▶ cpu_startup_entry() ── 进入空闲循环(永不返回)

关键设计思想

1. PID 1 和 PID 2 的特殊性

2. 当前线程的身份转变

执行 rest_init 的线程:

3. 永不返回

rest_init 的调用者永远不会看到它返回,因为最后一步进入了无限的空闲循环。这是内核启动流程的终点,也是系统正常运行状态的起点。

总结

rest_init 是整个内核初始化的压轴戏。它完成了从"单线程的内核初始化"到"多进程的正常运行"的转变:

从此,Linux 系统正式启动完成,进入了正常的运行状态:init 进程开始初始化用户空间,kthreadd 等待创建内核线程的请求,而空闲线程则在没有任务时运行。

  • 创建了两个最重要的系统进程(init 和 kthreadd)
  • 完成了启动线程到空闲线程的身份转变
  • 触发了第一次进程调度
  • 最后进入了系统的空闲循环
  • 最初是 boot CPU 上的启动线程
  • 在系统启动的最后阶段变成空闲线程
  • 这是一种优雅的资源重用:不需要专门创建一个空闲线程
  • PID 1 (init) 是所有用户进程的祖先,负责系统初始化
  • PID 2 (kthreadd) 是所有内核线程的祖先,负责创建其他内核线程
  • 这个顺序是固定的:必须先有 init,才能有 kthreadd
相关推荐
格林威6 小时前
SSD 写入速度测试命令(Linux)(基于工业相机高速存储)
linux·运维·开发语言·人工智能·数码相机·计算机视觉·工业相机
勇闯逆流河6 小时前
【LInux】linux控制(进程替换,自主shell的实现详解)
linux·运维·服务器
IMPYLH6 小时前
Linux 的 ls 命令
linux·运维·服务器·bash
笨笨饿6 小时前
33_顺序表(待完善)
linux·服务器·c语言·嵌入式硬件·算法·学习方法
wwj888wwj7 小时前
Ansible基础(复习1)
linux·运维·ansible
yj_xqj7 小时前
Linux network启动报错 && nmcli 的使用
linux·运维·服务器
程序猿编码7 小时前
eBPF代理:让SSH进程“溯源”,找到背后的客户端IP
linux·tcp/ip·ssh·ebpf
Shepherd06197 小时前
【IT 实战】解决 TP-Link USB 无线网卡在 Linux/PVE 下识别为存储设备的问题
linux·运维·服务器
开开心心_Every8 小时前
免费轻量电子书阅读器,多系统记笔记听书
linux·运维·服务器·神经网络·安全·机器学习·pdf
存储服务专家StorageExpert8 小时前
DELL EMC isilon/PowerScale 存储的健康检查方法
linux·运维·服务器·netapp存储·emc存储