【Linux从入门到精通】第14篇:Linux引导流程浅析——从按下电源到登录界面
目录
一、引言:开机那几十秒发生了什么?
二、第一阶段:BIOS/UEFI——硬件的“开机自检”
2.1 BIOS与UEFI的区别
2.2 固件做了什么?
三、第二阶段:GRUB2——引导加载程序
3.1 GRUB2的角色
3.2 GRUB2的三个阶段
3.3 GRUB2配置文件
3.4 常见启动参数
四、第三阶段:Kernel——内核加载
4.1 内核做了什么?
4.2 initramfs是什么?为什么需要它?
4.3 查看内核信息
五、第四阶段:systemd——服务的“交响乐指挥”
5.1 从System V init到systemd
5.2 systemd的启动目标
5.3 常用的systemd启动相关命令
六、单用户模式:密码急救实战
6.1 原理
6.2 CentOS/RHEL操作步骤
6.3 Ubuntu操作步骤
6.4 使用rd.break参数(RHEL/CentOS 7+)
七、本篇小结
动手练习
八、下篇预告
一、引言:开机那几十秒发生了什么?
从按下电源到看到登录界面,通常只有几十秒。但这几十秒里,系统完成了一系列精密而复杂的操作。理解这个过程,不仅能满足你对系统底层的好奇,更有两个实用价值:
启动故障排查:系统卡在某个阶段不动了,你知道该查什么
密码急救:忘记root密码时,可以通过修改引导参数进入单用户模式重置
今天我们就来拆解这个“从零到一”的过程。先看一张全景路线图:
text
按下电源 │ ▼ ┌──────────────┐ │ BIOS/UEFI │ 固件自检 → 选择启动设备 → 加载引导程序 └──────┬───────┘ │ ▼ ┌──────────────┐ │ GRUB2 │ 显示启动菜单 → 加载内核到内存 └──────┬───────┘ │ ▼ ┌──────────────┐ │ Kernel │ 初始化硬件 → 挂载根文件系统 → 启动init进程 └──────┬───────┘ │ ▼ ┌──────────────┐ │ systemd │ 按顺序启动所有服务 → 显示登录界面 └──────┬───────┘ │ ▼ 登录界面
下面逐一展开每个阶段。
二、第一阶段:BIOS/UEFI——硬件的“开机自检”
按下电源按钮后,CPU首先执行的是固化在主板上的固件程序。这段程序有两种形态:传统的BIOS和现代的UEFI。
2.1 BIOS与UEFI的区别
| 对比维度 | BIOS(传统) | UEFI(现代) |
|---|---|---|
| 全称 | Basic Input/Output System | Unified Extensible Firmware Interface |
| 出现年代 | 1981年 | 2007年后成为主流 |
| 磁盘分区表 | MBR(最大支持2TB磁盘) | GPT(支持超大磁盘) |
| 引导方式 | 读取磁盘第一个扇区(512字节) | 读取EFI系统分区中的.efi文件 |
| 界面 | 纯键盘操作,蓝底白字 | 支持鼠标和图形界面 |
| 安全启动 | 不支持 | 支持Secure Boot |
查看你的系统用的是哪种:
bash
ls /sys/firmware/efi # 如果目录存在,说明是UEFI启动;否则是传统BIOS
2.2 固件做了什么?
不管是BIOS还是UEFI,核心任务都是:
POST(上电自检):检测内存、键盘、硬盘等硬件是否正常
枚举设备:扫描所有PCI/PCIe总线上的设备
选择引导设备:按照CMOS中设定的启动顺序(U盘 > 硬盘 > 网络),找到第一个可引导的设备
加载引导程序:BIOS读取磁盘MBR中的GRUB2第一阶段代码;UEFI则直接加载EFI分区中的grubx64.efi文件
如果这个阶段出现问题,系统会通过蜂鸣器发出特定的长短音组合(报警音)来指示故障类型。如果屏幕没有任何显示,说明问题出在这一阶段——检查硬件连接和BIOS设置。
三、第二阶段:GRUB2——引导加载程序
3.1 GRUB2的角色
GRUB(GRand Unified Bootloader)是Linux最主流的引导加载程序,当前版本是GRUB2。它的核心任务很简单:找到内核文件,加载到内存,然后把控制权交给内核。
3.2 GRUB2的三个阶段
GRUB2将引导过程拆分为三个阶段,以突破MBR只有512字节的限制:
Stage 1(boot.img):写入MBR的前446字节,唯一作用是将Stage 1.5加载到内存
Stage 1.5(core.img):位于MBR之后的空闲扇区,加载文件系统驱动,识别/boot分区的文件系统
Stage 2:位于/boot/grub/目录下,加载grub.cfg配置文件,显示启动菜单,加载内核
3.3 GRUB2配置文件
核心配置文件位于:
bash
# 主配置文件(不要手动编辑) /boot/grub/grub.cfg # 通过编辑这个文件来控制启动行为 /etc/default/grub # 自定义脚本目录 /etc/grub.d/
不要直接编辑grub.cfg,而是编辑/etc/default/grub后,用命令重新生成:
bash
sudo grub2-mkconfig -o /boot/grub/grub.cfg # CentOS/RHEL sudo update-grub # Ubuntu/Debian
3.4 常见启动参数
在GRUB启动菜单中按e键,可以看到内核启动参数。以下是几个常用参数的用途:
| 参数 | 作用 | 使用场景 |
|---|---|---|
ro | 只读挂载根文件系统 | 默认参数,保证fsck能安全检查 |
rw | 读写挂载根文件系统 | 修复系统时需要写入操作 |
quiet | 不显示内核启动日志 | 希望看到简洁启动画面 |
splash | 显示启动画面 | 桌面版Linux的图形启动效果 |
single | 进入单用户模式 | 忘记root密码时的急救通道 |
init=/bin/bash | 直接启动bash,跳过init | 极端情况下的手动修复 |
nomodeset | 禁用内核模式设置 | 显卡驱动问题导致黑屏时使用 |
四、第三阶段:Kernel——内核加载
4.1 内核做了什么?
GRUB2将内核(vmlinuz文件)和initramfs加载到内存后,控制权交给内核。内核启动过程:
解压缩:内核是压缩存储的,先在内存中自解压
初始化硬件:设置中断控制器、内存管理单元、设备驱动
加载initramfs:这是一个临时的小型根文件系统,包含必要的设备驱动模块
挂载真实根文件系统:借助initramfs中的驱动访问真实磁盘,然后切换到真正的根文件系统
启动第一个进程:执行/sbin/init(在现代系统中通常是systemd的软链接)
4.2 initramfs是什么?为什么需要它?
一个经典的“鸡生蛋蛋生鸡”问题:
内核需要访问磁盘才能读取根文件系统
但访问磁盘需要磁盘驱动模块
而磁盘驱动模块存放在根文件系统里(/lib/modules/)
initramfs把这个循环打破了。它是一个打包在/boot/initramfs-*.img中的微型文件系统,里面存放了必要的设备驱动和挂载工具。内核先加载initramfs作为临时根目录,用里面的驱动挂载真实根文件系统,再切换过去。
4.3 查看内核信息
bash
uname -r # 查看当前内核版本 dmesg | less # 查看本次启动的内核日志 ls /boot # 查看/boot中的内核文件和initramfs
五、第四阶段:systemd——服务的“交响乐指挥”
内核启动的第一个用户空间进程(PID=1)是systemd(旧系统使用System V init)。它是整个用户空间的总指挥。
5.1 从System V init到systemd
传统的System V init使用串行启动——按顺序一个个拉起服务,启动较慢。systemd采用并行启动策略,可以同时启动互不依赖的服务,大幅缩短启动时间。
5.2 systemd的启动目标
systemd将启动过程划分为多个目标(Target),每个目标是一组服务的集合:
| 目标 | 含义 | 类比 |
|---|---|---|
default.target | 默认启动目标 | 系统启动的入口 |
multi-user.target | 多用户模式 | 命令行界面,不启动图形桌面 |
graphical.target | 图形界面模式 | 包含X Window和桌面环境 |
rescue.target | 救援模式 | 少量基本服务,适合修复系统 |
emergency.target | 紧急模式 | 最小化环境,只有少量关键服务 |
reboot.target | 重启系统 | — |
poweroff.target | 关机 | — |
5.3 常用的systemd启动相关命令
bash
# 查看当前默认启动目标 systemctl get-default # 设置默认为命令行模式(不启动图形界面) sudo systemctl set-default multi-user.target # 查看启动耗时 systemd-analyze # 查看各服务的启动耗时(找出拖慢启动的元凶) systemd-analyze blame # 查看服务依赖关系 systemd-analyze critical-chain
六、单用户模式:密码急救实战
假设你(或同事)忘记了root密码,并且没有其他sudo用户可用。不要慌,不需要重装系统。
6.1 原理
通过修改GRUB引导参数,让系统不进入正常启动流程,而是直接获得一个root权限的Shell。此时可以修改root密码。
6.2 CentOS/RHEL操作步骤
第一步:重启系统,在GRUB菜单界面按e
显示引导菜单时,选中要启动的内核条目,按e进入编辑模式。
第二步:找到linux开头的行,修改参数
找到以linux或linux16开头的行,将ro改为rw,并在末尾添加init=/bin/bash:
text
之前:linux ... ro ... quiet 之后:linux ... rw ... init=/bin/bash
rw确保挂载的文件系统可写,init=/bin/bash让内核直接启动bash而不是继续正常启动流程。
第三步:按Ctrl+X启动
系统会以root身份直接进入bash Shell,不需要密码。
第四步:修改root密码
bash
passwd root # 输入新密码两次
第五步:确保修改写入磁盘,然后重启
bash
exec /sbin/init # 继续正常启动流程 # 或者直接强制重启(如果上述命令失败) reboot -f
6.3 Ubuntu操作步骤
Ubuntu的GRUB配置略有不同。
第一步:重启,在GRUB菜单按e
第二步:找到linux行,修改参数
找到以linux开头的行,将ro quiet splash $vt_handoff替换为rw init=/bin/bash。
第三步:Ctrl+X启动,进入root Shell后操作
bash
passwd root reboot -f
6.4 使用rd.break参数(RHEL/CentOS 7+)
另一种方法是在GRUB编辑界面中,在linux行的末尾添加rd.break:
text
linux ... ro ... rd.break
启动后会进入initramfs的shell,此时实际根文件系统挂载在/sysroot下(只读):
bash
mount -o remount,rw /sysroot # 重新挂载为读写 chroot /sysroot # 切换到真实根文件系统 passwd root # 修改密码 touch /.autorelabel # SELinux重新标记(CentOS/RHEL必须) exit # 退出chroot reboot -f # 重启
⚠️ CentOS/RHEL上不要忘记
touch /.autorelabel,否则SELinux可能导致系统登录异常。
七、本篇小结
Linux启动流程的四个阶段:
| 阶段 | 负责程序 | 核心任务 | 故障特征 |
|---|---|---|---|
| 1 | BIOS/UEFI | 硬件自检,选择启动设备 | 屏幕无显示或不识别硬盘 |
| 2 | GRUB2 | 显示菜单,加载内核 | 停在grub>提示符或无启动菜单 |
| 3 | Kernel | 初始化硬件,挂载根文件系统 | 内核panic,不停重启 |
| 4 | systemd | 启动所有服务,显示登录界面 | 卡在某服务启动,登录后没反应 |
单用户模式密码重置流程:
重启,在GRUB菜单按
e在linux行添加
rw init=/bin/bash(或使用rd.break方法)进入root Shell,执行
passwd修改密码重启
动手练习
bash
# 1. 查看你的系统启动方式 ls /sys/firmware/efi # 有输出=UEFI,无输出=BIOS # 2. 查看启动耗时 systemd-analyze systemd-analyze blame | head -10 # 3. 查看GRUB配置文件 cat /etc/default/grub # 4. 查看当前运行级别 systemctl get-default runlevel # 旧版兼容命令 # 5. 查看内核日志(前30行) dmesg | head -30
⚠️ 单用户模式重置密码的练习请在虚拟机中进行,并确保提前创建快照。在生产服务器上操作需要谨慎,确保有物理或带外管理通道,防止改坏后无法远程恢复。
八、下篇预告
理解了systemd作为“启动总指挥”的角色后,下一篇我们将深入systemd的服务管理功能。
《Systemd初探——现代Linux的服务大管家》将带你学习:
Unit文件的概念与类型
systemctl start/stop/status/enable管理服务的完整操作如何自己编写一个.service文件来托管你的应用程序
掌握systemd,你就掌握了Linux服务管理的事实标准。
延伸思考:PID=1的进程有什么特殊之处?如果它被杀死,整个系统会立即崩溃(内核panic)。你可以做一个观察:执行ps -p 1,看看PID=1的进程叫什么名字——在现代Linux中,它通常是systemd。这个进程是用户空间的“祖先”,所有其他进程的直接或间接父进程。
本回答由 AI 生成,内容仅供参考,请仔细甄别。
