Linux启动流程详解:从BIOS/UEFI到systemd完整指南

Linux启动流程详解:从BIOS/UEFI到systemd完整指南 Linux 的启动过程是每个做运维、做嵌入式、或者单纯想搞懂操作系统的人在某个阶段都会回头补的一课。网上讲启动流程的文章很多但不少要么停留在“ BIOS - 内核 - systemd”这种过于笼统的层面要么直接甩出一堆内核源码让人劝退。这次我们换个方式不背源码直接把整个启动过程拆成几个阶段每个阶段讲清楚“谁在运行、读取什么配置、怎么验证、出问题怎么排查”。这篇文章不只讲概念还会把每个阶段对应的日志查看方式、配置文件位置、常见故障和排查命令一起给出来。你可以一边读一边在自己的 Linux 机器上敲命令对照这样一遍下来对系统启动的理解会比单独看十篇文章都扎实。如果你是正在准备 Linux 面试或者工作中遇到过“开机卡在某个界面”“内核 panic”“grub rescue 界面”这类问题这篇文章可以直接收藏。1. 核心知识速览项目说明启动阶段固件BIOS/UEFI- 引导器GRUB2- 内核 - initramfs - systemd - 登录目标关键配置文件/etc/default/grub、/boot/grub2/grub.cfg、/etc/fstab、/etc/systemd/system/关键日志dmesg、journalctl -b、/var/log/messages、/var/log/boot.log常见引导器GRUB2主流发行版默认、systemd-boot部分新装机、Syslinux轻量场景初始化系统systemd主流、SysV init老系统、OpenRCGentoo 等排查工具grub2-mkconfig、systemd-analyze blame、journalctl -p err -b、fsck适用人群Linux 运维、嵌入式开发、面试备考、系统爱好者从整体看Linux 启动可以概括为六个阶段通电自检、引导器加载、内核解压、initramfs 挂载根文件系统、systemd 执行默认目标、用户登录环境准备。下面按这个顺序展开。2. 启动流程全景一条命令看懂当前系统在正式拆解之前先在终端里敲一条命令看看你当前系统的启动方式# 查看系统使用的初始化系统 ps -p 1 -o comm # 查看固件类型输出的是 bios 或 efi [ -d /sys/firmware/efi ] echo UEFI || echo BIOS # 查看当前内核版本 uname -r # 查看默认 systemd 启动目标 systemctl get-default这三条命令分别回答了三个关键问题PID 1 是谁、固件是传统 BIOS 还是 UEFI、系统默认启动到哪个目标。不同组合对应不同的启动细节下面会分别提到。3. 第一阶段固件初始化BIOS 与 UEFI按下电源键之后CPU 首先执行的第一段代码不是 Linux 内核而是主板固件。这段固件负责硬件自检和寻找可启动设备。3.1 传统 BIOS 与 MBR传统 BIOS 模式下固件会按照 CMOS 中配置的启动顺序依次检查硬盘、U 盘、光驱等设备。它寻找的是设备第一个扇区MBR主引导记录中的引导代码。MBR 位于磁盘起始的 512 字节其中前 446 字节是引导代码后面是分区表。MBR 方案有两个明显的限制最多支持 4 个主分区。磁盘容量超过 2TB 时无法直接使用整块磁盘空间。因此传统 BIOS MBR 的组合在新硬件上已经很少见了但不少老服务器和嵌入式设备还在用。3.2 UEFI 与 GPTUEFI统一可扩展固件接口是替代 BIOS 的新方案。它不再从磁盘扇区加载代码而是直接读取 ESPEFI System Partition分区中的 .efi 引导文件。ESP 分区通常格式化为 FAT32挂载点在 /boot/efi。GPTGUID Partition Table是配合 UEFI 使用的分区表格式支持超过 2TB 的磁盘也支持更多分区数量。UEFI 固件可以直接识别 FAT32 文件系统因此不再需要 MBR 中那 446 字节的引导代码。3.3 如何确认当前系统是哪种启动方式# 如果存在 /sys/firmware/efi 目录说明是 UEFI 启动 ls /sys/firmware/efi # 查看磁盘分区表类型 sudo parted -l | grep -E Partition Table|Disk /dev # 查看 ESP 分区是否挂载 ls /boot/efi/EFI在实际运维中确认启动方式是排查引导问题的第一步。UEFI 和 BIOS 的引导修复命令完全不同搞错方向会浪费大量时间。4. 第二阶段引导器 GRUB2 的工作固件找到引导器之后控制权移交给 GRUB2。GRUB2 是绝大多数 Linux 发行版默认的引导器它的任务是加载内核镜像和 initramfs并把启动参数传递给内核。4.1 GRUB2 的配置体系GRUB2 的配置文件不是直接手工编辑的。用户真正修改的是 /etc/default/grub 和 /etc/grub.d/ 目录下的脚本然后通过 grub2-mkconfig 命令生成最终的 /boot/grub2/grub.cfg。查看当前系统的 GRUB2 关键配置cat /etc/default/grub比较常见的参数含义参数说明GRUB_TIMEOUT菜单等待时间单位秒GRUB_DEFAULT默认启动项可以是数字或菜单项名称GRUB_CMDLINE_LINUX传递给内核的通用命令行参数GRUB_CMDLINE_LINUX_DEFAULT默认启动项传递的内核参数GRUB_DISABLE_RECOVERY是否禁用恢复模式菜单项修改 /etc/default/grub 后需要重新生成配置文件# RHEL/CentOS/Fedora 系列 sudo grub2-mkconfig -o /boot/grub2/grub.cfg # Debian/Ubuntu 系列 sudo update-grub4.2 内核命令行参数GRUB2 菜单中按 e 键可以进入编辑模式这里能看到当前内核的启动参数。常见参数包括quiet减少内核日志输出。splash显示开机画面。rootUUIDxxx指定根文件系统所在设备。rhgbRed Hat 图形启动。systemd.unitrescue.target临时指定启动目标。nomodeset禁用内核显卡驱动常用于显卡兼容问题。这些参数直接影响内核和 systemd 的行为。比如系统启动卡在图形界面可以临时加上 systemd.unitmulti-user.target 进入命令行排查问题后再恢复。4.3 GRUB2 故障与修复最常遇到的 GRUB 问题是开机直接进入 grub rescue 提示符。这种情况通常是引导器找不到内核或根文件系统原因包括移动了 /boot 分区。修改了分区表。双系统更新后引导项丢失。磁盘损坏。在 grub rescue 提示符下先查看有哪些磁盘和分区ls ls (hd0,msdos1)/找到正确的 /boot 分区后可以手工设置根目录和加载正常模块set root(hd0,msdos1) set prefix(hd0,msdos1)/boot/grub2 insmod normal normal进入正常 GRUB 菜单后再进入系统重新安装引导器。注意上面的磁盘和分区编号只是示例实际需要根据 ls 输出判断。5. 第三阶段内核初始化与 initramfsGRUB2 把内核镜像 vmlinuz 和 initramfs 镜像加载到内存后控制权移交给内核。5.1 内核解压与 CPU 初始化内核映像本身是压缩过的。它首先解压自身然后开始初始化 CPU、内存管理、中断控制器、定时器等最基础的硬件。这个阶段几乎没有任何日志输出因为负责输出日志的驱动程序可能还没加载完成。5.2 initramfs 的作用initramfs初始 RAM 文件系统是一个临时根文件系统打包了内核启动早期阶段需要的驱动和工具。它的核心任务是加载根文件系统所在的磁盘驱动挂载真正的根分区然后切换到真实根文件系统。为什么需要 initramfs因为根文件系统可能位于 SATA 硬盘、NVMe SSD、LVM 逻辑卷、LUKS 加密分区或网络存储上。内核不可能把所有驱动都编译进去所以先在内存中跑一个微型系统把必要驱动加载完再挂载真实根分区。查看当前系统的 initramfs 内容# 查看 initramfs 镜像里的文件列表 lsinitrd /boot/initramfs-$(uname -r).img # 重新生成 initramfs # RHEL/CentOS/Fedora: sudo dracut -f # Debian/Ubuntu: sudo update-initramfs -u5.3 切换到真实根文件系统initramfs 完成驱动加载后会执行 switch_root 或类似操作把根文件系统切换到真实磁盘分区然后启动 PID 1也就是 systemd。如果这个阶段失败常见的表现是系统进入 dracut 紧急 shell 或者提示“Failed to mount /sysroot”。这时候需要检查/etc/fstab 中的根分区 UUID 是否还正确。磁盘驱动是否缺失。LVM 卷组是否激活。LUKS 加密分区密码是否正确。排查命令# 在 dracut 紧急 shell 中查看块设备 lsblk blkid # 检查 LVM 卷 lvm vgscan lvm vgchange -ay # 手动挂载根分区 mount /dev/mapper/系统卷 /sysroot6. 第四阶段systemd 启动与目标Target内核挂载真实根文件系统后执行 /sbin/init也就是 systemd。systemd 是 Linux 下主流的初始化系统负责启动所有用户空间服务。6.1 systemd 的启动顺序systemd 不是按照 .sh 脚本顺序执行的而是按照依赖关系启动单元unit。它首先读取默认目标default.target然后根据依赖树逐步启动基础服务。查看系统启动顺序# 列出所有单元及其启动耗时 systemd-analyze # 按耗时排序 systemd-analyze blame | head -20 # 查看关键单元的依赖树 systemd-analyze critical-chain6.2 Target 是什么Target 在 systemd 中相当于 SysV init 的运行级别runlevel。SysV 运行级别systemd Target说明0poweroff.target关机1 / Srescue.target单用户救援模式3multi-user.target多用户命令行5graphical.target图形界面6reboot.target重启修改默认启动目标# 查看当前默认目标 systemctl get-default # 设置默认启动到命令行 sudo systemctl set-default multi-user.target # 临时启动到救援模式 sudo systemctl isolate rescue.target6.3 systemd 服务加载流程systemd 会从以下目录读取单元文件优先级从低到高/usr/lib/systemd/system/软件包自带的默认单元。/run/systemd/system/运行时生成的单元。/etc/systemd/system/管理员自定义单元。实际使用中需要修改服务配置时不要直接编辑 /usr/lib/systemd/system/ 下的文件应该执行 systemctl edit 生成覆盖配置sudo systemctl edit nginx.service这样做的好处是软件更新不会覆盖你的自定义配置。6.4 日志查看systemd 统一管理日志查看本次启动的完整日志# 查看本次启动所有日志 journalctl -b # 查看本次启动的错误级别日志 journalctl -b -p err # 查看某个服务的启动日志 journalctl -u nginx.service -b # 持续跟踪日志输出 journalctl -f排查启动问题最常用的命令就是 journalctl -b -p err它会列出本次启动中所有错误级别及以上的日志信息基本能定位到 90% 的服务启动失败问题。7. 第五阶段挂载文件系统与基础服务启动systemd 启动后首先处理的是文件系统挂载和基础服务。7.1 /etc/fstab 与文件系统挂载/etc/fstab 是系统启动时自动挂载文件系统的配置文件。每一行依次表示设备、挂载点、文件系统类型、挂载选项、是否 dump、是否 fsck。# 查看当前 fstab cat /etc/fstab # 校验 fstab 是否有语法错误不会真正挂载 sudo findmnt --verify如果 fstab 写错系统启动时可能卡在“A start job is running for /data”这样的界面等待超时。遇到这种情况可以输入密码进入维护模式修正 fstab 后重启。常见挂载选项选项含义defaults默认选项包含 rw、suid、dev、exec、auto、nouser、asyncnoatime不更新访问时间减少磁盘写入延长 SSD 寿命noexec禁止在该分区执行二进制文件nodev不解析该分区上的设备文件nosuid忽略 suid 和 sgid 位7.2 基础服务启动顺序文件系统挂载完成后systemd 会并行启动网络、安全、日志等基础服务。常见服务包括systemd-journald日志服务。systemd-udevd设备管理。NetworkManager / systemd-networkd网络配置。firewalld / nftables防火墙。auditd审计服务。crond定时任务。这一步用户最直观的体验是屏幕上的启动日志滚动。如果某个服务启动失败默认情况下 systemd 不会阻塞整个启动流程除非该服务被标记为 critical。8. 第六阶段登录环境准备systemd 完成默认目标后系统进入登录界面。8.1 命令行登录默认目标为 multi-user.target 时系统启动 getty 服务在终端上显示登录提示符。这个阶段的配置项主要是# 查看当前启动的 getty 服务 systemctl status gettytty1 # 如果串口登录失效常见原因是 getty 服务未启动 sudo systemctl start serial-gettyttyS0.service热词里提到的 “linux respawn getty” 就是这个阶段的内容。getty 在用户退出登录后需要重新拉起如果配置出错会出现登录后立即退出、反复重启登录程序的问题。可以通过 systemctl status gettytty1 查看是否有 restart 状态异常。8.2 图形界面登录默认目标为 graphical.target 时systemd 会启动显示管理器Display Manager常见的有 GDM、SDDM、LightDM。显示管理器负责弹出自登录窗口并加载桌面环境。如果图形界面启动失败排查思路是# 查看显示管理器状态 systemctl status gdm # 查看显示管理器日志 journalctl -u gdm -b # 查看 Xorg/Wayland 相关日志 journalctl -b | grep -i -E gdm|xorg|wayland # 如果无法进入图形界面先切到命令行排查 sudo systemctl isolate multi-user.target8.3 用户会话与启动应用用户输入密码登录后系统会读取用户级启动文件来初始化环境/etc/profile全局环境变量。~/.bash_profile、~/.bashrc用户 Shell 配置。~/.xinitrc启动 X 窗口时执行的用户脚本。~/.config/autostart/桌面环境下开机自启的应用程序。如果用户登录后出现“一闪而过退回登录界面”的情况多半是 Shell 配置或图形会话脚本中某个命令报错可以从 ~/.xsession-errors 或 journalctl -b 查看错误原因。9. 启动流程中的性能观测与优化启动慢是 Linux 桌面用户常遇到的问题很多情况下并不是硬件不行而是服务之间等待超时导致的。systemd 提供了非常完善的分析工具。# 查看启动耗时概览 systemd-analyze # 查看每个服务的启动耗时 systemd-analyze blame # 查看启动关键链路 systemd-analyze critical-chain # 查看图形化依赖关系生成 SVG 后可用浏览器打开 systemd-analyze plot boot.svg优化启动速度的常见方法禁用不需要的服务。sudo systemctl disable bluetooth.service关闭 fstab 中非关键挂载的 fsck 检查。设置 systemd 超时时间避免服务启动失败等待过久。sudo mkdir -p /etc/systemd/system.conf.d sudo tee /etc/systemd/system.conf.d/timeout.conf /dev/null EOF [Manager] DefaultTimeoutStartSec15s DefaultTimeoutStopSec15s EOF但要注意缩短超时时间属于“快速失败”策略。它不会让某个服务本身变快只是让它失败得更快从而避免系统长时间卡住。10. 常见启动故障与排查方法下面汇总最常见的启动故障和处理方式覆盖前面提到的各个阶段。问题现象可能原因排查方式解决方案开机进入 grub rescue引导器找不到内核或根分区在 rescue 下执行 ls 查看分区手工 set root/prefix 后 normal进系统重装引导器开机卡在 “A start job is running for /data”fstab 中有无法挂载的分区输入密码进入维护模式注释或修正 fstab 对应行内核 panic 且屏幕无后续根文件系统驱动缺失或内核参数错误查看 panic 前的最后几行检查 root 参数、重新生成 initramfs启动后停在 dracut shell根分区无法挂载lsblk、blkid 查看设备手动挂载根分区修正 fstab 或重建 initramfs图形界面循环登录用户 Shell 配置或图形会话脚本报错查看 ~/.xsession-errors修复报错配置或重装显示管理器登录后立即退出再次回到登录界面getty 配置异常systemctl status gettytty1重启 getty 服务或检查 /etc/securetty开机服务启动慢卡在等待网络网络服务等待 DHCP 超时systemd-analyze blame为不必要联网的服务设置 afternetwork-online.target修改 fstab 后无法开机fstab 语法错误或 UUID 不对findmnt --verify从启动维护模式修正 fstabLVM 根分区无法挂载卷组未激活lvm vgscan vgchange -ay在救援 shell 中激活卷组后挂载启动时出现 pcie 相关报错内核与固件交互问题或 BIOS 设置dmesg 查看 pcie 报错上下文升级 BIOS 或内核参数中加 pcinommconf 测试11. 最佳实践与建议结合整个启动流程整理几条实用建议能帮你减少这类问题出现的概率。分区时始终给 /boot 独立分区或保证 /boot 空间充足避免内核更新时空间不足。修改 /etc/fstab 前先备份建议用 UUID 而不是 /dev/sdX 设备名避免设备名漂移导致挂载失败。修改内核参数或 GRUB 配置后先执行 grub2-mkconfig 或 update-grub 重新生成配置再重启。不要直接编辑 /usr/lib/systemd/system/ 下的服务文件使用 systemctl edit 生成覆盖配置。维护一个可用的救援 U 盘或 LiveCD双系统和服务器场景尤其重要。启动日志是故障排查的第一手材料优先查看 journalctl -b -p err 和 dmesg 的输出。遇到启动问题不要盲目重装系统按“固件 - 引导器 - 内核 - initramfs - systemd - 登录”的顺序逐层定位能解决绝大多数问题。生产环境修改启动相关配置前先在测试机验证特别是 fstab、GRUB 参数和 systemd 默认目标。涉及 LUKS 加密、LVM 等高级配置时必须确保 initramfs 包含对应驱动否则系统无法解锁根分区。使用 systemd-analyze 定期检查启动耗时及时清理无用服务长时间运行的服务器和桌面机都适用。12. 总结与下一步这次我们从按下电源键开始完整走了一遍 Linux 的启动流程。固件负责找设备GRUB2 负责找内核内核通过 initramfs 挂载真正的根文件系统systemd 再根据依赖关系拉起整个用户空间。每个阶段都有对应的配置文件和日志入口排查问题也基本按照这个链路逐层下探。建议你先在自己机器上把 systemd-analyze、journalctl -u、grub2-mkconfig、lsinitrd 这些命令跑一遍确认当前系统每个阶段实际是什么状态。然后找一个不用的虚拟机故意改坏 fstab 或者删掉 initramfs再尝试修复这个过程对理解启动机制的帮助比看十遍文档都大。后续可以继续扩展的方向包括自己动手写一个 systemd 服务并加入开机自启、制作自定义 initramfs、深入分析内核启动日志中各个子系统的初始化顺序、或者把启动流程与性能调优结合起来做一次系统瘦身。Linux 启动过程并不神秘它只是按固定顺序和依赖关系执行的一系列步骤。搞清每一步发生了什么遇到问题就不会慌。