Linux内核启动流程与关键进程解析
·
## 1. Linux内核启动流程深度解析
### 1.1 内核生命周期起点
内核执行入口为`start_kernel()`函数,该函数位于`init/main.c`文件中。作为内核的"main函数",其生命周期始于第一条语句执行,终于`rest_init()`函数的无限循环:
```c
asmlinkage __visible void __init start_kernel(void)
{
...
rest_init(); // 内核最终进入此函数不再返回
}
1.2 关键进程创建机制
内核启动过程中会创建两个核心线程:
-
1号进程
:由
kernel_init内核线程演化而来,最终被用户空间的init进程替代 -
2号进程
:
kthreadd内核线程,负责管理其他内核线程
进程状态可通过
ps
命令观察:
PID USER COMMAND
1 root init # 用户进程
2 root [kthreadd] # 内核线程
2. 启动流程关键阶段分析
2.1 早期初始化阶段
在
console_init()
调用前,内核已通过缓存机制输出日志。典型初始化序列包括:
void __init start_kernel(void)
{
set_task_stack_end_magic(&init_task);
smp_setup_processor_id();
boot_cpu_init();
pr_notice("%s", linux_banner); // 打印内核版本信息
setup_arch(&command_line);
...
console_init(); // 第131行初始化控制台
}
2.2 驱动初始化阶段
通过
do_initcalls()
机制完成各级驱动初始化:
static void __init do_initcalls(void)
{
for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
do_initcall_level(level); // 依次执行1-7级初始化函数
}
其中
module_init()
宏定义的模块属于第6级初始化,典型驱动初始化日志包括:
[ 0.044199] pps_core: LinuxPPS API ver. 1 registered
[ 0.045501] clocksource: Switched to clocksource arch_sys_counter
3. 进程调度与系统启动
3.1 rest_init()关键逻辑
static noinline void __ref rest_init(void)
{
// 创建init进程
pid = kernel_thread(kernel_init, NULL, CLONE_FS);
// 创建kthreadd守护进程
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
// 进入idle循环
cpu_startup_entry(CPUHP_ONLINE);
}
3.2 进程状态转换
-
0号进程
:由
cpu_startup_entry()演变的idle进程 -
1号进程
:通过
kernel_init()执行的用户init进程 -
2号进程
:持续运行的
kthreadd内核线程
4. 根文件系统挂载
内核完成驱动初始化后,通过以下流程挂载根文件系统:
[ 5.090424] EXT4-fs (mmcblk0p2): mounted filesystem
[ 5.106669] VFS: Mounted root (ext4 filesystem)
5. 关键调试技术
5.1 打印点定位
在
start_kernel()
中添加打印需注意:
- 过早添加可能导致系统无法启动
-
安全位置在
console_init()之后(约131行)
5.2 典型调试输出
printk("## start_kernel() --> console_init()\n");
printk("## run rest_init()\n");
6. 启动时间线总结
- CPU/内存等硬件初始化
- 各级驱动初始化(1-7级)
- 文件系统挂载
- 用户空间init进程启动
- 进入稳定状态(0号进程idle循环)
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)