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

相关文章

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

利用Python实现添加或读取Excel公式

《利用Python实现添加或读取Excel公式》Excel公式是数据处理的核心工具,从简单的加减运算到复杂的逻辑判断,掌握基础语法是高效工作的起点,下面我们就来看看如何使用Python进行Excel公... 目录python Excel 库安装Python 在 Excel 中添加公式/函数Python 读取

Python如何获取域名的SSL证书信息和到期时间

《Python如何获取域名的SSL证书信息和到期时间》在当今互联网时代,SSL证书的重要性不言而喻,它不仅为用户提供了安全的连接,还能提高网站的搜索引擎排名,那我们怎么才能通过Python获取域名的S... 目录了解SSL证书的基本概念使用python库来抓取SSL证书信息安装必要的库编写获取SSL证书信息

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

shell脚本自动删除30天以前的文件(最新推荐)

《shell脚本自动删除30天以前的文件(最新推荐)》该文章介绍了如何使用Shell脚本自动删除指定目录下30天以前的文件,并通过crontab设置定时任务,此外,还提供了如何使用Shell脚本删除E... 目录shell脚本自动删除30天以前的文件linux按照日期定时删除elasticsearch索引s

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.