2010年4月16日 星期五

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_”

04H

Check Sum

1 byte

用於檢查數據

05H

表結構長度

1 byte

Entry Point Structure表的長度

06H

Major版本號碼

1 byte

用於判斷SMBIOS版本

07H

Minor版本號碼

1 byte

用於判斷SMBIOS版本

08H

表結構大小

2 byte

用於即插即用接口方法獲得數據表結構長 度

0AH

EPS修正

1 byte


0B-0FH

格式區域

5 byte

存放解釋EPS修正的訊息

10H

關鍵字

5 byte

固定為“_DMI_”

15H

Check Sum

1 byte

Intermediate Entry Point Structure(IEPS)Check Sum

16H

數據表長度

2 byte

SMBIOS數據表長度

18H

數據表位址

4 byte

SMBIOS數據表的真實內存位置

1CH

數據表結構數目

2 byte

SMBIOS數據表的結構數目

1EH

SMBIOS BCD修正

1 byte


通過EPS表結構中的12H以 及14H處, 得出數據表長度和數據表地址,即可通過地址訪問結構表。從EPS表中的1CH處 可得知結構表結構的總數,其中TYPE0結構就是BIOSinformationTYPE1結 構就是SYSTEMInformation

每個結構的頭部是相同的,格式如下:

位置

名稱

長度

描述

00H

Type number

1 byte

結構的type number

01H

長度

1 byte

本結的長 度,就此type number的 結構而言

02H

Handle

2 byte

用於獲得SMBIOS結構,使用方法未知

每個結構都分為格式區域和字符串區域,格式區域就是一些本結構的信息,字符串區域是緊隨在格 式區域後的一個區域。結構01H處標識的結構長度僅是格式區域的長度,字符串區域的長度是不固定的。

下面以TYPE0BIOSinformation) 為例説明格式區域和字符串區域的關系


TYPE0BIOSinformation) 格式區域如下:

位置

名稱

長度

描述

00H

Type number

1 byte

結構的type number,此處是0

01H

長度

1 byte

Type 0格式區域的長度,一般為14H,也有13H

02H

Handle

2 byte

一般為0000H

04H

BIOS廠商訊息

1 byte

此處是BIOS賣方的訊息,可能是OEM廠商名,一般為01H,代表緊隨格式區域後的字串區域的第一個字串

05H

BIOS版本

1 byte

BIOS版本號,一般為02H,代表字串區域的第二個字串

06H

BIOS開始位址段

2 byte

用於計算常駐BIOS鏡像大小的計算,方法為(10000H-BIOS開始位址段)*16

08H

BIOS發佈日期

1 byte

一般為04H,表示字串區第三個字串

09H

BIOS ROM Size

1 byte

計算方法為(n+1)*64Kn為此處讀出的數值

0AH

BIOS特徵

8 byte

BIOS的功能支援特徵,如PCI,PCMCIA,FLASH等等

12H

BIOS特徵擴展

不定


緊隨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 的資料,通常被其他硬體偵測程式當作後端工具使用。

2010年4月14日 星期三

何謂RIL

Radio Interface Layer (RIL)提供了一個處理CellCore系統軟體以及無線電硬體之間通訊的介面.
RIL提供了一個抽象層使你可以建立一個驅動然後套用在不同的無線電硬體模組之上.
藉由把裝置之中的硬體相依元件的細節抽象化,RIL使OEM可以整合各式各樣的modem到設備之中
這樣的好處是可以提供產品市場區隔的機會,大幅縮短開發的流程.
Radio Interface Layer RIL(Radio Interface Layer)負責數據的可靠傳輸、AT命令的發送以及response的解析。應用處理器通過AT命令集與帶GPRS功能的無線通訊模塊通信。
AT command由Hayes公司發明,是一個調制解調器製造商採用的一個調制解調器命令語言,每條命令以字母"AT"開頭。
RIL是由RIL proxy以及RIL driver兩個模組所構成 proxy layer是一個base on WinCE的動態連結函式庫(DLL) 用來管理進入由底層打到driver layer的通知訊息以及IPCCellCore藉由link這個proxy的DLL來使用RIL的API



RIL proxy是由Microsoft所提供的但是我們必須去寫一個客製化的RIL driver以符合各種不同的無線電硬體 Microsoft亦提供了一個可以運作在一些GSM系統的RIL driver的sample作為參考



RIL driver 的工作,就是處理從 RIL Proxy 所下來的 IO Control,轉換成相對應的 AT Command,進行應該處理的工作,並且把回應回傳給上層的 Phone application。而同時也要處理 Modem 的 unsolicited response。
AT Command 的回應可以分為二類,unsolicited 與 solicited。如果這二類的 AT Command 都是一樣的回應,那麼 unsolicited 的 AT Command 的 parser 會先 parse Modem 的回應,然後後面的 OK 才會被 solicited 的 AT Command 的 parser 再分析。

2010年4月12日 星期一

Microsoft Foundation Classes

Microsoft Foundation Classes, 簡稱MFC,是一個微軟公司提供的類別庫(class libraries),以C++類的形式封裝了 Windows的API,並且包含一個應用程式框架,以減少應用程式開發人員的工作量。其中包含的類包含大量Windows控制代碼封裝類和很多Windows的內建控制項和元件的封裝類。


  • MFC的優點
    MFC的主要優點是可以用物件導向的方法來呼叫Windows API,以及應用程式開發的便捷。MFC將很多應用程式開發中常用的功能自動化,並且提供了文檔框架檢視結構和活動文檔這樣的便於自訂的應用程式框架。同時,在Visual C++內部也內建了很多對MFC的例如類精靈這樣的支援以減少軟體開發的時間,使用類精靈可以生成從hello world這樣的簡單程式到活動文檔伺服器這樣的複雜程式。MFC的訊息對映機制也避免了使用性能較低的龐大虛擬函式表。
  • MFC的缺點
    雖然MFC的原始碼對使用者是完全開放的,但是MFC的一些封裝過程過於複雜,以致於新使用者很難迅速掌握MFC的應用程式框架,以及在偵錯中定位問題的位置。同時,很多MFC物件不是執行緒安全的,致使在跨執行緒存取MFC物件時需要編寫額外的代碼。另外,MFC的很多類依賴於應用程式精靈生成的代碼,使得在使用Visual C++中其他型式的應用程式精靈生成的工程中添加MFC支援的難度大大增加。

Hierarchy Chart

2010年4月10日 星期六

驅動程式的環境設定

俗語說的好「工欲善其事,並先利其器。」因此,在我們在開發驅動程式之前,要先把開發工具準備好。然而開發驅動程式需要的工具有那些呢?

  •  Microsoft Windows Driver Kit

  •  Text Edit or Microsoft Visual C++

為何大部分介紹開發驅動程式的書都將 VC++列為工具之一呢?其實如果只是單純開發驅動程式是不需要,但是安裝、反安裝、啟動、停止驅動程式就需要用到 VC++的函式庫,因此大部分介紹驅動程式的都將 VC++列為開發程動程式的工具之一。
開發 Windows XP SP2 的驅動程式建使用 Windows Driver Kit 來組譯驅動程式碼才能正常的載入及啟動使用者的驅動程式。倘未使用 VC++ 2005 開發在Windows Vista 應用程式的話,只需在資源檔加入下列程式碼,即可讓執行的應用程式由使用者權限提升到 Administrator 的權限。














  • 準備好開發驅動工具之後,接下來就是如何安裝軟體及環境設定,別擔心,只需要順著以下的步驟,便能輕鬆完成開發驅動程式的工具及環境設定。

    1.1 WDK 的安裝過程
    安裝組譯驅動程式的 Microsoft Windows Driver Kit ,執行 setup.exe 即可。
    安裝完 Microsoft Windows Driver Kit 在 Windows Program Menu 中即可看到已經設定的驅動程式的組譯環境設定,只使用 text Edit 編輯驅動程式再利用組譯程式供的組譯環境即可產生開發中版本或者正式版的驅動程式。























    假 如 是 開 發 DEBUG version , 執 行 -> Windows Driver Kits -> WDK7 600.16385.0 -> Build Environments -> Window 7 -> x86 Checked Build Environment

















    執行組譯程式 Build –cZ 或者 bcz
















    1.2 VC++ 環境設定

    當然,如果使用 VC++來編輯驅動程式和使用 BATCH File 來組譯驅動程式的話,需要做一些環境上的設定,只需要隨著以下的步驟及可完成。
    1. 設定 DDK BOOT 目錄 –
    選擇『我的電腦』按右鍵選擇『內容』即可看到【系統內容】的視窗,選擇『進階』的選單,可以看到三個子選單、【環境變數】及【錯誤報告】,選擇『環境變數』,即可看到【xxx 的使用者變數】及【系統變數】,選擇【系統變數】 選 單 下 的 『 新 增 』 新 增 變 數 ( 變 數 名 稱 =DDKROOT 變 數 值,=C:/WINDDK/3790.1830)




















    2.建立 MyDriver 的目錄存放 Driver 的原始程式碼
    3.建立組譯驅動程式的批次檔
    Build.bat %1 %2 %3 %4
    %1 – 放驅動程式程式碼的目錄
    %2 – 要組譯的作業系統
    %3 – 要建立正式版或開發中版本
    %4 – 其他的參數和組譯程式相關
















    4.環境設定
    在 VC++應用程式中,選擇應用程式中,選擇『TOOL』『選單中的『Options』 【Options】,的 畫 面 中 , 在 『 Projects 』 選 項 的 『 C++ Directories 』 建 立 新 的 目 錄(E:/MyDriver)

















    5.建立一個驅動程式的專案建立一個驅動程式的專案
    在 VC++的應用程式中,選擇『的應用程式中,選擇『FILE』選單中的『NEW』的選項,在選單』的選項,在選單中選擇『Project...』子選項,即可看到【New Project】畫面,在『Project Types』選單中,選擇(General),而在『 Templates 』選單中,選擇
    (Makefile Project)輸入 PROJECT Name 和 Location 最後按下,,『OK』進行下一步。
















    在【Makefile Application Wizard】畫面的『Application Settings』選單,輸入(Build command line = build E: MyDriver WXP chk -cZ)和( Output = sample1.sys),最後按下『Finish』即完成專案的建立。
















    6.加入 makefile 和 source
    Makefile.def 是用來的告訴 NAMKE.EXE 要如何組譯驅動程式的參數,然而 DDK 早已當我們建立好一般驅動程式可用的 Makefile.def,所以我們只需要將 makefile.def 箝入 makefile 即可。














    Source 是用來宣告驅動程式包含了那些檔案及組譯後檔案種類和名稱,因為 DDK 除了可以組譯驅動程式之外也可以組譯應用程式,所以需要指定組譯後的檔案種類。

    TARGETNAME = 驅動程式的名稱
    TARGETPATH = 驅動程式的目錄,Default=C:/WINDDK/BIN
    SOURCES = 驅動程式的來源
    USE_MAPSYM=1 產生驅動程式的符號給 Microsoft Kernel Debug 做為偵錯用














    7.加入驅動程式的程式碼及版本控制
    在 VC++專案畫面的『Solution Explorer』選單中,加入程式碼

















    將滑鼠移到在『Resource Files』選項中,按右鍵選擇『Add』選項,在選單中選擇『Add New Item』 【Add New Item】。在的畫面中選擇『Resource File(.rc)』,然後輸入(Name=Sample1)最後按下『OPEN』進行下一步。


















    選擇『Sample1.rc』,按右鍵選擇『Add Resource ...』 【Add Resource】,在的畫面中選擇『Version』,按下『New』接著下一步。
















    填入驅動程式的版本及相關的資訊 『Build』,選單中 選擇, 『Build Solution』或 者 『 Rebuild Solution 』, 即 完 成 了 我 們 的 第 一 個 驅 動 程 式「sample1.sys」。

















    1.3 驅動程式的組譯過程
    完成驅動程式的環境設定後,驅動程式是如何組譯而成的呢?而 sample1驅動程式中的 source 和 makefile 又辦演什麼角色呢?















  • DIRS-是用來告知 BUILD UTILITY 有那些磁碟目錄需要被組譯,因此,如果我們的驅動程式落於不同的磁碟目錄,除了,原本的 SOURCE 檔案之外,記得還要加入 DIRS 來告知 NMAKE.EXE。
  • SOURCE-是用來告知 NMAKE.EXE 有那些檔案需要被組譯,
  • MAKEFILE-是將組譯驅動所需要的組譯參數傳給 NMAKE.EXE。即為MAKEFILE.DEF 檔案。
  • MAKE.EXE-參考 DIRS、SOURCE 及 MAKEFILE 來設定組譯驅動程式的環境,完成後,再啟動組譯程式開始組譯驅動程式。
  • .RC-用來宣告驅動程式的版本
  • .C 及.CPP-驅動程式的驅式碼
  • EVENT LOG-如果驅動程式會在系統事件中紀錄事件的話,可以加入EVENT LOG 的宣告來紀錄事件。
  • COMPLIER and LINKER-組譯驅動程式的程式碼變作系統的驅動程式

    驅動程式碼經過 nmake.exe、complier.exe 及 linker.exe 之後,驅動程式碼就變成作業系統的驅動程式。

    1.4 驅動程式的開發工具

    驅動程式設計開發上有一些非常有用的輔助工具,當然這些軟體也會隨著時代或需要而做修改,所以驅動程式設計者需要常常上網去取得最新的版本,或許可以縮短開發程式的時間。
  • Microsoft WinDbg – 由 Microsoft 所開發的,是驅動程式除錯最強的工具,可以做單機除錯或者除錯另一台電腦。一般驅動程式設計者,都是用來除錯另一台電腦 WinDbg 提供 COM PORT IEEE1394 USB 2.0,、、PORT 等方法連接另一台電腦來除錯。其中 COM PORT 和 IEEE1394才有支援在 Windows Easy Step 設除錯點的功能,但是現在的電腦已經很難找到有支援 COM PORT 或 IEEE1394 只能使用 USB 2.0 PORT來除錯,只是注意 USB 2.0 除錯只支援 Root Hub 的 PORT 0。
  • VMwave Player – 為了方便除錯,一般的驅動程式開發者,都會使用虛擬電腦來除錯,現今較多人使用的是 VMware Player,所以學會如何使用 WinDbg 配合 VMware Player 是必修的課程。


1.4.1 VMware Player
使用『Create a New Virtual Machine』建立一個新的虛擬電腦用來除錯。



然後,在虛擬電腦上新增一個『Serrial Port』並且設定如下:




















就可以使用虛擬電腦的虛擬 COM PORT 可以和 WinDbg 連線。

1.4.2 電腦設到除錯模式

在 Windows 7 上,執行『MSCONFIG.EXE』,選到『開機』的選項。
































選擇『進階選項』,選擇『偵錯』。
如果使用虛擬電腦的 COM PORT,就不需設傳輸速率。
如果使用實際的 COM PORT,需設傳輸速率。
如果使用 IEEE 1394,需要設定頻道
如果使用 USB 2.0,需要設定 USB 目標名稱




























重新開機就可以使用 WinDbg 來除錯了。

1.4.3 WinDbg

如果使用虛擬電腦連結 WinDbg 的情形下,虛擬電腦開到 Windows 7畫面出現時,就會停下來了。此時,使用以下的指令開啟 WinDbg。
『windbg -b -k com:pipe,port=\\.\pipe\com_1,resets=0』



載入驅動程式的程式碼

選擇【File】->【Source File Path】->【Browse…】找到程式碼存放的目錄,可以直接在程式碼上設偵錯點。

















2010年4月6日 星期二

與Linux 的第一次


什 麼是linux. 它像Windows和MacOS一樣同為一種作業系統.
而每種作業系統都有不一樣的操作方式.
Windows和 MacOS都是為client(客戶端以下以英文代之)的作業系統.
而Nt Linux和Unix都是能將這些client端整合起來.
並 且也能提供Server(伺服器)功能的作業系統.

Windows和Mac都是以圖形方式來操作系統.
基本上只要會按滑鼠. 在Winodws以及Mac上都可以很順利的操作.
當然也有例外. 像是Nt雖然也以圖形方式操作. 但可沒那麼簡單.
當然這並不在我們 討論範圍.
Linux則是以文字界面來操作. 什麼是文字界面???
當然就是早期的Dos界面囉. 白底黑字. 沒錯就是它.
這 對有Dos基礎的人來說算是一大福音. 當然它也像Dos要背一堆指令.
否則你就只能瞪著螢幕發呆的份了.
一般來講Linux和一般來說跟一般的Server差不多.
都能提供基本的Server功能. 隨著之後所安裝的套件而逐漸增加其功能.
嚴格說來Linux是一個電腦與各式各樣套件之間的橋樑.
Linux一裝好基本上你無法以它來跑 jsp或asp之類的程式語言.
必須另外安裝. 而隨著不同版本的Linux也有不同的功能形式.
不過大體上是大同小異的. 在提到版本之前必須先讓各位瞭解何謂distribution.
它是一個具備最低限度的必要程式. 就如同Windows對Windows的使用者來說.
它是一個最基本的軟體. 之後要聽歌再去裝winamp. 要玩Game再裝Game一樣.
Distribution 也是一個最基本的架構.
目前較常見的可分為 :

Red Hat Linux :
這是由Ret Hat Software公司所開發的. 它是目前Linux中佔有率最高的.
使用者一般來說只要按照步驟就可以輕鬆的將Linux裝起來. 也是以後
倉 木所會提及的Linux版本.

Slackware :
這是一個存在已久distribution. 軟體設計十分易於安裝.
它 是一款針對初學者想從安裝開始便獨立完成一切工作的使用者.

Debian Gun/Linux :
基本上這個 distribution在一安裝完成就會有許多程式供使用者選用.
除非有特殊的軟體.否則基本上一安裝完成就不太須要安裝其它的.
這是 對於有一定基礎概念的使用者. 初學者使用起來可能會覺得有所困難.

Turbo Linux :
商用的版本. 這套版本已在大陸香港放行. 有點像Ret Hat的中文化版本.

Android 終於來了 @

Android是基於Linux核心的軟體平台和作業系統,是Google在2007年11月5日公布的手機系統平台,早期由Google開發,後由開放手 機聯盟(Open Handset Alliance)開發。它採用了軟體堆層(software stack,又名以軟體疊層)的架構,主要分為三部分。低層以Linux核心工作為基礎,只提供基本功能,其他的應用軟體則由各公司自行開發,以java 作為編寫程式的一部分。另外,為了推廣此科技,Google和其它幾十個手機公司建立了開放手機聯盟(Open Handset Alliance)。Android在未公開之前常被傳聞為Google電話或gPhone。大多傳聞認為Google開發的是自己的手機電話產品,而不 是一套軟體平台。

早期Android裝置 (image from wikipedia)
藍色部分:應用程式。 綠色黃色部分:中間件。 紅色部分:作 業系統。 (image from wikipedia)


在Android架構,總共是由5個部份來組成。分別是:
(1)Applications(應用程式)
(2)Application Framework(應用程式架構)
(3)Libraries(函式庫)
(4)Android Runtime(Android執行環境)
(5)Linux Kernel(Linux核心)

Libraries (函式庫)
在Android SDK(軟體開發套件)包含一組系統元件,可以讓開發者呼叫來使用,而這一組系統元件使用的是C/C++的函式庫,開發者可以透過應用程式架構使用這些功能。

在Android SDK(軟體開發套件)的Android Runtime分成二個重要的元件來執行系統,雖然Android是用Java來開發、撰寫應用程式,但卻不使用Java Runtime來執行Java程式,而是自行研發Android Runtime來執行程式。
這二個重要元件分別是Core Libraries(核心函式庫),另一個是Dalvik Virtual Machine(Dalvik 虛擬機器)。
Core Libraries(核心函式庫)裡頭已經包含了絕大多數Java所需要呼用的函式,接著每一個Android應用程式都會以自屬的process(程序)。而且Android不是用一個Dalvik虛擬機器來同時執行多個Android應用程式,而是每個Android應用程式都用一個自屬的Dalvik虛擬機器來執行。
Dalvik Virtual Machine(Dalvik虛擬機器)是一種暫存器型態的虛擬機器。在撰寫開發時就已經設想用最少的記憶體資源來執行,以及前述的「同時可執行多個VM個體」。

所提供的核心系統服務,如下所述:
A.安全性(Security)
B.記憶體管理(Memory Management)
C.行程管理(Process Management)
D.網路堆疊(Network Stack)
E.驅動程式模型(Driver Model)包含下述這些常規的驅動程式:
(1)Display Driver
(2)Keypad Driver
(3)Camera Driver
(4)WiFi Driver
(5)Flash Memory Driver
(6)Audio Driver
(7)Binder(IPC) Driver
(8)Power Management