今天偶然发现 SMBIOS 2.X 和 3.X 存在一些差别,在处理的时候代码需要不同对待。
1. 入口点结构 (Entry Point Structure)定义的差异:
SMBIOS 2.X Entry Point
typedef struct {
UINT8 AnchorString[4]; // "_SM_"
UINT8 EntryPointStructureChecksum;
UINT8 EntryPointLength; // 0x1F
UINT8 MajorVersion;
UINT8 MinorVersion;
UINT16 MaxStructureSize;
UINT8 EntryPointRevision;
UINT8 FormattedArea[5];
UINT8 IntermediateAnchorString[5]; // "_DMI_"
UINT8 IntermediateChecksum;
UINT16 TableLength; // 表长度
UINT32 TableAddress; // 32位表地址
UINT16 NumberOfSmbiosStructures;
UINT8 SmbiosBcdRevision;
} SMBIOS_TABLE_ENTRY_POINT;
SMBIOS 3.X Entry Point
typedef struct {
UINT8 AnchorString[5]; // "_SM3_"
UINT8 EntryPointStructureChecksum;
UINT8 EntryPointLength; // 0x18
UINT8 MajorVersion;
UINT8 MinorVersion;
UINT8 DocRev;
UINT8 EntryPointRevision;
UINT8 Reserved;
UINT32 TableMaximumSize; // 表最大长度
UINT64 TableAddress; // 64位表地址
} SMBIOS_TABLE_3_0_ENTRY_POINT;
2. 主要技术差异
| 特性 | SMBIOS 2.X | SMBIOS 3.X |
|---|---|---|
| 地址空间 | 32位地址 | 64位地址 |
| 表大小限制 | 最大 65535 字节 | 最大 4GB |
| 入口点标识 | “SM” + “DMI“ | “SM3“ |
| 入口点大小 | 31 字节 (0x1F) | 24 字节 (0x18) |
| 结构计数 | 明确指定结构数量 | 不指定,需遍历到Type 127 |
| 校验和 | 两个校验和 | 一个校验和 |
实践发现,目前机器有不同的实现方式,比如:声明了 3.0 但是实际上仍然是 2.0 的结构;3.0 和 2.0 同时共存,这种情况下看起来 Windows 更倾向于使用 3.o 提供的信息。