Linux系统的启动过程

微信视频号:sph0RgSyDYV47z6
快手号:4874645212
抖音号:dy0so323fq2w
小红书号:95619019828

B站:UID:3546863642871878

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、内存、显卡、存储控制器、键盘等是否正常工作。
  • 如果检测到严重错误,会通过蜂鸣声或屏幕错误码提示。
  1. 固件初始化 (Firmware Initialization):
  • 配置硬件:初始化CPU、内存控制器、芯片组、总线(PCIe, USB, SATA等)、时钟。
  • 枚举连接的设备(存储设备、网卡、USB设备等)。
  • 建立硬件设备列表和访问方式(如中断、I/O端口、内存映射)。
  1. 选择启动设备 (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。
  1. 移交控制权 (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-xxxinitramfs-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 映像到内存中。
  1. GRUB2 配置文件 (grub.cfg):
  • 要加载的内核文件路径(如 /boot/vmlinuz-5.15.0-86-generic)。
  • 要加载的 initramfs 文件路径(如 /boot/initrd.img-5.15.0-86-generic)。
  • 传递给内核的命令行参数root=, ro, quiet, splash, init=, 特定驱动参数等)。
  • 根文件系统所在设备(在 initramfs 接管前可能需要)。
  • 通常由工具(如 grub-mkconfig, update-grub)根据 /etc/default/grub/etc/grub.d/ 下的脚本自动生成。
  • 定义了引导菜单项、默认选项、超时时间。
  • 每个菜单项指定了:
  1. 加载内核和 initramfs:
  • GRUB2 利用其文件系统驱动(或Stage 1.5)从 /boot 分区读取 vmlinuz-xxxinitrd.img-xxx 文件到内存的特定位置。
  • GRUB2 设置好内核启动所需的基本运行环境(如内存布局、视频模式)。
  1. 移交控制权给内核:
  • GRUB2 执行一个特殊的跳转指令,将CPU控制权交给内存中已加载的Linux内核映像的入口点(通常是 startup_32startup_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.)。
  • 初始化控制台(早期打印输出)。
  • 内核通常是压缩的(如 vmlinuzbzImage 格式)。内核入口代码首先解压自身到内存高端。
  • 进行极其底层的、与CPU架构相关的初始化:
  1. 通用内核初始化 (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()):
  • 其他重要初始化:
  1. 挂载根文件系统 (rootfs):
  • 内核在初始化早期会在内存中挂载一个最小的、内存中的根文件系统 (rootfs)。这通常是一个 tmpfsramfs
  • 这个初始 rootfs 为内核后续操作(如加载模块、访问 initramfs)提供了一个基础的文件系统环境。
  1. 处理 initramfs (populate_rootfs()):
  • 内核检查引导参数是否指定了 initramfs,以及GRUB是否加载了它。
  • 如果存在 initramfs,内核将其解压并提取到刚刚挂载的初始 rootfs。这通常会覆盖 rootfs 中的部分内容。
  • 这个解压出来的内容就是 initramfs 映像包含的文件和目录结构,它提供了在内核挂载真实根文件系统之前所需的关键工具、驱动和脚本。
  1. 移交控制权 (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 运行时的核心控制流程。
  1. 关键任务:
  • 这是 initramfs 的最后一步也是最关键的一步。
  • 将当前进程的根目录从 initramfs 切换到新挂载的真实根文件系统 (/root)。
  • 卸载或释放旧的 initramfs 占用的内存。
  • 使用加载好的驱动和工具访问根设备(由内核参数 root= 指定)。
  • 执行 mount 命令将真实的根文件系统挂载到 initramfs 内的某个目录(通常是 /root)。
  • 组装软件RAID (mdadm)。
  • 激活LVM卷组 (vgchange -ay)。
  • 解锁加密卷(请求密码或读取密钥文件)(cryptsetup luksOpen)。
  • 处理网络根文件系统(NFS)。
  • 加载必要的内核模块: 加载访问根设备所需的驱动(如SCSI控制器驱动、RAID驱动、LVM驱动、加密驱动 dm-crypt 用于LUKS分区、文件系统驱动如 ext4, btrfs, xfs 等)。这些驱动可能不在内核镜像中,而是作为模块打包在 initramfs 里。
  • 设备发现与等待: 探测硬件,可能需要等待慢速设备(如USB存储)就绪。
  • 处理复杂存储:
  • 挂载真正的根文件系统:
  • 切换根 (pivot_root / switch_root):
  1. 执行真正的 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菜单项添加 breakrd.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
  1. 确定启动目标 (default.target):
  • graphical.target: 图形界面多用户模式。
  • multi-user.target: 文本界面多用户模式。
  • rescue.target: 单用户救援模式。
  • systemd 启动的目标是达到一个预定义的“状态”(target)。默认启动目标通常是一个符号链接,指向例如:
  • 默认目标由 /etc/systemd/system/default.target 符号链接指定。
  1. 并行启动与服务管理:
  • 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 等)。
  1. 启动流程概要:
  • 如果目标是 graphical.target,则继续启动其依赖的服务:显示管理器(如gdm.service, lightdm.service, sddm.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):
  1. 依赖解析与状态维护:
  • systemd 持续监控所有单元的状态。
  • 如果服务崩溃,systemd 可以配置为自动重启。
  • 提供强大的命令(systemctl, journalctl)管理服务、查看日志、分析启动性能。
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)。
  1. 图形登录 (如果目标是 graphical.target):
  • 启动一个用户会话管理器(如 gnome-session, startplasma-x11, sway)。
  • 会话管理器加载用户的桌面环境(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 blame, systemd-analyze critical-chain, dmesg)。
  • 系统定制: 修改内核参数、GRUB配置、initramfs内容、systemd服务单元。
  • 安全加固: 配置Secure Boot、理解initramfs加密解锁过程、管理服务启动。
  • 应急恢复: 使用GRUB编辑启动参数进入单用户模式/rescue模式,使用initramfs shell修复系统。
微信视频号:sph0RgSyDYV47z6
快手号:4874645212
抖音号:dy0so323fq2w
小红书号:95619019828

B站:UID:3546863642871878

参考文献链接
posted @ 2025-08-10 06:14  吴建明wujianming  阅读(46)  评论(0)    收藏  举报