【UEFI实战】如何在OS下获取UEFI变量
说明
UEFI变量在BIOS启动过程中创建。
它们有不同的类型,可以直接看属性:
///
/// Attributes of variable.
///
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
并不是所有的变量都可以在OS下获取到,比如EFI_VARIABLE_BOOTSERVICE_ACCESS类型的变量当在UEFI下调用了ExitBootServices()之后就不能再使用了。
在《UEFI Spec》中有如下的章节:"Globally Defined Variables",它介绍了UEFI下定义的变量,它们都包含了EFI_VARIABLE_RUNTIME_ACCESS这个属性,因此可以在OS下访问到。
各个变量的使用方式见《UEFI Spec》。
Windows下访问UEFI变量
MSDN中有介绍UEFI变量访问的接口,主要是如下几个:
GetFirmwareEnvironmentVariable
GetFirmwareEnvironmentVariableEx
SetFirmwareEnvironmentVariable
SetFirmwareEnvironmentVariableEx
下面是一个示例:
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include "stdio.h"#define EFI_GLOBAL_VARIABLE "{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}"
#define ConOut "ConOut"
#define MAX_SIZE 200BOOL AdjustToken();int _tmain (int argc, _TCHAR* argv[])
{DWORD dwRet;PVOID pBuffer;DWORD nSize;DWORD index;dwRet = ERROR_SUCCESS;nSize = MAX_SIZE;pBuffer = malloc (nSize);AdjustToken ();//// 首先使用空(Dummy)的变量,来确定是否是在Legacy BIOS上安装的Windows;//dwRet = GetFirmwareEnvironmentVariable (_T (""),_T ("{00000000-0000-0000-0000-000000000000}"),pBuffer,nSize);if (0 == dwRet){//// 返回值是变量的大小,0表示的是没有获取到;//if (GetLastError () == ERROR_INVALID_FUNCTION){//// 如果Windows是装在Legacy BIOS上,返回值是ERROR_INVALID_FUNCTION;//printf ("Windows was installed using legacy BIOS.\n");}else{//// 如果返回998(ERROR_NOACCESS)表示没有这个GUID的变量,这也是正常的,因为访问的是空的变量;//printf ("ErrCode = %ld.\n", GetLastError ());printf ("Windows was installed using UEFI BIOS.\n");dwRet = GetFirmwareEnvironmentVariable (_T (ConOut),_T (EFI_GLOBAL_VARIABLE),pBuffer,100);if (0 == dwRet){printf ("ErrCode = %ld.\n", GetLastError ());}else{printf ("Variable size: %d.\n", dwRet);for (index = 0; index < dwRet; index++){printf ("%02x ", *((BYTE *)pBuffer + index));}printf("\n");}}}free (pBuffer);return ERROR_SUCCESS;
}
这里有几点说明:
1. 上述代码在VS2107 commnity上编译和使用,系统环境是Windows10,运行结果如下:
2. 需要在Administrator打开命令行并运行,这里是一个权限的问题;
3. 这里还需要一个函数AdjustToken(),也是用来处理权限的,代码来自下面的网址:
GetFirmwareEnvironmentVariable失败返回错误码1314_youyudexiaowangzi的专栏-CSDN博客
Linux下访问UEFI变量
要了解Linux下如何获取变量,可以从efibootmgr这个命令开始,下面是一个例子:
efibootmgr命令用来调整UEFI启动顺序,它就是通过操作UEFI变量来完成的。
efibootmgr的源代码可以在GitHub - rhboot/efibootmgr: efibootmgr development tree下载到。
查看源代码就会注意到里面操作变量的接口,下面是efibootmgr中读取启动项顺序的函数:
static int
read_order(const char *name, var_entry_t **order)
{int rc;var_entry_t *new = NULL, *bo = NULL;if (*order == NULL) {new = calloc(1, sizeof (**order));if (!new) {efi_error("calloc(1, %zd) failed",sizeof (**order));return -1;}*order = bo = new;} else {bo = *order;}rc = efi_get_variable(EFI_GLOBAL_GUID, name,&bo->data, &bo->data_size, &bo->attributes);if (rc < 0 && new != NULL) {efi_error("efi_get_variable failed");free(new);*order = NULL;bo = NULL;}if (bo) {/* latest apple firmware sets high bit which appears invalid* to the linux kernel if we write it back so lets zero it out* if it is set since it would be invalid to set it anyway */bo->attributes = bo->attributes & ~(1 << 31);}return rc;
}
里面可以看到读取UEFI变量的接口:efi_get_variable。
它的声明在头文件<efivar.h>中,而它的实现也可以在Github上找到:
GitHub - rhboot/efivar: Tools and libraries to work with EFI variables
具体的实现和例子就不用多说了,主要还是要看代码。
【UEFI实战】如何在OS下获取UEFI变量相关推荐
- 如何在firefox下获取下列框选中option的text
Firefox下面没有innerText,所以我们想在firefox下获取下列框选中option的text(注意不是value)时会比较吃力.笔者结合自己在项目中的解决方案和代码总结一下,请大家指教. ...
- python os.environ windows_python 获取系统环境变量 os.environ and os.putenv
从一段code说起 "if "BATCH_CONFIG_INI" in os.environ:" 判断环境变量的值有没有定义 如果定义的话就去环境变量的值,否则 ...
- 【UEFI实战】OS下如何查看系统相关信息
说明 本文主要介绍OS下如何来查看系统信息,这些系统信息大多是通过BIOS上传的.这里的OS主要分为Linux和Windows两个部分来说明,前者使用的发行版系统是Ubuntu18.04,后者使用的是 ...
- 【UEFI实战】EDK的编译流程说明
前言 使用EDK进行UEFI开发,开始的时候很容易遇到的问题就是编译不过,并非代码的问题,而是编译环境存在异常. 本文主要介绍EDK是如何进行编译的,使用的平台是Windows.这里还想说一点,事实上 ...
- 【UEFI实战】Redfish的BIOS实现1
Redfish的BIOS实现 EDK2提供了Redfish框架,用来实现带外的BIOS配置,其基本框架如下: 通过RedfishPkg中提供的Driver,可以实现BIOS与BMC或者其它的软件进行通 ...
- 【UEFI实战】UART的初始化
说明 UART全称是Universal Asynchronous Receiver/Transmitter,这里它表示的是一种实现串口通信的芯片,在整个串口系统中它的位置如下图所示: RS232 +- ...
- 【UEFI实战】Secure Boot
说明 Secure Boot,顾名思义就是用来保证启动安全的一套措施. Secure Boot是一个比较普通的说法,使用的场景也很多,所以这里要特别说明一下,这里指的是UEFI BIOS下的,用来启动 ...
- 如何获取UEFI开源资源?
1.认识TianoCore 2004 年 6 月,英特尔宣布将在开源许可下发布其可扩展固件接口 (EFI) 的"基础代码",这是 16 位 x86"传统"PC ...
- 【UEFI实战】LinuxBoot
综述 LinuxBoot是一个开源的固件,用来替代UEFI BIOS加载Linux的系统. 官网是LinuxBoot. 对应的代码库位于LinuxBoot · GitHub. 另外,本文是在[UEFI ...
最新文章
- 异步化,高并发大杀器
- C++类的使用(五)—— 多态
- 戴尔新鲜空气制冷的研究:在数据中心里面,让我们脱掉厚夹克换上一件夏威夷衬衫!...
- 4-5:TCP协议之连接管理机制(三次握手、四次挥手详解)
- Flink的累加器(Accumulator)应用
- fragment的懒加载
- 后 5G 时代,路在何方?
- C++使函数返回多个数组
- 如何在NEO区块链上实现信息加密
- 验证码的旋转与放缩代码
- 用文本文档写的代码怎么运行?
- Stata+R: 一文读懂中介效应分析
- python中del的用法
- 你需要的iPhoneX适配
- 谷歌创始人拉里·佩奇不为人知的故事
- 世界观、价值观和人生观三者之间的关系
- C# 图形处理-缩略图,图片合并,图片写文字,图片调整
- [转]Sqlite中文排序研究
- 【C#懒蛋编程——5分钟经验分享】02使用partial关键字,分离代码
- 25张漂亮的微距摄影作品欣赏