2. Linux 启动流程详解:从按下电源到登录界面
大家好,我是老赵。今天我们来聊聊 Linux 启动流程。这玩意儿,说白了就是一台服务器从「冷冰冰的硬件」变成「能干活的操作系统」的全过程。
我见过不少运维同事,遇到启动问题就慌。其实你只要把流程拆开看,每个阶段都有对应的日志和排查方法。今天我就把这套流程掰开揉碎了讲给你听。
2.1 BIOS/UEFI 阶段:硬件说了算
你按下电源键,CPU 第一个执行的是固件代码。老机器是 BIOS,新机器是 UEFI。我个人习惯把这一阶段叫做「硬件自检 + 启动设备选择」。
BIOS 会做 POST(加电自检),检查内存、CPU、显卡这些关键硬件。如果内存坏了,你会听到滴滴声——不同长短的蜂鸣声代表不同故障。UEFI 呢?它更智能,支持 GPT 分区表,启动速度也更快。
这个阶段结束后,固件会按照启动顺序去读取引导设备。传统 BIOS 读 MBR(主引导记录),UEFI 读 ESP(EFI 系统分区)里的引导文件。你可以在 BIOS 设置里调整启动顺序,比如从 U 盘启动装系统。
2.2 GRUB 引导阶段:内核的搬运工
GRUB 是 Linux 世界最常用的引导加载器。它的任务很简单:找到内核文件,把它加载到内存,然后跳转执行。
GRUB 有两个阶段:
- stage1:写在 MBR 或 ESP 里,很小,只够找到 stage2。
- stage2:在 /boot/grub 目录下,提供菜单、文件系统驱动、编辑内核参数等功能。
你启动时看到的那个选择菜单,就是 GRUB 的 stage2。你可以按 e 编辑启动参数,比如加个 single 进入单用户模式,或者加 rd.break 进入紧急模式。
# GRUB 配置文件位置(传统 BIOS)
/boot/grub/grub.conf
/boot/grub2/grub.cfg
# UEFI 系统
/boot/efi/EFI/centos/grub.cfg
# 查看当前 GRUB 版本
grub2-install --version
GRUB 加载内核后,还会加载 initramfs(初始 RAM 文件系统)。这里面包含了必要的驱动和工具,用来挂载真正的根文件系统。我曾经遇到过 initramfs 损坏导致系统无法启动的情况——启动卡在「dracut-initqueue」超时。解决办法是用救援模式重建 initramfs。
# 重建 initramfs(以 CentOS 7 为例)
dracut -f /boot/initramfs-$(uname -r).img $(uname -r)
2.3 内核初始化阶段:从裸机到有根
内核被加载到内存后,开始初始化。这个过程很快,但做的事情很多:
- 解压自身(内核是压缩的)
- 初始化 CPU、内存管理、中断控制器
- 加载 initramfs 中的驱动(磁盘、网络、文件系统)
- 挂载真正的根文件系统(从 initramfs 切换到 /)
- 执行第一个用户空间进程(PID 1)
内核启动日志可以通过 dmesg 查看。我个人习惯在排查启动问题时,先看 dmesg 里有没有硬件错误或者驱动加载失败。
# 查看内核启动日志
dmesg | less
# 只看错误和警告
dmesg | grep -iE "error|fail|warn"
# 查看某个驱动是否加载
dmesg | grep -i "ata\|scsi\|nvme"
rd.shell 进入 initramfs 的 shell。
2.4 systemd 启动阶段:现代 Linux 的管家
内核启动完,会执行 /sbin/init。在大多数现代发行版里,这个文件是 systemd 的符号链接。systemd 是 PID 1,它负责启动所有其他服务。
systemd 的启动流程是这样的:
- 读取默认 target(通常是 multi-user.target 或 graphical.target)
- 解析依赖关系,并行启动服务
- 按顺序执行各个 target 下的单元(unit)
你可以用 systemd-analyze 来分析启动时间:
# 查看总启动时间
systemd-analyze
# 查看每个服务的启动耗时(从快到慢排序)
systemd-analyze blame
# 查看关键事件的时序图
systemd-analyze critical-chain
systemd-analyze blame。如果某个服务启动时间异常长,比如超过 10 秒,那多半有问题。我曾经发现一个 NFS 挂载服务因为网络不通,硬等了 90 秒超时——这就是启动慢的罪魁祸首。
systemd 的日志用 journalctl 查看。启动日志特别用 -b 参数:
# 查看本次启动的日志
journalctl -b
# 查看上一次启动的日志(用于排查启动失败)
journalctl -b -1
# 只看错误级别
journalctl -b -p err
2.5 用户登录阶段:终于见到你
systemd 启动完所有服务后,会启动 getty(终端登录)或者显示管理器(图形界面)。
对于服务器,通常是 getty@tty1.service 在终端上显示登录提示。你输入用户名密码,经过 PAM(可插拔认证模块)验证,然后启动 shell。
登录相关的日志在:
| 日志文件 | 用途 |
|---|---|
| /var/log/secure | 认证日志(登录成功/失败、sudo 操作) |
| /var/log/wtmp | 登录历史记录(二进制,用 last 查看) |
| /var/log/btmp | 登录失败记录(二进制,用 lastb 查看) |
| /var/log/lastlog | 每个用户最后一次登录时间 |
# 查看最近登录记录
last
# 查看登录失败记录
lastb
# 实时监控登录尝试
tail -f /var/log/secure
2.6 启动流程总结:一张表看清
| 阶段 | 主要任务 | 关键日志/工具 | 常见故障 |
|---|---|---|---|
| BIOS/UEFI | 硬件自检、选择启动设备 | 蜂鸣码、POST 卡 | 硬件故障、启动顺序错误 |
| GRUB 引导 | 加载内核和 initramfs | GRUB 菜单、/boot/grub2/grub.cfg | GRUB 损坏、内核丢失、initramfs 损坏 |
| 内核初始化 | 驱动加载、挂载根文件系统 | dmesg、/var/log/messages | 内核恐慌、根文件系统无法挂载 |
| systemd 启动 | 并行启动服务、达到 target | systemd-analyze、journalctl -b | 服务启动超时、依赖循环 |
| 用户登录 | getty/显示管理器、PAM 认证 | /var/log/secure、last | 认证失败、磁盘满、PAM 配置错误 |
嗯,到这里 Linux 启动流程就讲完了。你可能会问:「知道这些有什么用?」
用处大了去了。下次服务器启动卡住,你就能根据卡住的位置判断是哪个阶段的问题。比如卡在 GRUB 菜单之后、内核加载之前,那多半是内核或 initramfs 的问题。如果卡在 systemd 启动服务阶段,那就用 systemd-analyze blame 找罪魁祸首。
记住一句话:启动流程就是排查地图。你心里有这张地图,遇到问题就不会慌。