UEFI——PCD的简单使用

news2024/11/13 14:37:51

一、PCD的定义及概念

在UEFI固件接口中,PCD(Platform Configuration Database)是一个用于存储和访问平台特定配置信息的机制。PCD允许UEFI驱动程序和应用程序在运行时获取和设置平台相关的参数,而无需硬编码这些值。PCD变量可以被动态的读取和修改。(类似于C语言中的宏而区别于宏)

PCD的种类可以分为两大类:

(1)在编译过程中起作用,包含PcdsFeatureFlag , PcdsFixedAtBuild 以及 PatchableInModule;其中FeatureFlag 类型PCD只能定义为Bool值,FixedAtBuild可以支持多种数据类型UINIT32、UINT8、VOID* 等,PcdsPatchableInModule类型PCD在编译阶段可以被GenPatchPcdTable修改其值,并且在运行时也可以改变其值(PatchableInModule 本质上就讲PCD存放在EFI module的data 段 )。

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

不同类型的PCD在文件中对应的块名称不同,使用多种类型的PCD要分别在INF文件中对应的块中引用。

 如果一个PCD被声明多种类型且在INF文件中引用时都放 [Pcd] 块中,编译工具会根据优先级决定PCD的类型:PcdsFixedAtBuild > PcdsPatchableInModule > PcdsDynamicDefault >

【PCD与宏的区别】

 PCD用于存储和访问平台特定的配置信息。这些配置信息可以在固件映像构建时设置,也可以在固件运行时动态地读取和修改。PCD变量用于控制固件的行为,如硬件设置、性能选项、调试级别等。宏定义用于在编译时替换代码中的文本。宏定义通常用于代码重用、代码简化、避免重复代码编写等,一旦定义是不可变的。

二、PCD的简单使用

 1、编写MyHelloWorldPCD.c

FeaturePcdGet宏是一个获取FeaturePcd变量的值的宏定义,使用了预处理器宏_PCD_GET_MODE_BOOL_,它将TokenName替换为FeaturePcd变量的Token Space和名称,其代码原型为:

/**
  Retrieves a Boolean PCD feature flag based on a token name.
  根据token名称检索布尔PCD特征标识

  Returns the Boolean value for the PCD feature flag specified by TokenName.
  If TokenName is not a valid token in the token space, then the module will not build.
  If TokenName is not a feature flag PCD, then the module will not build.

  @param   TokenName  The name of the PCD token to retrieve a current value for.

  @return  Boolean value for the PCD feature flag.

**/
#define FeaturePcdGet(TokenName)  _PCD_GET_MODE_BOOL_##TokenName

利用PcdGet32(TokenName)获取32位PCD值,代码原型为

/**
  Retrieves a 32-bit PCD token value based on a token name.
  根据Token名称检索一个32位的PCD token值

  Returns the 32-bit value for the token specified by TokenName.
  If TokenName is not a valid token in the token space, then the module will not build.

  @param   TokenName  The name of the PCD token to retrieve a current value for.

  @return  32-bit value for the token specified by TokenName.

**/

PcdGetPtr(TokenName)检索指向PCD token缓冲区的指针,代码原型为:

/**
  Retrieves a pointer to a PCD token buffer based on a token name.
  根据token名称检索PCD token缓冲区的指针

  Returns a pointer to the buffer for the token specified by TokenName.
  If TokenName is not a valid token in the token space, then the module will not build.

  @param   TokenName  The name of the PCD token to retrieve a current value for.

  @return  A pointer to the buffer. //返回一个指向缓冲区的指针

**/
#define PcdGetPtr(TokenName)  _PCD_GET_MODE_PTR_##TokenName

完整代码为:

#include <uefi.h> 
#include <Library/UefiLib.h> 
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PcdLib.h>

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)){ //PcdMyHelloWorldPrintEnable是一个token 名称,返回一个Boolean值
	Print (L"[MyHelloWorldPCD] PcdHelloWorldPrintEnable ..\n");
	
	PrintTimes = PcdGet32(PcdMyHelloWorldPrintTimes);
	for (i = 0; i < PrintTimes; i++){
		PrintStr = PcdGetPtr(PcdHelloWorldPrintString);
	    Print (L"[MyHelloWorldPCD]  Pcd  Str = %s\n",PrintStr);
	}
  }
  
  // DEBUG ((EFI_D_ERROR , "[MyHelloWorldPCD] MyHelloWorldPCDEntry End..\n"));
  Print(L"[MyHelloWorldPCD] MyHelloWorldPCDEntry End..\n");
 
  return Status;
}

 使用PCD要在INF文件中引用

#use to operate bool value
[FeaturePcd]
  gEfiMdeModulePkgTokenSpaceGuid.PcdMyHelloWorldPrintEnable  ## CONSUMES

[Pcd]
  gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString  ## CONSUMES
  gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes    ## SOMETIMES_CONSUMES

使用PCD要在DEC文件中声明

...
 [PcdsFeatureFlag]
  gEfiMdeModulePkgTokenSpaceGuid.PcdMyHelloWorldPrintEnable|FALSE|BOOLEAN|0x0001200d
  //PcdMyHelloWorldPrintEnable是PCD变量的名称;FALSE是PCD变量的默认值;BOOLEAN是PCD变量的数据类型;0x0001200d是PCD token的值,用于在PCD数据库中表示和引用特定的PCD变量。

 [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
  # @Prompt HellowWorld print times.
  gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes|3|UINT32|0x40000005

  # @Prompt HelloWorld print string.
  gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString|L"UEFI Hello World!\n"|VOID*|0x40000004
  ...

在DSC文件中修改(如果没有修改会使用DEC中默认的PCD值)

[...Pcd...]

PcdTokenSpaceGuidName.PcdTokenName | Value [ | DatumType[ |MaximumDatumSize ] ]

运行代码生成EFI文件,并将efi文件拷贝到虚拟盘HDD_BOOT.img中运行,运行结果如下:

参考文章

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

PCD配置和使用 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2098297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计推荐-基于Java的网上电子图书管理系统【Java-python-大数据定制】

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; 实战项目 文章目录 实战项目 一、基于Java的网上电子图书管理…

魏牌蓝山智驾版,长城的智能化「大反攻」

‍作者 |老缅 编辑 |德新 8月下旬&#xff0c;魏牌全新蓝山上市&#xff0c;定位「长城首款NOA智能六座旗舰SUV」。 新车分智驾Max和智驾Ultra两个版本&#xff0c;售价分别为29.98万元和32.68万元。 魏建军为蓝山的上市&#xff0c;时隔6年再度回到了发布会的舞台&#xff…

时序预测基础模型又中顶会!真心建议各位往这个方向发论文

时序领域又有新突破啦&#xff01;谷歌最新提出TimesFM&#xff0c;仅需200M参数&#xff0c;零样本预测性能超越有监督&#xff01;成功入选ICML 2024&#xff01; TimesFM是一种全新的时间序列通用基础模型&#xff0c;这类模型相比传统时序模型&#xff0c;拥有整合和利用广…

HDLC 和 PPP 原理与配置

HDLC简介 HDLC协议是一种通用的协议&#xff0c;工作在OSI参考模型的数据链路层。数据报文加上头开销和尾开销后封装成HDLC帧。 HDLC具有以下特点&#xff1a; •HDLC协议只支持点到点链路&#xff0c;不支持点到多点。 •HDLC协议不支持IP地址协商&#xff0c;不支持认证。 •…

【数据结构-二维前缀和】【列维护优化】力扣3212. 统计 X 和 Y 频数相等的子矩阵数量

给你一个二维字符矩阵 grid&#xff0c;其中 grid[i][j] 可能是 ‘X’、‘Y’ 或 ‘.’&#xff0c;返回满足以下条件的 子矩阵 数量&#xff1a; 包含 grid[0][0] ‘X’ 和 ‘Y’ 的频数相等。 至少包含一个 ‘X’。 示例 1&#xff1a; 输入&#xff1a; grid [[“X”,“…

用相图分析 bbr,inflight 守恒的收敛速度

以下的代码绘制了 bbr 的收敛相图&#xff1a; #!/opt/homebrew/bin/python3import numpy as np import matplotlib.pyplot as plt from scipy.integrate import odeintdef model(vars, t, C, g):x, y varsdxdt C * (g * x) / (g * x y) - xdydt C * (g * y) / (g * y x)…

读懂以太坊源码(1)-目录结构说明

要了解一个软件工程项目的代码&#xff0c;必须从代码的目录结构入手&#xff0c;从而大致了解软件实现的功能模块&#xff0c;使用了哪些相关的技术&#xff0c;大概的框架是怎么样的&#xff1f; 源码网址&#xff1a;https://github.com/ethereum/go-ethereum 以下是以太坊…

如何提升网站在Google的排名?

事实上&#xff0c;常规提升排名的方法无非就那么几种&#xff0c;关键词优化&#xff0c;高质量内容&#xff0c;网站结构优化&#xff0c;外链&#xff0c;确保网站没问题&#xff0c;这些都是常规的提升排名的方法&#xff0c;只能说没什么特别的&#xff0c;而除了这些常规…

流量焦虑?随身WiFi来救场!2024好的随身WiFi怎么挑,看这一篇文章就够了!包教会你识别随身WiFi哪个好!

相信大家买随身WiFi肯定是想要网速快&#xff0c;并且多用几年&#xff0c;那么在全网铺天盖地的广告、水军、好评的情况下&#xff0c;随身WiFi的品质好坏&#xff0c;我们该如何辨别呢&#xff1f; 主要看三个指标就能轻松分别&#xff0c;记得先收藏再观看&#xff01;一篇…

HIS系统|HIS系统开发源码

在数字医疗时代&#xff0c;医院信息系统&#xff08;HIS&#xff09;的开发至关重要。本文将深入探讨在开发HIS系统时需要关注的主要事项&#xff0c;从系统架构到数据安全&#xff0c;为医疗机构提供实用的开发指南。 1、需求分析与系统规划 在开发HIS系统的初期&#xff0c…

rknntoolkitlite2环境搭建

目录 前言 0、要下载的软件包 一、环境搭建步骤 1.1 安装Miniconda 1.2创建RKNN虚拟环境 1.3 安装rknntoolkitlite2软件包 1.4 安装opencv 前言 RKNN Toolkit Lite2 工具支持运行在 RK3568: Debian10/Debian11&#xff08;aarch64&#xff09;、Ubuntu20/22&#xff08;…

【微信小程序】自定义 tabBar

一、自定义 tabBar 1、案例效果 首先来看一下页面演示效果&#xff0c;页面中有下方标签栏是自定义 tabBar。自定义 tabBar 可以让开发者更加灵活地设置 tabBar 样式&#xff0c;以满足更多个性化的场景。 在此案例中&#xff0c;用到的主要知识点如下&#xff1a; 自定义组…

Spring 事务传播和自调用行为

为了方便讲解&#xff0c;这里的A、B、C类都是Spring管理的Bean。 自调用行为 自调用行为示例 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component…

【Python报错已解决】“ModuleNotFoundError: No module named ‘torch_scatter‘”

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述1.1 报错示例&#xff1a;1.2 报错分析&#xff1a;1.3 解决思路&#xff1a; 二、解决…

【golang-入门】环境配置、VSCode开发环境配置

golang介绍基础信息 windows环境配置安装包下载安装环境变量设置检查 VSCode开发配置插件配置在 Visual Studio Code 中安装通义灵码go hello word 参考资料 golang介绍 基础信息 golang官网&#xff1a;https://go.dev/golang学习网&#xff1a;https://studygolang.com/使用…

本地服务器使用Docker搭建Nacos动态服务管理平台并实现远程访问

文章目录 前言1. Docker 运行Nacos2. 本地访问Nacos3. Linux安装Cpolar4. 配置Nacos UI界面公网地址5. 远程访问 Nacos UI界面6. 固定Nacos UI界面公网地址7. 固定地址访问Nacos 前言 本文主要介绍如何本地部署动态服务发现、配置管理和服务管理平台 Nacos &#xff0c;并结合…

WCDMA 辅同步信号S_SCH介绍,MATLAB实现

本期主要介绍一下WCDMA辅同步信号S_SCH实现和映射&#xff0c;从公式生成开始介绍&#xff0c;最后用MATLAB实现&#xff0c;让大家了解对比一下3G时代辅同步信号和前面介绍的4G、5G和2G时代的辅同步信号共同点和不同点&#xff0c;不管在什么时候辅同步信号都要遵循一个码要正…

【3.9】贪心算法-解最低加油次数

一、题目 汽车从起点出发驶向目的地&#xff0c;该目的地位于出发位置东面 target 英里处。 沿途有加油站&#xff0c;用数组 stations 表示。其中 stations[i] [positioni, fueli] 表示第 i 个加油站位于出发位置东面 positioni 英里处&#xff0c;并且有 fueli 升汽油。 假设…

bladeX默认审批流flowable如何设置

下面就是流程图必须得写 ${taskUser} 你要配什么 就给审批流的service传什么

自己动手写CPU_step6.1_算数运算指令

序 接上篇的加减指令&#xff0c;本篇主要实现CLZ、CLO、SLT等指令。 CLZ&#xff1a;从最高位开始数0的个数直到遇到1。 例&#xff1a;0x0000,0001 CLZ指令结果&#xff1a;31 0x8000,ffff CLZ指令结果是0 CLZ&#xff1a;从高位开始数1的个数直到遇到0…