怎么读这张表
按真实执行顺序自上而下。判断依据不是想象,而是三份实测数据:启动耗时五段分解、systemd 关键链(真实串行依赖路径)、开机启用的单元清单。
| 列 | 含义 |
|---|---|
| 执行顺序 | 自上而下的真实先后;同一段内的项可能并行 |
| 大类型 | 固件 / 引导器 / 内核 / initrd / 系统 / 挂载 / 登录 / 会话 |
| 事项 | 这一步实际做了什么 |
| 进程或具体服务 | 干这件事的进程或系统单元 |
| 注册方或管理者 | 谁定义的 —— nix 选项、安装时生成的硬件配置、还是自建模块 |
Windows 用户的直觉对照:这里没有「注册表启动项」那种分散开关。每一行都能追到一个声明处 —— 要么是 nix 选项,要么是安装时生成的硬件扫描结果,要么是仓库里某个自建模块。不存在藏在系统角落的隐藏自启项。
命名说明:本文对含厂商 / 型号的服务名做了泛化(写成 gpu-<外置卡>-* 这种形式),实际单元名与设备型号一致。其余服务名均为通用件名,未做改动。
启动耗时分解(本机实测)
| 阶段 | 耗时 | 说明 |
|---|---|---|
| 固件 | 约 10 秒 | 上电自检 + 设备枚举 |
| 引导器 | 约 3 秒 | 菜单停留 2 秒 + 读内核 |
| 内核 | 约 0.8 秒 | 解压与核心初始化 |
| initrd | 约 3.3 秒 | 挂根、加载模块、切换根 |
| 用户空间 | 约 69 秒 | 服务与登录;关键链瓶颈是显示色深约束那一项(约 15 秒) |
合计约 1 分 26 秒。真正拖慢的是用户空间里的关键链,不是固件或引导器。
全链路处理项(按执行顺序)
| # | 大类型 | 事项 | 进程或具体服务 | 注册方或管理者 |
|---|---|---|---|---|
| 1 | 固件 | 上电自检;枚举 PCI / USB / NVMe,初始化显示硬件 | UEFI 固件 | 主板固件(NVRAM 里的启动项) |
| 2 | 固件 | 按启动顺序挑一个引导项 —— 本机引导程序以「顶替 Windows 引导文件位」的方式当门,故改启动顺序无效 | UEFI Boot Manager | 安装时由引导工具写入 NVRAM |
| 3 | 引导器 | 加载引导分区上的引导程序本体 | systemd-boot | boot.loader.systemd-boot.enable |
| 4 | 引导器 | 读入口配置,列出所有世代条目(当前 21 条);注释命名池条目不影响已有条目的显示名 | systemd-boot | 各世代的入口描述文件 |
| 5 | 引导器 | 停留 2 秒后选默认项(或用户手选) | systemd-boot | boot.loader.timeout |
| 6 | 引导器 | 把内核与 initrd 镜像读进内存 | systemd-boot | 世代构建产物 |
| 7 | 引导器 | 把内核命令行传给内核 | systemd-boot | boot.kernelParams + 系统默认项 |
| 8 | 内核 | 解压自身、初始化核心子系统与内建驱动(存储、显示、输入) | Linux kernel | 内核包(版本已钉死) |
| 9 | 内核 | 解析命令行:root=fstab(根设备在 fstab 里查)、日志级别、安全模块 | Linux kernel | 同上 |
| 10 | 内核 | 解包并启动 initrd | Linux kernel | initrd 镜像 |
| 11 | initrd | 拉起 udev 冷插拔,建立最小设备节点 | systemd-udevd(initrd 实例) | 系统内建 |
| 12 | initrd | 按清单加载可用内核模块(NVMe / USB 控制器 / 雷电 / 存储 / 读卡器) | modprobe | boot.initrd.availableKernelModules(本机 7 项,单独一个模块文件) |
| 13 | initrd | 挂载根文件系统(被标记为 initrd 阶段挂载) | systemd mount | fileSystems 的根声明(安装时硬件扫描生成) |
| 14 | initrd | 挂载软件仓库目录(与根同设备,作为独立挂载点) | systemd mount | 系统内建 |
| 15 | initrd | 切换根:从 initrd 交棒给真实系统的 init | systemd | 内核参数 init= |
| 16 | initrd | (若启用)向内核注入固定 EDID —— 本机已停用:写死的连接器名早已不存在,参数空转 | Linux kernel | 已注释的 EDID pin 模块 |
| 17 | 系统 | 加载声明的内核模块(本机约 7 秒,是 early boot 最慢项) | systemd-modules-load | 各模块文件里的 boot.kernelModules |
| 18 | 系统 | udev 完整实例:冷插拔全部设备,生成设备单元 | systemd-udevd | 系统内建 |
| 19 | 系统 | 等待关键设备就绪(TPM、串口等,本机各约 3.7 秒) | systemd device units | udev |
| 20 | 系统 | 起会话总线与日志(后续所有服务的前提) | dbus-broker / systemd-journald | 系统内建 |
| 21 | 挂载 | 根挂载单元 | -.mount | 根文件系统声明 |
| 22 | 挂载 | 引导分区挂载(FAT,权限收紧) | boot.mount | 引导分区声明 |
| 23 | 挂载 | 软件仓库挂载点 | nix-store.mount | 系统内建 |
| 24 | 挂载 | 运行期几个内存文件系统:密钥、提权包装器、凭据目录 | run-keys.mount / run-wrappers.mount / 凭据挂载 | 系统内建 |
| 25 | 挂载 | 每个已登录用户的运行目录(内存文件系统) | run-user-<uid>.mount | logind |
| 26 | 系统 | 大页、POSIX 消息队列、调试与追踪文件系统 | dev-hugepages.mount / dev-mqueue.mount / sys-kernel-*.mount | 系统内建 |
| 27 | 系统 | 网络管理(含在线等待、事件分发) | NetworkManager(主服务 / 事件分发 / 在线等待) | networking.networkmanager |
| 28 | 系统 | 防火墙:系统自带链 + 一份运行时规则表(自定义链插在系统链之前) | firewall.service / firewall-rules.service | 防火墙选项 + 自建运行时规则模块 |
| 29 | 系统 | 虚拟化守护进程 + 默认 NAT 网络 | libvirtd.service | virtualisation.libvirtd |
| 30 | 系统 | 蓝牙 | bluetooth.service | 蓝牙选项 |
| 31 | 系统 | 电源事件与盖子事件 | acpid.service | 系统内建 |
| 32 | 系统 | 合盖抑制锁(分交流 / 电池两档,只对交流档加锁) | lid-inhibit-ac / lid-inhibit-battery | 自建(logind 抑制锁,绑定到电源设备单元) |
| 33 | 系统 | 把「睡眠源 / 唤醒源」清单重放为运行时状态 | logind-awake-apply.service | 自建(清单是单一数据源) |
| 34 | 系统 | 显卡「宿主 / 直通」模式落地 —— 必须在图形会话之前 | gpu-mode-apply.service | 自建(显式声明在登录界面之前) |
| 35 | 系统 | 把归档镜像解释成块设备(只暴露、不挂载) | history-vhdx-attach.service | 自建挂载模块(开机附加=是 / 自动挂载=否) |
| 36 | 系统 | 菊花链下游的色深上限约束(关键链瓶颈,本机约 15 秒) | amdgpu-mst-bpc.service | 自建核显模块 |
| 37 | 系统 | 崩溃取证与上报接管 | drkonqi-coredump-processor@ | 自建崩溃治理模块 |
| 38 | 系统 | 用户 linger(无登录会话也运行用户级服务) | linger-users.service | 自建 |
| 39 | 系统 | 开机取证:记录外置显卡侧有没有认到屏(含两次等待,本机总耗时约 1 分钟,但不阻塞启动) | gpu-<外置卡>-boot-probe.service | 自建(排在登录界面之后) |
| 40 | 登录 | 放行用户会话(等基本系统就绪后开门) | systemd-user-sessions.service | 系统内建 |
| 41 | 登录 | 起图形登录界面(要求登录所需目录先挂好) | display-manager.service(sddm) | 显示管理器模块 |
| 42 | 登录 | 认证(可选指纹;指纹走独立 PAM 后端) | sddm → PAM | 显示管理器 + 指纹模块 |
| 43 | 会话 | 启动用户级 systemd 实例 | systemd user@<uid> | logind |
| 44 | 会话 | 桌面外壳与会话总线 | Plasma 桌面 / dbus-broker(用户级) | 桌面模块 |
| 45 | 会话 | 音频服务(含策略与会话管理) | pipewire / pipewire-pulse / wireplumber | 系统内建(用户单元) |
| 46 | 会话 | 显示配置守护:把布局落盘并应用 | plasma-kscreen.service | 独立显示库(随桌面环境装入) |
| 47 | 会话 | 布局守护:锁屏 / 熄屏前后保证布局一致(两条路径各存一份基准) | kscreen-layout-guard-lock / -watch | 自建 |
| 48 | 会话 | 输入法 | fcitx5(自启动单元) | 输入法模块 |
| 49 | 会话 | 容器运行时(rootless) | docker.service(用户级) | 自建 Docker 模块 |
| 50 | 会话 | Agent 网关(常驻服务) | hermes-gateway.service(用户级) | 自建 |
| 51 | 会话 | 用户自启动应用(聊天、浏览器、笔记、文件管理器… 按自启动项逐个生成用户单元) | app-*.service | 各应用的自启动条目 |
| 52 | 会话 | 桌面门户提供的文件访问挂载(沙箱用) | run-user-<uid>-doc.mount(FUSE portal) | xdg-desktop-portal |
几处值得单独说明
- 「挂载」不等于「登录后才挂」:根与软件仓库在 initrd 阶段就挂好了(否则系统起不来);引导分区与运行期内存文件系统由系统在 basic / local-fs 阶段接管;归档镜像则是「只把设备暴露出来、不挂载」(默认状态),需要时手动挂。
- 有一条规则的顺序不能错:显卡模式落地必须早于图形会话 —— 一旦图形栈先拿到设备,绑定就改不动了。所以它显式声明在登录界面之前。
- 有一项看着最慢但不影响开机:开机取证服务耗时约 1 分钟(内部有两次等待),但它排在登录界面之后且不阻塞,只在耗时榜上排第一。
- 真正拖慢开机的是关键链上的那一项:显示色深约束约 15 秒,因为它要等显示链路稳定。
- 用户会话里那些
app-*单元不是手写的:由桌面按各应用的自启动条目自动生成,删掉条目即消失。
排查入口(三条命令看全貌)
# 1) 五段耗时 + 关键链(哪一项在链上、耗时多少)
systemd-analyze && systemd-analyze critical-chain
# 2) 所有挂载单元与当前挂载点
systemctl list-units --type=mount --all / cat /proc/mounts
# 3) 开机启用的单元(系统级 + 用户级)
systemctl list-unit-files --state=enabled
systemctl --user list-unit-files --state=enabled