从按下电源键到出现登录提示符,Linux 系统究竟经历了什么?本文以 CentOS 7 为样本,逐层拆解「POST 自检 → MBR 引导 → GRUB2 菜单 → 内核加载 → systemd 初始化」的完整启动链路,并系统梳理 target 依赖体系、运行级别演进、root 密码重置、/etc/fstab 故障排查与 GRUB2 配置等高频实战场景,助你真正读懂 Linux 的"开机哲学"。
文章目录
-
- [一、 启动链路总览](#一、 启动链路总览)
-
- 阶段一:开机自检
- [阶段二:MBR 引导](#阶段二:MBR 引导)
- [阶段三:GRUB2 菜单](#阶段三:GRUB2 菜单)
- [阶段四:加载内核与 initramfs](#阶段四:加载内核与 initramfs)
- [阶段五:systemd 接管(PID 1)](#阶段五:systemd 接管(PID 1))
- [二、 系统 target 依赖体系](#二、 系统 target 依赖体系)
- [三、 系统启动级别:从 runlevel 到 target](#三、 系统启动级别:从 runlevel 到 target)
-
- 历史回顾:/etc/inittab
- [设置系统当前运行 target](#设置系统当前运行 target)
- [设置系统开机默认运行 target](#设置系统开机默认运行 target)
- 在系统启动时临时选择其它目标
- [四、 实战:重置 root 密码](#四、 实战:重置 root 密码)
- [五、 实战:/etc/fstab 引起的启动故障](#五、 实战:/etc/fstab 引起的启动故障)
- [六、 GRUB2 配置详解](#六、 GRUB2 配置详解)
- 七、总结
一、 启动链路总览
现代计算机系统是硬件与软件的复杂组合。从断电状态到拥有登录提示符的运行中系统,需要大量硬件与软件协同工作。以物理 X86_64 平台启动 CentOS 7 为例,较高层面的任务链路如下:
- 开机自检(POST)
- MBR 引导
- GRUB 菜单
- 加载内核
- 运行 systemd 进程(PID 1)

阶段一:开机自检
计算机接通电源后,系统固件(现代 UEFI 或更旧的 BIOS)运行开机自检(POST),并开始初始化硬件。
配置入口:在系统启动早期,通过按特定组合键(如 F2)进入并配置系统固件。
阶段二:MBR 引导
系统固件按配置顺序搜索启动磁盘上的主启动记录(MBR),从中读取 boot loader,并将系统控制权移交给它------在 CentOS 7 中,这个 boot loader 就是 GRand Unified Bootloader version 2(GRUB2)。
配置入口 :使用
grub2-install命令将 GRUB2 安装为磁盘上的启动加载器。
阶段三:GRUB2 菜单
GRUB2 从 /boot/grub2/grub.cfg 加载配置并显示操作系统菜单,供用户选择要启动的系统条目。
配置入口 :通过
/etc/grub.d/目录、/etc/default/grub文件与grub2-mkconfig命令生成/boot/grub2/grub.cfg。
阶段四:加载内核与 initramfs
boot loader 根据选定条目的配置,从磁盘加载 kernel 与 initramfs 并放入内存。initramfs 是一个存档,包含启动所需硬件的内核模块、初始化脚本等。随后 boot loader 将控制权交给 kernel,同时传递内核参数与 initramfs 在内存中的位置;内核在 initramfs 中找到所有硬件驱动程序并完成硬件初始化。
配置入口 :使用
/etc/dracut.conf.d/目录、dracut命令与lsinitrd命令检查和维护 initramfs 文件。
阶段五:systemd 接管(PID 1)
initramfs 执行 /sbin/init 作为 PID 1------在 CentOS 7 中,/sbin/init 是指向 systemd 的链接。此后 systemd 全面接管系统初始化:
-
systemd 加载内核命令行传递的 target,或加载系统配置的
default.target,该目标通常启动文本登录或图形登录界面。配置入口 :使用
systemctl设置默认 target。 -
default.target依赖sysinit.target,后者负责初始化系统,例如读取/etc/fstab挂载文件系统、激活 systemd-journald 等。配置入口 :使用
/etc/fstab配置文件系统开机自动挂载。 -
default.target激活所有开机自启单元。配置入口 :使用
systemctl enable设置服务开机启用。 -
default.target激活getty.target,打开 tty1 终端供用户登录。
二、 系统 target 依赖体系
systemd 使用类型为 target 的单元对其他单元进行分组。例如 multi-user.target 包含 chronyd.service、crond.service、firewalld.service 等服务;target 之间还可以层层嵌套------graphical.target 包含 multi-user.target,后者包含 basic.target,再往下包含 sysinit.target。
使用以下命令查看 target 之间的依赖关系:
bash
systemctl list-dependencies graphical.target
其输出呈现为一棵清晰的依赖树(节选结构如下):
bash
graphical.target
├─display-manager.service
├─systemd-update-utmp-runlevel.service
├─udisks2.service
└─multi-user.target
├─auditd.service
├─crond.service
├─dbus.service
├─irqbalance.service
├─kdump.service
├─mdmonitor.service
├─NetworkManager.service
├─restorecond.service
├─rngd.service
├─rsyslog.service
├─sshd.service
├─systemd-ask-password-wall.path
├─systemd-logind.service
├─systemd-update-utmp-runlevel.service
├─systemd-user-sessions.service
├─systemtap.service
├─tuned.service
├─basic.target
│ ├─-.mount
│ ├─tmp.mount
│ ├─paths.target
│ ├─slices.target
│ │ ├─-.slice
│ │ └─system.slice
│ ├─sockets.target
│ │ ├─dbus.socket
│ │ ├─dm-event.socket
│ │ ├─pcscd.socket
│ │ ├─systemd-coredump.socket
│ │ ├─systemd-initctl.socket
│ │ ├─systemd-journald-dev-log.socket
│ │ ├─systemd-journald.socket
│ │ ├─systemd-udevd-control.socket
│ │ └─systemd-udevd-kernel.socket
│ ├─sysinit.target
│ │ ├─dev-hugepages.mount
│ │ ├─dev-mqueue.mount
│ │ ├─dracut-shutdown.service
│ │ ├─hwclock-save.service
│ │ ├─kmod-static-nodes.service
│ │ ├─ldconfig.service
│ │ ├─lvm2-lvmpolld.socket
│ │ ├─lvm2-monitor.service
│ │ ├─proc-sys-fs-binfmt_misc.automount
│ │ ├─sys-fs-fuse-connections.mount
│ │ ├─sys-kernel-config.mount
│ │ ├─sys-kernel-debug.mount
│ │ ├─sys-kernel-tracing.mount
│ │ ├─systemd-ask-password-console.path
│ │ ├─systemd-binfmt.service
│ │ ├─systemd-hwdb-update.service
│ │ ├─systemd-journal-catalog-update.service
│ │ ├─systemd-journal-flush.service
│ │ ├─systemd-journald.service
│ │ ├─systemd-machine-id-commit.service
│ │ ├─systemd-modules-load.service
│ │ ├─systemd-network-generator.service
│ │ ├─systemd-random-seed.service
│ │ ├─systemd-sysctl.service
│ │ ├─systemd-sysusers.service
│ │ ├─systemd-tmpfiles-setup-dev-early.service
│ │ ├─systemd-tmpfiles-setup-dev.service
│ │ ├─systemd-tmpfiles-setup.service
│ │ ├─systemd-udev-trigger.service
│ │ ├─systemd-udevd.service
│ │ ├─systemd-update-done.service
│ │ ├─systemd-update-utmp.service
│ │ ├─cryptsetup.target
│ │ ├─integritysetup.target
│ │ ├─local-fs.target
│ │ │ ├─-.mount
│ │ │ ├─boot-efi.mount
│ │ │ ├─boot.mount
│ │ │ ├─systemd-fsck-root.service
│ │ │ ├─systemd-remount-fs.service
│ │ │ └─tmp.mount
│ │ ├─swap.target
│ │ │ └─dev-mapper-openeuler\x2dswap.swap
│ │ └─veritysetup.target
│ └─timers.target
│ ├─dnf-makecache.timer
│ └─systemd-tmpfiles-clean.timer
├─getty.target
│ └─getty@tty1.service
└─remote-fs.target
反过来,也可以查看某个单元被哪些 target 依赖(反向依赖):
bash
# 查看反向依赖
systemctl list-dependencies sshd.service --reverse
bash
sshd.service
● └─multi-user.target
○ └─graphical.target
三、 系统启动级别:从 runlevel 到 target
CentOS 6 及之前使用**启动级别(runlevel)**控制系统开机激活哪些服务;CentOS 7 之后改用 target 承担同一职责。二者对应关系如下:
| runlevel | target | 作用 |
|---|---|---|
| 0 | poweroff.target | 关机。init 0 同 poweroff 和 systemctl poweroff |
| 1 | emergency.target / rescue.target | 单用户模式、救援模式和紧急模式,用于修复系统 |
| 2 | --- | 多用户文本界面,不具备 NFS 功能 |
| 3 | multi-user.target | 多用户文本界面 |
| 4 | --- | 未使用 |
| 5 | graphical.target | 多用户图形界面 |
| 6 | reboot.target | 重启。init 6 同 reboot 和 systemctl reboot |
历史回顾:/etc/inittab
/etc/inittab 是 RHEL 6 之前版本初始化系统使用的配置文件,部分内容如下:
bash
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
# 设置运行级别为 5,也就是图形化方式启动
id:5:initdefault:
设置系统当前运行 target
bash
# 设置系统当前运行 target 为 multi-user.target
systemctl isolate multi-user.target
# 设置系统当前运行 target 为 graphical.target
systemctl isolate graphical.target
设置系统开机默认运行 target
bash
# 查看系统开机默认运行 target
systemctl get-default
# 输出示例:multi-user.target
# 设置系统开机默认运行 target
systemctl set-default multi-user.target
# 重启验证
reboot
在系统启动时临时选择其它目标
要在启动时选择其他目标,将 systemd.unit=target.target 参数附加到内核命令行。该配置临时生效,常用于系统启动过程中的故障排除。操作步骤:
- 启动或重新启动系统;
- 按任意键(Enter 除外,它用于执行正常启动)中断启动加载器菜单倒计时;
- 将光标移至要启动的内核条目;
- 按
e编辑当前条目; - 将光标移至以
linux开头的行------此即内核命令行; - 附加
systemd.unit=target.target,例如systemd.unit=emergency.target; - 按
Ctrl+x使用这些更改进行启动。
四、 实战:重置 root 密码
如果管理员仍处于登录状态(无论是拥有完全 sudo 权限的非特权用户,还是 root 用户),直接执行 passwd 即可。但若管理员未登录,任务就复杂了:CentOS 6 及更早版本可将系统启动到 runlevel 1 获取 root 提示符,而 CentOS 7 之后与 runlevel 1 最接近的紧急目标与救援目标都需要 root 密码才能登录。
常见的绕过思路有两种:其一,使用 Live CD 启动系统、挂载根文件系统后编辑 /etc/shadow(删除 root 密码字段,或替换为已知密码字段);其二,让 initramfs 在特定断点暂停,提供 root 身份的 shell 来重置密码。后者又分为两个经典方法。
方法一:rd.break(官方推荐,优先使用)
中断点 :initramfs 阶段,尚未切换真实根,提示符为 switch_root:/#。
- 重新启动系统;
- 按任意键(Enter 除外)中断启动加载器倒计时;
- 将光标移至要启动的内核条目,按
e编辑;

- 将光标移到内核命令行(以
linux开头的行),附加rd.break。利用该选项,系统在从 initramfs 向实际系统移交控制权前中断。kernel 行可能有多个 console 参数,以最后一个为准,有时需要设置console=tty0;

- 按
Ctrl+x使用更改启动; - 此时系统显示 root shell,磁盘上的实际根文件系统以只读 方式挂载在
/sysroot。依次执行:
bash
# 以读/写形式重新挂载 /sysroot
switch_root:/# mount -o remount,rw /sysroot
# 切换 root 位置,把 /sysroot 作为文件系统树的根
switch_root:/# chroot /sysroot
# 设置新 root 密码
sh-4.2# passwd root
# 若系统开启 SELinux,确保未标记文件(含 /etc/shadow)在启动过程中重新获得标记
sh-4.2# touch /.autorelabel
- 键入
exit两次:第一次退出 chroot 环境,第二次退出 initramfs 调试 shell。系统将继续启动、执行完整的 SELinux 重新标记,然后再次重启; - 登录验证。
方法二:init=/bin/bash
作用 :内核启动完成后不启动 systemd(PID 1),而是直接把 /bin/bash 作为 PID 1,直接拿到系统 shell。此时根文件系统默认只读挂载。
- 重新启动系统;
- 按任意键(Enter 除外)中断启动加载器倒计时;
- 将光标移至要启动的内核条目,按
e编辑;

- 将光标移到内核命令行,附加
init=/bin/bash,请开启一个 root shell。kernel 行可能有多个 console 参数,以最后一个为准,有时需要设置console=tty0;

- 按
Ctrl+x使用更改启动; - 此时系统显示 root shell,磁盘上的实际根文件系统以只读方式挂载在
/。依次执行:
bash
# 以读/写形式重新挂载根文件系统
bash-4.2# mount -o remount,rw /
# 设置新 root 密码
sh-4.2# passwd
# 若系统开启 SELinux,确保未标记文件(含 /etc/shadow)在启动过程中重新获得标记
sh-4.2# touch /.autorelabel
# 拉起 systemd,正常走完启动流程(切勿直接断电/重启)
sh-4.2# exec /sbin/init
- 登录验证。
两种方法对比
| 对比项 | rd.break | init=/bin/bash |
|---|---|---|
| 中断阶段 | initramfs,切换真实根之前 | 已切换到真实根,替代 systemd(PID 1) |
| 根文件系统位置 | 真实根在 /sysroot,需要 chroot | 直接就是真实系统 / |
| SELinux | 依然生效,必须写 /.autorelabel | 依然生效,也要 /.autorelabel |
| 磁盘支持 | LVM、RAID、iSCSI 都正常识别,initramfs 驱动完整 | 同样加载 initramfs,磁盘驱动正常 |
| 退出方式 | 两次 exit 正常继续启动 | 不能直接断电/重启,必须执行 exec /sbin/init |
| 风险点 | 几乎无风险,官方标准方式 | 忘记 exec /sbin/init 直接重启,极易损坏文件系统 |
| 官方态度 | RHEL/CentOS 官方文档标准方案 | 兼容旧方式,不推荐生产使用 |
五、 实战:/etc/fstab 引起的启动故障
环境准备
bash
# 设置磁盘分区管理方案
parted /dev/sdb mklabel msdos
# 创建分区
parted /dev/sdb unit MiB mkpart primary 1 10241
# 格式化为 xfs 文件系统
mkfs.xfs /dev/sdb1
# 创建挂载点
mkdir /data01
# 设置持久化挂载
echo '/dev/sdb1 /data01 xfs defaults 0 0' >> /etc/fstab
# 挂载并验证
mount -a
df -h /data01
bash
文件系统 容量 已用 可用 已用% 挂载点
/dev/sdb1 10G 33M 10G 1% /data01
故障一:挂载点不存在
bash
umount /data01
rmdir /data01
重启系统验证:系统可以正常进入 ,挂载点会被自动创建,df -h /data01 输出与之前一致。这说明挂载点缺失并非致命错误,systemd 会自动补建目录。
故障二:设备名称写错或找不到设备
bash
vim /etc/fstab
# 将原先的 sdb1 修改为 sdb2
# /dev/sdb2 /data01 xfs defaults 0 0
重启系统验证:
- 启动过程中找不到该设备;

- 等待 1 分 30 秒超时后,系统进入 emergency 模式 ,输入 root 密码进行修复;

- 修改为正确的值或注释该条目,确保系统正常启动;

- 输入
reboot重新启动系统;若系统没有继续启动,可强制关机重启。
故障三:破坏文件系统
bash
dd if=/dev/zero of=/dev/sdb1 bs=1M count=1
重启系统验证:
- 系统启动过程中尝试修复文件系统,修复失败后提示进入 emergency 模式修复;

- 进入 emergency 模式后执行修复命令:

bash
xfs_repair /dev/sdb1
- 修复完成后,输入
exit继续启动,系统即可正常进入。
六、 GRUB2 配置详解
主要配置文件
/boot/grub2/:GRUB2 主要配置文件所在目录,例如grub.cfg、grubenv、user.cfg;/etc/grub2.cfg:指向/boot/grub2/grub.cfg的软连接。不要直接修改该文件 ------它由系统自动生成;如需自定义,应修改/etc/grub.d/中的脚本与/etc/default/grub,再通过grub2-mkconfig生成。使用 EFI 启动方式时,配置文件为/etc/grub2-efi.cfg;/etc/grub.d/:存放多个数字开头的脚本,按从小到大的顺序执行。例如00_header会调用/etc/default/grub实现最基本的开机界面配置;/etc/default/grub:定义 GRUB 启动部分变量信息,例如菜单超时时间、内核参数等;/boot/grub2/grubenv:设定默认启动条目。
修改菜单超时时间
bash
vim /etc/default/grub
# 修改 GRUB_TIMEOUT 为 10
GRUB_TIMEOUT=10
# 重新生成 grub2.cfg 配置文件使其生效
grub2-mkconfig -o /etc/grub2.cfg
bash
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-1160.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-1160.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-c6e36d35c9a846d7b64d9fdf929b09f6
Found initrd image: /boot/initramfs-0-rescue-c6e36d35c9a846d7b64d9fdf929b09f6.img
done
bash
# 重启验证
reboot
重启后即可看到 GRUB2 菜单按新的超时时间展示启动条目,配置生效。

七、总结
本文以 CentOS 7 为样本,完整拆解了 Linux 启动的五段式链路:固件 POST 自检、MBR 移交 GRUB2、GRUB2 加载内核与 initramfs、systemd 以 PID 1 接管初始化、target 依赖树逐级激活服务直至打开登录终端。在此基础上,文章进一步梳理了 runlevel 与 target 的演进对应、临时与永久运行目标设置、rd.break 与 init=/bin/bash 两种 root 密码重置方案的差异与风险,以及 /etc/fstab 三类典型故障的现象与修复路径,并给出 GRUB2 配置的正确修改姿势。理解启动原理,是排查开机故障、加固系统安全、优化启动性能的基石,也是每一位 Linux 运维工程师从"会操作"走向"懂原理"的必经之路。