4. SMBIOS数据结构

SMBIOS(System Management BIOS)以“结构表”的方式描述平台硬件与固件信息。整张表由一条条结构(Structure)顺序拼接而成,每条结构都以一个固定长度的头部(Header)开始,后面紧跟与类型相关的格式化区域(Formatted Area),再以一组以 0x00 结尾的字符串集合(String Set)收尾。理解 Type 0~Type 3 这四类最基础的结构,是后续定制 Type 11、Type 17、Type 41 等复杂结构的前提。

一条 SMBIOS 结构的通用布局:
[Type 1B][Length 1B][Handle 2B] → [Formatted Area (Length-4) B] → [String1\0][String2\0]…[0x00]
其中 Length 只统计头部与格式化区域,不含字符串区;字符串区以“双零”结束。

下面这张图把四种常见类型放在同一张 SMBIOS 表中,展示它们的字段构成、字符串引用关系以及 Handle 的定位作用。

SMBIOS 结构表:Type 0 / 1 / 2 / 3 字段与字符串引用关系 Type 0 — BIOS Information(Handle 0x0000) Vendor(Str) · BIOS Version(Str) · BIOS Starting Addr Release Date(Str) · ROM Size · Characteristics Ext Characteristics · System BIOS Major/Minor 字符串:厂商 / 版本 / 日期 Type 1 — System Information(Handle 0x0100) Manufacturer(Str) · Product Name(Str) Version(Str) · Serial Number(Str) UUID(16B) · Wake-up Type · SKU Number(Str) 字符串:整机厂商 / 机型 / 序列号 Type 2 — Baseboard Information(Handle 0x0200) Manufacturer(Str) · Product(Str) · Version(Str) Serial Number(Str) · Asset Tag(Str) Feature Flags · Board Type · Chassis Handle 字符串:主板厂商 / 板型 / 资产标签 Type 3 — System Enclosure(Handle 0x0300) Manufacturer(Str) · Type · Version(Str) Serial Number(Str) · Asset Tag(Str) Boot-up State · Power Supply State 字符串:机箱厂商 / 机箱类型 / 序列号 共享字符串区(String Set,以 0x00 0x00 结束) 1: "Vendor-A" 2: "1.2.3" 3: "2024-06-01" 4: "Model-X" 5: "SN-0001" 6: "MB-Z790" 7: "Chassis-ATX" 8: "AT-7788" … 0x00 0x00 关键关联与定位规则 • Type 2 的 Chassis Handle 指向 Type 3,形成“主板—机箱”的物理归属关系。 • Type 1 的 UUID 是系统唯一标识,Type 0 的 BIOS Version 决定固件版本判定。 • 所有字符串字段只存“索引号”,真实文本统一放在字符串区,便于复用与压缩。 • Handle 是结构间跳转的“地址”,定制时需保证引用目标存在且唯一。

一、核心原理:头部、格式化区与字符串区

每条 SMBIOS 结构的前 4 个字节含义固定:Type 表示结构类别,Length 表示头部加格式化区的总长度,Handle 是该结构在表中的唯一句柄。格式化区字段的偏移量由规范严格定义,例如 Type 0 的 Vendor 位于偏移 0x04,BIOS Version 位于 0x05,Release Date 位于 0x08。字符串字段本身只保存一个字节的索引值,0 表示“无字符串”,1 表示字符串区中的第 1 条,以此类推。

字符串区紧跟在格式化区之后,每条字符串以 0x00 结尾,整个字符串集合再以一个额外的 0x00 结束。这种“双零结尾”设计让解析器可以明确知道字符串区何时结束,从而正确跳到下一条结构。

二、四类基础结构详解

类型 名称 典型 Handle 核心字段 定制关注点
Type 0 BIOS Information 0x0000 Vendor、BIOS Version、Release Date、ROM Size、Characteristics 版本号与日期需与固件实际一致,避免误判升级
Type 1 System Information 0x0100 Manufacturer、Product Name、Serial Number、UUID、SKU UUID 必须唯一,序列号不可重复
Type 2 Baseboard Information 0x0200 Manufacturer、Product、Version、Serial、Asset Tag、Chassis Handle Chassis Handle 必须指向有效 Type 3
Type 3 System Enclosure 0x0300 Manufacturer、Type、Version、Serial、Boot-up State、Power Supply State 机箱类型编码需符合 SMBIOS 规范枚举值

三、方法流程:从需求到结构落地

  1. 确定字段来源:明确哪些信息来自固件配置、哪些来自产线烧录、哪些需要运行时生成(如 UUID)。
  2. 分配 Handle:为每条结构分配唯一句柄,并保证跨结构引用(如 Type 2 → Type 3)指向正确。
  3. 填充格式化区:按规范偏移写入数值字段,字符串字段先写索引占位。
  4. 构建字符串区:按索引顺序写入字符串,末尾补双零。
  5. 校验长度与校验和:确认 Length 与实际字节数一致,并检查结构表整体完整性。

四、案例场景:定制一台工控机的 SMBIOS

假设需要为某工控机定制 SMBIOS,要求:BIOS 版本显示为 “1.2.3”,整机厂商为 “Vendor-A”,主板型号为 “MB-Z790”,机箱类型为 “ATX”。定制时先构造 Type 0,写入版本与日期;再构造 Type 1,写入厂商、机型与 UUID;接着构造 Type 2,写入主板信息并将 Chassis Handle 指向 Type 3;最后构造 Type 3,写入机箱厂商与类型编码。四条结构共享同一字符串区,索引从 1 开始依次排列。

Type 0  Handle 0x0000  Len 0x18
  Vendor        = 0x01  -> "Vendor-A"
  BIOS Version  = 0x02  -> "1.2.3"
  Release Date  = 0x03  -> "2024-06-01"

Type 1  Handle 0x0100  Len 0x1B
  Manufacturer  = 0x01  -> "Vendor-A"
  Product Name  = 0x04  -> "Model-X"
  Serial Number = 0x05  -> "SN-0001"

Type 2  Handle 0x0200  Len 0x0F
  Product       = 0x06  -> "MB-Z790"
  Chassis Handle= 0x0300

Type 3  Handle 0x0300  Len 0x15
  Manufacturer  = 0x01  -> "Vendor-A"
  Version       = 0x07  -> "Chassis-ATX"
  Type          = 0x03  (ATX)

五、误区与复盘

常见误区一:Length 只算头部。 Length 必须包含头部 4 字节与格式化区全部字节,漏算会导致解析器错位,后续结构全部读错。
常见误区二:字符串索引从 0 开始。 0 表示“无字符串”,有效索引从 1 开始;若把第 1 条字符串写成索引 0,系统将读不到内容。
复盘建议: 定制完成后,用 dmidecode 或自研解析工具逐条打印 Type 0~Type 3,核对字段值与字符串区是否一致;重点检查 Handle 引用、Length 长度和双零结尾三处,这三处是现场问题的高发点。

掌握 Type 0~Type 3 的字段布局与字符串引用机制后,再扩展到 Type 4(处理器)、Type 7(缓存)、Type 16(内存阵列)、Type 17(内存设备)等结构时,就能沿用同一套“头部—格式化区—字符串区”的解析思路,快速定位字段偏移并完成定制写入。