SMBIOS( System Management BIOS)是主板或者系统制造商以标准格式显示产品信息所遵循的规范。依据该规范,BIOS在POST阶段可以知道如何去创建。OS阶段,操作系统和应用程序知道如何使用,解释内存区域表示什么意思。在物理上,SMBIOS是上电开机,BIOS在内存中建立的一块区域,保存了平台的相关信息。在 EFI 系统中,SMBIOS 表的地址可以通过 SMBIOS GUID (SMBIOS_TABLE_GUID)在 EFI 配置表(EFI Configuration Table)中找到 。
SMBIOS 表中 SMBIOS 记录的总数可以从其起始数据结构 (SMBIOS Entry Point Structure)中获得。应用程序可以从 SMBIOS Entry Point Structure 中获得所有 SMBIOS 记录的起始地址,并且通过遍历每一个 SMBIOS 记录来获得各种系统信息。
SMBIOS_TABLE_ENTRY_POINT:
SMBIOS 表的起始数据结构和 SMBIOS 记录的关系:
每一个 SMBIOS 记录包含两个部分,一是 SMBIOS 规范定义的部分,该部分是必须存在的;另一个是非规范定义的部分,该部分是可选的(SMBIOS 规范没有定义该部分的内容和长度)。每一个 SMBIOS 记录都必须以 0000h 做为结束标志。
当一个 SMBIOS 记录的规范定义部分的某个域是字符串,该域只存放字符串在非规范定义的部分的索引号,字符串的内容放在非规范定义部分。
SMBIOS 数据结构
EFI_SMBIOS_PROTOCOL
EFI_SMBIOS_PROTOCOL 是 PI 规范中定义的协议。它给用户提供了接口用来添加,获取或 者删除 SMBIOS 表。产生 EFI_SMBIOS_PROTOCOL 协议的驱动负责创建 SMBIOS 表并且将 SMBIOS 表的指针安装到 EFI 系统配置表 (EFI System Configuration Table) 中。SMBIOS 协议的 调用者需要保证添加的 SMBIOS 表与 MajorVersion 和 MinorVersion 规定的 SMBIOS 规范的版 本一致。
Add: 增加一条 SMBIOS 记录(SMBIOS Record)到 SMBIOS 表中;
UpdateString:更新某条 SMBIOS 记录中字符串内容;
Remove: 删除某条 SMBIOS 记录;
GetNext: 遍历所有的 SMBIOS 记录;
MajorVersion:SMBIOS 表的主版本号;
MinorVersion:SMBIOS 表的次版本号。
EFI_SMBIOS_RECORD_HEADER
每一条 SMBIOS 记录都由 EFI_SMBIOS_RECORD_HEADER 和 SMBIOS 记录的内容构成的。
HeaderSize 是 EFI_SMBIOS_RECORD_HEADER 的大小,RecordSize 是包括 EFI_SMBIOS_RECORD_HEADER 大小 在内的整个 SMBIOS 记录的大小。ProducerHandle 是 SMBIOS 记录创建者的句柄,用来标识 该 SMBIOS 记录的创建者。NumberOfStrings 是该 SMBIOS 记录中字符串的数量。
EFI_SMBIOS_ENTRY
所有 SMBIOS 记录构成一个单向循环链表,链表中每一个节点的数据结构定义如下。
RecordHeader 指向某条 SMBIOS 记录,Link 用来构成该单向循环链表,并且可以通过 SMBIOS_ENTRY_FROM_LINK 来获取 Link 所在的数据结构 SMBIOS_ENTRY_FROM_LINK。
SMBIOS_INSTANCE
实现 EFI_SMBIOS_PROTOCOL 协议的驱动定义了 SMBIOS_INSTANCE 内部数据结构。 Signature 用来标识这个数据结构,其定义如下:
Handle 用来安装 EFI_SMBIOS_PROTOCOL 协议。Smbios是 EFI_SMBIOS_PROTOCOL 协议的实现。 DataListHead 是由多个 SMBIOS 记录组成的链表。AllocatedHandleListHead 用来记录已经分配 给 SMBIOS 记录的句柄(Handle)。
SMBIOS 驱动模块用两个链表维护系统中所有产生的 SMBIOS 记录。以 DataListHead 为起始的链表记录了系统中已经产生的 SMBIOS 记录,以 AllocateHandleListHead 为起始的链表记录 了产生的 SMBIOS 记录的句柄(Handle)。 SMBIOS 规范要求每一个 SMBIOS 记录的句柄是不能重复的,当用户添加一个新的 SMBIOS 记录时,SMBIOS 驱动模块就用 AllocateHandleListHead 链表获得一个未用的句柄,用来产生新的 SMBIOS 纪录。
SMBIOS_HANDLE_ENTRY
SMBIOS_HANDLE_ENTRY 数据结构组成了一个链表,记录了已经使用的 SMBIOS 句柄。我们 可以通过查找这个链表知道一个 SMBIOS 句柄是否已经被一个 SMBIOS 记录使用。可以通过 SMBIOS_HANDLE_ENTRY_FROM_LINK 来获取 Link 所在的数据结构 SMBIOS_HANDLE_ENTRY。
EFI_SMBIOS_TABLE_HEADER
EFI_SMBIOS_TABLE_HEADER是 SMBIOS 记录中特定的数据。其中,Type 是 SMBIOS 记录的类型,0~127 是 SMBIOS 规范使用的,128~256 可以让 BIOS 厂商使 用。Length 是该 SMBIOS 记录的大小。Handle 是标识该 SMBIOS 记录的唯一的句柄。
SMBIOS 函数
SmbiosAdd() 用来增加一条 SMBIOS 记录,即增加一个新的 SMBIOS 记录在DataListHead 链表中,以及增加一个新的 SMBIOS 句柄在 AllocatedHandleListHead 链表中。
SmbiosRemove() 根据调用者传入的 SMBIOS 句柄(SmbiosHandle)删除某个 SMBIOS 记录。
SmbiosGetNext() 用于遍历所有的 SMBIOS 记录。
SmbiosTableConstruction() 是 ReadyToBoot 事件的回调函数,当 ReadyToBoot 事件被触发时被 调用。它根据所有的 SMBIOS 记录创建最终的 SMBIOS 表,并且安装到 EFI 系统配置表(EFI System Configuration Table)中。
SmbiosCreateTable() 根据所有的 SMBIOS 记录创建最终的 SMBIOS 表。
【关于SMBIOS的添加和读取本人已经上传了C代码资源,如有需要请移至下载处自行下载。
资源连接:https://blog.csdn.net/weixin_45258382?type=download 】