小華的部落格

搜尋此網誌

網頁

星期二, 9月 04, 2012

快快樂樂學EFI (2)


 
快快樂樂學EFI
Harrison Hsieh 2010/07/19
Chap 2 Build EFI How to
      這一章是用來說明如何去Build 你的EFI Tool Kit或是EDK,經由一步一步的帶領之下可以讓你很快的擁有一個EFI 開發環境。
 
2.1 Build EFI Tool Kit
首先,你必須透過SVN去下載一套EFI Tool Kit,假設我下載後是放在 D:\efitoolkit,則他的目錄結構會長的像下圖一樣:
 

 
首先,我們先去修改Build.cmd這個檔案,這個檔案最主要是去控制一些環境變數,這邊環境變數會影響你產生的輸出檔案是 IA32/X64
set SDK_BUILD_ENV=em64t  
set SDK_INSTALL_DIR=
D:\efitoolkit
SDK_BUILD_ENV - 是用來選擇你產生的執行檔是希望在哪個platform中執行,目前一共有幾種Platform可以選擇,像是nt32/sal64/em64t/bios32,而我們選擇的是em64t,他的意思代表我們要產生X64的執行檔
這樣子你才可以放在一個64 bit DXE環境下執行。 如果你想在一個NT32模擬環境或是PEI 32bit環境下執行,那你就要選擇 nt32.
 
SDK_INSTALL_DIR - 指定你的EFI Tool kit擺放的位置,我是放在D:\efitoolkit
 
接下來,你還需要去設定D:\efitoolkit\em64t\sdk.env ,這個檔案是決定你要使用哪一種Compiler 工具,預設是WinDDK,但是小弟總是喜歡來點不一樣的,因此我改使用VS2005!
為了使用VS2005,所以我就必須去修改這個檔案。

 
修改方式很簡單,就是指定到我的VS2005內的Compiler 目錄就可以了:
#MSSdk = C:\WINDDK\3790.1830\bin\win64\x86\amd64
MSSdk = "
C:\Program Files\Microsoft Visual Studio 8\VC\bin\x86_amd64"
然後就是重點了,你必須使用的是Visual Studio 2005 X64 Cross Tools Command Prompt ,而不是一般32 bitCommand Prompt.

接著切換目錄到你的EFI Tool Kit目錄,然後先執行Build.cmd設定環境後,就可以使用nmake 開始編譯你的環境。

 
編譯的結果會產生在 bin output 這兩個目錄內:
D:\efitoolkit\em64t\bin
D:\efitoolkit\em64t\output
 
所以你可以在這些目錄內找到你要的執行檔。
 
[Note]
如果你要build nt32,記得改一下SDK_BUILD_ENV = nt32,並改用Visual Studio 2005 Command Prompt (32bit)
 
2.2 Build EDK
 
EDK 內有許多的Platform 可以使用,其中比較常使用到的就是Nt32Developer's UEFI Emulation (DUET)/X64,下面就介紹這3PlatformBuild的方式:
2.2.1 Nt32 platform
使用VS2005 Build EDKNt32環境時需要注意的地方是把config.env內的USE_VC8 打開,然後再使用VS2005 Command prompt (32 bit)就可以去Build Nt32
(1)SET EDK_SOURCE=D:\EDK
     SET EDK_TOOLS_PATH=%VCINSTALLDIR% <--可有可無
(2)D:\EDK\Sample\Platform\Nt32\Build\Config.env
     USE_VC8 =
 YES
(3) 
然後依照下圖一步一步的做即可 (進入到Build folder,然後鍵入nmake all)

 
(4) Nt32還有個好處就是可以執行NT32模擬器,而執行的方式就是執行 system.cmd 設定 EFI Shell 模擬環境,然後再鍵入 nmake run

然後就會看到下圖:

 
2.2.2 DUET/X64 platform
DUET 這是一個開發者的模擬環境,在你執行nmake all之前,你必須設定下面的環境變數:
        set EDK_SOURCE=d:\edk
        set WIN_DDK_PATH=
可忽略,如果你是VS2003的話就必須設定
        set MASMPATH=c:\MASM615

另外就是要把config.env內的設定打開,這樣子才能使用VS2005
USE_VC8 = YES
USE_VC8_X64 = YES
接著,使用VS2005 Command prompt (32 bit)就可以去Build
 
[Note]
X64 platform build的方式如同DUEF,而且內含有X64 EFI Shell可以讓你在X64 platform使用。
DUET/X64 platform不支援nmake run的模擬環境,所以你沒辦法在你的工作機上運行。
 
 
 
 
  

快快樂樂學EFI (1)


快快樂樂學EFI
Harrison Hsieh 2010/07/19
Chap 1 EFI How to
1.1 概論
     有感於當初學習EFI的時候是直接經由BIOS vendor: "I公司"的網路上的訓練課程以及他們派了一組人來幫我們上了一星期Bring up之後,就直接在客戶的案子上邊做邊學,所以很多EFI基本的基礎都沒有學好!因此,最近想化整為零把EFI 重頭學習一遍! EFI 入門該學些甚麼呢?!  個人覺得,工欲善其事必先利其器! 所以先去抓一套可以編譯工具以及一套EDK或是 EFI Tool kits 來學習是最簡單的方式 所以我們的學習目標就是了解甚麼是EFI/UEFI ,然後再告訴你如何去找到你需要的資料以及建構出一個可以撰寫EFI code的環境。

1.2 EFI 歷史回顧
     Extensible Firmware Interface (EFI,可擴充韌體介面) 是一個規範,他規範了一個介面,界於作業系統(例如: Windows)與平台韌體(Platform firmware)之間的一個橋樑。 EFI 的改進是被用來取代傳統BIOS的介面(這個傳統的介面被稱之為IBM PC compatible PC BIOS或稱之為Legacy BIOS). 最初EFI是由Intel 所主導發展,Intel 已於2005年此規範交給目前UEFI論壇(Unified EFI Forum) 的會員一起共同維護與推廣,這便是眾所皆知的UEFI (Unified EFI,統一的EFI).
最初EFI發展動機是為了在1990年中的Intel-HP Itanium 系統,當時的PC BIOS有一個限制(支援16 bit 的處理器模式,1MB 位址空間與AT 硬體架構),而這個限制使的他無法支援大型伺服器平台的系統Intel-HP Itanium 最初的時候Intel 只是為了解決這些BIOS啟動時的限制,後來就乾脆改變它的名稱,且稱之為EFI

Intel Platform Innovation Framework for EFI
   Intel
 在其平台上為了EFI去建立了一個新框架(Framework),而這個框架的最初代號叫做Tiano,這個框架非常的完整,它包含了EFI對原本傳統韌體的所有支援,他也可以透過所謂的compatibility support module(CSM)來支援傳統的PC BIOS,簡單說就是傳統BIOS能做的EFI也能做,但是不是完整支援就要看CSM支援的程度。
特別是,這個框架包含了在Power- On後,所有必要的初始化步驟去初始化一個平台(Platform);但是這些步驟的運作並沒有被定義在EFI specification內,而是被定義在 Platform Initialization Specification(簡稱PI Spec)內的章節。 Intel 並沒有將這個架構完整的開放給一般的End-User知道,他只有開放這些資訊給一些獨立的BIOS 廠商(稱之為IBV),像是安邁 (American Megatrends AMI) 或是系微(Insyde Software)、鳳凰科技(Phoenix) …等的BIOS韌體供應商。
而在TianoCore project(也就是所謂的EFI Developer Kit EDK)Open source之中,會提到如何去開發這個Framework。這個開發工具中含括了EFI的一些硬體初始化的程式碼(只針對一些硬體,但並不包含韌體本身) ,至於這些程式碼的授權包含BSD license  Eclipse Public License等。
Tiano是為了取代BIOS的一種框架,所以透過EFI可以讓PC的設備自己撰寫一個驅動程式來管理這個設備。而對於開放原始碼來說,這也代表大家可以從TianoCore.org 下載這個專案,然後以BSDBerkley Software Distribution)的授權方式來生產你的產品。BSD的授權,你自己去修改它的軟體並且發展出屬於你自己的產品,但BSD並不會去要求你把修改的地方公開出來,而這種方法會有助於你去保護你的智慧財產權。
歷史故事簡略介紹完了,廢話不多說我們就馬上進入EFI 世界中,告訴你一個EFI的環境需要哪些工具來編譯、去哪裡下載EFI 工具包、如何建構你的編譯環境。

1.3 Compiler 工具
   為了能夠編譯一套EDK或是EFI Tool kits ,你會需要使用到 WinDDK或是VisualStudio,這是為了提供一些Compiler 工具像是CCompiler : CL.EXE或是像Lib工具: LIB.EXE 以及連結工具Link.exe...etc
   另外你可能還需要使用到MASM 來組譯一些少部分的組合語言程式碼,因此軟體需求如下:
(1) WinDDK version 3790.11830(EFI Tool kits預設)/ VisualStudio 2003(EDK預設)/VisualStudio 2005/VisualStudio 2008
(2) EFI Tools Kit /EDK source code.
(3) MASM
(4) TortoiseSVN
1.4 EFI Resource
  在茫茫網海中,如何蒐尋EFI 相關資源?! 小弟我不是幫Google 打廣告,是因為我常使用他去找資料 那我們要輸入哪些關鍵字可以找到我們要的資料呢?

 首先進入Google搜尋引擎,輸入關鍵字 "EFI EDK",你就會看到下面的連結 http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK

目前EFI 相關資訊比較完整的地方就是這個網站,裡面你可以下載到你需要的EFI Tool kit/EDK ,並且有一些相關的文件可以幫助你開始你的EFI之旅。

1.5 EFI Tool Kits
  
接下來我們就開始看看這些不同的專案有哪些是可以幫助我們入門,首先要介紹的是 EFI 工具組(EFI Tool Kits),他是一個可以支援快速開發EFI 應用程式的一個環境,讓你可以快速的開發32 bit/64bit EFI應用程式。
這些應用程式包含 : EFI based applications, protocols, device drivers, EFI shells 以及不同平台的 OS loaders  (IA-32, IA-64(IPF) and Intel 64(EM64T or X64) platforms),你可以透過他的Source Repository下載。
在下載之後,如何得知你下載的EFI Tool kit 版本 : 例如 D:\efitoolkit\doc\RELNOTE.pdf 文件內會有版本,如下圖所示:

  EDK指的是Open-source的一個EFI “Framwork”元件,英特爾依照EFI規範所實做出來的一套Code,當時的開發的代號為“Tiano”

  EDK的基本上是一個範例元件,裡面有為框架的基礎程式碼(Framework's Foundation code)和驅動程序範例(Sample Driver)

  EDK也是一個開發工具包,可以用來Debugging/Testing EFI Framework's driver
你可以透過下面的連結去取得一些相關的資訊以及說明:
   (2) 一些Framework Spec : http://www.intel.com/technology/framework/spec.htm
從下圖中的紅色框框的地方就是SVN下載的連結

1.7 Download EDK/EFI Tool kits
 首先,你必須先安裝 TortoiseSVN,這是一個版本控制的軟體,可以幫助你去Server端把code抓下來! 如果你沒有使用過的人就請先研究看看這個東西要如何使用,這邊就不多說明!
    
 http://tortoisesvn.tigris.org/

 
接著,透過這個TortoiseSVN去抓一套最新版的EDK /EFI Tool kits 下來 方法很簡單,就是透過TortoiseSVNExport功能,在他的URL地方輸入你要抓的Code的位置(也就是前面提到的Source Repository)然後輸入好Export directory(例如存放到 D:\EfiToolKit ),然後就等他下載好就可以了,例如下面的圖示與步驟 https://efi-toolkit.svn.sourceforge.net/svnroot/efi-toolkit/trunk/efi-toolkit (下載EFI Tool Kits)

 
1.8 Reference
  

星期二, 7月 10, 2012

Windows 8 WHQL/HCT/WLK filter

Windows WHQL 的一些問題有時候可以用Filter 過濾掉,此時就可以透過底下網站去查詢看看有沒有相關的Filter

DTM Filter 查詢: HCT Filter / WLK Filter / Errata

https://sysdev.microsoft.com/en-US/Hardware/EC/

相關WHQL討論區
http://social.msdn.microsoft.com/Forums/zh-TW/1295/threads

星期三, 5月 23, 2012

uEFI EDKII Using Re-Mapped Functions

BIOS最近熱門話題除了Windows 8之外,就是EDK II / EDK 2了。

想必大家應該也都開始在玩EDK II了,不過這個EDKII有沒有甚麼地方是跟EDK 衝突的呢?

答案是: 【有】

在你使用 EDKII Glue Library時,裡面有一個東西是需要大家注意的地方,就是所謂的Re-Mapped Functions.

在使用手冊中就開宗明義地跟你說,他為了解決EDKII Glue Library與EDK codebase的函數名稱衝突,所以【有些】函數名稱被他使用了巨集(Macro)來重新定義了。

這是甚麼意思呢? 他提出了一個範例:

如果你的Driver有include到這個Header file 叫做 "EdkIIGlueBaseMemoryLib.h" 或是"EdkIIGlueMemoryAllocationLib.h",他會使用C語言的#define重定義定CopyMem函數名稱 (不只這一個函數名稱還有很多個) :


#define CopyMem(_DESTINATIONBUFFER, _SOURCEBUFFER, _LENGTH) 
        GlueCopyMem(_DESTINATIONBUFFER, _SOURCEBUFFER, _LENGTH) 


這個定義會造成你原本在EDK source code內呼叫:

gBS->CopyMem (Dest, Source, Length);  

的這個動作,會在C 語言的Preprocessor時被換名稱成:

gBS->GlueCopyMem (Dest, Source, Length); 

然後在Compiler過程中就會造成一個錯誤訊息,而這個錯誤訊息會告訴你GlueCopyMem並不是EFI_BOOT_SERVICES中的一個成員(Members),這是因為那個#define 的關係,所以你的函數名稱會在Preprocessor時被偷偷換掉,因此為了避免這個Re-Mapped function的問題,請把你原先的CODE加上括號來避免Compiler error問題,如下所示:

(gBS->CopyMem) (Dest, Source, Length);  


那...............幹嘛搞那麼麻煩呢? 

我個人認為EDKII這些Library 就是想把大家平常會幹的事情又可能跟硬體相依性高的事情全部指向一個共同的Library內(ex: EntryPoint/Functions),以後如果要換不同平台的時候,只要把Library抽換換掉就可以了。

用說的不清楚,我來個範例好了:

以前我們會在source code中直接呼叫 gBS->FreePool();來釋放記憶體,如果導入/使用 EDKII Glue Library,你就應該寫成呼叫EDKII Glue Library所提供的FreePool(); 來取代你原來的做法,而 EdkIIGlueBaseMemoryLib.h/EdkIIGlueMemoryAllocationLib.h 中會去重新定義名稱,所以實際上是呼叫FreePool() 等於呼叫 GlueFreePool() :

#define FreePool(_BUFFER)                           GlueFreePool(_BUFFER)

而在Glue Library中,以目前EDK中,其實他還是去呼叫 gBS->FreePool(); 來釋放記憶體:


GlueFreePool (IN VOID   *Buffer)
{
...
  Status = (gBS->FreePool) (Buffer);
...
}


幹嘛繞一大圈??? 其實那這樣子做的好處是如果有一天,你釋放記憶體的方式不再是gBS->FreePool();時,你只要換掉你Link的那一個 Library,就可以做到你要的目的,而不用直接改到你原來的Source Code。

感覺就像是抽換掉底層的東西,上層不用改變,這樣說不知道看倌們有沒有那種感覺?!

今天就說到這邊,下課!

星期三, 2月 15, 2012

Turbo C 不能在64 bit的Windows下執行 (won't work in Windows 64-bit)



由於工作上的需要,偶爾還是會去寫一些DOS的工具,所以常常會遇到比較新版的OS就無法向下相容一些軟體的問題! 像是Turbo C 3.0 就沒辦法在64 bit OS下執行,執行時你會看到上面圖片中的警告訊息。

而市面上也有一些軟體就是針對這些問題去解決,像是DOSBOX就是個模擬器,可以讓你在64 bit OS中去模擬DOS的環境。

使用方式很簡單,在安裝好DOSBOX for 64 bit軟體後直接點兩下執行他,接著要使用MOUNT指令先建立一個磁碟機,例如我的TurboC 3.0是放在E:\TCC30

指令的格式 : mount [隨便的磁碟機]  [你要映對的路徑]
所以我鍵入 mount e:  e:\

接著我就可以切換磁碟機到e: 然後進入我的tcc30的目錄中執行Turbo C.


很簡單吧~ 這個工具的下載位置在下面的連結!
下載 DOSBOX for 64 bit

星期三, 2月 01, 2012

Win7磁碟分割

如果你拿到了一台NB,裡面安裝的Image只有一個硬碟分割區,但是你又想要多分割幾個區域,你會怎麼辦?

1.Ghost/備份原來的磁區,然後重新分割後再還原?
2.使用市面上的分割軟體分割?

其實Win7已經有內建分割功能,只要透過磁碟管理工具選擇你原來的C磁碟機,然後選擇【壓縮磁碟區】把空間釋放出來就可以了,底下的圖示中就可以看到輸入你要壓縮的空間(釋放出來的大小給另一個磁碟使用),很方便吧!

星期二, 1月 31, 2012

重新安裝Chrome後要求輸入加密通關密語

如果大家在重新安裝Chrome之後,要求你要輸入加密通關密語,這是方便保護你的雲端資料的一種方式。

大家可以在Chrome內設定,如果你沒有設定過的密碼的話,他的預設加密通關密語就是跟你的Gmail登入時的密碼是同一個!

星期三, 1月 25, 2012

心得分享: 學習UEFI 之你把C語言學好了嗎?!

很多人在問我說: 小華要怎樣子把UEFI 學好?! 其實寫BIOS的人答案應該只有一個,把SPEC看懂看完然後融會貫通! 這樣子的答案好像有跟沒有是一樣的!

小弟就以我的學習經驗來分享給大家吧!(雖然我也沒學好,但是教學相長啦~)

首先呢你要會C語言,不是C++喔! 因為目前UEFI還是使用C語言開發,其中最主要的原因是因為C的code size會比較小一點,會比較適合Firmware的開發!

學C語言的時候要注意甚麼是#define ? #define 高級用法有哪些?! 甚麼是typedef,這東西跟UEFI 的關係是甚麼? 為什麼UEFI 中是使用UINT32? 而不是一般的unsigned int ? 還有甚麼是function pointer? 這要如何使用與宣告?! 另外就是Link List再處理資料結構時的應用!

大致上C的應用學會,UEFI的code大概就看得懂! 當你看得懂的時候,再去看SPEC就會更瞭解人家在做甚麼了! (記住我的話 : 工欲善其事必先利其器,先把C學好,你才能做更多的事情!)

接下來你要會一些些MASM組合語言,因為在除錯(debug)時多少都要看得懂! 如果時間夠多就去修一下微處理器架構,順便了解一下CPU是如何設計出來的,他對於指令的提取/解碼又是甚麼動作? 甚麼是指令被優化? 他跟CPU的關係是甚麼/組語的Library是怎麼回事?組合語言呼叫C語言是如何呼叫的? 16 bit vs 32 bit vs 64 bit 又有何差別?segment 跟記憶體管理又是甚麼關係? ...etc 這些相關知識如果能懂的話會更好!

然後就是X86的一些架構性的知識,像是中斷是甚麼?! 中斷的種類有幾種?! 為什麼要有中斷?! 中斷跟OS還有CPU之間是怎麼配合的?! 設備的中斷跟CPU的中斷的差別是甚麼? 個別的運作原理又是甚麼? 另外像是甚麼是CPU工作模式(真實模式/保護模式/SMM...etc)/定址又是甚麼東西?!

還有像是PCI bus/SATA/SMBIOS/ACPI....相關的知識都必須要知道,更深入的就會去瞭解到CPU是如何初始化?! Chipset初始化? Memory sizing? 不過這些知識都比較被保護住,所以非相關產業應該得不到這些資訊! 所以先把架構性學好,等待有機會在更深入研究!

綜合上述所說,要學的東西還真的很多! 學BIOS不可能一蹴即成! 往往都需要時間慢慢累積! 但是現在UEFI的入門門檻已經變很低了,只要懂C 在加上遇到好的老師(我在鳳凰科技遇到一個C語言活字典Timothy)或學長,一般大概一年就能獨立接案子! 其他的就是靠自己努力!

還記得我在鳳凰科技的時候有個資深學長(Joe)曾說過一句名言: 我只有一年的BIOS經驗重複了10幾年而已! 所以就是一直重複累積更多的知識與經驗啦!

星期四, 1月 19, 2012

~鳳凰科技~

今天是中國兔年最後一天上班日,也是我在鳳凰科技的最後一天上班日!

感謝過去這幾年同事在BIOS上或是生活上的互相幫忙、還有主管的提攜以及我的Team member的情義相挺!

謝謝你們大家,才能讓我留下了那麼多美好的回憶!!!

-Harrison

發佈文章

星期三, 10月 19, 2011

UEFI #pragma intrinsic( function1 [, function2, ...] )

在UEFI C語言中使用 #pragma intrinsic( function1 [, function2, ...] )方式可以簡化你拉Library的動作,但是這個功能是與Compiler相關,因此當你不使用Microsoft Compiler時,可能就要注意原本的UEFI CODE中使用這些方法的地方可能會有問題!
使用方式是在任何xxx.c 中宣告函數原型跟 #pragma intrinsic(),之後就可以在你的CODE中使用他!
//宣告函數原型int            _inp (unsigned short port);
int            _outp (unsigned short port, int databyte );


#pragma intrinsic(_inp)
#pragma intrinsic(_outp)


VOID CMOSWrite(UINT8 Port,UINT8 databyte)
{
_outp(0×70, Port);
_outp(0×71, databyte);
}



參考網站 : 
http://msdn.microsoft.com/zh-tw/library/tzkfha43.aspx