UEFI——Shell下读取SMBIOS信息

2024-09-06 08:04
文章标签 读取 shell 信息 uefi smbios

本文主要是介绍UEFI——Shell下读取SMBIOS信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、SMBIOS简介

SMBIOS的全称为System Management BIOS,它不是一个BIOS,只是与BIOS相关。它是一个规范,定义了BIOS传递给操作系统的系统管理信息。它也表示了一系列的数据结构,包含了各类信息,由BIOS启动过程中创建并放在特定的内存,之后操作系统可以拿来用。

整个 SMBIOS_STRUCTURE 结构体定义了 SMBIOS 表中的一个基本单元。每个 SMBIOS 结构都包含一个类型、长度和句柄,后面跟着与该类型相关的特定数据。这些结构体被组织成一个链表,可以在系统启动时由系统固件、操作系统或管理工具读取,以获取系统的硬件配置和管理信息。

typedef struct {SMBIOS_TYPE      Type;UINT8            Length;SMBIOS_HANDLE    Handle;
} SMBIOS_STRUCTURE;

二、Shell下读取SMBIOS信息

首先介绍结构体_EFI_SMBIOS_PROTOCOL,用于定义在EFI应用程序和驱动程序中管理SMBIOS表的接口。其代码原型为:

struct _EFI_SMBIOS_PROTOCOL {EFI_SMBIOS_ADD              Add; //添加SMBIOS记录EFI_SMBIOS_UPDATE_STRING    UpdateString;EFI_SMBIOS_REMOVE           Remove;EFI_SMBIOS_GET_NEXT         GetNext;UINT8                       MajorVersion; ///< The major revision of the SMBIOS specification supported.UINT8                       MinorVersion; ///< The minor revision of the SMBIOS specification supported.
};

其中添加SMBIOS记录的为EFI_SMBIOS_ADD,

typedef
EFI_STATUS
(EFIAPI *EFI_SMBIOS_ADD)(IN CONST      EFI_SMBIOS_PROTOCOL     *This, //手动添加的This指针,始终指向当前的EFI_SMBIOS_PROTOCOL实例IN            EFI_HANDLE              ProducerHandle OPTIONAL, //与 SMBIOS 信息关联的控制器或驱动程序的句柄。NULL 表示没有句柄。IN OUT        EFI_SMBIOS_HANDLE       *SmbiosHandle, //输出参数,要添加的 SMBIOS 记录的句柄。如果为 FFFEh,则将为 SMBIOS 记录分配唯一句柄。如果 SMBIOS 句柄已在使用中,则会返回 EFI_ALREADY_STARTED,并且不会更新 SMBIOS 记录。IN            EFI_SMBIOS_TABLE_HEADER *Record //SMBIOS记录的固定部分的数据);

更新SMBIOS信息字符串用EFI_SMBIOS_UPDATE_STRING

typedef
EFI_STATUS
(EFIAPI *EFI_SMBIOS_UPDATE_STRING)(IN CONST EFI_SMBIOS_PROTOCOL *This, //EFI_SMBIOS_PROTOCOL实例IN       EFI_SMBIOS_HANDLE   *SmbiosHandle, //要更新字符串的SMBIOS句柄IN       UINTN               *StringNumber, //要更新的字符串IN       CHAR8               *String //用于更新的字符串);

删除SMBIOS记录用EFI_SMBIOS_REMOVE

typedef
EFI_STATUS
(EFIAPI *EFI_SMBIOS_REMOVE)(IN CONST EFI_SMBIOS_PROTOCOL *This,IN       EFI_SMBIOS_HANDLE   SmbiosHandle //要删除的SMBIOS记录的句柄);

允许调用者查找全部或部分SMBIOS记录用EFI_SMBIOS_GET_NEXT

typedef
EFI_STATUS
(EFIAPI *EFI_SMBIOS_GET_NEXT)(IN     CONST EFI_SMBIOS_PROTOCOL     *This,IN OUT       EFI_SMBIOS_HANDLE       *SmbiosHandle, //进入时,指向 SMBIOS 记录的上一个句柄。退出时,指向下一个 SMBIOS 记录句柄。如果输入时为 FFFEh,则将返回第一个 SMBIOS 记录句柄。如果它在退出时返回 FFFEh,则没有更多的 SMBIOS 记录。IN           EFI_SMBIOS_TYPE         *Type              OPTIONAL, //进入时,它指向要返回的下一条 SMBIOS 记录的类型。如果为 NULL,则表示将返回任何类型的下一条记录。此函数不会修改 Type。OUT          EFI_SMBIOS_TABLE_HEADER **Record, //输出参数,退出时,指向指向 SMBIOS 记录的指针,该记录由格式化区域和未格式化区域组成。未格式化区域(可选)包含文本字符串。OUT          EFI_HANDLE              *ProducerHandle    OPTIONAL //输出参数,带有 SmbiosHandle 的 SMBIOS 记录是最后一条可用记录。);

 在使用SMBIOSProtocol的时候,首先通过LocateProtocol找到实例

  Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, //gEfiSmbiosProtocolGuid是一个全局变量,用于唯一标识EFI_SMBIOS_PROTOCOLNULL,(VOID**)&Smbios //输出参数,指向找到的EFI_SMBIOS_PROCOTOL实例);

宏定义SMBIOS_HANDLE_PI_RESERVED设定了一个特定的值0xFFFE,这个值在SMBIOS协议中被保留用于特定的目的,SMBIOS_HANDLE通常是一个唯一标识符,用在SMBIOS表中引起特定的SMBIOS结构

//根据SMBIOS 2.7版本的6.1.2章节,以及UEFI平台初始化规范,宏定义SMBIOS_HANDLE_PI_RESERVED 设置为 0xFFFE,当 EFI_SMBIOS_PROTOCOL.Add() 函数的 Handle 参数被设置为 0xFFFE 时,它指示固件自动分配一个未被使用的句柄号给新的 SMBIOS 结构。这意味着调用者不需要指定具体的句柄号,而是由固件来选择一个合适的、未被占用的句柄号。
//0xFFFE这个值不会被用作任何其他目的,它专门用作自动分配句柄号
#define SMBIOS_HANDLE_PI_RESERVED  0xFFFE

 完整代码如下:

#include <uefi.h> 
#include <Library/UefiLib.h> 
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/Smbios.h>EFI_STATUS
EFIAPI
MyHelloWorldSmbiosAppEntry(IN EFI_HANDLE        ImageHandle,IN EFI_SYSTEM_TABLE  *SystemTable
)
{ EFI_STATUS  Status = EFI_SUCCESS;EFI_SMBIOS_PROTOCOL           *Smbios;EFI_SMBIOS_HANDLE             SmbiosHandle;EFI_SMBIOS_TABLE_HEADER       *Record;DEBUG ((EFI_D_ERROR , "[MyHelloWorldSmbios] MyHelloWorldSmbiosAppEntry Start..\n"));//// Find the SMBIOS protocol//Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid,NULL,(VOID**)&Smbios);if (EFI_ERROR (Status)) { //需要注意的是EFI_SUCCESS通常被定义为0,即成功为0,不成功为非0return Status;}SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);while (!EFI_ERROR(Status)) {DEBUG ((EFI_D_ERROR, "[MyHelloWorldSmbios] %d ..\n", Record->Type));// if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {// Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;// StrIndex = Type0Record->BiosVersion;// GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);// FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);// if (*FirmwareVersionString != 0x0000 ) {// FreePool (NewString);// NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);// UiCustomizeFrontPageBanner (3, TRUE, &NewString);// HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);// } else {// UiCustomizeFrontPageBanner (3, TRUE, &NewString);// HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);// FreePool (NewString);// }// }Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);}DEBUG ((EFI_D_ERROR, "[MyHelloWorldSmbios] MyHelloWorldSmbiosAppEntry End..\n"));return Status;
}

这篇关于UEFI——Shell下读取SMBIOS信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141457

相关文章

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

使用Python检查CPU型号并弹出警告信息

《使用Python检查CPU型号并弹出警告信息》本教程将指导你如何编写一个Python程序,该程序能够在启动时检查计算机的CPU型号,如果检测到CPU型号包含“I3”,则会弹出一个警告窗口,感兴趣的小... 目录教程目标方法一所需库步骤一:安装所需库步骤二:编写python程序步骤三:运行程序注意事项方法二

PostgreSQL如何查询表结构和索引信息

《PostgreSQL如何查询表结构和索引信息》文章介绍了在PostgreSQL中查询表结构和索引信息的几种方法,包括使用`d`元命令、系统数据字典查询以及使用可视化工具DBeaver... 目录前言使用\d元命令查看表字段信息和索引信息通过系统数据字典查询表结构通过系统数据字典查询索引信息查询所有的表名可

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Linux命令(11):系统信息查看命令

系统 # uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo # 查看CPU信息# hostname # 查看计算机名# lspci -tv # 列出所有PCI设备# lsusb -tv

【小迪安全笔记 V2022 】信息打点9~11

第9天 信息打点-CDN绕过篇&漏洞回链8接口探针&全网扫指&反向件 知识点: 0、CDN知识-工作原理及阻碍 1、CDN配置-域名&区域&类型 2、CDN绕过-靠谱十余种技战法 3、CDN绑定-HOSTS绑定指向访问 CDN 是构建在数据网络上的一种分布式的内容分发网。 CDN的作用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避