4. 工作空间与包:Workspace 概念、Package (.dec) 定义与结构、DSC 文件与 FDF 文件基础
EDK II 的构建系统围绕 工作空间 (Workspace) 和 包 (Package) 两个核心概念组织。理解它们之间的关系以及 .dec、.dsc、.fdf 三种描述文件的作用,是进行模块开发与集成的基础。
4.1 Workspace 概念与结构
Workspace 是 EDK II 构建系统的顶层目录,它定义了所有源文件、库、平台描述文件和生成固件映像的边界。一个 Workspace 通常包含多个 Package,以及一个或多个平台描述文件。
关键点: Workspace 本身不是一个物理文件,而是一个目录结构约定。构建工具通过环境变量
WORKSPACE 或 PACKAGES_PATH 定位该目录。
4.1.1 典型 Workspace 目录布局
Workspace/
├── edk2/ # 核心 EDK II 代码库 (一个 Package 集合)
│ ├── MdePkg/
│ ├── MdeModulePkg/
│ ├── UefiCpuPkg/
│ └── ...
├── MyPlatform/ # 自定义平台 Package
│ ├── MyPlatformPkg/
│ │ ├── MyPlatformPkg.dec
│ │ ├── MyPlatformPkg.dsc
│ │ ├── MyPlatformPkg.fdf
│ │ ├── Include/
│ │ ├── Library/
│ │ └── ...
│ └── ...
├── MyDrivers/ # 自定义驱动 Package
│ ├── MyDriverPkg/
│ │ ├── MyDriverPkg.dec
│ │ ├── MyDriverPkg.dsc
│ │ └── ...
│ └── ...
└── Build/ # 构建输出目录 (由工具自动生成)
└── ...
4.2 Package (.dec) 定义与结构
Package 是 EDK II 中代码组织和分发的基本单元。一个 Package 是一个逻辑上相关的模块、库、头文件和协议的集合。每个 Package 必须包含一个 .dec (Declaration) 文件,作为该 Package 的“身份证”和“目录”。
4.2.1 .dec 文件的作用
- 声明 GUID:定义该 Package 中所有模块、协议、PPI、GUID 的全局唯一标识符。
- 声明 PCD:定义该 Package 提供的平台配置数据库 (PCD) 条目及其默认值。
- 声明 Include 路径:指定该 Package 对外公开的头文件目录。
- 声明 Library Classes:列出该 Package 提供的库类 (Library Class) 名称。
4.2.2 .dec 文件结构示例
## @file
# MyDriverPkg.dec
# 声明 MyDriverPkg 的 GUID、PCD 和 Include 路径
#
[Defines]
DEC_SPECIFICATION = 0x0001001A
PACKAGE_NAME = MyDriverPkg
PACKAGE_GUID = 12345678-9ABC-DEF0-1234-56789ABCDEF0
PACKAGE_VERSION = 1.0
[Includes]
Include # 公开头文件目录
[LibraryClasses]
MyCustomLib|Include/Library/MyCustomLib.h
[Guids]
gMyDriverGuid = { 0x11111111, 0x2222, 0x3333, { 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB } }
[PcdsFixedAtBuild]
gMyDriverPcdTokenSpaceGuid.PcdMyDriverDebugLevel|0x00000003|UINT32|0x30000001
4.2.3 .dec 文件主要章节
| 章节名称 | 用途 | 示例内容 |
|---|---|---|
[Defines] |
定义 Package 元数据 | PACKAGE_NAME, PACKAGE_GUID, DEC_SPECIFICATION |
[Includes] |
声明公开头文件搜索路径 | Include, Include/Protocol |
[LibraryClasses] |
声明库类及其头文件映射 | MyLib|Include/Library/MyLib.h |
[Guids] |
声明该 Package 拥有的所有 GUID | gMyProtocolGuid = { ... } |
[PcdsFixedAtBuild] |
声明编译时固定的 PCD | gMyPkg.PcdMyValue|0x5|UINT32|0x40000001 |
[PcdsDynamic] |
声明运行时可动态修改的 PCD | gMyPkg.PcdMyDynamicValue|0x0|UINT8|0x50000001 |
最佳实践: 每个 Package 应只包含一个
.dec 文件。所有对外接口(GUID、PCD、Library Class)都应在此文件中声明,以实现接口与实现的分离。
4.3 DSC 文件基础
DSC (Platform Description) 文件是平台级别的描述文件,它定义了构建一个特定固件映像所需的所有模块、库实例、PCD 值和构建选项。DSC 文件是构建过程的“主控清单”。
4.3.1 DSC 文件核心章节
[Defines]:定义平台名称、GUID、固件版本、目标架构等。[LibraryClasses]:将抽象的 Library Class 映射到具体的 Library Instance (INF 文件)。[PcdsFixedAtBuild]/[PcdsDynamic]:覆盖或设置该平台下所有模块使用的 PCD 值。[Components]:列出需要构建并包含进固件映像的所有模块 (INF 文件)。
4.3.2 DSC 文件片段示例
[Defines]
PLATFORM_NAME = MyPlatform
PLATFORM_GUID = 22222222-3333-4444-5555-666677778888
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x0001001C
SUPPORTED_ARCHITECTURES = IA32|X64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
FLASH_DEFINITION = MyPlatformPkg/MyPlatformPkg.fdf
[LibraryClasses]
# 将 UefiDriverEntryPoint 库类映射到 MdePkg 中的实例
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000
[Components]
# 列出要构建的模块
MyDriverPkg/MyDriver/MyDriver.inf
MdeModulePkg/Universal/HelloWorld/HelloWorld.inf
4.4 FDF 文件基础
FDF (Flash Description File) 文件定义了固件映像在 Flash 设备上的物理布局。它描述了哪些模块、固件卷 (FV)、固件文件系统 (FFS) 以及原始二进制数据应该被放置在 Flash 的哪个地址和区域。
4.4.1 FDF 文件核心概念
- FD (Flash Device):代表整个 Flash 芯片。
- FV (Firmware Volume):Flash 设备内的逻辑存储区域,包含一个或多个 FFS 文件。
- FFS (Firmware File System):FV 内部的组织结构,用于存储模块、数据文件等。
- INF 文件引用:在 FDF 中通过
INF语句引用 DSC 中已声明的模块,将其打包进指定的 FV。
4.4.2 FDF 文件片段示例
[FD.MyPlatform]
BaseAddress = 0xFFF00000
Size = 0x00100000
ErasePolarity = 1
BlockSize = 0x1000
NumBlocks = 0x100
# 定义第一个固件卷
0x00000000|0x00080000
FV = PEI_FV
# 定义第二个固件卷
0x00080000|0x00080000
FV = DXE_FV
[FV.PEI_FV]
FvAlignment = 16
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
READ_DISABLED_CAP = FALSE
READ_ENABLED = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = FALSE
WRITE_DISABLED_CAP = FALSE
WRITE_ENABLED = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = FALSE
INF MdeModulePkg/Core/Pei/PeiMain.inf
INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
[FV.DXE_FV]
FvAlignment = 16
ERASE_POLARITY = 1
MEMORY_MAPPED = TRUE
STICKY_WRITE = TRUE
LOCK_CAP = TRUE
LOCK_STATUS = TRUE
READ_DISABLED_CAP = FALSE
READ_ENABLED = TRUE
READ_LOCK_CAP = TRUE
READ_LOCK_STATUS = FALSE
WRITE_DISABLED_CAP = FALSE
WRITE_ENABLED = TRUE
WRITE_LOCK_CAP = TRUE
WRITE_LOCK_STATUS = FALSE
INF MdeModulePkg/Core/Dxe/DxeMain.inf
INF MyDriverPkg/MyDriver/MyDriver.inf
4.5 三文件关系与构建流程
下图展示了 .dec、.dsc、.fdf 三者在 EDK II 构建系统中的协作关系。
4.6 三文件职责对比
| 文件类型 | 核心职责 | 作用域 | 关键内容 |
|---|---|---|---|
| .dec | 声明 Package 的公共接口 | Package 级别 | GUID、PCD 定义、Library Class 声明、Include 路径 |
| .dsc | 描述平台构建配置 | 平台级别 | 模块列表、库实例映射、PCD 赋值、构建选项 |
| .fdf | 描述 Flash 设备布局 | 平台级别 | FD 区域划分、FV 定义、FFS 文件放置、INF 引用 |
常见错误: 初学者常将模块的
.inf 文件与 .dec 文件混淆。.inf 描述单个模块的构建信息,而 .dec 描述整个 Package 的公共接口。一个 Package 可以有多个 .inf,但通常只有一个 .dec。
4.7 本章小结
- Workspace 是顶层目录,包含所有 Package 和平台文件。
- Package 是代码组织单元,其
.dec文件声明了所有对外接口。 - DSC 文件 是平台构建的“主控清单”,决定构建哪些模块以及如何配置。
- FDF 文件 是 Flash 的“施工图纸”,决定固件映像的物理布局。
- 三者通过 GUID、PCD 和 INF 引用紧密协作,最终由 Build 工具生成固件映像。