4. SMBIOS Type 1 (System Information):Manufacturer、Product Name、Version、Serial Number、UUID 的生成规则与填充实践

SMBIOS Type 1 是系统信息结构,它向操作系统和上层管理软件提供设备的基本身份标识。在嵌入式固件开发中,Type 1 的字段填充质量直接影响资产管理、远程运维和合规性审计。本章将深入解析五个核心字段的生成规则、填充策略与调试方法。

4.1 Type 1 结构总览

Type 1 结构位于 SMBIOS Entry Point 之后,通常作为第一个或第二个结构体出现。其结构定义如下:

偏移 长度 字段名 说明
00h BYTE Type 固定为 0x01
01h BYTE Length 结构体总长度(通常 27h)
02h WORD Handle 结构句柄,唯一标识
04h BYTE Manufacturer 字符串索引
05h BYTE Product Name 字符串索引
06h BYTE Version 字符串索引
07h BYTE Serial Number 字符串索引
08h BYTE[16] UUID 16 字节二进制数据
18h BYTE Wake-up Type 唤醒方式枚举
19h BYTE SKU Number 字符串索引(可选)
1Ah BYTE Family 字符串索引(可选)
关键提示:字符串索引值 0 表示该字段未使用(空字符串),索引值 1 表示指向结构体后的第一个字符串,索引值 2 表示第二个字符串,以此类推。字符串区域以双 NULL 结尾。

4.2 五个核心字段的生成规则

4.2.1 Manufacturer(制造商)

制造商字段应使用公司注册的法定名称,不可使用缩写或代号。常见规则:

  • 标准名称:如 "Intel Corporation"、"Dell Inc."、"Huawei Technologies Co., Ltd."
  • OEM 定制:ODM 厂商应填写品牌方名称,而非代工厂名称
  • 长度限制:建议不超过 64 个 ASCII 字符,避免字符串区域溢出

4.2.2 Product Name(产品名称)

产品名称应唯一标识硬件平台,通常与产品标签一致:

  • 主板级:如 "X11DPi-NT"、"B660M PRO RS"
  • 整机级:如 "ThinkPad X1 Carbon Gen 11"、"PowerEdge R750"
  • 嵌入式:如 "NVIDIA Jetson AGX Orin Developer Kit"

4.2.3 Version(版本号)

版本号反映硬件修订级别,常见格式:

  • 数字版本:"1.0"、"2.1"、"Rev 3.0"
  • 字母版本:"A01"、"B02"、"Rev C"
  • 日期版本:"2024.03.15"(较少使用)

4.2.4 Serial Number(序列号)

序列号是设备唯一标识,生成规则最为严格:

  • 唯一性:每台设备必须唯一,不可重复
  • 格式:通常为字母数字组合,长度 8~32 字符
  • 不可包含:空格、特殊字符(如 @#$%)、中文
  • 生产写入:建议在产线烧录阶段写入 SPI Flash 的 NVRAM 区域

4.2.5 UUID(通用唯一标识符)

UUID 是 128 位全局唯一标识,遵循 RFC 4122 规范:

  • 格式:16 字节二进制,以小端序存储(Intel 架构)
  • 版本:推荐使用 UUID v4(随机)或 UUID v5(基于命名空间+名称的 SHA-1)
  • 特殊值:全 0 表示未设置,全 1 表示不支持
  • 持久性:同一设备生命周期内不可变更
常见陷阱:部分 BIOS 代码将 UUID 以大端序存储,导致 Windows 和 Linux 下读取的 UUID 字符串不一致。务必确认 CPU 架构的字节序,x86 使用小端序,ARM 通常也使用小端序。

4.3 字段填充实践

4.3.1 字符串索引填充流程

Type 1 的字符串字段通过索引指向结构体后的字符串区域。填充流程如下:

  1. 在内存中分配 Type 1 结构体(固定长度 27h)
  2. 在结构体后依次追加字符串:Manufacturer、Product Name、Version、Serial Number
  3. 每个字符串以 NULL 结尾,字符串区域以双 NULL 结束
  4. 将结构体中的索引字段设置为对应字符串的序号(从 1 开始)
// 示例:Type 1 字符串索引填充(C 语言伪代码)
typedef struct {
    UINT8   Type;           // 0x01
    UINT8   Length;         // 0x27
    UINT16  Handle;
    UINT8   Manufacturer;   // 索引 1
    UINT8   ProductName;    // 索引 2
    UINT8   Version;        // 索引 3
    UINT8   SerialNumber;   // 索引 4
    UINT8   UUID[16];
    UINT8   WakeUpType;
    UINT8   SKUNumber;      // 索引 5
    UINT8   Family;         // 索引 6
} SMBIOS_TYPE1;

// 字符串区域布局(内存连续):
// [结构体 27h 字节]
// "Intel Corporation\0"          // 索引 1
// "X11DPi-NT\0"                  // 索引 2
// "1.0\0"                        // 索引 3
// "SN202403150001\0"             // 索引 4
// "SKU-12345\0"                  // 索引 5
// "Server\0"                     // 索引 6
// "\0"                           // 双 NULL 结束

4.3.2 UUID 字节序处理

UUID 在 SMBIOS 规范中定义为 16 字节二进制,但不同操作系统解析方式不同:

字段 字节偏移 长度 字节序 示例(小端序存储)
time_low 0~3 4 字节 小端 0x12345678 → 78 56 34 12
time_mid 4~5 2 字节 小端 0x9ABC → BC 9A
time_hi_and_version 6~7 2 字节 小端 0xDEF0 → F0 DE
clock_seq_hi_and_reserved 8 1 字节 大端 0x12 → 12
clock_seq_low 9 1 字节 大端 0x34 → 34
node 10~15 6 字节 大端 0x112233445566 → 11 22 33 44 55 66
// UUID 小端序填充示例(x86 平台)
UINT8 UuidBuffer[16] = {
    0x78, 0x56, 0x34, 0x12,  // time_low (小端)
    0xBC, 0x9A,              // time_mid (小端)
    0xF0, 0xDE,              // time_hi_and_version (小端)
    0x12,                    // clock_seq_hi_and_reserved
    0x34,                    // clock_seq_low
    0x11, 0x22, 0x33, 0x44, 0x55, 0x66  // node
};
// 对应 UUID 字符串:12345678-9ABC-DEF0-1234-112233445566

4.4 字段填充的 SVG 架构图

SMBIOS Type 1 字段填充架构 数据源 NVRAM / SPI Flash 产线烧录文件 硬件寄存器 UUID 生成算法 OEM 默认值 固件处理层 字符串索引计算 字节序转换 长度校验 默认值回退 SMBIOS 结构组装 SMBIOS 输出 Type 1 结构体 字符串区域 UUID 二进制块 校验和 Entry Point 注册 调试验证工具 dmidecode -t 1 wmic csproduct GetSystemFirmwareTable UEFI Shell smbiosview 逻辑分析仪 SPI 抓包 关键约束 字符串索引从 1 开始 UUID 字节序依赖 CPU 序列号必须唯一

4.5 常见问题与调试方法

问题现象 可能原因 调试方法
Manufacturer 显示乱码 字符串索引指向错误偏移 使用十六进制编辑器检查字符串区域起始位置
UUID 全零 UUID 生成算法未执行或 NVRAM 未初始化 检查固件中 UUID 生成逻辑的调用时机
Serial Number 为空 产线烧录数据未正确写入 SPI Flash 使用 SPI 编程器读取 NVRAM 区域验证
Windows 和 Linux 下 UUID 不同 字节序处理不一致 确认固件使用小端序存储 UUID
Product Name 显示 "To be filled by O.E.M." BIOS 代码未覆盖默认字符串 在固件配置表中添加产品名称字符串

4.6 调试命令速查

# Linux 下查看 Type 1 信息
dmidecode -t 1

# 输出示例:
# Handle 0x0001, DMI type 1, 27 bytes
# System Information
#   Manufacturer: Intel Corporation
#   Product Name: X11DPi-NT
#   Version: 1.0
#   Serial Number: SN202403150001
#   UUID: 12345678-9ABC-DEF0-1234-112233445566
#   Wake-up Type: Power Switch
#   SKU Number: SKU-12345
#   Family: Server

# Windows 下查看
wmic csproduct get name, vendor, version, identifyingnumber

# UEFI Shell 下查看
smbiosview -t 1
实战建议:在固件开发阶段,建议在 BIOS 启动早期(PEI 阶段)打印 Type 1 各字段的原始字节和字符串内容,便于快速定位填充错误。使用 Serial Debug 工具或 ITP 调试器可以实时捕获这些日志。

4.7 本章小结