本文章对SMBIOS内容,从整体层面做了详细介绍和说明,让读者对SMBIOS有一个整体认识。
1. SMBIOS是什么
首先,我们可以看下百度百科是如何介绍说明的,如下:
SMBIOS(System Management BIOS)是由桌面管理任务组(DMTF)制定的开放性技术标准,旨在规范主板及系统制造商以统一格式管理产品信息。该标准与桌面管理接口(DMI)共同构建系统信息管理体系,其中DMI作为信息收集接口需遵循SMBIOS规范运作,适用于多种硬件平台与操作系统。
从上面说明,我们不难看出,其实SMBIOS就是一套规范,包含主板或系统制造者的各种硬件信息。
2. SMBIOS的数据结构
SMBIOS 的整个数据结构,主要包括SMBIOS EPS数据结构(Entry Point structure)、SMBIOS structures数据结构,整个数据关系可以参考下图1:
图1
2.1 SMBIOS EPS结构(Entry Point structure)
SMBIOS是以一个标准的数据结构SMBIOS_TABLE_ENTRY_POINT( Entry Point Structure)作为起始,在非 EFI 系统中,应用程序可以在 000F0000h 到 000FFFFFh 的内存地址范围内查找字符串“SM “”(5F 53 4D 5F)来获的 SMBIOS 的起始地址。在 EFI 系统中,SMBIOS 的地址可以通过 SMBIOS GUID (SMBIOS_TABLE_GUID)在 EFI 配置表(EFI Configuration Table)中找到。
SMBIOS_TABLE_ENTRY_POINT的数据结构定义如下:
typedef struct {
UINT8 AnchorString[4]; // "_SM_"
UINT8 EntryPointStructureChecksum; // Checksum of the Entry Point Structure (EPS)
UINT8 EntryPointLength; // Length of the Entry Point Structure
UINT8 MajorVersion;
UINT8 MinorVersion;
UINT16 MaxStructureSize; // Size of the largest SMBIOS structure, in bytes, and encompasses the structure’s formatted area and text strings
UINT8 EntryPointRevision;
UINT8 FormattedArea[5];
UINT8 IntermediateAnchorString[5];// "_DMI_"
UINT8 IntermediateChecksum;
UINT16 TableLength; // Total length of SMBIOS Structure Table
UINT32 TableAddress; // physical starting address of the SMBIOS Structure Table
UINT16 NumberOfSmbiosStructures;// Total number of structures present in the SMBIOS Structure Table
UINT8 SmbiosBcdRevision;
} SMBIOS_TABLE_ENTRY_POINT;
NOTE:64-bit SMBIOS 的数据结构定义为SMBIOS_TABLE_3_0_ENTRY_POINT,这里不在详细描述。
2.2 SMBIOS structures数据结构
SMBIOS structures(SMBIOS table)的总个数可以从 SMBIOS 的起始数据结构 (SMBIOS Entry Point Structure)中获得。每一个 SMBIOS table包含两个部分,如下:
(1) 规范定义区,该区域是必须存在的,都是以4字节的头开始;
// The Smbios structure header.
typedef struct {
SMBIOS_TYPE Type;
UINT8 Length;
SMBIOS_HANDLE Handle;
} SMBIOS_STRUCTURE;
(2)非规范定义区,该区域是可选的,SMBIOS 规范没有定义该区的内容和长度。这个区域一般用来存放 SMBIOS table中的全部字符串内容。
每一个 SMBIOS table都必须以 0000h 做为结束标志。当一个 SMBIOS table的规范定义区的某个字段是字符串,该区只存放字符串在非规范定义区的索引号,字符串的内容存放在非规范定义区。
举例说明如下:
(1)BIOS Information with strings
BIOS_Info LABEL BYTE
1 db 0 ; Indicates BIOS Structure Type
2 db 13h ; Length of information in bytes
3 dw ? ; Reserved for handle
4 db 01h ; String 1 is the Vendor Name
5 db 02h ; String 2 is the BIOS version
6 dw 0E800h ; BIOS Starting Address
7 db 03h ; String 3 is the BIOS Build Date
8 db 1 ; Size of BIOS ROM is 128K (64K * (1 + 1))
9 dq BIOS_Char ; BIOS Characteristics
10 db 0 ; BIOS Characteristics Extension Byte 1
11 db ‘System BIOS Vendor Name’,0 ;
12 db ‘4.04’,0 ;
13 db ‘00/00/0000’,0 ;
14 db 0 ; End of strings
上面内容是类型为 0 的 SMBIOS Table,该内容的第 4 、5、 7 行的字段为字符串,可以看到这几行只填入了字符串的索引,该索引从 1开始。从第 11 行开始,是真正字符串的内容,每个字符串以 00 结尾,第 13 行再加一个 00,与第14 行字符串结尾 0 构成 0000 作为这个 SMBIOS Table结束。
(2)BIOS Information without strings
BIOS_Info LABEL BYTE
1 db 0 ; Indicates BIOS Structure Type
2 db 13h ; Length of information in bytes
3 dw ? ; Reserved for handle
4 db 00h ; No Vendor Name provided
5 db 00h ; No BIOS version provided
6 dw 0E800h ; BIOS Starting Address
7 db 00h ;== No BIOS Build Date provided==
8 db 1 ; Size of BIOS ROM is 128K (64K * (1 + 1))
9 dq BIOS_Char ; BIOS Characteristics
10 db 0 ; BIOS Characteristics Extension Byte 1
11 dw 0000h ; Structure terminator
这个 BIOS_Info内容没有包含任何字符串,因此第 4 、 5 、7 行填入 00,表明没有字符串,最后依然以 0000 结尾。
3 SMBIOS代码组织
1. 代码路径
| 文件 | 文件描述 |
|---|---|
| MdePkgIncludeGuidSmbios.h | 定义UEFI规范中SMBIOS 表的GUID |
| MdePkgIncludeProtocolSmbios.h | 定义SMBIOS协议的数据结构 |
| MdeModulePkgUniversalSmbiosDxeSmbiosDxe.h | 实现SMBIOS协议的数据结构 |
| MdeModulePkgUniversalSmbiosDxeSmbiosDxe.c | 实现SMBIOS协议的函数,比如增删改查 |
2. 全局变量
| 变量 | 类型 | 文件描述 |
|---|---|---|
| mPrivateData | SMBIOS_INSTANCE | SMBIOS协议实例化数据结构 |
| EntryPointStructure | SMBIOS_TABLE_ENTRY_POINT* | SMBIOS 表头部的指针 |
| EntryPointStructureData | SMBIOS_TABLE_ENTRY_POINT | SMBIOS 表头部的数据 |
