系列文章目录
UEFI 之SMBIOS解析系列1——SMBIOS概述
文章目录
系列文章目录前言一、SMBIOS数据结构关系二、SMBIOS表的增删改查1.EFI_SMBIOS_PROTOCOL 数据结构2.EFI_SMBIOS_ENTRY 数据结构3.SMBIOS_ENTRY内部数据结构关系
总结
前言
本章节主要介绍UEFI EDK2的SMBIOS的源码,并进行分析,使读者能够了解SMBIOS底层实现原理。
一、SMBIOS数据结构关系
SMBIOS的数据结构关系如下图1所示。
如果我们在OS下输入 dmidecode命令,就能查询到对应的SMBIOS type信息,实际上是从EPS数据结构中TableAddress指向的地址获取的。

NOTE:dmidecode命令查询到SMBIOS对应信息的背后实现逻辑,后续我会单独一个章节去讲解这方面的内容。
二、SMBIOS表的增删改查
怎么对EPS数据结构中TableAddress指向的SMBIOS Type内容进行增删改查呢?
1.EFI_SMBIOS_PROTOCOL 数据结构
EFI_SMBIOS_PROTOCOL 给用户提供了对应的接口用来添加、获取、更新或者删除SMBIOS 表。产生EFI_SMBIOS_PROTOCOL 协议的驱动负责创建SMBIOS 表并且将
SMBIOS表的指针安装到 EFI系统配置表 (EFI System Configuration Table) 中。
EFI_SMBIOS_PROTOCOL 数据结构定义如下:
struct _EFI_SMBIOS_PROTOCOL {
EFI_SMBIOS_ADD Add;
EFI_SMBIOS_UPDATE_STRING UpdateString;
EFI_SMBIOS_REMOVE Remove;
EFI_SMBIOS_GET_NEXT GetNext;
UINT8 MajorVersion; ///< The major revision of the SMBIOS specification supported.
UINT8 MinorVersion; ///< The minor revision of the SMBIOS specification supported.
};
其中EFI_SMBIOS_ADD 、EFI_SMBIOS_UPDATE_STRING 、EFI_SMBIOS_REMOVE 、EFI_SMBIOS_GET_NEXT都是指针函数,通过驱动入口函数SmbiosDriverEntryPoint来初始化全局变量mPrivateData(SMBIOS_INSTANCE结构体)和协议安装等,部分代码如下:
EFI_STATUS
EFIAPI
SmbiosDriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
mPrivateData.Signature = SMBIOS_INSTANCE_SIGNATURE;
mPrivateData.Smbios.Add = SmbiosAdd;
mPrivateData.Smbios.UpdateString = SmbiosUpdateString;
mPrivateData.Smbios.Remove = SmbiosRemove;
mPrivateData.Smbios.GetNext = SmbiosGetNext;
mPrivateData.Smbios.MajorVersion = (UINT8) (PcdGet16 (PcdSmbiosVersion) >> 8);
mPrivateData.Smbios.MinorVersion = (UINT8) (PcdGet16 (PcdSmbiosVersion) & 0x00ff);
......
}
2.EFI_SMBIOS_ENTRY 数据结构
对SMBIOS表的操作,其实都是通过SMBIOS_INSTANCE 这个内部数据结构来完成的,其数据结构定义如下:
typedef struct {
UINT32 Signature;
EFI_HANDLE Handle;
//
// Produced protocol
//
EFI_SMBIOS_PROTOCOL Smbios;
//
// Updates to record list must be locked.
//
EFI_LOCK DataLock;
//
// List of EFI_SMBIOS_ENTRY structures.
//
LIST_ENTRY DataListHead;
//
// List of allocated SMBIOS handle.
//
LIST_ENTRY AllocatedHandleListHead;
} SMBIOS_INSTANCE;
(1)Handle 用来安装 EFI_SMBIOS_PROTOCOL协议。
(2)Smbios是 EFI_SMBIOS_PROTOCOL协议的实现。
(3)DataListHead 是由多个SMBIOS表组成的链表。
(4)AllocatedHandleListHead 用来记录已经分配给 SMBIOS表的句柄(Handle)。
3.SMBIOS_ENTRY内部数据结构关系
SMBIOS_ENTRY用两个链表维护所有产生的 SMBIOS Type内容。
(1)使用DataListHead 为开始的链表维护产生的 SMBIOS Type数据内容;
(2)使用 AllocateHandleListHead 为开始的链表维护产生的 SMBIOS Type handle。

总结
本文章主要讲了SMBIOS源码中增删改查涉及的数据结构和内部结构之间的数据组织关系,下一章节我们将继续分析SMBIOS源码中的增删改查涉及的操作函数。


