一、Variable简介
Variable Services是Runtime Services的一部分,提供关于variable的一些服务,Variable被定义为键值对,由标识信息加上属性(键)和任意数据(值)组成。用在固件部内部和固件与操作系统之间传递信息。
变量的用途:
配置和数据存储:UEFI变量用于存储固件配置设置、系统状态、以及启动选项等信息。
操作系统启动:操作系统启动管理器使用UEFI来存储启动项
安全性:UEFI变量可用于存储安全相关的信息。如启动授权、平台密钥等。
UEFI规范为Variable Services定义了四个接口,如图所示
GetVariable接口的作用是返回一个指定Variable的值,其函数原型为:
/*
返回指定variable的值
每个供应商可以使用唯一的VendorGuid创建和管理自己的变量
*/
typedef
EFI_STATUS
(EFIAPI *EFI_GET_VARIABLE)(
IN CHAR16 *VariableName, //指向变量名称的指针,变量名称是一个以null字符结尾的Unicode字符串
IN EFI_GUID *VendorGuid, //指向供应商GUID的指针,这个GUID用于标识变量的供应商
OUT UINT32 *Attributes OPTIONAL, //输出参数,指向变量属性的指针,如果设置非空。函数将返回变量的属性。
IN OUT UINTN *DataSize, //输入,输出参数,指向变量数据大小的指针,用于指定输入的期望数据大小或输出的实际数据大小
OUT VOID *Data OPTIONAL //输出参数,指向变量数据的指针,如果设置非空,将返回变量的数据
);
SetVariable接口的作用是设置变量的值,这个接口可用于创建新的变量或修改现有变量的值,函数原型为
/*
设置变量的值
*/
typedef
EFI_STATUS
(EFIAPI *EFI_SET_VARIABLE)(
IN CHAR16 *VariableName, //输入参数,指向变量名称的指针
IN EFI_GUID *VendorGuid, //输入参数,变量供应商的GUID
IN UINT32 Attributes, //输入参数,变量的属性
IN UINTN DataSize, //输入参数,期望输入数据的大小,即数据缓冲区的大小(字节数)
IN VOID *Data //输入参数,变量的值
);
其中变量的属性有三种
/// Attributes of variable.
///
#define EFI_VARIABLE_NON_VOLATILE 0x00000001 //非易失性,设置变量后,变量在系统重启后仍保持其值。
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 //启动服务访问,变量可以在UEFI引导服务启动时被访问
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 //运行时访问,变量可以在UEFI运行时服务启动时被访问
变量的属性可以通过 | 来组合 ,例如
UINT32 Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
将创建一个非易失性变量,在UEFI引导服务启动时访问。
GetNextVariableName接口的作用是枚举当前变量名,其函数原型为
typedef
EFI_STATUS
(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(
IN OUT UINTN *VariableNameSize, //输入、输出参数,变量名缓冲区的大小
IN OUT CHAR16 *VariableName, //输入,输出参数,变量名称
IN OUT EFI_GUID *VendorGuid //输入,输出参数,变量供应商的GUID
);
二、Variable的简单使用
编写源代码:
#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/UefiRuntimeServicesTableLib.h>
#include <Library/PcdLib.h>
//ShellCEntryLib call user interface ShellAppMain
EFI_STATUS
EFIAPI
MyHVariableAppEntry(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINTN DataSize;
UINT64 CSDNEnable = 1;
EFI_GUID gEfiCsdnEnableGuid = { 0xb71604d2, 0xb8ba, 0x4d9c, { 0x78, 0x88, 0xac, 0xcf, 0x1d, 0xa2, 0x26, 0xc3 }};
DataSize = sizeof (CSDNEnable);
Status = gRT->SetVariable (
L"CSDNEnable",
&gEfiCsdnEnableGuid,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS,
DataSize,
&CSDNEnable
);
ASSERT(Status);
DEBUG ((EFI_D_ERROR," [CSDN]: Setvariable CSDNEnable 0x%x.\n", CSDNEnable));
CSDNEnable = 0;
DataSize = sizeof (CSDNEnable);
Status = gRT->GetVariable (
L"CSDNEnable",
&gEfiCsdnEnableGuid,
NULL,
&DataSize,
&CSDNEnable
);
ASSERT(Status);
if (CSDNEnable) {
DEBUG ((EFI_D_ERROR, "[CSDN] CSDNEnable\n"));
}
return EFI_SUCCESS;
}
编写INF文件,运行并生成efi文件(在运行efi文件的时候卡住了,原因未知)