EDKII 工程结构介绍
EDK2工程结构介绍
目录
一、EDK2工程目录的一级结构
ayuan@ayuan-virtual-machine:~/src/edk2$ tree -L 1
.
├── ArmPkg # ARM架构相关代码
├── ArmPlatformPkg
├── ArmVirtPkg
├── BaseTools # 编译EDK2所需基础工具集,包含编译器,链接器等
├── Build # 构建输出目录,编译后生成的文件,包括各种平台的固件镜像
├── Conf # target.txt文件用于定义要构建的平台,构建目标和工具链配置
├── CONTRIBUTING.md
├── CryptoPkg # OpenSSL加密支持
├── DynamicTablesPkg
├── edksetup.bat
├── edksetup.sh # 环境配置脚本,设置编译环境变量,初始化工作环境
├── EmbeddedPkg
├── EmulatorPkg
├── FatPkg
├── FmpDevicePkg
├── IntelFsp2Pkg
├── IntelFsp2WrapperPkg
├── License-History.txt
├── License.txt
├── Maintainers.txt
├── MdeModulePkg # 模块化核心包
├── MdePkg # 最基础的核心包,UEFI标准定义,基本数据类型和库函数
├── NetworkPkg # 网络协议栈
├── OvmfPkg # 虚拟机固件
├── PcAtChipsetPkg
├── pip-requirements.txt
├── PrmPkg
├── ReadMe.rst
├── RedfishPkg
├── SecurityPkg # 安全功能
├── ShellPkg # shell命令行界面
├── SignedCapsulePkg
├── SourceLevelDebugPkg
├── StandaloneMmPkg
├── UefiCpuPkg # x86 CPU相关功能
├── UefiPayloadPkg
└── UnitTestFrameworkPkg
29 directories, 8 files
二、常用的目录文件
2.1 BaseTools--构建工具链
-
主要的子目录
BaseTools/ ├── Source/ │ ├── C/ # 用 C 写的底层工具(如 GenFw、GenFds) │ ├── Python/ # Python脚本,如 build.py、TargetTool.py │ └── Vfr/ # 处理 VFR (Visual Form Representation) 文件 └── Scripts/ -
BaseTools相当于编译器+脚本+构建系统。EDk2中所有工程编译都依赖这个目录里的工具,在编译EDk2工程之前,首先就要执行make -C BaseTools。编译出的关键命令如:GenFw、GenFds、build、VfrCompile等。随后执行edksetup.sh,上面编译出的命令就会被添加到环境变量PATH中。
2.2 Conf--配置目录
-
主要的目录文件
Conf/ ├── target.txt # 构建目标(最重要!) ├── tools_def.txt # 定义编译器工具链 └── build_rule.txt # 定义构建规则 # 以上文件在执行 source edksetup.sh 之后自动从 BaseTools/Conf 复制到当前的 Conf/ 目录中 -
Conf中最主要的文件是target.txt。它告诉编译系统使用哪个平台(.dsc),目标架构是什么,使用的编译工具链是什么,输出的目录位置等。要修改的主要参数如下:# 适用于本地x86_64的最小配置 ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc TARGET = DEBUG TARGET_ARCH = X64 TOOL_CHAIN_TAG = GCC5 BUILD_RULE_CONF = Conf/build_rule.txt -
也可以
build的时候设置临时参数build -a X64 -t GCC5 -p OvmfPkg/OvmfPkgX64.dsc -b DEBUG。
2.3 MdePkg--基础核心包
-
内容
Include/ # 各种 UEFI 接口头文件(例如 Uefi.h) Library/ # 各种库(如 DebugLib、BaseLib) Protocol/ # UEFI 协议定义 -
MdePkg相当于C标准库和操作系统内核API,提供了整个EDK2架构所需的基础定义和接口。
2.4 MdeModulePkg -- 常用模块包
-
目录结构
MdeModulePkg/ ├── Application/ # 应用(比如 HelloWorld) ├── Library/ ├── Universal/ # 通用驱动模块 └── Bus/ # 各种总线类驱动 -
MdeModulePkg在MdePkg的基础上实现了很多实际可用的模块,比如,UEFI驱动(Driver),UEFI应用(Application),常见的服务(如Variable服务、Boot Manager)。
2.5 OvmfPkg--OVMF固件工程目录
Open Virtual Machine Firmware Package
-
目录结构
OvmfPkg/ ├── OvmfPkgX64.dsc # 平台描述文件 ├── OvmfPkgX64.fdf # 镜像布局文件 ├── PlatformDxe/ # 平台初始化驱动 ├── Include/ └── Library/ -
这是用于在
QEMU虚拟机上运行的完整的UEFI固件工程,支持X64、IA32平台。该虚拟平台固件实现包在编译后输出文件OVMF.fd(完整的固件镜像)和OVMF_CODE.fd/OVMF_VARS.fd分区镜像(代码和变量区分离版本)。要编译该镜像,前面我们配置了target.txt中ACTIVE_PLATFORM=OvmfPkg/OvmfPkgX64.dsc。
2.6 Build 编译输出路径
EDKII 的编译输出路径高度依赖与构建目标,它由以下几部分组成:[架构]/[工具链]/[构建模式]。
- 架构:例如
X64,IA32,ARM,AARCH64等。 - 工具链:例如
VS2017x86(Windows),GCC5(Linux),XCODE5(macOS) 等。 - 构建模式
DEBUG,RELEASE。
-
编译出的镜像文件
# 典型的路径结构 <Your_Edk2_Workspace>/Build/<PlatformPkg>/<Architecture>/<Toolchain>/<BuildMode> # 假设编译的是 OvmfPkg,目标架构是 X64,使用 GCC5 工具链,编译为 DEBUG 模式。 ~/edk2/Build/OvmfX64/DEBUG_GCC5/FV/OVMF.fdFV 目录是指固件卷,包含了构成固件的各个模块和最终镜像。
OVMF.fd: 这是最终的 扁平化镜像,包含了所有代码和数据,可以直接被虚拟机加载。这是用于 QEMU/KVM 的最重要的文件。OVMF_CODE.fd: 代码部分的镜像,通常需要与OVMF_VARS.fd配对使用。OVMF_VARS.fd: 变量存储部分的镜像,用于保存 UEFI 设置。\*.fv: 其他固件卷文件,它们是OVMF.fd的组成部分。
-
在 UFFI Shell 下运行的驱动程序或应用程序,它们的路径与模块的编译方式(是否被包含在平台 DSC 文件中)有关。
-
作为平台固件的一部分被编译。当应用/驱动在平台的 DSC 文件 (
[Components]部分) 中定义时,它会被编译并链接到最终的.fd文件中。同时,它也会有一个独立的.efi文件被生成。# 路径结构 <Your_Edk2_Workspace>/Build/<PlatformPkg>/<Architecture>/<Toolchain>/<BuildMode>/[Architecture] # 举例 # 假设我们编译了 MdeModulePkg/Application/HelloWorld/HelloWorld.inf 这个应用。 ~/edk2/Build/OvmfX64/DEBUG_GCC5/X64/HelloWorld.efi -
单独编译一个模块。使用
build命令单独编译一个模块时,输出路径类似,但PlatformPkg部分会被替换。build -p MdeModulePkg/MdeModulePkg.dsc -m MdeModulePkg/Application/HelloWorld/HelloWorld.inf -a X64 -t GCC5 # 输出路径 ~/edk2/Build/MdeModule/DEBUG_GCC5/X64/HelloWorld.efibuild 命令中,
-p/--platform用于指定平台描述文件的路径。MdeModulePkg/MdeModulePkg.dsc表示使用MdeModulePkg目录下的MdeModulePkg.dsc文件作为平台配置文件。该文件定义了模块的构建规则、库依赖、编译选项等全局配置。-m/--module指定要单独构建的模块描述文件(.inf文件)的路径。例子中的命令表示仅构建HelloWorld模块,其配置由HelloWorld.inf文件定义(如源代码文件、依赖的库等)。# 构建平台所有模块 build -p MdeModulePkg/MdeModulePkg.dsc -a X64 -t GCC5
-
-
.dsc和.inf是什么上面涉及到两个平台描述文件,编译固件镜像时使用到的
OvmfPkg/OvmfPkgX64.dsc和编译模块时使用到的MdeModulePkg/MdeModulePkg.dsc,二者的差异本质是平台级配置和模块级配置的分工。平台描述模块(
.dsc)的作用:- 定义构建目标(X64,DEBUG/RELEASE,GCC5等)
- 模块列表与依赖,通过
[Components]字段列出所有需编译的模块(.inf文件),并指定模块间的依赖关系。如OvmfPkgX64.dsc会包含虚拟化相关的驱动(如VirtioBlkDxe.inf),而MdeModulePkg.dsc可能包含通用模块(如UefiShell.inf)。
模块描述文件(
.inf)的作用:- 描述单个模块:定义模块类型(如
UEFI_APPLICATION、DXE_DRIVER)、源文件、依赖库([LibraryClasses])和编译选项。如,HelloWorld.inf会指定源文件HelloWorld.c和依赖库UefiLib。 - 模块级编译控制:通过
[BuildOptions]覆盖平台级的编译选项(如优化级别、警告处理)。如:为HelloWorld.inf添加-O2优化标志,仅影响该模块。
维度 OvmfPkgX64.dsc MdeModulePkg.dsc 角色 平台级配置,定义虚拟化固件的整体构建规则。 模块集合,提供通用 UEFI 模块的默认配置。 内容 包含虚拟化驱动、平台初始化代码、内存布局等。 包含文件系统、网络栈、Shell 等通用模块。 使用场景 构建完整的 OVMF(Open Virtual Machine Firmware)固件。 作为模块库,供其他平台或自定义固件引用。 依赖关系 可能依赖 MdeModulePkg中的模块。独立提供模块,无外部平台依赖。
附录
DSC 文件说明
DSC 文件的全称是 Platform Description File,它像一个项目的“总编译清单”或“Makefile”。它描述了要构建一个完整的、可启动的固件镜像,需要编译哪些模块,以及如何编译它们。它通常以平台名命名比如OvmfPkg/OvmfPkgX64.dsc,如果是我们自己的硬件开发平台包YourBoardPkg/YourBoardPkg.dsc。它定义了全局的编译选项、支持的架构、使用的库、以及最重要的——需要编译的模块组件列表。
[Components] 是DSC文件中的一个特定区块,它通过节 来定义。作用是列出所有需要被编译并链接到最终固件镜像中的模块。
DSC 文件举例:
[Defines]
PLATFORM_NAME = OvmfX64
PLATFORM_GUID = ...
SUPPORTED_ARCHITECTURES = X64
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
# ... 其他部分,比如 [LibraryClasses] ...
[Components]
# 首先,包含来自其他Package的组件
MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
MdeModulePkg/Core/Dxe/DxeMain.inf
MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
# 平台自身的组件
OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
OvmfPkg/VirtioNetDxe/VirtioNet.inf
# !!!这里就是关键所在!!!
# 如果HelloWorld应用被包含在这里,它就会被编译进固件
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
# ... 还有很多很多其他的组件 ...
-
当你在EDKII根目录下执行
build -p OvmfPkg/OvmfPkgX64.dsc ...时,构建系统会读取这个DSC文件。 -
构建系统会找到
[Components]这一节。 -
然后,它会依次去编译列表中每一个
.inf文件所描述的模块。-
构建系统根据
HelloWorld.inf的指导,将C源代码编译、链接,生成一个独立的UEFI应用程序。 -
链接到最终的
.fd文件。
-
总结
本文只是对EDK2工程主要文件的一个大概理解,有助于建立系统性的思考,后续深入学习中会继续补充。
寄语:每天进步一点点,践踏实地!

浙公网安备 33010602011771号