11.02
任务目标 // 进度:
- SMBIOS学习,编写DOS下小工具,读取SMBIOS表信息,并解析TYPE0/TYPE1/TYPE4/TYPE7/TYPE17等Type信息。
工作结果:
学习笔记:
DMI(Desktop Management Interface )
SMBIOS(System Management BIOS)
EPS(Entry Point Structure)
1.访问方式
1.1.通过即插即用功能接口访问 SMBIOS 结构,这个在 SMBIOS2.0 标准里定义了,从 SMBIOS 2.1 开始这个访问方法不再被推荐使用。
1.2.基于表结构的方法,表内容是 table entry point 的数据,这个访问方法从 SMBIOS 2.1 以后开始被使用,从 2.1 开始,以后的版本都推荐使用这种访问方式。在 2.1 版本中允许支持这两种方法中的任意一种和两种都支持,但在 2.2 以后的版本,必须支持方法 2 。在最新的 2.7.0 版中第一种方法已经废弃。
1.2.1.访问 SMBIOS EPS表
对于非 EFI 的系统,访问 SMBIOS EPS 表的操作过程如下:
1.从物理内存 0x000F0000-0x000FFFFF 之间寻找关键字 “ _SM_” 。("_"对应地址0x000f05e0)
2.找到后再向后 16 个字节,看后面 5 个 BYTE 是否是关键字 “_DMI_” ,如果是, EPS 表即找到。
进入EPS表和进入数据表:
1.EPS-入口结构表 (Entry Piont Structure)(输入00H地址0x000f05e0)
2.SMBIOS数据表(18H)(输入18H地址0xb7eea)
EPS表:
00H | SM |
---|---|
10H | DMI |
16H | 数据表长度 |
18H | 数据表地址 |
1CH | 数据表结构的总数 |
SMBIOS数据存储结构表由两部分构成:格式区,字符串区
注:结构 01H 处标识的结构长度仅是格式区域的长度,字符串区域的长度是不固定的。有的结构有字符串区域,有的则没有。
Type 0 | BIOS Information BIOS信息 |
---|---|
Type 1 | System Information 系统信息 |
Type 7 | Cache Information 高速缓存信息 |
Type 4 | Processor Information 处理器信息 |
Type 17 | Memory Device 存储设备 |
处理器信息 (Type 4) :插座指示、处理器类型、处理器家族、制造商、 ID 、版本、电压伏特数、外部时钟频率 (MHz) 、最大速率 (MHz) 、当前速率、状态、处理器升级、 L1 级缓存信息结构的句柄、 L2 级缓存信息结构的句柄、 L3 级缓存信息结构的句柄、序列号、资产标签、部件号码、内核个数、激活的内核个数、线程个数、处理器特征、处理器家族 2 。
高速缓存信息 (Type 7) :插座指示、缓存配置、最大缓存容量、已安装的容量、支持的 SRAM类型、当前 SRAM 类型、缓存速率、纠错类型、系统缓存类型、关联性。
存储设备 (Type 17) : 用于描述物理存储器阵列中的单个存储设备。在物理存储器阵列中的句柄、存储错误信息句柄、存储总宽度、数据宽度、存储容量、形体尺寸、设备集、设备定位 器、记忆槽定位器、存储器类型、类型额外细节、速率、制造商、序列号、资产标签、部件号码、属性标志、已扩展的容量、已配置的存储时钟速率。
每个字符串都以 00H 作为结束标志。如果我们要找下一个 TYPE ,因为最后一个字符串以 00H 结尾,而整个字符区域又以 00H 结尾,故只要在字符串区域找到连续的0000H 即可。
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef struct {
uchar Type;
uchar Length;
ushort Handle;
} HEADER;
ushort FindStructure(char* TableAddress, ushort StructureCount, uchar Type) {
ushort i, handle;
uchar lasttype;
i=0;
handle=0xFFFF;
/* 从整个SMBIOS的首个结构开始搜索指定类型的第一个结构 */
while(i<StructureCount && handle==0xFFFF) {
i++;
lasttype=((HEADER *)TableAddress)->Type; /* 获取当前结构的类型 */
if(lasttype==Type) {
handle=((HEADER *)TableAddress)->Handle;
}else {
/* 移动到当前结构的字符串区域处 */
TableAddress+=((HEADER *)TableAddress)->Length;
while(*((int *)TableAddress)!=0) /* 移动到字符串区域的结尾符0000h处 */
TableAddress++;
TableAddress+=2; /* 跳过0000h,移动到下一结构起始处 */
}
}
return handle;
}
程序读取信息的步骤可以概括为:通过GUID将EPS表找到,根据EPS表的TableAddress找到所有Type的起始地址,然后遍历Type表,找到要读取的Type读取相应信息。其中遍历每一个Type表并返回每一个Type的起始地址是最关键的部分,代码中由函数LibGetSmbiosString 实现。
PCH(Platform Controller Hub):Intel集成南桥
MCH(Memory Control Hub):intel北桥
翻页:
PauseBreak+enter
/p
> name.txt
edit name.txt