对于符合SMBIOS规范的计算机,可以通过访问SMBIOS的结构获得系统信息,共有两种办法可以访问:
1.通过即插即用功能接口访问SMBIOS结构,这个在SMBIOS2.0标准里定义了,从SMBIOS 2.1开始这个访问方法不再被推荐使用。
2.基于表结构的方法,表内容是table entry point的数据,这个访问方法从SMBIOS 2.1以后开始被使用,从2.1开始,以后的版本都推荐使用这种访问方式。在2.1版本中允许支持这两种方法中的任意一种和两种都支持,但在2.2已经以后的版本,必须支持方法2。
鉴于市场上计算机已经均支持SMBIOS2.3标准,所以只考虑方法2,基于表结构的访问方式。
基于表结构访问SMBIOS的过程是先找到Entry Point Structure(EPS)表,然后通过Entry Point Structure(EPS)表的数据找到SMBIOS数据表。
访问SMBIOS EPS表的操作过程如下:
1. 从物理内存0xF0000-0xFFFFF间寻找关键字“ _SM_”
2. 找到后再向后16个字节,看后面5个BYTE是否是关键字“_DMI_”,如果是,EPS表即找到。
注:按照SMBIOS规范说明,找到关键字”_SM_”后就可以确定此处就是EPS表结构,但我在实际操作中发现有为数不少的计算机的指定64K内存中有不只一个“_SM_”,所以不能仅用找到”_SM_”来确定,需要继续判断16个字节后是否是“_DMI_”。
SMBIOS EPS表结构如下:
位置
|
名称
|
长度
|
描述
|
00H
|
关键字
|
4BYTE
|
固定是”_SM_”
|
04H
|
校验和
|
1BYTE
|
用于校验数据
|
05H
|
表结构长度
|
1BYTE
|
Entry Point Structure表的长度
|
06H
|
Major版本号
|
1BYTE
|
用于判断SMBIOS版本
|
07H
|
Minor版本号
|
1BYTE
|
用于判断SMBIOS版本
|
08H
|
表结构大小
|
2BYTE
|
用于即插即用接口方法获得数据表结构长度
|
0AH
|
EPS修正
|
1BYTE
|
|
0B-0FH
|
格式区域
|
5BYTE
|
存放解释EPS修正的信息
|
10H
|
关键字
|
5BYTE
|
固定为“_DMI_”
|
15H
|
校验和
|
1BYTE
|
Intermediate Entry Point Structure (IEPS)的校验和
|
16H
|
数据表长度
|
2BYTE
|
SMBIOS数据表的长度
|
18H
|
数据表地址
|
4BYTE
|
SMBIOS数据表的真实内存位置
|
1CH
|
数据表结构数
|
2BYTE
|
SMBIOS数据表的结构数目
|
1EH
|
Smbios BCD修正
|
1BYTE
|
|
通过EPS表结构中的12H以及14H处,得出数据表长度和数据表地址,即可通过地址访问结构表。从EPS表中的1CH处可得知结构表结构的总数,其中TYPE 0结构就是BIOS information,TYPE 1结构就是SYSTEM Information。
每个结构的头部是相同的,格式如下:
位置
|
名称
|
长度
|
描述
|
00H
|
TYPE号
|
1BYTE
|
结构的TYPE号
|
01H
|
长度
|
1BYTE
|
本结构的长度,就此TYPE号的结构而言
|
02H
|
句柄
|
2BYTE
|
用于获得SMBIOS结构,使用方法未知
|
每个结构都分为格式区域和字符串区域,格式区域就是一些本结构的信息,字符串区域是紧随在格式区域后的一个区域。结构01H处标识的结构长度仅是格式区域的长度,字符串区域的长度是不固定的。
下面以TYPE 0(BIOS information)为例说明格式区域和字符串区域的关系
TYPE 0(BIOS information)格式区域如下:
位置
|
名称
|
长度
|
描述
|
00H
|
TYPE号
|
1BYTE
|
结构的TYPE号,此处是0
|
01H
|
长度
|
1BYTE
|
TYPE 0格式区域的长度,一般为14H,也有13H
|
02H
|
句柄
|
2BYTE
|
一般为0000H
|
04H
|
Bios厂商信息
|
1BYTE
|
此处是bios卖方的信息,可能是OEM厂商名,一般为01H,代表紧随格式区域后的字符串区域的第一个字符串
|
05H
|
BIOS版本
|
1BYTE
|
BIOS版本号,一般为02H,代表字符串区域的第二个字符串
|
06H
|
Bios开始地址段
|
2BYTE
|
用于计算常驻BIOS镜像大小的计算,方法为
(10000H-BIOS开始地址段)×16
|
08H
|
BIOS发布日期
|
1BYTE
|
一般为04H,表示字符区第三个字符串
|
09H
|
BIOS rom size
|
1BYTE
|
计算方法为(n+1)×64K,n为此处读出数值
|
0AH
|
BIOS特征
|
8BYTE
|
Bios的功能支持特征,如PCI,PCMCIA,FLASH等
|
12H
|
Bios特征扩展
|
不定
|
|
紧随TYPE 0(BIOS information)结构区域之后的就是TYPE 0(BIOS information)字符串区域,如下所示:
db ‘System BIOS Vendor Name’,0 ; 字符串以零结尾,第一个字符串:卖方信息
db ‘
db ‘00/00/
db 0 ; 以O为整个字符区域的结尾,所以要找下一个TYPE,只要在字符区域找到连续的OOOOH即可
注:当有EPS表中得到结构表的开始地址后,可以直接按结构来寻找相应的TYPE号,找到后直接读取就是该TYPE对应的结构的格式区域信息,然后向后移动结构区域长度(机构区域长度由该结构的O1H处读出)个BYTE,即是该TYPE机构的字符串区域。
由上面介绍可知,获得BIOS信息的办法就是:
1. 通过EPS表的12H和14H数据找到TYPE结构表,然后找到TYPE 0的内存地址。(不一定是首个)
2. 由TYPE 0结构区域中得出相应BIOS信息是否存在(存在则是上面所述的 01H,02H,03H依次排布,不存在则是相应的位置上为00H)。
3. 如存在信息,则从字符串区域中读取对应BIOS信息。
获得SYSTEM信息方法同上,只是TYPE结构区域有所不同,请参照SMBIOS Reference Specification