当前位置:首页 > Linux > 正文

linux内核如何启动

nux内核启动涉及BIOS/UEFI初始化、Bootloader加载内核、内核解压与初始化、设备驱动加载、内存管理建立、init进程启动及系统服务初始化等步骤,最终进入用户空间运行状态

nux内核的启动是一个复杂而精细的过程,涉及多个阶段和组件,以下是对Linux内核启动过程的详细解析:

固件初始化(Firmware Initialization)

  1. BIOS/UEFI启动

    • BIOS(传统固件):执行硬件自检(POST,Power-On Self Test),检测CPU、内存、存储设备等,读取启动盘的主引导记录(MBR,Master Boot Record),定位引导加载程序(Bootloader)。
    • UEFI(新型固件):支持更大的磁盘容量、安全启动(Secure Boot)等特性,通过EFI系统分区(ESP,EFI System Partition)查找引导程序(如grubx64.efi)。
  2. 引导加载程序(Bootloader)

    • 常见工具:GRUB(GNU GRand Unified Bootloader)、LILO、SYSLINUX等。
    • 核心功能:加载内核映像,从磁盘读取压缩的内核文件(如/boot/vmlinuz-xxx)到内存;加载初始RAM磁盘,读取initramfs或initrd(Initial Ramdisk),用于临时根文件系统和硬件驱动;传递启动参数,将用户配置的参数(如root=/dev/sda1 rw)传递给内核。

内核入口与架构相关初始化

  1. 内核入口函数

    压缩的内核映像(如vmlinuz)被加载到内存后,首先执行架构特定的启动代码,以x86为例,32位内核的入口为arch/x86/boot/start.S中的start函数,64位内核的入口为arch/x86/boot/header.S,最终跳转到start_kernel函数(定义于init/main.c)。

  2. 早期初始化(架构相关)

    • 关闭中断:确保初始化过程不受干扰。
    • 设置内存映射:建立物理内存到虚拟地址的映射(页表初始化)。
    • 检测CPU特性:如支持PAE、SSE、超线程等。
    • 解压缩内核:若内核为压缩格式(如zImage、bzImage),解压缩到内存中的目标位置。

内核核心初始化(start_kernel阶段)

  1. 基础子系统初始化

    linux内核如何启动  第1张

    • 调度器初始化:注册进程调度类(如CFS完全公平调度器),初始化运行队列(sched_init())。
    • 内存管理初始化:初始化页分配器(伙伴系统,Buddy System)和slab分配器;检测内存布局(mem_init()),标记可用内存区域。
    • 中断子系统:初始化中断描述符表(IDT)和可编程中断控制器(PIC/APIC)。
    • 调试与跟踪:初始化kprintf、日志系统(log_init())、性能分析工具(如ftrace)。
  2. 设备与驱动初始化

    • 总线与设备模型:初始化sysfs和kobject框架,建立设备、总线、驱动的关联(device_model_init())。
    • 块设备与文件系统:注册文件系统(如ext4、xfs)和块设备驱动,初始化虚拟文件系统(VFS)。
    • 网络子系统:初始化网络协议栈(如TCP/IP)、注册网络设备驱动(net_init())。
  3. 关键组件初始化

    • 进程子系统:创建首个内核线程kthreadd(PID 2),作为所有内核线程的父进程。
    • 安全模块:初始化SELinux、AppArmor等安全框架(若内核启用)。
    • 电源管理:初始化ACPI/APM,设置电源状态管理逻辑。

根文件系统挂载与用户空间启动

  1. 挂载初始根文件系统(initramfs/initrd)

    内核首先挂载initramfs(嵌入在内核中的临时文件系统)或独立的initrd,initramfs包含必要的驱动模块(如存储控制器驱动),用于访问真正的根文件系统,以及启动脚本(通常为/init),负责检测硬件、加载驱动、挂载实际根文件系统(如/dev/sda1)。

  2. 切换到真实根文件系统

    通过pivot_root系统调用,将根目录从initramfs切换到实际的磁盘文件系统(如/dev/sda1),卸载initramfs,释放相关资源。

  3. 启动用户空间初始化程序

    内核执行第一个用户空间进程init,其路径由内核参数或配置决定,传统init系统的路径为/sbin/init(如SysVinit),systemd时代的路径为/usr/lib/systemd/systemd(现代Linux默认),init进程的PID固定为1,是所有用户空间进程的祖先。

用户空间初始化(systemd/SysVinit)

  1. systemd初始化流程(以systemd为例)

    • 加载配置:读取/etc/systemd/system/default.target(默认启动目标,如graphical.target)。
    • 启动服务:按依赖关系并行启动系统服务(如网络、日志、图形界面等)。
    • 多用户模式:启动登录会话(如agetty),等待用户登录。
  2. 关键步骤

    • 挂载文件系统:根据/etc/fstab挂载额外的文件系统(如/home、/var)。
    • 启动守护进程:如sshd、systemd-journald等。
    • 用户会话:启动终端(tty)或图形桌面环境(如GNOME、KDE)。

启动完成与系统运行

内核启动完成后,进入多任务调度循环,由进程调度器(如CFS)管理CPU资源分配,用户通过登录会话交互,系统进入正常运行状态。

阶段 主要任务
固件初始化 硬件自检,加载Bootloader
内核入口与架构相关初始化 执行架构特定代码,解压缩内核
内核核心初始化 初始化基础子系统、设备与驱动、关键组件
根文件系统挂载与用户空间启动 挂载initramfs/initrd,切换到真实根文件系统,启动init进程
用户空间初始化 systemd或SysVinit启动服务,挂载额外文件系统,启动守护进程
启动完成与系统运行 进入多任务调度循环,等待用户登录

FAQs

  1. 什么是initramfs和initrd,它们有什么区别?

    initrd(Initial RAM Disk)和initramfs(Initial RAM File System)都是用于Linux系统启动时提供一个临时的文件系统环境,以便在根文件系统可用之前,内核可以挂载并使用必要的文件和驱动程序,initrd是一个实际的磁盘映像,包含一个临时的根文件系统,而initramfs是一个基于ramfs的文件系统,直接集成在内核映像中,initramfs通常比initrd性能更好,因为它在内存中操作,没有磁盘I/O的开销。

  2. 如何查看Linux内核的启动日志?

    • 可以使用dmesg命令查看Linux内核的启动日志,该命令会显示内核启动过程中输出的所有信息,包括硬件检测、驱动程序加载、文件系统挂载等,这些信息对于诊断系统启动问题非常有帮助
0