目录
1. PCD的说明
PCD的类型
2.PCD在文件中的声明和定义
2.1 PCD声明格式:
2.1 在 .dec 文件中声明:
2.2 在 .dsc 文件中配置
2.3 在 .inf 文件中引用:
1). 定义和作用范围
2). 修改时机
3. PCD相关的函数的使用
PCD值的函数
特殊用途的函数
4.PCD与GUID的关系
1). TokenSpaceGuid 的作用
2). 使用范围
3). 注意事项
4)总结
1. PCD的说明
在UEFI开发中,PCD(Platform Configuration Database,平台配置数据库)是一种用于管理平台配置数据的机制,允许在编译时或运行时对配置数据进行读取和修改。
PCD的类型
PCD类型 | 特点 |
FeatureFlag |
|
FixedAtBuild |
|
PatchableInModule |
|
Dynamic |
|
DynamicEx |
|
PCD变量:
TokenSpaceGuidCName.PcdCName
其中TokenSpaceGuidCName是一个GUID,而PcdCName是这个PCD变量的名字,这两个加在一起构成了一个PCD变量。
2.PCD在文件中的声明和定义
PcdsFeatureFlag
是一种非常有用的 PCD 类型,适用于在编译时控制功能的启用或禁用。通过在 .dec
文件中声明、在 .inf
文件中引用以及在 .dsc
文件中配置,开发人员可以灵活地管理功能开关,而无需修改代码。
PcdsFixedAtBuild
是 UEFI 开发中的一种 PCD(Platform Configuration Database,平台配置数据库)类型,用于在编译时设置固定的配置值。这些值在编译完成后无法修改,因此具有较高的稳定性和性能。
2.1 PCD声明格式:
PcdTokenSpaceGuidName.PcdTokenName | Value | [DatumType ] | [MaxSize] | Token
[ ]内的是可选项。Value也叫做DefaultValue 就是这个PCD变量的默认值,如果后面的.dsc文件中没有重新配置它的值,就用这个默认值。DatumType是这个PCD变量的数据类型,有UINT 8 16 32 等,如果是VOID * 的话还要在MaxSize部分写上这个Buffer的最大值,比如128、256等等。Token是UINT 32类型的,每个.dec文件中的PCD都有独一无二的Token。
(参考博文 原文链接:https://blog.csdn.net/WKYFP/article/details/127507390)
2.1 在 .dec
文件中声明:
在 .dec
文件中声明 FeatureFlag
,定义其默认值。示例:
[PcdsFeatureFlag]
gMyTokenSpaceGuid.PcdMyFeatureFlag|FALSE|BOOLEAN|0x00010001
gMyTokenSpaceGuid
是 TokenSpaceGuid。
PcdMyFeatureFlag
是 PCD 的名称。
FALSE
是默认值。
BOOLEAN
是数据类型。
0x00010001
是 Token 的唯一标识
[PcdsFixedAtBuild]gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber | 256# PcdBootManagerMenuFile其值是一个GUIDgEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile | { 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0 gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange | FALSEgEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler | 0x10 gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize | $(CACHEASRAM_RAM_SIZE)
PCD的定义通常位于 .dec
文件中,其值可以在 .dsc
文件中重新设置,但也可以通过 .fdf
文件中的 SET
语句进行配置。
# Set NVS AreaSET gUefi$(PLATFORMPKG_NAME)PkgTokenSpaceGuid.PcdNVSAreaBase = $(NVS_AREA_START)SET gUefi$(PLATFORMPKG_NAME)PkgTokenSpaceGuid.PcdNVSSize = $(NVS_SIZE)
2.2 在 .dsc
文件中配置
.dsc
文件中可以重新设置 FeatureFlag
的值,覆盖 .dec
文件中的默认值.dsc
文件中可以重新设置 FeatureFlag
的值,覆盖 .dec
文件中的默认值。
[PcdsFeatureFlag]
gMyTokenSpaceGuid.PcdMyFeatureFlag|TRUE
2.3 在 .inf
文件中引用:
在模块的 .inf
文件中引用 .dec
文件中声明的 PCD
。
格式:
[Pcd]
gMyTokenSpaceGuid.PcdMyFeatureFlag
实列:
[Pcd]gUefiLoongsonPlatformPkgTokenSpaceGuid.PcdFlashDxeFvBasegUefiLoongsonPlatformPkgTokenSpaceGuid.PcdMemDxeFvBase[FixedPcd]gUefiLoongsonPlatformPkgTokenSpaceGuid.PcdLockedMemBasegUefiLoongsonPlatformPkgTokenSpaceGuid.PcdLockedMemSize
其中[FixedPcd]
和[Pcd]
是两种不同类型的PCD(Platform Configuration Database,平台配置数据库),它们的主要区别如下:
1). 定义和作用范围
-
[FixedPcd]
:-
FixedPcd
是编译时确定的PCD类型,其值在编译阶段就已经固定,不可在运行时修改。 -
作用范围:它是模块级别的,不同模块可以配置不同的
FixedPcd
值。
-
-
[Pcd]
:-
[Pcd]
通常指动态PCD,如PcdsDynamic
、PcdsDynamicEx
等其值可以在运行时动态修改。 -
作用范围:它是系统级别的,一个
[Pcd]
的修改会影响整个系统。
-
2). 修改时机
-
[FixedPcd]
:由于其值在编译时确定,因此在运行时无法修改。 -
[Pcd]
:动态PCD可以在运行时修改,具体取决于其类型。例如:-
PcdsDynamicHii
:修改后可以跨重启生效。 -
PcdsDynamicDefault
:在运行时可以修改,但重启后会丢失。
-
3. PCD相关的函数的使用
-
使用
PcdLib
提供的接口(如PcdGetBool()
)来读取FeatureFlag
的值。 -
示例:
-
if (PcdGetBool (PcdMyFeatureFlag)) {// 功能启用 } else {// 功能禁用 }
PCD值的函数
PcdGet8()
:获取8位(UINT8
)的PCD值。
UINT8 MyFeatureValue8 = PcdGet8 (PcdMyFeatureValue8);
PcdGet16()
:获取16位(UINT16
)的PCD值。
UINT16 MyFeatureValue16 = PcdGet16 (PcdMyFeatureValue16);
PcdGet32()
:获取32位(UINT32
)的PCD值。
UINT32 MyFeatureValue32 = PcdGet32 (PcdMyFeatureValue32);
PcdGet64()
:获取64位(UINT64
)的PCD值。
UINT64 MyFeatureValue64 = PcdGet64 (PcdMyFeatureValue64);
PcdGetPtr()
:获取指向PCD缓冲区的指针,用于获取字符串或其他复杂数据类型的PCD值。
CONST CHAR16* MyFeatureString = PcdGetPtr (PcdMyFeatureString);
PcdGetBool()
:获取布尔类型的PCD值。
BOOLEAN MyFeatureFlag = PcdGetBool (PcdMyFeatureFlag);
PcdGetSize()
:获取PCD缓冲区的大小。
UINTN MyFeatureSize = PcdGetSize (PcdMyFeatureValue);
特殊用途的函数
FeaturePcdGet()
:FeaturePcdGet
是一个宏用于获取布尔类型的 PcdsFeatureFlag
的值。
if (FeaturePcdGet (PcdMyFeatureFlag)) {// 功能启用
}PcdGetBool 是一个通用的函数,用于获取布尔类型的PCD值。它可以用于任何布尔类型的PCD,包括 PcdsFixedAtBuild 和 PcdsDynamic 类型的PCD。FeaturePcdGet 是一个宏,专门用于获取 PcdsFeatureFlag 类型的PCD值。如果你需要获取布尔类型的PCD值,可以使用 PcdGetBool。
如果你需要获取 PcdsFeatureFlag 类型的PCD值,建议使用 FeaturePcdGet,因为它更简洁且具有类型检查。
PcdGetExXX()
:
-
用途:获取扩展类型的PCD值(
PcdsDynamicEx
)。 -
UINT32 MyFeatureValue32 = PcdGetEx32 (&gMyTokenSpaceGuid, PcdMyFeatureValue32);
FixedPcdGetxx
()的使用方式类似于 PcdGet32
,但它专门用于 FixedPcd
类型的PCD。以下是具体的使用示例:
UINT32 MyFixedPcdValue = FixedPcdGet32 (PcdMyFixedPcdValue32);
4.PCD与GUID的关系
gEfiMdeModulePkgTokenSpaceGuid.PcdMyFeatureFlag 是只能用在模块MdeModulePkg中吗 ?
gEfiMdeModulePkgTokenSpaceGuid
是一个特定的 TokenSpaceGuid,它与 MdeModulePkg 模块包相关联。这意味着,任何使用 gEfiMdeModulePkgTokenSpaceGuid
的 PCD 变量通常都是在 MdeModulePkg 的上下文中定义和使用的。不过,这并不意味着这些 PCD 变量只能用在 MdeModulePkg 中。实际上,它们可以在任何引用了 MdeModulePkg 的模块或平台中使用。
1). TokenSpaceGuid 的作用
TokenSpaceGuid 是一个全局唯一的标识符,用于将 PCD 变量与特定的模块或包关联起来。它确保了不同模块或包中的 PCD 变量不会相互冲突。例如:
-
gEfiMdeModulePkgTokenSpaceGuid
是 MdeModulePkg 的 TokenSpaceGuid。 -
gEfiMdePkgTokenSpaceGuid
是 MdePkg 的 TokenSpaceGuid。
2). 使用范围
虽然 gEfiMdeModulePkgTokenSpaceGuid
是为 MdeModulePkg 定义的,但它可以在任何引用了 MdeModulePkg 的模块或平台中使用。这意味着:
-
MdeModulePkg 中定义的 PCD 变量(如
gEfiMdeModulePkgTokenSpaceGuid.PcdMyFeatureFlag
)可以在其他模块或平台中引用。 -
其他模块或平台可以通过
.inf
文件引用这些 PCD 变量。
3). 注意事项
-
依赖关系:确保你的模块或平台正确地引用了 MdeModulePkg。如果未正确引用,编译时会报错。
-
版本兼容性:确保使用的 MdeModulePkg 版本中定义了所需的 PCD 变量。
4)总结
gEfiMdeModulePkgTokenSpaceGuid.PcdMyFeatureFlag
是在 MdeModulePkg 中定义的,但它可以在任何引用了 MdeModulePkg 的模块或平台中使用。TokenSpaceGuid 的作用是确保 PCD 变量的全局唯一性,而不是限制其使用范围。