一
1.什么是SMBIOS?
A: SMBIOS(System Management BIOS),是主板或者系统制造者以标准的格式显示产品管理信息所需遵循的统一规范。也就是不管你是怎么去实现的,结果必须要遵循规范。
2.什么是DMI?
A:DMI(Desktop Management Interface)的缩写,即桌面管理界面,它包含有关系统硬件的配置信息。每次计算机启动时都要对DMI数据进行校验,如果数据有问题或者硬件有变动,就会对机器进行检测,并把测试的数据写入BIOS芯片保存。所以在BIOS setup里面把BIOS芯片的刷新功能或者在主板上用跳线禁止BIOS芯片的刷新功能,那么这台机器的DMI数据不会更新,如果你换了硬件的话,当你进入windows的时候机器仍按照就的数据信息配置进行工作,可能你换过的硬件就会有故障或不能发挥好的性能。DMI 的主要组成部分是 Management Information Format (MIF) 数据库。这个数据库包括了所有有关电脑系统和配件的信息。通过 DMI ,用户可以获取序列号、电脑厂商、串口信息以及其它系统配件信息。
3.对于符合SMBIOS的计算机如何访问SMBIOS结构里系统信息?
1.通过即插即用功能接口访问,这个在SMBIOS2.1之后已不再推荐使用,如今最新的SMBIOS是否还支持可以查看SMBIOS SPEC。
2.基于表结构的方法,表内容是tanle entry point的数据。这种方法是2.1以后版本书推荐的。
二,
这里我先介绍第二种方法。基于表结构的访问SMBIOS,首先需要找到Entry Point structure(EPS)表,然后通过此表的数据再去找到SMBIOS结构表。
对于非EFI系统,访问SMBIOS EPS表的操作如下(EFI希望后面有时间可以去探索):
1.从物理内存0x000F0000—0x000FFFFF之间找到"_SM_"关键字。
2.找到后再向后16个字节,其后5个字节是否是关键字"_DMI_",如果是,则EPS表找到了。
SMBIOS EPS 表结构如下:
这就是我们找到的EPS表。
通过 EPS 表结构中 16H 以及 18H 处,得出数据表长度和数据表地址,即可通过地址访问 SMBIOS 数据结构表。从 EPS 表中的 1CH 处可得知数据表结构的总数,其中 TYPE 0 结构就是 BIOS information , TYPE 1 结构就是 SYSTEM Information 。其中每一种TYPE结构都有一个结构头(结构区域的部分)如下:
位置 名称 长度 描述
0H TYPE 号 1BYTE 结构的TYPE 号
01H 长度 1BYTE 本结构的长度,就此TYPE 号的结构而言
02H 句柄 2BYTE 用于获得本SMBIOS 结构,其值不定
每个结构都分为格式区域和字符串区域,格式区域就是一些本结构的信息,字符串区域是紧随在格式区域后的一个区域。结构 01H 处标识的结构长度仅是格式区域的长度,字符串区域的长度是不固定的。有的结构有字符串区域,有的则没有。
下面以TYPE0(BIOS Information)为例,介绍下格式区域和字符串区域,TYPE 0的格式区域:
位置 名称 长度 描述
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 一般为03H ,表示字符区第三个字符串
09H BIOS rom size 1BYTE 计算方法为(n +1 )×64K ,n 为此处读出数值
0AH BIOS 特征 8BYTE Bios 的功能支持特征,如PCI,PCMCIA,FLASH 等
12H Bios 特征扩展 0 or more bytes 保留给将来支持功能特征的空间
14H BIOS Major Release BYTE 识别SYSTEM BIOS 的major release,如对于revision 10.22的major是0AH,revision 2.1是02h。
15H BIOS Minor Release BYTE 识别minor release,16H->revision 10.22,01h->revision 2.1.
16H EC Firmware Major BYTE 识别Embedded controller firmware,作用参考14H
17H EC Firmware minor BYTE 识别Embedded controller firmware,作用参考14H
紧随 TYPE 0 ( BIOS information )结构区域之后,即在 Bios 特征扩展域后面的就是 TYPE 0 ( BIOS information )字符串区域,一个例子如下所示:
db ‘System BIOS Vendor Name’,0 ; 字符串以零结尾,第一个字符串:BIOS厂商
db ‘4.04’,0 ; 第二个:BIOS版本
db ‘00/00/0000’,0 ; 第三个:BIOS发布日期
db 0 ; 以0为整个字符中区域的结尾
大家注意到每一个字符串都是以00h结尾的,整个字符串区域是以0000H结尾,所以比如我们看下面:
|--------------------------------格式区域开始--------------------------------------------------|
| BYTE LABEL BIOS_Info |
| db 0 ; Indicates BIOS Structure Type |
| db 13h ; Length of information in bytes |
| dw ? ; Reserved for handle |
| db 01h ; String 1 is the Vendor Name |
| db 02h ; String 2 is the BIOS version |
| dw 0E800h ; BIOS Starting Address |
| db 03h ; String 3 is the BIOS Build Date |
| db 1 ; Size of BIOS ROM is 128K (64K * (1 + 1)) |
| dq BIOS_Char ; BIOS Characteristics |
| db 0 ; BIOS Characteristics Extension Byte 1 |
|--------------------------字符串区域开始(格式区域结束)----------------------------- |
| db ‘System BIOS Vendor Name’,0 ; |
| db ‘4.04’,0 ; |
| db ‘00/00/0000’,0 ; |
| db 0 ; End of strings |
|--------------------------字符串区域结束------------------------------------------------------|
BIOS 特征域表示BIOS 对一些特性的支持情况,Bit 1 和Bit 1 保留,Bit 2 未知,Bit 3 表示本BIOS 特征域是否被支持。
Bit 4-Bit 19 分别表示是否支持ISA 、MCA 、EISA 、PCI 、PCMCIA 、PnP 、APM 、BIOS 刷新、BIOS 影像(把 BIOS 的只读内容拷贝到快一些的内存中)、VL-VESA 、ESCD 、从CD 引导、可选择的引导、BIOS ROM 是否被插装、从PCMCIA 引导、EDD 规范。
Bit 20-Bit 25 表示对各种型号的软盘支持情况(均为中断Int 13h ),包括NEC 9800 1.2MB 软盘、Toshiba 1.2MB 软盘、5.25”/360KB 软盘、5.25”/1.2MB 软盘、3.5”/720KB 软盘、3.5”/2.88MB 软盘。
Bit 26-Bit 29 表示是否支持中断Int 5h(PrintScreen 屏幕截取服务) 、Int 9h(8042 键盘服务) 、Int 14h( 串口服务) 、Int 17h( 打印机服务) 、Int 10h(CGA/Mono 视频服务) 、NEC PC-98 。
Bit 32:47 保留给BIOS 厂商使用。
Bit 48:63 保留给计算机系统厂商使用。
BIOS 特征扩展字节1( 偏移12h 处) 表示对另外一些设备的支持情况,Bit 0-Bit 1 分别表示是否支持ACPI 、USB 遗留、AGP 、I2O 引导、LS-120 SuperDisk 引导、ATAPI ZIP 驱动器引导、1394 引导、智能电池。
BIOS 特征扩展字节2( 偏移13h 处) 表示对一些高级特性的支持情况。Bit 1-Bit3 表示是否支持功能键初始化网络服务引导、激活目标内容分发、UEFI 规范。Bit 4 表示SMBIOS 表描述的是一台虚拟机,Bit 5:7 保留。
三,
上面这么多就是理解SMBIOS的结构,那么访问SMBIOS的方法就是:
1.找到EPS,EPS怎么找?看前面搜"_SM_",后16字节有5BYTE是"_DMI_".然后从EPS结构中的16h和18h找到数据表的长度和地址也就是TYPE0的内存地址。(1CH处可以得到type数)。
2.有TYPE0的结构区域得到BIOS信息是否存在(结构头是不是全为00H)。
3.存在这读取信息。
4.直接读字符串区域->按结构找到TYPE号(每个TYPE结束都是以0000H),然后读取结构中的长度即结构区域长度,再直接移动结构区域长度到字符串区域。
-->.找到EPS结构表这样才可以获取TYPE数和address:
1 unsigned char far *TblAddress;
2
3 unsigned int TblLen;
4
5 /*seach the table's address*/
6
7 int Search_Strs()
8
9 {
10
11 char *str1="_SM_";
12
13 char *str2="_DMI_";
14
15 unsigned char far *ptr;
16
17 int j;
18
19 //initialise the address pointer
20
21 ptr=(unsigned char far *)0xf0000000;
22
23 //seach the address,0x000F0000-0x000FFFFF ,but under the dos,we will use the 20bit,so the address is F000:0000 - F000:FFFF
24
25 for(; ptr<=0xf000FFFf;)
26
27 {
28
29 for(j=0; j<strlen(str1); j++)
30
31 {
32
33 if(*(ptr+j)!=*(str1+j))
34
35 break;
36
37 }
38
39 if(j>=strlen(str1)) /*则已找到第一个字符串'_SM_',在其后16byte的5个byte是否是关键字'_DMI_'*/
40
41 {
42
43 ptr+=0x10;//地址加16个byte
44
45 for(j=0; j<strlen(str2); j++)
46
47 {
48
49 if(*(ptr+j)!=*(str2+j))
50
51 break;
52
53 }
54
55 if(j>=strlen(str2))//找到第二个字符串'_DMI_'
56
57 {
58
59 TblAddress=ptr+8;//SMBIOS结构表地址
60
61
62
63 TblLen=*((unsigned int far *)(ptr+6));
64
65 return 1;
66
67 }
68
69
70
71 }
72
73 else
74
75 {
76
77 ptr+=0x10;//没有找到第一个字符串,ptr+0x10重新search。
78
79 }
80
81 }
82
83 return 0;
84
85 }
-->.假如我们已经找到了,那么我可以打印出TYPE0了:
2014-04-25