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

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

一、概述

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 表的结构:

c 复制代码
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的首地址,然后访问表结构信息:

c 复制代码
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:

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

c 复制代码
///
/// 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 中的一个结构头部

c 复制代码
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)。

c 复制代码
  SMBIOS_TABLE_3_0_ENTRY_POINT  *SMBiosTable;
  SMBiosTable = NULL;
  LibSmbios64BitGetEPS (&SMBiosTable);

2、初始化和检查入口点

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

c 复制代码
  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 字段识别结构类型,并根据需要解析结构的特定信息。

c 复制代码
    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),解析每种结构的数据。对不同类型的结构提取相应的信息,如系统制造商、产品名称等。

c 复制代码
SmbiosPrintStructure (&SmbiosStruct, gShowType);

6、输出信息

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

7、错误处理

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

相关推荐
冰帝海岸3 小时前
01-spring security认证笔记
java·笔记·spring
小二·4 小时前
java基础面试题笔记(基础篇)
java·笔记·python
朝九晚五ฺ5 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
wusong9997 小时前
mongoDB回顾笔记(一)
数据库·笔记·mongodb
猫爪笔记7 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
Resurgence037 小时前
【计组笔记】习题
笔记
pq113_67 小时前
ftdi_sio应用学习笔记 3 - GPIO
笔记·学习·ftdi_sio
澄澈i7 小时前
设计模式学习[8]---原型模式
学习·设计模式·原型模式
爱米的前端小笔记8 小时前
前端八股自学笔记分享—页面布局(二)
前端·笔记·学习·面试·求职招聘
alikami8 小时前
【前端】前端学习
学习