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

相关文章

业务中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的作用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避

Weex入门教程之4,获取当前全局环境变量和配置信息(屏幕高度、宽度等)

$getConfig() 获取当前全局环境变量和配置信息。 Returns: config (object): 配置对象;bundleUrl (string): bundle 的 url;debug (boolean): 是否是调试模式;env (object): 环境对象; weexVersion (string): Weex sdk 版本;appName (string): 应用名字;

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

下载/保存/读取 文件,并转成流输出

最近对文件的操作又熟悉了下;现在记载下来:学习在于 坚持!!!不以细小而不为。 实现的是:文件的下载、文件的保存到SD卡、文件的读取输出String 类型、最后是文件转换成流输出;一整套够用了; 重点: 1:   操作网络要记得开线程; 2:更新网络获取的数据 切记用Handler机制; 3:注意代码的可读性(这里面只是保存到SD卡,在项目中切记要对SD卡的有无做判断,然后再获取路径!)

ROS1 + Realsense d455 固件安装+读取rostopic数据

目录 安装固件(一定要匹配)ROS1 wrapper 安装方法Realsense SDK 安装方法Realsense Firmware 安装方法 修改roslaunch配置文件,打开双目图像和IMU数据其他坑点参考链接 安装固件(一定要匹配) 如果你是使用ROS1获取realsense数据的话,一定要注意,SDK, Firmware的版本不是越新越好!!,这是因为intel已经不