nix:梳理系统启动链路

怎么读这张表

按真实执行顺序自上而下。判断依据不是想象,而是三份实测数据:启动耗时五段分解、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-bootboot.loader.systemd-boot.enable
4引导器读入口配置,列出所有世代条目(当前 21 条);注释命名池条目不影响已有条目的显示名systemd-boot各世代的入口描述文件
5引导器停留 2 秒后选默认项(或用户手选)systemd-bootboot.loader.timeout
6引导器把内核与 initrd 镜像读进内存systemd-boot世代构建产物
7引导器把内核命令行传给内核systemd-bootboot.kernelParams + 系统默认项
8内核解压自身、初始化核心子系统与内建驱动(存储、显示、输入)Linux kernel内核包(版本已钉死)
9内核解析命令行:root=fstab(根设备在 fstab 里查)、日志级别、安全模块Linux kernel同上
10内核解包并启动 initrdLinux kernelinitrd 镜像
11initrd拉起 udev 冷插拔,建立最小设备节点systemd-udevd(initrd 实例)系统内建
12initrd按清单加载可用内核模块(NVMe / USB 控制器 / 雷电 / 存储 / 读卡器)modprobeboot.initrd.availableKernelModules(本机 7 项,单独一个模块文件)
13initrd挂载根文件系统(被标记为 initrd 阶段挂载)systemd mountfileSystems 的根声明(安装时硬件扫描生成)
14initrd挂载软件仓库目录(与根同设备,作为独立挂载点)systemd mount系统内建
15initrd切换根:从 initrd 交棒给真实系统的 initsystemd内核参数 init=
16initrd(若启用)向内核注入固定 EDID —— 本机已停用:写死的连接器名早已不存在,参数空转Linux kernel已注释的 EDID pin 模块
17系统加载声明的内核模块(本机约 7 秒,是 early boot 最慢项)systemd-modules-load各模块文件里的 boot.kernelModules
18系统udev 完整实例:冷插拔全部设备,生成设备单元systemd-udevd系统内建
19系统等待关键设备就绪(TPM、串口等,本机各约 3.7 秒)systemd device unitsudev
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>.mountlogind
26系统大页、POSIX 消息队列、调试与追踪文件系统dev-hugepages.mount / dev-mqueue.mount / sys-kernel-*.mount系统内建
27系统网络管理(含在线等待、事件分发)NetworkManager(主服务 / 事件分发 / 在线等待)networking.networkmanager
28系统防火墙:系统自带链 + 一份运行时规则表(自定义链插在系统链之前)firewall.service / firewall-rules.service防火墙选项 + 自建运行时规则模块
29系统虚拟化守护进程 + 默认 NAT 网络libvirtd.servicevirtualisation.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