2008年9月3日 星期三

符合SMBIOS規範的電腦系統訊息獲取方法

符合SMBIOS規範的電腦系統訊息獲取方法
作者:ramble(如需轉載請注明作者)
SMBIOS (System Management BIOS, SMBIOS),它是一種定出主機板及系統廠商如何以標準的格式顯示產品管理資訊的規格。
SMBIOS 及 DMI(Desktop Management Interface)規格兩者皆是由 Desktop Management Task Force (DMTF) 所草擬的,它是一個由業界所領導,實行技術規格以確認開放性標準的組織。
符合SMBIOS規範的電腦,可以通過訪問SMBIOS的結構獲得系統息,共有兩種辦法可以訪問:

1.通過即插即用功能接口訪問SMBIOS結構,這個在SMBIOS2.0標准裏定義了,從SMBIOS2.1開始這個訪問方法不再被推薦使用。
2.基表結構的方法,表内容是tableentry point的數據,這個訪問方法從SMBIOS2.1以後開始被使用,從2.1開始,以後的版本都推薦使用這種訪問方式。在2.1版本中允許支這兩種方法中的任意一種和兩種都支,但在2.2已經以後的版本,必須支方法2

市場上計算機已經均支SMBIOS2.3標准,所以只考慮方法2,基表結構的訪問方式。
表結構訪問SMBIOS的過程是先找到EntryPoint StructureEPS)表,然後通過EntryPoint StructureEPS)表的數據找到SMBIOS數據表。
訪問SMBIOSEPS表的操作過程如下:
1.從物理内存0xF0000-0xFFFFF間尋找關鍵字“_SM_”
2.找到後再向後16個字節,看後面5BYTE是否是關鍵字“_DMI_”,如果是,EPS表即找到。
注:按照SMBIOS規範説明,找到關鍵字”_SM_”後就可以確定此處就是EPS表結構,但我在實際操作中發現有為數不少的電腦的指定64K内存中有不只一個“_SM_”,所以不能用找到”_SM_”來確定,需要繼續判斷16個字節後是否是“_DMI_”
SMBIOSEPS表結構如下:
位置名稱長度描述
00H關鍵字4 byte固定是“_SM_”
04HCheck Sum1 byte用於檢查數據
05H表結構長度1 byteEntry Point Structure表的長度
06HMajor版本號碼1 byte用於判斷SMBIOS版本
07HMinor版本號碼1 byte用於判斷SMBIOS版本
08H表結構大小2 byte用於即插即用接口方法獲得數據表結構長度
0AHEPS修正1 byte
0B-0FH格式區域5 byte存放解釋EPS修正的訊息
10H關鍵字5 byte固定為“_DMI_”
15HCheck Sum1 byteIntermediate Entry Point Structure(IEPS)Check Sum
16H數據表長度2 byteSMBIOS數據表長度
18H數據表位址4 byteSMBIOS數據表的真實內存位置
1CH數據表結構數目2 byteSMBIOS數據表的結構數目
1EHSMBIOS BCD修正1 byte
通過EPS表結構中的12H以及14H處,得出數據表長度和數據表地址,即可通過地址訪問結構表。從EPS表中的1CH處可得知結構表結構的總數,其中TYPE0結構就是BIOSinformationTYPE1結構就是SYSTEMInformation
每個結構的頭部是相同的,格式如下:
位置名稱長度描述
00HType number1 byte結構的type number
01H長度1 byte本結的長度,就此type number的結構而言
02HHandle2 byte用於獲得SMBIOS結構,使用方法未知
每個結構都分為格式區域和字符串區域,格式區域就是一些本結構的信息,字符串區域是緊隨在格式區域後的一個區域。結構01H處標識的結構長度僅是格式區域的長度,字符串區域的長度是不固定的。
下面以TYPE0BIOSinformation)為例説明格式區域和字符串區域的關系

TYPE0BIOSinformation)格式區域如下:

位置名稱長度描述
00HType number1 byte結構的type number,此處是0
01H長度1 byteType 0格式區域的長度,一般為14H,也有13H
02HHandle2 byte一般為0000H
04HBIOS廠商訊息1 byte此處是BIOS賣方的訊息,可能是OEM廠商名,一般為01H,代表緊隨格式區域後的字串區域的第一個字串
05HBIOS版本1 byteBIOS版本號,一般為02H,代表字串區域的第二個字串
06HBIOS開始位址段2 byte用於計算常駐BIOS鏡像大小的計算,方法為(10000H-BIOS開始位址段)*16
08HBIOS發佈日期1 byte一般為04H,表示字串區第三個字串
09HBIOS ROM Size1 byte計算方法為(n+1)*64Kn為此處讀出的數值
0AHBIOS特徵8 byteBIOS的功能支援特徵,如PCI,PCMCIA,FLASH等等
12HBIOS特徵擴展不定
緊隨TYPE0BIOSinformation)結構區域之後的就是TYPE0BIOSinformation)字符串區域,如下所示:
db‘System BIOS Vendor Name’,0 ; 字符串以零結尾,第一個字符串:賣方
db‘4.04’,0 ; 第二個:BIOS版本
db‘00/00/0000’,0 ; 第三個:發布日期
db0 ; 0為整個字符區域的結尾,所以要找下一個TYPE,只要在字符區域找到連續的0000H即可
注:當有EPS表中得到結構表的開始地址後,可以直接按結構來尋找相應的TYPE號,找到後直接讀取就是該TYPE對應的結構的格式區域息,然後向後移動結構區域長度(構區域長度由該結構的01H處讀出)個BYTE,即是該TYPE機構的字符串區域。


由上面介紹可知,獲得BIOS息的辦法就是:

1.通過EPS表的12H14H數據找到TYPE結構表,然後找到TYPE0的内存地址。(不一定是首個)
2.由TYPE0結構區域中得出相應BIOS息是否存在(存在則是上面所述的 01H,02H,03H依次排布,不存在則是相應的位置上為00H)。
3.如存在息,則從字符串區域中讀取對應BIOS息。
獲得SYSTEM信息方法同上,只是TYPE結構區域有所不同,請參照SMBIOSReference Specification

在Linux環境裏可以使用dmidecode這支程式去dump SMBIOS的資料
dmidecode主要功能:
桌面管理介面提供標準化的電腦硬體描述,包括硬體的特性,比如 BIOS 的序號、與硬體連接線。dmidecode 提供由 BIOS 輸出 DMI 的資料,通常被其他硬體偵測程式當作後端工具使用。

沒有留言: