1. 课程导入
在进入 EDK II 模块开发与集成之前,先建立一张清晰的“地图”非常关键。EDK II 不是单一工具,也不是单纯的 UEFI 规范实现,而是一套围绕固件工程化开发构建的开源框架。它把 UEFI/PI 规范中的抽象概念,落地为可编译、可复用、可集成的模块、包、库和平台描述。理解这一点,后续学习模块拆分、包依赖、构建系统和平台集成时,才不会把“规范”和“实现”混为一谈。
本节核心问题:EDK II 是什么?它和 UEFI 规范是什么关系?学完本课程后,你应该具备哪些能力?整个 30 章的学习路径如何展开?
一、EDK II 是什么:从规范到工程框架
UEFI 规范定义了固件与操作系统之间的接口标准,包括启动服务、运行时服务、协议、设备路径、变量服务等。它回答的是“固件应该对外表现成什么样”。而 EDK II 回答的是“如何组织代码、如何描述模块、如何构建固件、如何把不同厂商和不同平台的组件集成起来”。
可以把 EDK II 理解为三层能力的集合:
- 模块化开发模型:每个功能单元以模块形式存在,模块通过 INF 文件描述自身类型、源文件、依赖库和协议使用情况。
- 包与依赖管理:通过 DEC、DSC、FDF 等文件描述包、平台和固件布局,形成可复用的包生态。
- 构建与集成系统:通过 BaseTools、build 命令、目标文件生成和固件卷布局,把源码变成可烧录的固件镜像。
因此,EDK II 既是 UEFI 固件的一种主流实现框架,也是固件工程师进行模块开发、平台移植和功能集成的工程基础设施。
二、UEFI 与 EDK II 的关系:规范与实现的分工
UEFI 是规范,EDK II 是实现框架。规范不规定你必须用哪种目录结构、哪种构建工具、哪种模块拆分方式;EDK II 则提供了一套被广泛采用的工程约定。例如,UEFI 规范定义了 EFI_BOOT_SERVICES 和 EFI_RUNTIME_SERVICES,而 EDK II 通过 MdePkg 提供这些结构的头文件、库和基础服务封装。
再比如,UEFI 规范定义了 EFI_DRIVER_BINDING_PROTOCOL,但如何编写一个 UEFI 驱动、如何安装协议、如何管理控制器,EDK II 给出了 Driver Model、UefiDriverEntryPoint、gBS->InstallProtocolInterface 等具体实现路径。规范保证互操作性,EDK II 保证开发效率和可维护性。
三、学习目标:从“会看”到“会做”
本课程的目标不是让你背诵规范条文,而是让你具备独立开发和集成 EDK II 模块的能力。具体包括:
- 能读懂 EDK II 源码目录结构,区分 MdePkg、MdeModulePkg、UefiCpuPkg、平台包等不同职责。
- 能编写一个符合规范的 INF 模块,并正确声明模块类型、源文件、库依赖和协议使用。
- 能理解 DSC 与 FDF 的作用,完成平台描述和固件卷布局配置。
- 能使用 build 命令完成模块编译、平台构建和镜像生成,并定位常见构建错误。
- 能基于 Driver Model 编写 UEFI 驱动,安装协议并管理控制器。
- 能进行模块集成、依赖分析和启动阶段调试,理解 SEC、PEI、DXE、BDS 的衔接关系。
四、整体课程框架与学习路径
30 章内容按照“认知—基础—开发—集成—调试—进阶”的路径展开。前几章建立全局认知和开发环境;中间章节深入模块、包、库、协议和驱动模型;后段聚焦平台集成、构建系统、启动流程、调试排障和工程实践。
| 阶段 | 章节范围 | 核心内容 | 学习产出 |
|---|---|---|---|
| 认知导入 | 第 1~3 章 | EDK II 概述、UEFI 关系、开发环境与源码结构 | 建立全局地图,能搭建构建环境 |
| 模块基础 | 第 4~9 章 | INF、DEC、DSC、FDF、库、模块类型 | 能编写并编译简单模块 |
| 驱动开发 | 第 10~16 章 | Driver Model、协议、事件、变量、设备路径 | 能开发 UEFI 驱动并安装协议 |
| 平台集成 | 第 17~23 章 | 平台包、固件卷、启动流程、SEC/PEI/DXE/BDS | 能完成平台级模块集成 |
| 调试与进阶 | 第 24~30 章 | 构建排障、调试手段、性能、安全与工程实践 | 能定位问题并优化固件工程 |
五、典型场景:一个模块从源码到固件
假设你要为一个新平台添加一个 UEFI 应用,用于在启动时打印平台信息。典型流程如下:
1. 创建模块目录:MyPlatformPkg/Application/PlatformInfo/PlatformInfo.inf
2. 编写源文件:PlatformInfo.c,实现 UefiMain 入口
3. 在包的 DEC 中声明包信息与依赖
4. 在平台 DSC 中把该模块加入 [Components]
5. 在 FDF 中把生成的 EFI 文件放入固件卷
6. 执行构建:
build -p MyPlatformPkg/MyPlatform.dsc -a X64 -t GCC5
7. 得到固件镜像,烧录后验证应用是否出现在启动菜单或自动执行
这个流程贯穿了本课程的核心:模块描述、包依赖、平台配置、固件布局和构建命令。任何一步出错,都可能导致模块不参与编译、协议找不到或镜像中缺失。
学习建议:每学一个概念,都回到真实源码中找对应文件。例如学 INF 时,打开 MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf;学 DSC 时,查看一个真实平台包的 .dsc 文件。把抽象概念和具体文件对应起来,理解速度会明显提升。
六、常见误区与复盘
- 误区一:把 UEFI 规范当成 EDK II 教程。规范定义接口,不教你如何组织工程。学习 EDK II 必须同时看规范、源码和构建文件。
- 误区二:只改 C 代码,不看 INF/DSC/FDF。模块能否被编译、能否进入固件,往往由描述文件决定,而不是由 C 代码决定。
- 误区三:忽略模块类型和依赖关系。DXE_DRIVER、UEFI_APPLICATION、PEIM 的入口和运行阶段不同,选错类型会导致入口不执行或依赖缺失。
- 误区四:构建失败只看最后一行。EDK II 构建日志较长,应关注第一个错误、缺失的包依赖和 DSC/FDF 中的路径问题。
复盘要点:EDK II 的学习难点不在语法,而在“工程约定”。模块、包、平台、固件卷、库和构建工具之间形成了一张依赖网。先理解这张网,再写代码,才能避免“代码写对了但固件里没有”的典型问题。
本章作为导入,目标是让你先看清 EDK II 的全貌:它是 UEFI 规范的主流实现框架,用模块、包、平台和固件布局把规范落地为可构建、可集成的固件工程。接下来,课程将沿着这条路径逐步展开,从环境搭建和源码结构开始,进入模块开发与平台集成的具体实践。