引言
从按下电源到登录界面,Linux 要经过 固件 → 引导加载 → 内核 → initramfs → systemd 五段接力。理解启动流程,是排查「开机卡住」「内核 panic」「文件系统起不来」等问题的前提。本文按时间线拆解 Linux 启动全流程:先讲 BIOS/UEFI 固件引导,再讲 GRUB 引导加载与内核参数,接着解释 initramfs 为什么存在、内核如何交接给 systemd,最后讲 systemd 启动目标(multi-user/graphical)、内核模块加载与启动排错方法。
前置:/linux-process-management/(systemd 服务)、/linux-systemd-services/(unit 与 target)。内核原理深入见 [[os]]。
目录
- 1. 启动全流程总览:五段接力
- 2. 第一阶段:BIOS/UEFI 固件引导
- 3. 第二阶段:GRUB 引导加载与内核参数
- 4. 第三阶段:内核启动与 initramfs
- 5. 第四阶段:systemd 接管与启动目标
- 6. 启动目标详解:multi-user 与 graphical
- 7. 内核模块:加载、参数与黑名单
- 8. 启动性能分析:systemd-analyze
- 9. 启动排错:日志、单用户与救援模式
- 10. 速查表
- 延伸阅读
1. 启动全流程总览:五段接力
1. 固件(BIOS/UEFI):POST 自检 → 找到引导设备
↓
2. 引导加载(GRUB):加载内核 + initramfs + 参数
↓
3. 内核启动:解压 initramfs → 挂载根文件系统 → 启动 init
↓
4. systemd(PID 1):并行拉起系统服务 → 达到启动目标
↓
5. 用户层:multi-user(命令行)→ graphical(图形界面)→ 登录
各阶段耗时对比:
固件/BIOS:1-3s(可快 10 倍,SSD + UEFI 快启)
GRUB:0.5s
内核 + initramfs:1-3s
systemd 服务:2-10s(并行,占大头)
图形登录:1-3s
心智:启动是「接力赛」——每段各司其职,排错先定位「卡在哪一段」,再对症下药。
2. 第一阶段:BIOS/UEFI 固件引导
BIOS vs UEFI:
| 维度 | BIOS(传统) | UEFI(现代) |
|---|---|---|
| 寻址 | 16 位,MBR 分区 | 64 位,GPT 分区 |
| 启动 | 找 MBR 引导代码 | 读 EFI 系统分区(ESP) |
| 容量 | 2TB 上限 | 大容量 |
| 安全 | 无 | Secure Boot 安全启动 |
| 界面 | 蓝屏 | 图形化 |
UEFI 启动链:
按下电源 → UEFI 固件 POST → 读 NVRAM 启动项
→ 找 ESP 分区(/boot/efi)里的 .efi 文件(如 GRUB)
→ 加载引导加载器
Secure Boot:校验引导加载器签名——未签名的 GRUB 会被拒(内核也要签名)。
记忆:UEFI + GPT 是现代标配——Secure Boot 管「信任链」,签名不合法就不让启动。
3. 第二阶段:GRUB 引导加载与内核参数
GRUB 干什么:把内核 vmlinuz + initramfs + 命令行参数交给内核。
GRUB 配置文件:
/boot/grub/grub.cfg # 生成的主配置(别手改)
/etc/default/grub # 生成来源(改这里)
/boot/grub/grub.cfg # 通过 update-grub 重新生成
常见内核参数:
| 参数 | 作用 |
|---|---|
| quiet / splash | 安静模式(隐藏内核日志) |
| single | 单用户模式 |
| init=/bin/bash | 指定替代 init |
| nomodeset | 禁用内核显卡驱动(黑屏救急) |
| root=/dev/sda1 | 指定根设备 |
| rd.break | 在 initramfs 停住(排错) |
| selinux=0 | 禁用 SELinux(临时) |
临时改启动参数(排错常用):
开机进 GRUB → 按 e 编辑启动项
→ 在 linux 行末尾追加参数 → Ctrl+X 启动
永久改:
sudo sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="nomodeset"/' /etc/default/grub
sudo update-grub # 重新生成 grub.cfg
记忆:GRUB 是「启动菜单 + 参数注入器」——排错时
e编辑加参数,比改配置快得多。
4. 第三阶段:内核启动与 initramfs
initramfs(初始内存盘)为什么存在:
内核要挂载根文件系统,但根设备驱动(如 NVMe/LVM/加密)在根 fs 上!
→ 鸡生蛋问题
→ initramfs:把「挂载根所需的驱动 + 工具」打进内存盘
→ 内核先用 initramfs 里的 init 加载驱动、组装根设备
→ 然后真正的根 fs 挂载、交接给 systemd
initramfs 内容:
drivers(磁盘/网卡/文件系统)
lvm / mdadm / cryptsetup(卷组/RAID/加密工具)
init 脚本(发现并挂载真正的根)
内核启动顺序:
1. 解压 vmlinuz → 初始化内存管理/调度器
2. 加载 initramfs 到内存
3. 执行 initramfs 的 init → 探测根设备
4. 挂载真实根文件系统(switch_root)
5. 执行 /sbin/init(systemd)→ PID 1 接管
查看 initramfs 内容:
lsinitramfs /boot/initrd.img-$(uname -r)
# 或
zcat /boot/initrd.img-$(uname -r) | file -
心智:initramfs 是「先遣队」——把内核从「无法挂载根」的困境里解放出来,再交接给 systemd。
5. 第四阶段:systemd 接管与启动目标
内核交接给 systemd(PID 1):
内核 exec /sbin/init → systemd(PID 1)
→ 并行读取 unit 依赖图
→ 按目标(target)逐步拉起服务
→ 达到 default.target
启动目标(target)体系:
default.target
└─ multi-user.target(命令行)
├─ network.target / ssh / cron / nginx...
└─ graphical.target(图形,依赖 multi-user)
└─ display-manager.service(登录界面)
切换目标:
systemctl isolate multi-user.target # 切到命令行模式
systemctl isolate graphical.target # 切回图形
systemctl get-default # 看默认目标
systemctl set-default multi-user.target # 设默认
记忆:target 是「启动里程碑」——graphical 依赖 multi-user,multi-user 依赖底层服务,层层推进直到 default.target。
6. 启动目标详解:multi-user 与 graphical
两个核心 target 对比:
| 目标 | 是什么 | 何时用 |
|---|---|---|
| multi-user.target | 无图形界面的多用户命令行 | 服务器/排查 |
| graphical.target | 图形桌面 | 桌面机 |
multi-user.target 的关键服务:
systemd-udevd → 设备热插拔
dbus → 系统总线
network-online → 网络就绪
getty@tty1 → 登录终端
ssh / cron / 业务服务 → 用户层
查看每个 target 有哪些服务:
systemctl list-dependencies multi-user.target
systemctl list-dependencies graphical.target | head -30
排查卡在某服务:
systemctl list-units --failed # 哪些服务失败
systemctl show <svc> --property=StartLimitHit # 是否启动失败重试
记忆:graphical = multi-user + 显示管理器——服务器只需 multi-user,卡启动先查
--failed。
7. 内核模块:加载、参数与黑名单
内核模块(驱动)的加载时机:
启动时:udev 按硬件探测自动加载
运行时:modprobe 手动加载
模块管理命令:
lsmod # 已加载模块
modinfo nvidia # 模块信息
modprobe <module> # 加载
modprobe -r <module> # 卸载
modprobe -c | grep -i xx # 查看配置
模块参数:
# 运行时指定
modprobe drm debug=1
# 永久:/etc/modprobe.d/xx.conf
echo 'options drm debug=1' > /etc/modprobe.d/drm.conf
黑名单(禁用模块):
# /etc/modprobe.d/blacklist.conf
blacklist nouveau # 禁用 nouveau(N 卡开源驱动)
开机强制加载某模块:
# /etc/modules-load.d/xx.conf
echo 'nvidia_drm' | sudo tee /etc/modules-load.d/nvidia.conf
记忆:模块三文件——
/etc/modprobe.d(参数/黑名单)、/etc/modules-load.d(开机加载)、modprobe(运行时)。
8. 启动性能分析:systemd-analyze
启动时间分析:
systemd-analyze # 总时间
systemd-analyze blame # 每个服务耗时排行
systemd-analyze critical-chain # 关键启动链
systemd-analyze plot > boot.svg # 可视化启动图(浏览器看)
blame 输出解读:
3s postgresql.service
2s network-wait-online.target ← 常见瓶颈(等网络)
1s nginx.service
启动优化手段:
| 手段 | 效果 |
|---|---|
| 去掉 network-wait-online | 省 2-5s(业务不依赖可去掉) |
| 服务延迟/按需 | Socket 激活懒启动 |
| 并行(systemd 默认) | 已并行,别手动顺序化 |
| 减少无用服务 | 禁用不用的 target 成员 |
systemctl disable network-wait-online.service # 常见提速
记忆:启动慢先
systemd-analyze blame找大头——network-wait-online 是经典瓶颈,业务不依赖就去掉。
9. 启动排错:日志、单用户与救援模式
启动卡住/失败的排错三阶梯:
1. 看启动日志:dmesg / journalctl -b
2. 单用户模式:GRUB 加 single
3. 救援模式:GRUB 加 rd.break 或 init=/bin/bash
查看启动日志:
journalctl -b -p err # 本次开机的错误
dmesg | grep -i -E 'error|fail' # 内核启动错误
journalctl -b -1 # 上一次开机
单用户模式(修复模式):
GRUB → 按 e → 在 linux 行加 single → Ctrl+X
→ 进入单用户 shell(root,无密码)
→ 修复:fsck、改 fstab、禁坏服务
内核 panic(最严重):
画面定格 + 错误滚动(如 VFS: Unable to mount root fs)
常见原因:根设备驱动缺失 / fstab 错误 / initramfs 损坏
修复:用 live CD 进系统,重建 initramfs 或修 fstab
重建 initramfs:
sudo update-initramfs -u -k $(uname -r)
# 或全部内核
sudo update-initramfs -c -k all
铁律:启动排错先看「卡在哪一段」——固件→GRUB→内核→initramfs→systemd,逐段定位,别一上来瞎改。
10. 速查表
| 需求 | 做法 |
|---|---|
| 看启动耗时 | systemd-analyze blame |
| 看服务失败 | systemctl list-units --failed |
| 切换目标 | systemctl isolate multi-user.target |
| 设默认目标 | systemctl set-default graphical.target |
| 临时加参数 | GRUB e 编辑 linux 行 |
| 永久加参数 | /etc/default/grub + update-grub |
| 看内核日志 | dmesg / journalctl -b -p err |
| 重建 initramfs | update-initramfs -u |
| 单用户修复 | GRUB 加 single |
| 模块加载 | modprobe |
| 模块禁用 | /etc/modprobe.d/blacklist.conf |
| 启动提速 | 去 network-wait-online |
一句话记忆:Linux 启动五段接力——UEFI 固件 → GRUB 引导 → 内核 + initramfs(先遣队挂根)→ systemd 并行拉服务 → 达到 multi-user/graphical 目标;排错先定位卡哪段、看 systemd-analyze blame 和 journalctl -b、GRUB e 加参数进单用户修复;模块归 modprobe 管、initramfs 坏了就 update-initramfs -u 重建——理解启动链,开机问题不再玄学。
延伸阅读
- /linux-systemd-services/ — Unit 与 target 依赖
- /linux-process-management/ — PID 1 与进程
- /linux-journald-logging/ — journalctl 启动日志
- [[os]] — 操作系统内核原理
- [[infra]] — 服务器运维与排障
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。