UEFI学习笔记(十一):SMBIOS的概述与访问

news/2024/10/16 19:22:42 标签: 学习, 笔记, uefi

UEFI学习笔记(十一):SMBIOS的概述与访问

    • 一、概述
      • 1、硬件信息获取:
      • 2、系统管理:
      • 3、与固件的交互:
    • 二、SMBIOS结构
    • 三、SMBIOS的访问
      • 1、获取 SMBIOS 入口点
      • 2、初始化和检查入口点
      • 3、访问 SMBIOS 结构表
      • 4、遍历 SMBIOS 结构
      • 5、解析每个结构
      • 6、输出信息
      • 7、错误处理

一、概述

SMBIOS(System Management BIOS)是一种在计算机系统中用于管理和获取硬件信息的标准接口。它提供了一种结构化的方式,通过 BIOS 来传递有关系统硬件的详细信息,包括处理器、内存、主板、以及其他组件的信息。SMBIOS 数据结构以表的形式存在,通常在系统启动时由 BIOS 提供,操作系统可以通过读取这些表来获取所需的信息。SMBIOS 主要用于以下目的:

1、硬件信息获取:

操作系统和应用程序可以通过 SMBIOS 查询硬件信息,以便更好地管理系统资源。

2、系统管理:

系统管理软件可以利用 SMBIOS 提供的信息进行资产管理、系统监控和故障排除。

3、与固件的交互:

SMBIOS 使得操作系统能够与固件进行有效的交互,获取系统硬件配置的相关信息。

二、SMBIOS结构

可以通过基于表结构访问 SMBIOS 。先找到 Entry Point Structure ( EPS )表,然后通过 Entry Point Structure ( EPS )表的数据找到 SMBIOS 结构表。以下是 EPS 表的结构:

typedef struct {
  UINT8   AnchorString[4];                //关键字 固定是”_SM_”
  UINT8   EntryPointStructureChecksum;    //校验和 	用于校验数据
  UINT8   EntryPointLength;               //表结构长度  Entry Point Structure 表的长度
  UINT8   MajorVersion;                   //Major版本号  用于判断SMBIOS 版本
  UINT8   MinorVersion;                   //Minor版本号  用于判断SMBIOS 版本
  UINT16  MaxStructureSize;               //表结构大小
  UINT8   EntryPointRevision;             //EPS修正
  UINT8   FormattedArea[5];               //格式区域    存放解释EPS修正的信息
  UINT8   IntermediateAnchorString[5];    //关键字      固定为“_DMI_”
  UINT8   IntermediateChecksum;           //校验和      Intermediate Entry Point Structure (IEPS)的校验和
  UINT16  TableLength;                    //结构表长度  SMBIOS 结构表的长度(总长度)
  UINT32  TableAddress;                   //结构表地址  SMBIOS 结构表的真实内存位置
  UINT16  NumberOfSmbiosStructures;       //结构表个数  SMBIOS 结构表数目
  UINT8   SmbiosBcdRevision;              //Smbios BCD 修正
} SMBIOS_TABLE_ENTRY_POINT;

主要用于描述 SMBIOS 的入口点。这个结构包含了有关 SMBIOS 数据表的信息,并为系统提供了访问这些信息的方式。可以通过TableAddress访问到SMBIOS的首地址,然后访问表结构信息:

typedef union {
  SMBIOS_STRUCTURE      *Hdr;
  SMBIOS_TABLE_TYPE0    *Type0;
  SMBIOS_TABLE_TYPE1    *Type1;
  SMBIOS_TABLE_TYPE2    *Type2;
  SMBIOS_TABLE_TYPE3    *Type3;
  SMBIOS_TABLE_TYPE4    *Type4;
  SMBIOS_TABLE_TYPE5    *Type5;
  SMBIOS_TABLE_TYPE6    *Type6;
  SMBIOS_TABLE_TYPE7    *Type7;
  SMBIOS_TABLE_TYPE8    *Type8;
  SMBIOS_TABLE_TYPE9    *Type9;
  SMBIOS_TABLE_TYPE10   *Type10;
  SMBIOS_TABLE_TYPE11   *Type11;
  SMBIOS_TABLE_TYPE12   *Type12;
  SMBIOS_TABLE_TYPE13   *Type13;
  SMBIOS_TABLE_TYPE14   *Type14;
  SMBIOS_TABLE_TYPE15   *Type15;
  SMBIOS_TABLE_TYPE16   *Type16;
  SMBIOS_TABLE_TYPE17   *Type17;
  SMBIOS_TABLE_TYPE18   *Type18;
  SMBIOS_TABLE_TYPE19   *Type19;
  SMBIOS_TABLE_TYPE20   *Type20;
  SMBIOS_TABLE_TYPE21   *Type21;
  SMBIOS_TABLE_TYPE22   *Type22;
  SMBIOS_TABLE_TYPE23   *Type23;
  SMBIOS_TABLE_TYPE24   *Type24;
  SMBIOS_TABLE_TYPE25   *Type25;
  SMBIOS_TABLE_TYPE26   *Type26;
  SMBIOS_TABLE_TYPE27   *Type27;
  SMBIOS_TABLE_TYPE28   *Type28;
  SMBIOS_TABLE_TYPE29   *Type29;
  SMBIOS_TABLE_TYPE30   *Type30;
  SMBIOS_TABLE_TYPE31   *Type31;
  SMBIOS_TABLE_TYPE32   *Type32;
  SMBIOS_TABLE_TYPE33   *Type33;
  SMBIOS_TABLE_TYPE34   *Type34;
  SMBIOS_TABLE_TYPE35   *Type35;
  SMBIOS_TABLE_TYPE36   *Type36;
  SMBIOS_TABLE_TYPE37   *Type37;
  SMBIOS_TABLE_TYPE38   *Type38;
  SMBIOS_TABLE_TYPE39   *Type39;
  SMBIOS_TABLE_TYPE40   *Type40;
  SMBIOS_TABLE_TYPE41   *Type41;
  SMBIOS_TABLE_TYPE42   *Type42;
  SMBIOS_TABLE_TYPE43   *Type43;
  SMBIOS_TABLE_TYPE126  *Type126;
  SMBIOS_TABLE_TYPE127  *Type127;
  UINT8                 *Raw;
} SMBIOS_STRUCTURE_POINTER;

在 SMBIOS(System Management BIOS)中,类型 0 到类型 127 表示不同的结构,每种结构都包含特定的硬件和系统信息。例如:
类型 0:
BIOS 信息。包含 BIOS 制造商、版本、发布日期等信息。

类型 1:
系统信息。包含系统制造商、产品名称、版本、序列号等信息。

///
/// BIOS Information (Type 0).
///
typedef struct {
  SMBIOS_STRUCTURE             Hdr;
  SMBIOS_TABLE_STRING          Vendor;
  SMBIOS_TABLE_STRING          BiosVersion;
  UINT16                       BiosSegment;
  SMBIOS_TABLE_STRING          BiosReleaseDate;
  UINT8                        BiosSize;
  MISC_BIOS_CHARACTERISTICS    BiosCharacteristics;
  UINT8                        BIOSCharacteristicsExtensionBytes[2];
  UINT8                        SystemBiosMajorRelease;
  UINT8                        SystemBiosMinorRelease;
  UINT8                        EmbeddedControllerFirmwareMajorRelease;
  UINT8                        EmbeddedControllerFirmwareMinorRelease;
  //
  // Add for smbios 3.1.0
  //
  EXTENDED_BIOS_ROM_SIZE       ExtendedBiosSize;
} SMBIOS_TABLE_TYPE0;

类型 2:
基本硬件信息。包含系统的硬件特性,如主板制造商、产品、版本等。

类型 3:
设备信息。包含设备的详细信息,如物理 ID 和设备类型。

类型 4:
内存信息。描述系统内存的详细信息,包括内存条的大小和速度。

第一个字段SMBIOS_STRUCTURE *Hdr可以访问到SMBIOS 中的一个结构头部

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

Type:
这个字段表示 SMBIOS 结构的类型。每种类型的结构都有特定的格式和信息。例如,类型 0 代表 BIOS 信息,类型 1 代表系统信息等。

Length:
该字段表示整个 SMBIOS 结构的长度(以字节为单位),包括头部和后续数据。

Handle:
这个字段是一个句柄,通常用来唯一标识该结构实例。它在同一类型的结构之间是唯一的,可以用于查找或引用。

三、SMBIOS的访问

在smbiosview源码中,Smbios数据的访问流程如下:

1、获取 SMBIOS 入口点

使用特定的内存地址或系统调用获取 SMBIOS 表的入口点(Entry Point Structure, EPS)。

  SMBIOS_TABLE_3_0_ENTRY_POINT  *SMBiosTable;
  SMBiosTable = NULL;
  LibSmbios64BitGetEPS (&SMBiosTable);

2、初始化和检查入口点

检查获取到的 EPS 是否有效,验证其 AnchorString 字段是否为 SM,确保表的版本和长度符合预期。

  if (CompareMem (SMBiosTable->AnchorString, SMBIOS_3_0_ANCHOR_STRING, SMBIOS_3_0_ANCHOR_STRING_LENGTH) == 0) {
  ...
  }

3、访问 SMBIOS 结构表

使用 EPS 中的 TableAddress 字段访问 SMBIOS 结构表,此地址指向存储 SMBIOS 结构的内存区域。

4、遍历 SMBIOS 结构

根据 EPS 中的 NumberOfStructures 字段确定要遍历的结构数量。
使用循环逐个访问 SMBIOS 结构,读取每个结构的 Type、Length 和 Handle 字段,根据 Type 字段识别结构类型,并根据需要解析结构的特定信息。

    for (Index = 0; Index < mNumberOfSmbios64BitStructures; Index++) {
      //
      // if reach the end of table, break..
      //
      if (Handle == INVALID_HANDLE) {
        break;
      }
      //
      // handle then point to the next!
      //
      if (LibGetSmbios64BitStructure (&Handle, &Buffer, &Length) != DMI_SUCCESS) {
        break;
      }
      ...
      ...
    }

5、解析每个结构

根据 SMBIOS 结构的类型(例如类型 0 到类型 127),解析每种结构的数据。对不同类型的结构提取相应的信息,如系统制造商、产品名称等。

SmbiosPrintStructure (&SmbiosStruct, gShowType);

6、输出信息

解析完毕后,将所有结构的相关信息输出到控制台或保存到文件中,供用户查看。

7、错误处理

在整个流程中,包含错误处理机制,以应对内存访问错误或无效数据等问题,确保程序不会因为未处理的异常而崩溃。


http://www.niftyadmin.cn/n/5708418.html

相关文章

IDEA如何用maven打包(界面和命令两种方式)

前言 我们在使用IDEA开发时&#xff0c;如果是springboot项目的话&#xff0c;一般是用maven来管理我们的依赖的。然后&#xff0c;当我们开发完成之后&#xff0c;就需要打包部署了。 那么&#xff0c;我们应该如何打包呢&#xff1f; 如何打包&#xff08;jar包&#xff09…

Linux防火墙与SElinux

文章目录 一、防火墙介绍二、iptables和firewalld的区别操作方式&#xff1a;配置层面&#xff1a;性能和管理&#xff1a; 三、iptables与firewalld的优缺点iptablesfirewalld 四、iptables的工作流程五、firewalld的工作流程六、iptables安装与使用6.1、关闭firewalld服务6.2…

C++—#pragam once

C—#pragama once #pragma once 是一个非标准的预处理指令&#xff0c;但它在许多现代编译器中都被广泛支持&#xff0c;包括GCC、Clang和MSVC&#xff08;Microsoft Visual C&#xff09;。这个指令的目的是防止头文件被多次包含&#xff08;include&#xff09;到同一个源文…

尚硅谷rabbitmq 2024 Federation配置 第60节答疑

rabbitmq联邦队列怎么做 要在 RabbitMQ 中设置联邦队列&#xff08;Federated Queues&#xff09;&#xff0c;你需要遵循以下步骤。联邦队列允许你在不同的 RabbitMQ 实例之间共享队列&#xff0c;从而实现消息的分布式处理和高可用性。 ### 步骤 1&#xff1a;安装 RabbitMQ…

Java避坑案例 - ConcurrentHashMap 的使用陷阱

文章目录 Pre概述场景问题复现现象 问题分析解决方案&#xff1a;加锁版本Fix效果 改进与更优方案&#xff1a;使用原子操作避免加锁使用 computeIfAbsent 等原子方法单线程执行填充操作 总结 Pre J.U.C Review - 并发容器集合解析 Java Review - 并发组件ConcurrentHashMap使…

java-重要知识01

1. 各个语言的擅长点 C&#xff1a;几乎其他语言的全部功能 速度快 C 速度快 JAVA 大型web开发&#xff0c;手机安卓 本来有桌面开发&#xff0c;后来被C#挖人 GO 大型web开发 C# 中小型web&#xff0c;桌面程序开发 Python 数学处理&#xff0c;中小型网站 性…

【linux】Microsoft Edge 的 Bookmarks 文件存储位置

在 Linux 系统中&#xff0c;Microsoft Edge 的书签&#xff08;Bookmarks&#xff09;文件存储在用户的配置目录下。具体路径通常如下&#xff1a; ~/.config/microsoft-edge/Default/Bookmarks说明&#xff1a; 路径解释&#xff1a; ~ 表示当前用户的主目录。.config 是一个…

【开源】第三期:数字货币程序化交易终端开源

关于初衷&#xff1a; 这篇文章&#xff0c;其实应该在六年前发出来&#xff0c;但是受制于各种杂事和生活琐事&#xff0c;一直拖到现在&#xff0c;想必有朋友看到在"终端"那期里&#xff0c;聊到的数字货币交易的实践&#xff0c;那个时候遍地都是数字货币交易所&…