Linux 究竟如何启动:从固件到登录界面

Linux 究竟如何启动:从固件到登录界面

💡 原文英文,约3100词,阅读约需12分钟。
📝

内容提要

本文以一次真实启动为例,讲解Linux启动的四个阶段:固件、引导程序、内核和用户空间。通过systemd-analyze分析,固件耗时约6秒、GRUB倒计时5秒、内核3秒、用户空间12秒。文章指出systemd-analyze blame会误导,应查看critical-chain,并建议缩短GRUB超时以加速启动。

🔎

延伸解读

启动时间四阶段:各司其职,测量方式不同

systemd-analyze 将启动分为固件、引导程序、内核和用户空间四个阶段,每个阶段由不同组件测量。固件时间来自 ACPI FPDT 表,若固件不提供该表,则无法从 Linux 内获取;引导程序时间包含 GRUB 倒计时;内核时间从内核开始执行算起;用户空间时间由 systemd 统计。理解这些差异,才能正确解读数字,避免误判。

systemd-analyze blame 的误导性

blame 列出所有已启动单元的耗时,但其中许多单元由定时器触发,并不在启动路径上。例如 fstrim.service 显示耗时近四分钟,实际由定时器触发,与登录界面出现时间无关。因此,blame 回答的是“每个单元花了多久”,而非“什么拖慢了启动”。要分析启动瓶颈,应使用 critical-chain。

关键链:识别真正的启动瓶颈

critical-chain 显示从 graphical.target 回溯的依赖链,标出每个单元的激活时间和自身耗时。例如 docker.service 耗时 4.875 秒,NetworkManager-wait-online.service 耗时 4.106 秒,两者串行,共占用户空间近九秒。但需注意,它只展示一条链,且 @ 时间并非因果顺序,应关注 + 值(成本)和依赖结构。

优化启动:从 GRUB 超时和网络等待入手

GRUB 倒计时是引导程序阶段的主要耗时,可通过设置 GRUB_TIMEOUT=1 并更新配置来缩短。用户空间阶段,NetworkManager-wait-online.service 会阻塞直到网络就绪,在笔记本上可能浪费数秒;若服务不依赖网络,可考虑禁用它。但优化前应确认服务是否必要,避免影响功能。

Q&A

Linux启动过程分为哪几个阶段?

Linux启动过程分为四个阶段:固件、引导程序、内核和用户空间。固件负责找到可启动设备并移交控制权;引导程序加载内核和初始文件系统;内核初始化硬件、挂载根文件系统并启动PID 1;用户空间由PID 1启动所有其他进程。

systemd-analyze blame 命令为什么可能误导人?

systemd-analyze blame 列出所有单元启动所花的时间,但其中许多单元并非启动路径上的必要部分,例如由定时器触发的 fstrim.service 可能显示耗时数分钟,但实际上并不影响启动速度。它回答的是“每个单元启动花了多久”,而不是“什么拖慢了启动”。

如何查看Linux启动的关键路径?

使用 systemd-analyze critical-chain 命令。它会显示从 graphical.target 到各个依赖单元的链,并标注每个单元激活的时间(@)和自身耗时(+),帮助识别真正影响启动速度的服务。

GRUB_TIMEOUT 设置如何影响启动时间?

GRUB_TIMEOUT 是引导程序等待用户按键的超时时间,默认可能为5秒。这段时间内系统不做任何工作,只是倒计时。将 GRUB_TIMEOUT 设置为1秒或更短,可以显著减少启动时间。

initramfs 是什么?它解决了什么问题?

initramfs 是一个小型文件系统,由引导程序加载到内存中,包含挂载根文件系统所需的驱动和工具。它解决了“内核需要驱动来挂载根文件系统,但驱动又存放在根文件系统上”的鸡生蛋问题。成功挂载后,它会切换到真正的根文件系统并执行 /sbin/init。

为什么不同机器的Linux启动时间差异很大?

启动时间受多个因素影响:固件时间取决于硬件初始化和枚举,差异最大;引导程序时间主要由超时设置决定;内核时间受硬件数量和 initramfs 大小影响;用户空间时间则取决于安装的服务,例如 Docker 可能增加数秒。因此每台机器的启动时间都不同。

🏷️

标签

➡️

继续阅读