EFI 基础教程 (八)- PCD 简单使用

一、 编写源代码
  1. 编写UEFI Application
    代码C:\edkii\OvmfPkg\MyHelloWorldPCD\MyHelloWorldPCD.c,
EFI_STATUS
EFIAPI
MyHelloWorldPCDEntry(
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
)
{ 
  EFI_STATUS  Status = EFI_SUCCESS;
  UINT32  PrintTimes ;
  UINT32  i ;
  CONST CHAR16 *PrintStr; 
  // DEBUG ((EFI_D_ERROR , "[MyHelloWorldPCD] MyHelloWorldPCDEntry Start..\n"));
  Print(L"[MyHelloWorldPCD] MyHelloWorldPCDEntry Start..\n");
  
  if (!FeaturePcdGet(PcdMyHelloWorldPrintEnable)){
    Print (L"[MyHelloWorldPCD] PcdMyHelloWorldPrintEnable ..\n");
    
    PrintTimes = PcdGet32(PcdMyHelloWorldPrintTimes);
    for (i = 0; i < PrintTimes; i++){
        PrintStr = PcdGetPtr(PcdMyHelloWorldPrintString);
        Print (L"[MyHelloWorldPCD]  Pcd  Str = %s\n",PrintStr);
    }
  }
  
  // DEBUG ((EFI_D_ERROR , "[MyHelloWorldPCD] MyHelloWorldPCDEntry End..\n"));
  Print(L"[MyHelloWorldPCD] MyHelloWorldPCDEntry End..\n");
 
  return Status;
}

  1. 修改 C:\code\local_edkrepo_10nm\Edk2\OvmfPkg\MyHelloWorldPCD\MyHelloWorldPCD.inf
#use to operate bool value
[FeaturePcd]
  gEfiMdeModulePkgTokenSpaceGuid.PcdMyHelloWorldPrintEnable  ## CONSUMES

[Pcd]
  gEfiMdeModulePkgTokenSpaceGuid.PcdMyHelloWorldPrintString  ## CONSUMES
  gEfiMdeModulePkgTokenSpaceGuid.PcdMyHelloWorldPrintTimes    ## SOMETIMES_CONSUMES
  1. 修改 C:\code\local_edkrepo_10nm\Edk2\MdeModulePkg\MdeModulePkg.dec
...
 [PcdsFeatureFlag]
  gEfiMdeModulePkgTokenSpaceGuid.PcdMyHelloWorldPrintEnable|FALSE|BOOLEAN|0x0001200d
  
 [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
  # @Prompt HellowWorld print times.
  gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes|1|UINT32|0x40000005

  # @Prompt HelloWorld print string.
  gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
  ...
二、 编译生成EFI文件

运行edksetup.bat编译整个OvmfPkg Package

三、 运行 UEFI APP MyHelloWorldPCD.efi
  1. 拷贝 C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\FV\OVMF.fdC:\qemu;拷贝C:\edkii\Build\OvmfX64\DEBUG_VS2013x86\X64\OvmfPkg\MyHelloWorldPCD\MyHelloWorldPCD\OUTPUT\MyHelloWorldPCD.efi 到 虚拟盘HDD_BOOT.img
  2. 执行setup-qemu-x64.bat| findstr MyHelloWorldPCD , 然后在UEFI SHELL 中执行 MyHelloWorldPCD.efi,结果如下,
    在这里插入图片描述
四、 小结

PCD(Platform Config DataBase)块用于定义平台配置数据。它的目的是在不改动.inf文件的情况下完成对平台的配置。PCD类别分为两大类:
1)在编译过程中起作用,这类PCD类似C语言中的全局静态变量,但是其值不能修改,包含PcdsFeatureFlagPcdsFixedAtBuild 以及 PatchableInModule;其中FeatureFlag 类型PCD只能定义为Bool值,FixedAtBuild可以支持多种数据类型UINIT32UINT8VOID* 等,PcdsPatchableInModule类型PCD在编译阶段可以被GenPatchPcdTable修改其值,并且在运行时也可以改变其值(PatchableInModule 本质上就讲PCD存放在EFI module的data 段 )。

2)在运行过程中起作用,这类PCD包括PcdsDynamicDefaultPcdsDynamicExDefaultPcdsDynamicHiiPcdsDynamicExHiiPcdsDynamicVpdPcdsDynamicExVpdPcdsDynamic PcdsDynamicEx
其中, PcdsDynamicDefault
PcdsDynamicExDefault
在Runtime阶段可以被改变, 但是当内存掉电后change值将会丢失,格式如下:

[PcdsDynamic]
gEfiCpuTokenSpaceGuid.PcdCpuProcessorFeatureCapability|0|UNIT32|0x4000002

该PCD值为0, 类型为UNIT32,token number为0x4000002。

PcdsDynamicHiiPcdsDynamicExHii将用来定义缺省的Variable,当某个EFI Variable未定义时,一个心的non-volatile Variable将会被创建,并且default值将会被设置,格式如下:

[ PcdsDynamicHii.common.DEFAULT]  
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEEfiGlobalVariableGuid|0x0 | 5

例子中,Hii Variable name被设置为"TimeOut",Variable Guid设定为gEEfiGlobalVariableGuid, Variable Offset设定为0, 缺省值设定为5(PcdsDynamicHii 最终会调用Variable service)。

PcdsDynamicVpdPcdsDynamicExVpd修饰的PCD变量将会存放在VPD数据库中(位于在Flash上),对PCD的操作将直接映射到Flash上的VPD 区域, 其格式如下:

[PcdsDynamicVpd.common.DEFAULT]
gEfiE6xxTokenSpaceGuid.PcdIgdPreAllocSize | 4 | 0x2

例子中, Pcd VpdOffset为4,初始值为2(VPD类型PCD不能使用PCD Set 接口)。
PcdsDynamic PcdsDynamicEx与PcdsDynamicDefault与PcdsDynamicExDefault类似,如果一个PCD module集成到PlatformBuild中,PcdsDynamic PcdsDynamicEx与PcdsDynamicDefault等价,即源代码中调用为PcdGetxx(PcdSampleDynamicPcd); 如果该module以独立的binary 发布,则要使用PcdsDynamicEx,即源代码中调用为PcdGetxx(gEfiMyTokenSpaceGuid, PcdSampleDynamicPcd)

本文程序主要对静态PCD的使用做了简单实现,在MdeModulePkg.dec文件中定义PcdMyHelloWorldPrintEnable、PcdHelloWorldPrintTimes、PcdHelloWorldPrintString,在MyHelloWorldPCD.inf文件中对PCD进行引用,最后在MyHelloWorldPCD.c使用PcdGetXX函数获取PCD的默认值并简单处理。

PCD DEMO源码

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值