小華的部落格: 2007/11/11 - 2007/11/18

搜尋此網誌

星期四, 11月 15, 2007

EFI Framework 概述

如果有下載Intel EFI Spec的人就知道每次提到EFI的時候就會有一個很大的綠色的H,這個就是EFI 的framework。

什麼是Framework呢? 這邊就簡單說一下整個EFI framework架構。

我個人猜想,當初Intel 開發EFI其實只是為了要擴充BIOS的功能,因為在Legacy BIOS的年代,很多的東西都沒有模組化,因此當硬體或是Platform有比較大的變動的時候,對於整個BIOS開發的時間就會延長,那種感覺就好像是你每次都要對一個新的硬體重新寫一次你的BIOS程式碼,很沒有效率。

另外在Legacy BIOS年代,所有的BIOS程式碼的開發幾乎都是不同的BIOS vendor與Chipset 廠商ㄧ同合作,因此不同家的BIOS Vendor對於相同Chipset 廠商所寫出來的程式碼的穩定度就會不同,這對於 Intel 來說就等於要多花好幾倍的時間去跟不同BIOS Vendor 來討論以及處理問題。

因此,假如Intel 能夠把底層的BIOS程式碼變成模組化容易抽換,那麼BIOS在開發的過程中就會快速以及方便許多,而這種概念就像是Windows裡面的HAL 層的概念,簡單說在Windows系統中實際存取硬體是透過ㄧ個叫做HAL介面的處理,所以當Windows想要在不同的硬體上執行的時候,他只要把HAL的介面換成新的硬體的處理方式就可以了,而在Windows可以不用再重新改寫,例如你把Windows拿到Apple上面去執行,對於微軟的工程師來說,只要把HAL從新改寫就可以了。

而EFI的Framework 就像是HAL,Intel 本身提供了一些Protocol以及一些Lib來存取他們的硬體,而這一層就叫做Framework。對於Intel來說,不管你是哪一家的BIOS Vendor就不會再出現A廠商存取Intel Chipset有問題而B廠商不會,因為最底層都是Intel 自己負責。

而建構在Framework 上的一些功能就是各家BIOS Vendor自己去負責,感覺就像我之前說的,Inetl 留下一些地方給BIOS Vendor填寫他們的程式碼,然後BIOS Vendor在留下一些地方給OEM/ODM BIOS填寫ㄧ些程式碼,彼此關係就是一層一層環環相扣。

這邊還要提到EFI Framework 除了前面說的那些之外,他還提供了一些Boot Flow的控制,這就像是說從Power On--->POST--->Boot to OS的一些流程的控制也是由這個Framework 提供,感覺就像是你寫了一個main{},而裡面的FunA()/FunB()/FunC() 的先後順序的執行你也都寫好了,之後FunA() 內要填什麼樣的子程式碼就屬於BIOS Vendor跟OEM/ODM BIOS自己決定了。
//--------------------------------------------------
// EFI Framework 的概念與C語言對應的示意圖
//--------------------------------------------------
#include <--Intel提供的函數
main() <--Intel 提供的Boot Flow
{
Dispatch FunA(); <--SEC
Dispatch FunB(); <--PEI
Dispatch FunC(); <--DXE
Dispatch FunD(); <--BDS
...
}

EFI Framework還有另一個優點就是移植性高,例如Intel 可以把整個EFI Framework概念移到嵌入式系統上去實做BIOS,這樣子他們能夠開發的市場就會越來越大。

前面提到這些都是Intel提供的EFI Framework,那麼AMD/其他廠商怎麼辦? 對,我也在想這個問題,由上面的說法可以看出Intel 的野心,他想把原本BIOS Vendor做的事情自己拿來做,為了不讓人家知道太多Chipset內的秘密,他自己寫Chipset的函數並做成Framework給BIOS vendor使用,所以我個人在思考幾個問題:

a) 假設不同 BIOS Vendor 都使用相同的函數的情況下,彼此的優缺點是不是只剩下誰提供的OEM/ODM Features比較多 ?

b) 假設不同 BIOS Vendor 都使用相同的Framework下,當底層換成AMD或是其他廠商後,彼此的優缺點是不是只剩下誰對不同廠商的支援度比較高,市場佔有率就比較高?

c)假設OEM/ODM BIOS 都使用相同的Framework後,開發時間縮短相對的被取代的性質是否也相對提高?

d) Others..

以上大致上就是個人對於EFI Framework 的一些理解跟想法,如有誤請先進不吝指正,謝謝!

星期三, 11月 14, 2007

BIOS 開發環境

這篇文章主要是概述 BIOS 開發環境下的一些基礎知識,有助於了解如何自己去撰寫一個屬於你自己的 BIOS。

大家都知道Legacy BIOS是使用Assembly 所撰寫,目前的UEFI則是使用C語言,但是不論是哪一種BIOS,其開發環境下的基礎知識都還是相同。

ㄧ般BIOS工程師開始學習BIOS Vendor所提供的BIOS Code時,最主要會學習下列幾個項目:

1.Build process : BIOS ROM是如何產生,這部份要去了解的是整個流程為何?
例如: (ㄧ堆Source code) --> 經過哪些Build process --> (產生BIOS.ROM)

2.Directory : BIOS Code的目錄架構為何? 哪些是屬於Framework/Kernel/Oem ?

3.Build Config : BIOS 相關參數的設定,每家Vendor設定方式都不同!

4.Build Tools : BIOS 建立時使用了哪些工具,ㄧ般都是MASM+VisualStudio+DDK+Bios Vendor自己開發的一些Tools。

5.Build your BIOS ROM : 如何建立你的第一個BIOS ROM,ㄧ般都是使用nmake/直接在IDE(整合開發環境下)下設定好,就可以直接去Buildㄧ個完整的BIOS ROM。

有了上述的整理分類,其實不難發現,實際上我們撰寫的BIOS code只是一個BIOS Vendor做出來的環境下(或稱為框架下)去"填寫"一些屬於我們的程式碼,就像是C語言的開發環境下你只需要知道在main(){.....} 的括號內去撰寫程式碼就好了,後面的事情BIOS Vendor都幫你做好了。

所以OEM/ODM端的BIOS能夠處理的東西都是比較偏向客戶端的需求而去撰寫一些程式碼,我們稱這些程式碼為"Features"。而這些部份就像你買Asus /Acer/...etc 不同家的電腦,裡面所能提供的功能會不同。

雖然好像看起來只是"填入"ㄧ些程式碼,但是這部分又與整個硬體運作以及BIOS Vendor所提供的程式碼的"穩定度"有很大的關係,所以如果只是單純修改這些程式碼約1年可以上手,但是如果要能處理bug,那麼可能就需要多年的經驗累積了。因此在這種OEM/ODM BIOS與BIOS Vendor分工合作的情況之下,OEM/ODM端的BIOS有自己負責解決問題的地方,而BIOS Vendor也有自己負責要處理的地方,大家相互合作。

說了這麼多,對於BIOS開發環境應該有所了解,但是最近案子開始在忙了,所以會寫Blog時間會比較少了,等過陣子等案子不忙的時候,我再告訴大家如何如果要實做一個類似BIOS vendor開發環境,你需要哪些工具,還有怎樣子做。

星期一, 11月 12, 2007

Debug.com 查看記憶體資料的方式

ㄧ般我們都知道Debug.com 可以寫一些組合語言程式、除錯以及查看一些資料,但是要如何用呢?

這邊就簡單描述幾個基本的Debug 用法,用來查看一些BIOS留在記憶體中的一些資訊。

ㄧ開始我先介紹一下指令的用法以及我們要搜尋的內容是哪些:
1) 在執行Debug.com 後會出現"-" 的提示訊息,意思是說"換你了"
所以我們可以在提示訊息後面開始鍵入我們要的指令來達到一些目的
例如:
指令 S :搜尋記憶體內的內容,語法是 S <起始位址> <範圍> <搜尋的內容>
-S E000:0 ffff '1234' <--搜尋E0000h~Effffh 內的記憶體,找'1234' 指令D : 傾印記憶體內容,語法 D <起始位址> <結束位址,可略>
-D E000:0 <--查看E0000h內的記憶體內容 -D E000:0 100 <--查看E0000h~E0100h的記憶體內容 2)而這篇文章的範例中我們要找的是DMI Table 跟ACPI Table 的Entrypoint a.在搜尋DMI Table時我們要先找到SMBIOS的關鍵字 '_SM_' 所在位置,然後在經由這個位址找到實際DMI Table擺放的位址。 b.在搜尋ACPI Table的Entrypoint時,只要在E0000h~FFFFFh中搜尋關鍵字就可以找到了。 上面所提到的關鍵字都是標準的SMBIOS/ACPI Spec中所提到的,所以BIOS會依照這些Spec去建立一些資訊,並把他們擺放在1MB以下的記憶體中,也因此我們可以利用這些關鍵字去找到BIOS到底在這些Structure中填入了什麼樣的資料。 以下就是實際範例: 1.首先先點選"開始"-->"執行" 並且鍵入"cmd" 後按下"確定"按鍵:


2.依照下圖鍵入相關指令你就可以查看DMI Table Info:

上圖可以看出在記憶體F000:6D20 的地方有關鍵字'_SM_',然後使用D 指令去看這個記憶體的內容,再依照Spec中提到的偏移位址找到DMI Table擺放位址

接著ㄧ樣使用D指令去看DMI Table的內容,其中00 代表Type 0,18代表Type 0的長度...etc,其他就對照著Spec看就可以了。


3.依照下圖鍵入相關指令你就可以查看ACPI Table 的 EntryPoint:
上圖可以看到搜尋E0000h~Effffh找不到關鍵字'RSD PTR',所以接著搜尋F0000h~FFFFFh。

在找到關鍵字的位址後,ㄧ樣使用D指令去查看記憶體內的內容,在畫面右邊你可以看到"RSD PTR",他對應的記憶體內容就是 52 53 44 20 50 54 52,其他的部份你就可以查看ACPI Spec然後看其他欄位到底代表什麼意思。

[結論]

這篇文章最主要目的是簡介Debug.com 如何去查看BIOS所留下來的內容,有助於了解BIOS撰寫時你寫了什麼樣的程式碼,留下了什麼資料在哪一塊記憶體中。

※上面所提到的記憶體位址會依照不同BIOS而有所不同,所以你在你的電腦內看到的記憶體位址也會與本文中的範例不同。