Linux内核主函数(start_kernel())是内核初始化的核心入口,在系统启动过程中扮演着全局协调者的角色。以下是其关键作用的深度分析:
setup_arch()解析CPU架构(x86/ARM等),初始化页表、内存映射、早期I/O端口等硬件相关配置。mm_init()建立完整的物理内存管理框架(Buddy System),初始化Slab分配器(kmem_cache_init())为后续对象分配提供支持。sched_init()初始化CFS等调度类,构建runqueue数据结构,但此时尚未启用任务切换(需等待rest_init()创建第一个内核线程后激活)。trap_init()设置IDT(x86)或异常向量表(ARM),init_IRQ()完成中断控制器(如APIC)的编程。time_init()初始化高精度计时器(HPET/TSC),为调度和延迟操作提供时间基准。vfs_caches_init()创建dcache和inode的哈希表,为后续挂载根文件系统做准备。fork_init()设置task_struct的SLAB缓存,proc_caches_init()初始化进程描述符相关缓存。*_initcall机制(如early_initcall、device_initcall)按优先级顺序加载模块,避免资源竞争。rest_init()中创建内核线程kernel_init(PID=1)和kthreadd(PID=2),最终由kernel_init加载用户空间init进程(如systemd),完成从内核态到用户态的切换。security_init()加载LSM(如SELinux/AppArmor)框架,建立初始安全策略。cmdline传递的启动参数(如quiet、root=),影响后续模块加载和行为。printk_init()建立环形缓冲区,支持早期调试输出(通过early_printk)。lockdep_init()启用锁依赖跟踪,预防运行时死锁问题。asmlinkage __visible void __init start_kernel(void) {
setup_arch(&command_line); // 架构相关初始化
mm_init(); // 内存管理
sched_init(); // 调度器
time_init(); // 定时器
rest_init(); // 创建init线程
}
early_printk检查卡死前的最后输出,常见于硬件初始化失败(如ACPI表解析错误)。CONFIG_DEBUG_KMEMLEAK检测内核启动阶段的内存泄漏。ftrace跟踪kernel_init线程的创建过程。start_kernel()通过严格的初始化顺序和依赖管理,确保Linux内核从"混沌"的引导状态逐步过渡到稳定的多任务环境,其设计体现了层次化初始化和按需延迟加载的核心思想。