恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Linux系统启动全流程解析:从BIOS/UEFI到systemd的故障排查实战

  • 首页
  • 资讯中心
  • /
  • Linux系统启动全流程解析:从BIOS/UEFI到systemd的故障排查实战

相关资讯

Flutter在OpenHarmony上实战:开发美食烹饪助手“今日推荐”功能 2026/10/8 2:51:06
莫以Skill小而不为:Agent技能包实战指南 2026/10/8 2:51:06
MAX30102实战指南:从PPG原理到心率血氧算法 2026/10/8 2:51:06

最新资讯

趣博思 AI 科普课:把实践报告当成 “讲故事“,但讲的是真事
H3C交换机配置实例教程:从VLAN划分到路由排错全攻略
天津博涛广告:5项软著,户外广告牌精度与产能同时具备
检测模板管理实战:从硬编码到JSON Schema驱动的自定义配置
药食同源发酵OEM工厂怎么选 源头供货工厂选择指南
C++编译期矩阵运算:用模板元编程和constexpr实现零运行时开销

今日推荐

context-mode实战指南:从全量塞入到结构化裁剪与检索增强
大模型对话上下文管理实战:三种模式与Token优化
抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

本周热门

MR25H40CDF + PIC18F65K40:工业记录仪高可靠存储实战
基于STM32的数控恒压恒流电源设计:从硬件到PID调参全解析
LT9211 MIPI重定时器原理与双路扇出实战指南

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

Linux系统启动全流程解析:从BIOS/UEFI到systemd的故障排查实战

发布时间:2026/10/8 2:51:06
Linux系统启动全流程解析:从BIOS/UEFI到systemd的故障排查实战 干 Linux 运维这些年每次听到系统启动这四个字我的第一反应不是教科书里那张分层图而是这些年熬夜排查过的一堆真实故障开机卡在 GRUB 菜单、内核 panic、systemd 等某个服务等满 90 秒、fstab 写错直接进维护模式……Linux 系统启动看起来只是通电到登录之间短短几十秒实际上它是整个操作系统最浓缩的一条地图也是运维事故最高发的环节。这篇文章我打算抛开那种从 BIOS 讲到用户态的干巴巴套路换成我平时排查问题的视角把启动全流程、关键配置、常见故障和修复手段串成一条实际操作链路。不管你是刚接触 Linux 的新人还是已经有几年经验、想根治启动坏了就重装这个老毛病的同行按着这条链路走一遍收益都会很直观。1. 先看懂 Linux 启动全流程你机器开机时到底在干什么1.1 从按下电源键到引导程序的完整链路很多人把开机当成一个黑盒操作其实 CPU 通电后的每一步都是有迹可循的。用 x86 平台举例按下电源键后CPU 会从复位向量地址取值跳进去执行的第一段代码不是 Linux 内核也不是 GRUB而是主板固件——传统 BIOS 或者现代 UEFI。传统 BIOS 的开机过程是先做加电自检POST检测内存、键盘、磁盘控制器这些基础硬件然后按照 CMOS 里配置的启动顺序去找引导设备。找到设备后BIOS 会读取该设备第一个扇区的前 446 字节也就是 MBR主引导记录。这 446 字节里放的就是引导加载器的第一阶段代码BIOS 无条件地把它读进内存并跳转执行。UEFI 的路径不太一样它读取 NVRAM 里保存的启动项列表从专用的 EFI 系统分区ESP一个 FAT 文件系统分区中加载.efi引导程序。因为 UEFI 自带文件系统驱动所以它可以直接读取分区内文件比 BIOS 那种裸读扇区的方式灵活得多也因此现代发行版几乎都默认 UEFI 引导。这里有个常见误区很多人以为启动顺序是BIOS → MBR → GRUB → 内核在纯 UEFI 环境下这套描述并不成立。UEFI 直接加载 ESP 分区里的grubx64.efiMBR 那套只在传统 BIOS 启动模式下才用得上。判断自己机器用的是哪种模式可以在 Linux 下看/sys/firmware/efi目录是否存在存在即 UEFI。1.2 谁在什么时候做什么事启动阶段速查我习惯把启动过程拆成四个大阶段每个阶段的执行主体和交接点都很清晰阶段执行者核心任务典型结束标志固件阶段BIOS/UEFI自检、初始化硬件、选择启动设备读取引导程序并跳转引导阶段GRUB 等引导加载器加载内核与 initramfs 到内存跳转到内核入口内核阶段Linux 内核初始化硬件、驱动、内存管理挂载根文件系统并启动 PID 1用户态阶段systemd/init拉起系统所有服务和目标登录界面或命令行提示符这四段之间的交接点是故障的高发地带。No bootable device说明固件没找到可引导设备error: file not found大概率是 GRUB 找不到内核文件VFS: Unable to mount root fs就是内核挂不上根文件系统。记住每个阶段结束的标志排查时就能快速缩小范围——先确认卡在哪两个阶段之间再决定往哪个方向查。2. 引导加载器 GRUB系统启动的第一道关口2.1 GRUB 的两种引导路径与磁盘空间约束GRUB 全称 GRand Unified Bootloader是目前绝大多数 Linux 发行版默认的引导管理器。它的工作流程在不同固件环境下差异不小。传统 BIOS/MBR 模式下GRUB 需要分阶段加载。MBR 只有 512 字节前 446 字节是引导代码中间 64 字节是磁盘分区表最后 2 字节是结束标志0xAA55。这点空间放不下任何文件系统驱动所以 GRUB 只能把第一阶段代码boot.img塞进 MBR它的唯一任务就是找到并加载核心镜像core.img。core.img通常放在 MBR 和第一个分区之间那段空闲扇区里体积一般几十 KB包含了 GRUB 的基础文件系统驱动。有了驱动GRUB 才能去/boot/grub目录读取完整的配置文件和模块。我之前见过有教程直接往 MBR 里dd写东西写着写着就把整个引导弄没了——了解这个空间约束以后你就会明白为什么 GRUB 安装这件事不能拿十六进制编辑器乱来。UEFI 模式下就简单多了。GRUB 以.efi可执行文件的形式放在 ESP 分区UEFI 固件能直接识别 FAT 文件系统于是加载整个 GRUB 成为一体操作不再需要分阶段跳转。这也是为什么 UEFI 机器上引导损坏后用grub-install修复时除了指定磁盘还要注意--efi-directory指向 ESP 分区的挂载点。我踩过最典型的坑就是把 ESP 误挂到了/boot上结果grub-install把文件写进了跟系统文件混在一起的分区重启后固件依然找不到启动项。2.2 grub.cfg 里那几个字段值得你逐行看懂很多人不敢碰 GRUB 配置其实核心就那么几行。以常见的 Debian/Ubuntu 为例一个典型的菜单项长这样menuentry Ubuntu { recordfail load_video insmod gzio insmod part_gpt insmod ext2 search --no-floppy --fs-uuid --setroot 2a4ae7a9-...-... linux /vmlinuz-5.15.0-91-generic rootUUID2a4ae7a9-...-... ro quiet splash initrd /initrd.img-5.15.0-91-generic }逐行解读一下insmod ext2加载 ext2/ext3/ext4 文件系统模块。GRUB 必须能识别出/boot所在分区的文件系统才能读取后续的vmlinuz和initrd文件。search --no-floppy --fs-uuid --setroot按文件系统的 UUID 找到/boot所在分区并把它设为 GRUB 的根设备。用 UUID 而不是设备名是因为/dev/sda这种设备名会随磁盘枚举顺序变化插个 U 盘重启就可能变UUID 则稳定得多。linux /vmlinuz-... rootUUID... ro quiet splash指定内核文件的路径以及传递给内核的参数。其中root用来告诉内核真正的根文件系统设备在哪。initrd /initrd.img-...指定 initramfs 映像路径这部分后面详聊。实际操作中千万不要直接手工编辑/boot/grub/grub.cfg。这个文件是发行版用脚本生成的下次更新内核或重新部署引导时就会被覆盖。正确做法是去改/etc/default/grub比如换内核参数、调整菜单超时时间改完执行update-grubRHEL 系是grub2-mkconfig -o /boot/grub2/grub.cfg。我当时第一次改启动等待时间就踩过这个坑手工改了 GRUB_TIMEOUT结果内核一升级全被冲掉又等回去。2.3 GRUB 损坏后的急救思路GRUB 损坏的场景太多了双系统装 Windows 把 MBR 覆盖、开了 Secure Boot 导致 GRUB 拒绝加载、分区结构调整后路径失效。真要遇到也别慌急救路径是固定的用任何 Linux 安装 U 盘或 live 环境启动到救援模式。把原系统的根分区挂载到/mnt如果/boot独立分区也要一并挂上。使用chroot切换到原系统环境重新生成 GRUB 配置并执行安装命令。mount /dev/sda2 /mnt mount /dev/sda1 /mnt/boot mount --bind /dev /mnt/dev mount --bind /proc /mnt/proc mount --bind /sys /mnt/sys chroot /mnt # BIOS 模式 grub-install /dev/sda # UEFI 模式 grub-install --targetx86_64-efi --efi-directory/boot --bootloader-idUbuntu grub-mkconfig -o /boot/grub/grub.cfg有个细节进入 chroot 前/dev、/proc、/sys一定要 bind 挂载否则grub-install可能探测不到设备甚至会把设备节点写进错误的路径。这一步不做好后面所有操作都会跑偏。3. 内核初始化与 initramfs破解根文件系统的鸡生蛋问题3.1 initramfs 到底是干嘛的内核被 GRUB 加载以后第一件大事就是把你的根文件系统挂载上来。但这里有个逻辑死锁根文件系统在磁盘上要读它需要文件系统驱动如果磁盘是 NVMe、LVM、RAID 或加密设备还需要对应的高级驱动而这些驱动编译成模块后存放在根文件系统的/lib/modules目录里——内核都还没挂上根文件系统上哪去读这些驱动解决这个死锁的东西就是 initramfs。它是一个迷你根文件系统通常由发行版用 dracut 或 update-initramfs 生成以压缩的 cpio 归档形式存放在/boot/initrd.img-*文件里。内核启动时会把这个归档解压到内存临时根目录执行其中的/init脚本。这个脚本的角色是过渡管家加载好真正根文件系统需要的所有驱动模块挂载真实根设备然后通过switch_root或pivot_root切换到真实根再执行真正的 PID 1 程序现在是 systemd。很多人被initrd和initramfs这两个名字绕晕了。历史上 initrd 是一个块设备镜像内核要先提供一个 RAM disk 块设备来承载它现在绝大多数发行版用的都是 initramfs本质是内存中的 tmpfs不需要额外块设备。虽然文件名还叫initrd.img但内部机制已经是 initramfs 了用file /boot/initrd.img-...能直接看到它是 gzip/xz 压缩的 cpio 归档。我在排查启动问题时会用lsinitramfs /boot/initrd.img-...查看里面真的有哪些模块和脚本这一步对判断驱动是不是没打进去非常有用。3.2 start_kernel 之后的内核初始化从通电到 PID 1内核入口分两条路底层体系结构相关的汇编代码先完成最早的页表、寄存器设置然后进入架构无关的start_kernel()。顺着start_kernel()往下看这个函数像极了一位新上任的管理者第一天点名setup_arch()梳理处理器架构相关的内存布局知道这台机器有多少物理内存、内核镜像放哪。trap_init()/init_IRQ()搭建中断和异常处理框架否则内核连被打断的能力都没有。time_init()初始化系统时钟之后的调度、超时统计全依赖它。mem_init()建立内存管理系统为后续创建进程准备资源。rest_init()创建两个关键进程——PID 1 的 init 进程和 PID 2 的 kthreadd 内核线程守护进程。rest_init()之后的剧情就交给了用户空间。PID 1 先运行 initramfs 里的/init脚本完成驱动加载和真实根挂载之后通过switch_root切换到真实根最终 exec 成/sbin/init或/usr/lib/systemd/systemd。也就是说内核本身在启动阶段忙的事情其实相当收敛把基础框架搭好然后立刻把控制权交给用户空间的管理者。理解这一点以后再看dmesg里那些密密麻麻的初始化日志你就能根据时间线大致判断内核卡在哪一步了。3.3 内核启动参数调试和维护的万能钥匙GRUB 菜单里可以按e临时编辑内核参数这对现场调试极其有用。以下是我日常用得最多的几个参数参数作用典型场景quiet隐藏绝大部分内核日志正常启动配合splash显示开机动画loglevel7打开 debug 级别内核日志内核阶段卡住时看最后的输出single/s进入单用户模式忘记 root 密码需要重置密码rd.break在 initramfs 执行早期中断进入急救 shell解密 LUKS 失败、根驱动加载异常systemd.unitemergency.target直接进入 systemd 紧急目标某个服务反复挂掉导致无法正常进系统panic10内核 panic 后 10 秒自动重启无人值守机器避免一直挂死拿忘记 root 密码举例在 GRUB 菜单选中内核按e编辑在linux那一行末尾加上rd.break然后按引导继续。系统会停在 initramfs 阶段的 shell 里这时根文件系统可能还没完整挂载你需要用mount -o remount,rw /sysroot把真实根以可写方式挂到/sysroot再chroot /sysroot就能执行passwd重置密码了。注意这要求sysroot在 initramfs 中已经被挂载实际操作中如果挂载点不对可以先看ls /sysroot里的内容再决定。用完rd.break后记得把参数删掉否则每次开机都会停在 shell。我的习惯是临时调试参数只加到 GRUB 的临时编辑确认有效后再写进/etc/default/grub的GRUB_CMDLINE_LINUX里持久化。4. systemd 接管从内核态到用户态的切换艺术4.1 systemd 凭什么比旧 init 快早期 SysV init 的启动方式是典型的串行执行按脚本编号 S01、S02、S03……一项接一项跑后面的服务必须等前面的完成。这种方式逻辑简单但效率极低而且脚本之间真正的依赖关系被数字顺序掩盖了——你在 S40 放数据库、S41 放网站服务如果两台机器上的脚本顺序排布不同启动结果可能完全不同。systemd 的核心理念是把执行顺序换成依赖关系每个服务单元通过After、Requires、Wants声明自己依赖谁。systemd 启动时先读取所有单元解析成一个依赖关系图然后从图里找没有依赖冲突的节点并行拉起。依赖关系允许并行没有依赖关系的服务也可以并行所以整个用户态阶段的时间被大幅压缩。这也就是为什么同样的硬件RHEL 7 及以上开机比 RHEL 6 明显更快。除此之外systemd 还支持 socket 激活和 D-Bus 激活。比如一个服务平时没人访问就没有必要在开机时立刻启动systemd 可以先监听它对应的 socket等第一个请求到来时再把服务进程拉起来。这种按需启动看着有点绕但在减少开机服务数方面非常有效也是现代桌面系统启动迅速的原因之一。4.2 Target 单元不是运行级别而是状态集合很多人习惯把 systemd 的 target 对应成 SysV 的运行级别这个理解方向对但细节不同。SysV 的运行级别是单一的数字systemd 的 target 是一组单元的集合进入某个 target 意味着把属于它的所有单元都拉起来。常用对应关系如下systemd Target说明类比 SysV 运行级别poweroff.target关机0rescue.target单用户救援模式只挂载必要文件系统1multi-user.target多用户字符界面3graphical.target图形界面在 multi-user 上叠加显示管理器5reboot.target重启6日常高频操作里最实用的命令是切换默认启动目标。比如服务器装了图形界面想省掉不一定要卸载桌面套件直接执行systemctl set-default multi-user.target下次开机就只进字符界面。想临时切换救援模式则执行systemctl isolate rescue.target。需要注意的是isolate会停掉当前 target 里不属于新 target 的单元操作前留意是否有未保存的数据。4.3 用 systemd-analyze 定位启动慢的关键环节系统开机慢第一反应先别瞎猜服务用 systemd 自带的性能分析工具把数据拉出来systemd-analyze blame | head -20 systemd-analyze critical-chainblame按耗时从高到低列出每个单元的启动时间适合快速锁定谁最拖。critical-chain则展示从启动到当前目标的关键路径能看出整条链路里哪个环节最慢。我常见的一种输出类似这样graphical.target 3.541s └─multi-user.target 3.541s └─network-online.target 3.540s └─NetworkManager-wait-online.service 118ms 3.422s每次看到NetworkManager-wait-online.service占着几秒钟我都想吐槽——这个服务的意义是等待网络完全就绪但对很多普通客户端来说开机网络根本没有硬性依赖。如果机器上网络环境稳定systemctl mask NetworkManager-wait-online.service能立省几秒甚至几十秒的启动时间。注意这里用的是mask而不是disablemask 相当于把这个服务彻底屏蔽连手动启动都不行想恢复就systemctl unmask NetworkManager-wait-online.service。这俩命令的区别我最初也搞混过disable 只是取消开机自动启动mask 是直接禁止拉起。5. 启动故障排查典型案例与修复实录5.1 开机卡住的通用排查路径开机卡住是最常见的故障但卡住这个词太笼统。我习惯先回答一个问题到底卡在哪个阶段判断方法很简单——看屏幕上的动态还没出现任何引导信息就停在品牌 logo 或黑屏固件或硬件层面先查 BIOS/UEFI 设置、启动顺序、内存、磁盘。能看到 GRUB 菜单但选完删除后黑屏引导阶段问题检查 GRUB 配置、内核文件是否存在。黑色屏幕上滚动大量内核日志然后停住内核或 initramfs 阶段日志的最后一行通常是线索。启动动画结束或输出几行 systemd 信息后长时间停滞用户态服务问题大概率是某个服务在超时等待。定位阶段之后内核阶段的问题把 GRUB 菜单里的内核参数暂时改成loglevel7观察内核最后输出的几行内容。systemd 阶段的问题在 GRUB 里临时加systemd.unitrescue.target进入救援模式用journalctl -xb翻启动日志。我处理过最典型的卡住案例是Reached target Multi-User System之后无故冻住最后用journalctl -xb发现/etc/fstab里一个不存在的挂载点让 systemd 死等 90 秒直到超时才放弃。5.2 fstab 配置错误导致进入维护模式的完整修复fstab 是 Linux 启动故障排名前三的元凶。它的格式是六列设备、挂载点、文件系统类型、挂载选项、dump 备份标记、fsck 检查顺序。只要有一行写错设备 UUID启动时系统就会尝试等待对应设备出现等不到就进入 emergency 模式屏幕上出现 Give root password for maintenance 或提示输入 root 密码进行维护。我记得有一次紧急处理远程服务器用户反馈开机后进不了系统只停在维护提示。排查路径如下输入 root 密码进入维护 shell执行mount -o remount,rw /让根文件系统可写。cat /etc/fstab找到可疑的那一行——某个 UUID 开头的条目用blkid对照真实设备的 UUID确认 UUID 确实不存在。用注释符#把错误行临时注释掉保存重启。确认系统能正常进入后如果是笔误改正 UUID如果是设备已经移除直接把那一行删除。如果错误的挂载写入被固化进 initramfs再执行update-initramfs -u重新生成 initramfs。过程中最容易犯的错是直接对根文件系统执行fsck而这一步在根已经被挂载的状态下是不该做的。对已挂载的文件系统做 fsck 轻则工具拒绝执行重则造成文件系统元数据损坏。要 fsck就得从 live U 盘启动或进入 initramfs 的rd.breakshell在根未挂载或只读挂载的前提下操作。5.3 服务启动超时拖慢开机的实战记录有时候系统最终能进但得等上很长一段时间这通常不是起不来问题而是某一个服务起不动。我用systemd-analyze blame定位过一次典型的 90 秒延迟罪魁是一个负责挂载网络共享的服务它依赖的网络地址迟迟不可达。系统显示a start job is running for ... (90s / no limit)等满 90 秒才跳过。处理这种服务超时有几个思路如果服务确实没必要在开机时执行systemctl disable或mask掉。如果服务要做但网络条件差在它的单元文件里调整TimeoutStartSec和TimeoutStopSec缩短不合理的等待时长。对网络挂载类需求fstab 条目上加_netdev或x-systemd.automount让 systemd 在该设备真正被访问时才去挂载而不是开机时死等。不要一上来就乱删服务先systemctl status看服务的实际状态journalctl -u 服务名看具体日志。很多超时的根因是上游依赖网络、其他服务没就绪单纯延长本服务超时只是治标。如果服务彻底不需要mask才是最干净的方案这样连依赖它的其他单元也不会因为等待它而被拖慢。6. 从启动流程延伸优化省时与操作习惯6.1 启动性能优化实测有效的几个方向服务端和桌面端对开机快的需求不同但优化方向大体一致。我试过综合应用以下手段普通 x86 机器启动耗时能肉眼可见地缩短精简内核模块普通桌面机器的 initramfs 里经常塞了很多用不到的驱动。Debian/Ubuntu 上可以修改/etc/initramfs-tools/initramfs.conf里的模块列表用update-initramfs -u重新生成让 initramfs 更小、加载更快。RHEL 系则用 dracut 的--omit-drivers选项。注意留出余地别把磁盘控制器驱动也剔出去。mask 掉确定无用的服务上面提到的 NetworkManager-wait-online、不需要的 bluetooth、打印服务等mask省下的是排队等待时间。默认目标切到multi-user.target如果服务器不需要图形界面这一步省掉的是整个显示管理器及其依赖。检查并修复 fstab 里的异常等待项任何无法立刻满足的挂载需求都会让 systemd 傻等 90 秒这条最不起眼但收益最大。优化项节省时间参考风险等级mask 无用网络等待服务2~30 秒低精简 initramfs 模块0.5~3 秒中切换到 multi-user.target3~10 秒低修复 fstab 异常等待最多 90 秒低6.2 这些操作习惯能帮你少踩启动的坑以我这些年修过的机器为教训有几个习惯真的能救命改任何系统关键文件fstab、grub 配置、内核参数之前先备份cp /etc/fstab /etc/fstab.bak花不了 1 秒但能让你在恢复现场时从容十倍。远程机器上做引导相关操作前反复确认。修改 grub 配置、重新安装引导、切换内核后不要立刻远程重启先再想一遍有没有哪个环节可能让你连不上机器。真做过一次因为改 GRUB 导致远程机器失联的事此后我所有引导操作都先在维护窗口期执行并确保能通过带外管理接口或现场访问。升级内核后保留旧内核不要立即删除。发行版默认保留多个内核版本启动菜单里可以按高级选项进入旧内核。一旦新内核有驱动或模块问题导致起不来旧内核就是最可靠的回滚通道。等新内核稳定运行两周以上再用apt purge或dnf remove清理旧内核。学会看日志而不是遇到启动故障就重装。journalctl -xb、dmesg、systemctl status、systemd-analyze这四个工具组合使用能覆盖 90% 以上的启动问题定位。重装系统往往意味着数据丢失和时间成本而排查流程一旦熟练多数问题半小时内能找到思路。这几年我最大的体会是Linux 启动流程不是一个背完就忘的知识点。每次遇到启动故障回头对照这条链路查一遍你可能又对内核、对 systemd、对文件系统多了一层理解。别怕启动起不来怕的是没有任何排查路径。把这条链路刻进脑子里下次再看到屏幕上那些滚动日志或 systemd 的报错你会比之前任何时候都镇定——因为你已经知道是谁在执行、可能卡在哪一步、以及下一步该看什么日志了。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号