1. 课程导入
EDK II(EFI Development Kit II)是 UEFI 固件开发的事实标准框架,被广泛应用于服务器、PC、嵌入式与国产计算平台。它并不是一个“能直接烧进芯片的固件”,而是一套工程化构建体系:用包(Package)、模块(Module)、库(Library)、协议(Protocol)和 PCD(Platform Configuration Database)把固件拆解为可复用、可配置、可移植的组件,再通过构建工具生成最终的固件镜像。学习本课程的目标,是让你从“会改几行代码”进阶到“能独立搭建并交付一个平台固件工程”。
一、学习目标:从使用者到平台构建者
本课程围绕一条主线展开:以平台(Platform)为中心,把 EDK II 的构建机制、驱动模型与启动流程串成完整工程能力。完成学习后,你应当能够:
- 理解 UEFI 规范与 EDK II 实现之间的对应关系,知道规范中的协议、服务在代码里落在哪里;
- 独立创建 DSC、FDF、DEC 等平台描述文件,并组织 Package 与 Module 的目录结构;
- 掌握 PEI、DXE、BDS、SMM 等阶段的职责边界与驱动加载顺序;
- 使用 PCD、库实例、条件编译等手段实现同一套代码适配不同主板;
- 具备定位启动失败、驱动加载异常、构建报错等问题的基本排障能力。
二、核心概念:五个必须建立的心智模型
EDK II 的概念很多,但真正决定工程结构的是以下五个对象,它们之间的关系可以用一张结构图清晰表达。
理解这张图的关键在于:Package 提供可复用资产,Module 是编译单元,Library 解决“同一接口多种实现”,Protocol 解决“驱动之间如何找到彼此”,PCD 解决“同一份代码如何适配不同平台”。而 DSC/FDF 则是把这些对象组装成一台具体机器固件的“总装图纸”。
三、整体框架与学习路径
EDK II 工程可以按“构建期”和“运行期”两条线理解。构建期关注源码如何变成 FD/ROM 镜像;运行期关注固件从上电到交出控制权的阶段推进。两条线的交汇点,就是平台描述文件。
| 阶段 | 核心文件/对象 | 工程关注点 |
|---|---|---|
| 工程组织 | Package、DEC、目录结构 | 代码复用与接口声明 |
| 模块定义 | INF、源文件、库类 | 编译单元与依赖关系 |
| 平台组装 | DSC、FDF、PCD | 选模块、绑库、定布局 |
| 构建输出 | FV、FD、ROM 镜像 | 可烧录固件的生成 |
| 运行启动 | SEC → PEI → DXE → BDS | 阶段职责与驱动调度 |
建议的学习路径是:先跑通一次构建,建立“源码到镜像”的直觉;再逐层拆解 DSC/FDF,理解平台如何被描述;然后进入 PEI/DXE 驱动模型,掌握协议与库的用法;最后通过真实平台移植与排障,把知识固化为工程能力。
四、典型场景:一个新平台的固件从零到可启动
假设你要为一款新主板交付 EDK II 固件,典型流程如下:
- 基于参考平台(如 MinPlatform 或厂商参考板)复制一份 Platform Package;
- 修改 DEC 中的 PCD 默认值与 GUID,声明平台特有接口;
- 在 DSC 中选择需要的模块、绑定库实例、设置 PCD 覆盖值;
- 在 FDF 中规划 FV 分区与 FD 布局,确定各阶段固件体积;
- 执行构建命令,生成固件镜像并烧录验证。
# 典型构建命令(以 EDK II 标准构建为例)
edksetup.sh
build -p Platform/MyBoard/MyBoard.dsc \
-a X64 -t GCC5 \
-b DEBUG
# 输出目录中可看到
Build/MyBoard/DEBUG_GCC5/FV/
MYBOARD.fd # 最终固件镜像
FVMAIN.fv # 主固件卷
五、常见误区与复盘建议
- 把 EDK II 当成普通 C 工程:它有自己的构建系统、依赖描述和阶段模型,直接套用 Makefile 思维容易迷路。
- 忽视 PCD 的作用:很多“平台差异”本应通过 PCD 参数化,却被硬编码进驱动,导致代码无法复用。
- 混淆库类与库实例:INF 中声明的是库类,DSC 中才绑定具体实例,二者分离是 EDK II 可移植性的关键。
- 跳过启动阶段模型:不理解 PEI 与 DXE 的边界,就无法判断一个驱动该放在哪里、依赖什么服务。