Linux系统的启动过程

Linux系统的启动过程是一个精心设计的接力过程,涉及多个阶段,从硬件初始化到用户空间服务的完全启动。下面进行详细深入分析:

核心阶段概述

  1. 硬件初始化 (BIOS/UEFI)
  2. 引导加载程序 (Boot Loader)
  3. 内核初始化 (Kernel Initialization)
  4. initramfs (Initial RAM Filesystem)
  5. 用户空间初始化 (Systemd / SysV init / etc.)
  6. 登录管理器 / Shell

阶段 1:硬件初始化 (BIOS/UEFI)

  1. 电源开启 (Power On):

     用户按下电源按钮。

  2. POST (Power-On Self-Test):
    • 主板固件(BIOS或UEFI)执行硬件自检。

    • 检查关键硬件组件:CPU、内存、显卡、存储控制器、键盘等是否正常工作。

    • 如果检测到严重错误,会通过蜂鸣声或屏幕错误码提示。

  3. 固件初始化 (Firmware Initialization):
    • 配置硬件:初始化CPU、内存控制器、芯片组、总线(PCIe, USB, SATA等)、时钟。

    • 枚举连接的设备(存储设备、网卡、USB设备等)。

    • 建立硬件设备列表和访问方式(如中断、I/O端口、内存映射)。

  4. 选择启动设备 (Boot Device Selection):
    • 根据固件设置的启动顺序(Boot Order),查找可启动的设备(硬盘、SSD、USB驱动器、网络PXE等)。

    • BIOS:查找每个设备第一个扇区(512字节)末尾的引导签名 0xAA55(Magic Number)。找到签名即认为该设备可引导,并加载该扇区(MBR)到内存 0x7C00 处执行。

    • UEFI:查找EFI系统分区(通常是FAT32格式),然后在该分区下按照特定路径(如 \EFI\ubuntu\grubx64.efi)查找并直接加载EFI应用程序(Boot Loader的可执行文件)。UEFI本身理解分区表和文件系统,无需加载MBR。

  5. 移交控制权 (Handover):
    • 硬件平台初始化完成。

    • 将控制权移交给从选定启动设备加载的第一阶段引导加载程序(BIOS是MBR,UEFI是EFI Application)。

关键点:

  • BIOS vs UEFI:

     UEFI更现代,支持更大的磁盘(GPT分区表)、更安全的启动(Secure Boot)、更快的启动速度、模块化设计。Secure Boot会验证引导加载程序的签名。

  • MBR (Master Boot Record):

     位于磁盘第一个扇区(512字节),包含:

    • 446字节:Stage 1 Boot Loader(初始引导代码)。

    • 64字节:分区表(4个主分区条目,每个16字节)。

    • 2字节:引导签名 0x55AA(小端序存储为 0x55, 0xAA)。

  • GPT (GUID Partition Table):

     UEFI使用的新分区方案,克服了MBR的限制(如分区数量、分区大小限制)。


阶段 2:引导加载程序 (Boot Loader)

主要任务: 找到并加载操作系统内核(vmlinuz-xxx)和可选的初始RAM磁盘映像(initrd.img-xxx 或 initramfs-xxx.img),并将控制权交给内核。

常见引导加载程序:GRUB2 (Grand Unified Bootloader version 2)

  1. GRUB2 的阶段 (BIOS 环境):
    • Stage 1 (MBR):

       被BIOS加载到 0x7C00 执行。其代码量极小,主要目的是加载Stage 1.5。它通常嵌入在MBR中或紧跟在MBR之后的扇区中。

    • Stage 1.5:

       位于MBR之后到第一个分区开始前的间隙(通常约31KB)。它包含了访问常见文件系统(如ext2, ext3, ext4, FAT)的基本驱动。它的核心任务是找到并加载位于 /boot/grub 目录下的 Stage 2 核心映像(core.img)。

    • Stage 2 (core.img):

       被加载到内存中。它提供了完整的GRUB功能:解析配置文件 /boot/grub/grub.cfg,显示引导菜单,允许用户选择操作系统或内核版本,加载模块(如支持LVM、RAID、加密、网络引导等)。其核心任务是加载Linux内核映像和 initramfs 映像到内存中。

  2. GRUB2 配置文件 (grub.cfg):
    • 要加载的内核文件路径(如 /boot/vmlinuz-5.15.0-86-generic)。

    • 要加载的 initramfs 文件路径(如 /boot/initrd.img-5.15.0-86-generic)。

    • 传递给内核的命令行参数root=roquietsplashinit=, 特定驱动参数等)。

    • 根文件系统所在设备(在 initramfs 接管前可能需要)。

    • 通常由工具(如 grub-mkconfigupdate-grub)根据 /etc/default/grub 和 /etc/grub.d/ 下的脚本自动生成。

    • 定义了引导菜单项、默认选项、超时时间。

    • 每个菜单项指定了:

  3. 加载内核和 initramfs:
    • GRUB2 利用其文件系统驱动(或Stage 1.5)从 /boot 分区读取 vmlinuz-xxx 和 initrd.img-xxx 文件到内存的特定位置。

    • GRUB2 设置好内核启动所需的基本运行环境(如内存布局、视频模式)。

  4. 移交控制权给内核:
    • GRUB2 执行一个特殊的跳转指令,将CPU控制权交给内存中已加载的Linux内核映像的入口点(通常是 startup_32 或 startup_64,取决于架构)。

    • 同时,它将包含引导参数(cmdline)、内存磁盘地址(initramfs位置)、硬件信息(如BIOS内存映射)等数据的引导信息结构体(如struct boot_params on x86)传递给内核。

关键点 (UEFI):

  • 在UEFI系统中,GRUB2 被编译为一个 EFI 应用程序(如 grubx64.efi)。

  • UEFI 固件直接加载并执行这个 .efi 文件(位于EFI系统分区)。

  • 后续流程(加载 grub.cfg, 内核, initramfs)与BIOS环境下的Stage 2类似。UEFI GRUB自身就包含了访问文件系统等所需的驱动。


阶段 3:内核初始化 (Kernel Initialization)

内核开始执行,接管硬件控制权,进行复杂的初始化工作,目标是挂载真正的根文件系统(/)并启动第一个用户空间进程(通常是 /sbin/init)。

  1. 解压与设置 (Architecture-Specific Setup):
    • 设置CPU运行模式(x86: 从实模式/保护模式切换到长模式/64位模式)。

    • 初始化基本内存管理:设置页表,启用分页(MMU)。

    • 设置中断描述符表(IDT)和全局描述符表(GDT)。

    • 检测CPU特性(FPU, MMX, SSE, etc.)。

    • 初始化控制台(早期打印输出)。

    • 内核通常是压缩的(如 vmlinuz 是 bzImage 格式)。内核入口代码首先解压自身到内存高端。

    • 进行极其底层的、与CPU架构相关的初始化:

  2. 通用内核初始化 (start_kernel()):

     这是内核C语言代码的入口点(init/main.c)。进行一系列关键子系统初始化:

    • 初始化 RCU (Read-Copy Update):

       高性能同步机制。

    • 初始化定时器 (tick_init(), time_init()):

       设置系统时钟和定时器中断。

    • 初始化控制台 (console_init()):

       如果之前是早期控制台,现在初始化完整控制台驱动。

    • 初始化模块子系统 (module_init()):

       支持可加载内核模块(LKM)。

    • 初始化/proc, /sys等虚拟文件系统 (vfs_caches_init(), proc_root_init()).
    • 初始化安全框架 (security_init()).
    • 初始化设备模型 (do_basic_setup()->driver_init()):

       建立设备、总线、驱动程序的模型,为后续探测硬件做准备。

    • 在 start_kernel() 的末尾,调用 rest_init()

    • rest_init()

       使用 kernel_thread() 创建内核线程 kernel_init (这就是未来的1号进程 /sbin/init 的内核线程部分)。

    • rest_init()

       创建另一个内核线程 kthreadd (2号进程,负责创建其他内核线程)。

    • rest_init()

       自身最终调用 cpu_startup_entry() 成为 0号进程 (idle 进程)

    • 初始化伙伴系统(物理页帧分配器)。

    • 初始化虚拟内存管理(VM)。

    • 解析并保留引导信息中传递的物理内存布局。

    • printk() 初始化:

       建立内核日志缓冲区。

    • 陷阱和中断初始化:

       设置异常处理程序,初始化中断控制器(如APIC/IOAPIC)。

    • 调度器初始化 (sched_init()):

       初始化进程调度器数据结构,创建0号进程 (idle 进程或 swapper 进程)。这是内核创建的第一个“进程”,它运行在内核空间,当CPU空闲时执行。

    • 内存管理初始化 (mm_init()):
    • 创建 init 进程上下文 (rest_init()):
    • 其他重要初始化:
  3. 挂载根文件系统 (rootfs):
    • 内核在初始化早期会在内存中挂载一个最小的、内存中的根文件系统 (rootfs)。这通常是一个 tmpfs 或 ramfs

    • 这个初始 rootfs 为内核后续操作(如加载模块、访问 initramfs)提供了一个基础的文件系统环境。

  4. 处理 initramfs (populate_rootfs()):
    • 内核检查引导参数是否指定了 initramfs,以及GRUB是否加载了它。

    • 如果存在 initramfs,内核将其解压并提取到刚刚挂载的初始 rootfs 中。这通常会覆盖 rootfs 中的部分内容。

    • 这个解压出来的内容就是 initramfs 映像包含的文件和目录结构,它提供了在内核挂载真实根文件系统之前所需的关键工具、驱动和脚本。

  5. 移交控制权 (kernel_init):
    • 内核执行 kernel_init 内核线程(即1号进程的内核部分)。

    • 如果存在 initramfskernel_init 会尝试执行 initramfs 根目录下的 /init 程序(这是一个用户空间程序,尽管此时还没有完整的用户空间环境)。

    • 如果没有 initramfs 或 /init 执行失败,内核会尝试直接执行指定的根文件系统上的 /sbin/init/etc/init/bin/init/bin/sh 等(通过 root= 参数指定根设备)。

    • 此时,内核将控制权交给用户空间的第一个程序 (/init 或 /sbin/init),标志着内核初始化阶段的结束和用户空间初始化的开始。

关键点:

  • 0号、1号、2号进程:

     内核创建的关键进程。

  • initramfs 的作用:

     为内核在挂载真实根文件系统之前提供必要的工具、驱动和脚本,解决了“先有鸡还是先有蛋”的问题(需要驱动访问根设备,但驱动可能在根设备上)。


阶段 4:initramfs (Initial RAM Filesystem)

initramfs 是一个临时的、基于内存的根文件系统。它的主要职责是为内核挂载真正的根文件系统 (/) 做准备,处理那些需要在内核启动后但在访问真实根设备之前完成的任务。

  1. /init 程序执行:
    • 内核启动 initramfs 中的 /init 程序(通常是一个shell脚本或可执行文件,如BusyBox init)。

    • 这个程序是 initramfs 运行时的核心控制流程。

  2. 关键任务:
    • 这是 initramfs 的最后一步也是最关键的一步。

    • 将当前进程的根目录从 initramfs 切换到新挂载的真实根文件系统 (/root)。

    • 卸载或释放旧的 initramfs 占用的内存。

    • 使用加载好的驱动和工具访问根设备(由内核参数 root= 指定)。

    • 执行 mount 命令将真实的根文件系统挂载到 initramfs 内的某个目录(通常是 /root)。

    • 组装软件RAID (mdadm)。

    • 激活LVM卷组 (vgchange -ay)。

    • 解锁加密卷(请求密码或读取密钥文件)(cryptsetup luksOpen)。

    • 处理网络根文件系统(NFS)。

    • 加载必要的内核模块:

       加载访问根设备所需的驱动(如SCSI控制器驱动、RAID驱动、LVM驱动、加密驱动 dm-crypt 用于LUKS分区、文件系统驱动如 ext4btrfsxfs 等)。这些驱动可能不在内核镜像中,而是作为模块打包在 initramfs 里。

    • 设备发现与等待:

       探测硬件,可能需要等待慢速设备(如USB存储)就绪。

    • 处理复杂存储:
    • 挂载真正的根文件系统:
    • 切换根 (pivot_root / switch_root):
  3. 执行真正的 init:
    • 切换根成功后,initramfs 的 /init 程序(或它调用的脚本)会执行真实根文件系统上的 /sbin/init(或内核参数 init= 指定的程序)。

    • 控制权正式移交给真实根文件系统上的初始化系统(如systemd, SysV init)。

    • initramfs

       的使命完成,其占用的内存通常会被回收。

关键点:

  • 必要性:

     对于使用复杂存储配置(LVM, RAID, 加密)、特殊文件系统、或根在网络的系统,initramfs 是必需的。

  • 生成工具:

     常用工具如 dracut (RHEL/Fedora/CentOS), mkinitramfs (Debian/Ubuntu), mkinitcpio (Arch Linux) 负责根据当前系统配置生成包含所需驱动和脚本的 initramfs 映像。

  • 调试:

     在启动时按特定键(如dEsc)或在GRUB菜单项添加 break 或 rd.break 参数可以中断 initramfs 的执行进入shell进行调试。


阶段 5:用户空间初始化 (Systemd / SysV init / etc.)

真正的根文件系统挂载后,第一个用户空间进程 /sbin/init (通常是 systemd 或 SysV init 的符号链接) 开始运行。它负责启动所有用户空间的服务、守护进程、设置登录环境等。这里以systemd(现代主流发行版标准)为例:

  1. systemd 进程启动 (PID 1):
    • 作为内核直接启动的 /sbin/init,成为系统的1号进程,是所有其他用户空间进程的祖先。

    • 它读取其配置文件 /etc/systemd/system.conf 和 /usr/lib/systemd/system.conf

  2. 确定启动目标 (default.target):
    • graphical.target

      : 图形界面多用户模式。

    • multi-user.target

      : 文本界面多用户模式。

    • rescue.target

      : 单用户救援模式。

    • systemd

       启动的目标是达到一个预定义的“状态”(target)。默认启动目标通常是一个符号链接,指向例如:

    • 默认目标由 /etc/systemd/system/default.target 符号链接指定。

  3. 并行启动与服务管理:
    • Socket Activation:

       按需启动服务。当有连接到达监听socket时,才启动对应的服务。避免服务闲置占用资源。

    • D-Bus Activation:

       类似Socket Activation,基于D-Bus消息激活服务。

    • Mount & Automount Units:

       管理文件系统挂载点。

    • Path Activation:

       监控文件路径变化来触发服务启动。

    • systemd

       的核心优势是并行启动服务,显著加速启动过程。

    • 它通过定义服务之间的依赖关系(在 .service.socket.target 等单元文件中声明)来决定启动顺序。

    • 关键机制:

    • systemd

       读取 /etc/systemd/system/ (系统管理员配置) 和 /usr/lib/systemd/system/ (发行版默认配置) 目录下的单元文件(.service.target.socket.device.mount.timer 等)。

  4. 启动流程概要:
    • 如果目标是 graphical.target,则继续启动其依赖的服务:显示管理器(如gdm.servicelightdm.servicesddm.service)。

    • 显示管理器负责启动X Server或Wayland Compositor,并显示登录窗口。

    • 所有定义为 multi-user.target 依赖的服务(如网络、远程登录sshd、打印cupscron等)都启动完成。

    • 系统进入命令行多用户模式,可以接受文本登录。

    • 日志服务 (systemd-journald):收集和管理内核及服务日志。

    • 网络服务 (systemd-networkd, NetworkManager):配置网络接口、IP地址、路由。

    • 认证服务 (systemd-logind):管理用户登录会话。

    • 定时器服务 (systemd-timedated)。

    • D-Bus 系统总线 (dbus.service):进程间通信总线。

    • 挂载 /proc/sys/dev/dev/pts/run 等虚拟文件系统。

    • 设置hostname、locale、时钟(NTP)、内核参数 (sysctl)、加载内核模块(通过 .mount 和 .service 单元)。

    • 激活swap空间。

    • 初始化udev:管理 /dev 下的设备节点,处理热插拔事件。udev 规则在 /etc/udev/rules.d/ 和 /usr/lib/udev/rules.d/ 下。

    • 设置随机数生成器种子。

    • 基础系统初始化:
    • 启动核心系统服务:
    • 到达基本多用户状态 (multi-user.target):
    • 到达图形界面状态 (graphical.target):
  5. 依赖解析与状态维护:
    • systemd

       持续监控所有单元的状态。

    • 如果服务崩溃,systemd 可以配置为自动重启。

    • 提供强大的命令(systemctljournalctl)管理服务、查看日志、分析启动性能。

SysV init (传统方式) 对比:

  • 使用 /etc/inittab 文件定义默认运行级别。

  • 运行级别 (0-6) 对应不同状态(0关机,1单用户,3多用户文本,5图形)。

  • 每个运行级别对应 /etc/rcX.d/ (X为运行级别) 目录,包含以 S(Start) 或 K(Kill) 开头的脚本链接,指向 /etc/init.d/ 下的实际脚本。

  • 按脚本文件名顺序(字母顺序)串行执行 S 脚本启动服务,执行 K 脚本停止服务。

  • 启动速度较慢,依赖关系管理复杂(通常靠脚本命名顺序和脚本内部处理)。


阶段 6:登录管理器 / Shell

  1. 文本登录 (如果目标是 multi-user.target):
    • 系统启动 getty 服务(如 agetty)。

    • getty

       在虚拟终端 (tty1-tty6) 上显示 login: 提示符。

    • 用户输入用户名和密码。

    • 认证过程(通常通过 PAM - Pluggable Authentication Modules)。

    • 认证成功后,启动用户指定的登录 shell (如 /bin/bash/bin/zsh),通常在 /etc/passwd 中定义。

    • shell

       读取并执行其配置文件(如 .bashrc.zshrc)。

  2. 图形登录 (如果目标是 graphical.target):
    • 启动一个用户会话管理器(如 gnome-sessionstartplasma-x11sway)。

    • 会话管理器加载用户的桌面环境(DE)或窗口管理器(WM),启动相关的用户级程序(面板、文件管理器、设置守护进程等)。

    • 执行用户的自动启动程序(~/.config/autostart/~/.xinitrc 等)。

    • 显示管理器 (DM) 启动并显示图形登录界面。

    • 用户选择用户并输入密码。

    • 认证(同样通过PAM)。

    • 认证成功后,DM:

    • 用户进入图形桌面环境。


总结与可视化流程

  +--------------------------+
  |       Power On           |
  +------------+-------------+
               |
               v
  +--------------------------+
  |   BIOS/UEFI Firmware     |
  |   - POST                 |
  |   - HW Init              |
  |   - Find Boot Device     |
  +------------+-------------+
               | (Loads MBR / EFI App)
               v
  +--------------------------+
  |   Boot Loader (GRUB2)    |
  |   - Loads menu           |
  |   - Loads kernel & initramfs |
  +------------+-------------+
               | (Hands off to kernel entry point)
               v
  +--------------------------+
  |   Linux Kernel           |
  |   - Decompress self      |
  |   - Arch-specific setup  |
  |   - start_kernel()       |
  |     * Core subsystems    |
  |     * Create PID 0, 1, 2|
  |   - Mount rootfs (tmpfs) |
  |   - Extract initramfs    |
  |   - Run /init (PID 1)    |
  +------------+-------------+
               | (User space begins)
               v
  +--------------------------+
  |   initramfs /init        |
  |   - Load modules (drivers)|
  |   - Assemble RAID/LVM    |
  |   - Unlock crypto        |
  |   - Mount real root (/)  |
  |   - pivot_root/switch_root|
  |   - Exec /sbin/init      |
  +------------+-------------+
               | (Real root FS)
               v
  +--------------------------+
  |   Systemd (PID 1)        |
  |   - Parse unit files     |
  |   - Start base system    |
  |   - Reach default.target |
  |   - Start services       |
  +------------+-------------+
               |
               +-------------------> [multi-user.target] ---> Getty ---> Login Shell
               | (Text Login)
               |
               v
               +-------------------> [graphical.target] ---> Display Manager ---> Desktop Session
                                      (Graphical Login)

深入理解 Linux 启动过程对于系统管理员至关重要,它能帮助:

  • 故障诊断:

     准确定位启动失败发生在哪个阶段(BIOS/UEFI? GRUB? Kernel Panic? initramfs? systemd service?)。

  • 性能优化:

     分析启动时间瓶颈(使用 systemd-analyze blamesystemd-analyze critical-chaindmesg)。

  • 系统定制:

     修改内核参数、GRUB配置、initramfs内容、systemd服务单元。

  • 安全加固:

     配置Secure Boot、理解initramfs加密解锁过程、管理服务启动。

  • 应急恢复:

     使用GRUB编辑启动参数进入单用户模式/rescue模式,使用initramfs shell修复系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值