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 保证开发效率和可维护性。

UEFI 规范与 EDK II 实现框架的分层关系 UEFI / PI 规范 启动服务、运行时服务、协议 设备路径、变量、事件、驱动模型 回答:固件对外应表现成什么 EDK II 实现框架 模块 INF、包 DEC、平台 DSC 库、驱动、应用、固件卷 FDF 回答:如何组织、构建与集成 规范约束 实现落地 EDK II 核心工程对象 模块(INF) · 包(DEC) · 平台(DSC) · 固件布局(FDF) · 库(LIB) · 构建工具(BaseTools) 目标产物:可烧录固件镜像 SEC · PEI · DXE · BDS · Runtime · 平台驱动 · 固件卷布局 构建与集成

三、学习目标:从“会看”到“会做”

本课程的目标不是让你背诵规范条文,而是让你具备独立开发和集成 EDK II 模块的能力。具体包括:

  1. 能读懂 EDK II 源码目录结构,区分 MdePkg、MdeModulePkg、UefiCpuPkg、平台包等不同职责。
  2. 能编写一个符合规范的 INF 模块,并正确声明模块类型、源文件、库依赖和协议使用。
  3. 能理解 DSC 与 FDF 的作用,完成平台描述和固件卷布局配置。
  4. 能使用 build 命令完成模块编译、平台构建和镜像生成,并定位常见构建错误。
  5. 能基于 Driver Model 编写 UEFI 驱动,安装协议并管理控制器。
  6. 能进行模块集成、依赖分析和启动阶段调试,理解 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 规范的主流实现框架,用模块、包、平台和固件布局把规范落地为可构建、可集成的固件工程。接下来,课程将沿着这条路径逐步展开,从环境搭建和源码结构开始,进入模块开发与平台集成的具体实践。