2. UEFI基础概念
UEFI(Unified Extensible Firmware Interface)不是一次成型的规范,而是从 Intel 的 EFI 1.10 逐步演进为 UEFI 2.x 的开放标准。理解它的版本脉络,是判断固件能力边界、选择优化手段的前提。UEFI 2.0 确立了启动服务与运行时服务的双服务模型,2.1 引入网络栈与安全启动雏形,2.3 之后强化了 Capsule 更新、内存属性与 ACPI 协同,2.7/2.8 则进一步规范了 HTTP Boot、RISC-V 支持与安全启动密钥管理。对性能优化而言,版本决定了可用的协议、可裁剪的模块以及可观测的计时点。
一、规范演进与平台固件的分层关系
UEFI 规范只定义接口,不规定实现。真正落地时,平台固件通常由芯片厂商的参考代码、IBV 的框架代码和 OEM 的板级配置共同组成。规范演进带来的直接影响是:同一段启动代码在不同版本上可能走不同的协议路径,例如从旧的 Simple Network Protocol 迁移到 UEFI 2.x 的 SNP + MNP + TCP 分层栈,启动耗时结构会明显变化。
关键认知:UEFI 是接口规范,PI(Platform Initialization)规范才定义 SEC/PEI/DXE/BDS 等阶段的执行模型。做性能优化时,两者必须对照阅读:UEFI 管“能调什么”,PI 管“什么时候调”。
二、启动流程阶段划分:从加电到操作系统交接
按照 PI 规范,平台初始化被划分为 SEC、PEI、DXE、BDS、TSL 五个阶段。它们不是简单的顺序执行,而是存在服务迁移和权限交接:SEC 在临时内存中运行,PEI 建立永久内存,DXE 提供完整驱动模型,BDS 选择启动项,TSL 把控制权交给操作系统加载器。
三、各阶段职责与关键数据结构
SEC 阶段运行在 CPU 复位后的临时内存中,核心任务是建立可信执行环境并完成最基础的平台校验。它不提供 UEFI 服务,只通过 SEC Core 调用 TempRamInit 等平台原语,并把控制权交给 PEI Core。此阶段的关键结构是 SEC_PLATFORM_INFO 和临时 RAM 的布局描述。
PEI 阶段负责内存初始化与硬件发现。它通过 PEIM 的调度机制按依赖顺序执行模块,并用 HOB(Hand-Off Block)把内存、CPU、平台信息传递给 DXE。HOB 是阶段间数据传递的核心载体,也是性能分析中判断“信息是否重复获取”的重要依据。PEI 阶段还提供 PPI(PEIM-to-PEIM Interface),用于模块间解耦调用。
DXE 阶段是 UEFI 驱动模型真正展开的地方。DXE Core 维护 Handle Database,驱动通过 Protocol 暴露能力,消费者通过 LocateProtocol 获取服务。EFI_SYSTEM_TABLE 和 EFI_BOOT_SERVICES 在此阶段完整可用。DXE 的调度顺序、驱动依赖和协议绑定次数,直接决定启动中段的耗时。
BDS 阶段负责启动策略:枚举启动项、处理 BootOrder、连接控制台设备、执行 Boot#### 变量指向的加载器。它消费 DXE 建立的协议,并最终调用 EFI_LOADED_IMAGE 的入口。BDS 的优化重点在于减少无效枚举、避免重复连接以及合理设置启动超时。
TSL 阶段是过渡阶段,操作系统加载器调用 ExitBootServices 后,启动服务失效,运行时服务保留。此时内存映射被冻结并交给 OS,EFI_HANDLE 和 Memory Map 成为最后的交接数据。TSL 本身耗时通常很短,但若 ExitBootServices 因内存映射变化而重试,会显著拖慢交接。
四、阶段职责与优化关注点对照
| 阶段 | 核心职责 | 关键数据结构 | 常见性能问题 |
|---|---|---|---|
| SEC | 安全校验、临时环境建立 | SEC_PLATFORM_INFO、临时RAM布局 | 校验算法过重、临时内存过小 |
| PEI | 内存初始化、硬件发现 | HOB、PPI、PEI_SERVICES | PEIM 串行过多、内存训练反复 |
| DXE | 驱动分发、协议绑定、服务提供 | Handle DB、Protocol、System Table | 驱动依赖链过长、重复绑定 |
| BDS | 启动策略、设备选择、加载器调用 | Boot####、BootOrder、Loaded Image | 启动项枚举慢、控制台连接冗余 |
| TSL | 退出启动服务、交接 OS | Memory Map、EFI_HANDLE | ExitBootServices 重试、映射碎片 |
五、案例场景:一次典型的启动耗时定位
某服务器平台冷启动约 28 秒,其中 PEI 占 9 秒、DXE 占 11 秒、BDS 占 5 秒。通过固件串口日志和性能计时点发现:PEI 阶段内存训练重复执行两次,原因是 HOB 中内存信息未被后续 PEIM 正确复用;DXE 阶段有 14 个驱动串行加载,其中网卡与存储驱动存在隐式依赖;BDS 阶段启动项枚举扫描了全部可移动设备。
PEI : 9.2s (MemoryInit 5.8s, PEIM Dispatch 3.4s)
DXE : 11.4s (Driver Load 7.1s, Protocol Bind 4.3s)
BDS : 5.1s (Boot Enum 3.6s, Console Connect 1.5s)
TSL : 0.3s
Total: 26.0s
优化动作包括:在 PEI 中缓存内存训练结果并写入 HOB;将无依赖的 DXE 驱动改为按需加载;在 BDS 中限制启动项扫描范围并缩短超时。调整后总耗时降至 17 秒左右,其中 PEI 减少约 4 秒,DXE 减少约 3 秒,BDS 减少约 2 秒。
经验提示:阶段耗时不是孤立指标。PEI 省下的时间可能被 DXE 的重复探测吃掉,BDS 的快速跳过也可能导致 OS 加载器重新枚举设备。优化必须看端到端,而不是单阶段数字。
六、常见误区与复盘
- 误区一:把 UEFI 等同于 BIOS 的简单替换。UEFI 是接口规范,PI 是执行模型,二者分层不同,混为一谈会导致优化目标错位。
- 误区二:认为阶段越少越好。SEC/PEI/DXE/BDS/TSL 的划分是为了职责隔离和可移植性,盲目合并会破坏安全边界和驱动模型。
- 误区三:只盯 DXE 驱动数量。PEI 的内存训练和 BDS 的枚举往往才是隐藏的大头,必须结合 HOB 和启动变量一起分析。
- 误区四:忽略 ExitBootServices 的重试成本。内存映射在 TSL 前若发生变化,OS 加载器会重试,造成看似“最后一步很慢”的假象。
复盘要点:建立阶段级计时基线,记录 HOB 内容、驱动加载顺序和 BootOrder 变化。任何优化前后都要对比端到端时间,避免把耗时从一个阶段搬到另一个阶段。
掌握规范演进、阶段划分和关键数据结构,是后续所有性能优化工作的坐标系。只有先看清 SEC 到 TSL 的职责边界与数据流向,才能判断某个优化动作究竟是在减少真实工作,还是仅仅改变了耗时分布。