- Firmware Storage
- Firmware Storage 是非揮發性的memory儲存BISO或Firmware的code。UEFI的其中一個優勢是DXE和PEI 可以把code解壓到firmware storage外。 Firmware Storage最小的單位是UEFI Firmware File,再來是Firmware File System(FFS)、Firmware Volumn(FV)及Firmware Device(FD)。
- UEFI Firmware Files
- UEFI Firmware Files是最小/少的模組化的code,包含了Code及Data存放在FV中。每一個UEFI Firmware File都有Name、Type、Alignment及Size等四個attribute。 UEFI build tool會建立Firmware Files。Firmware Files的組成如下圖:
- 其中,entry point包含在Data區塊裡頭。
- Firmware File System
- Firmware File System(FFS)描述FV的file及free space的資訊。每一個FFS都有一個unique的GUID來連結FV。FFS參考FAT 32的作法,他的header如下圖。
- 同時,我們也利用UEFI Build tool建立FFS。
- Firmware Volumes
- 一個Firmware Volumes對應著一個logical firmware device。FV是由FFS來組成的,Firmware file則是FV組成的元件。FV可以表示flash的一部分或是多個flash或甚至一個partition或是network。所有PI component都存放在FV,在PI的過程中,必須透過FFS去讀取。
- Firmware Devices
- Firmware Device是指非揮發性的Storage。包含了Firmware Code、Firmware Data及Fault Tolerant。
- Firmware Device包含了FV Main放置了DXE Driver,FV Recovery放置了security及PEI code。我們以Recovery FV為例作解釋。Recovery FV包含了FFS放置著Boot Block Code(包含了PEI security phase code) 及Recovery code(包含了也許USB stack來讀取USB device)。
- Creating UEFI Firmware Files
- 我們如何產生UEFI Image呢?
- 撰寫C code
- 用build tool編譯產生Library及object file
- 產生的Library及object file是intermediate file,利用微軟的compiler把他們轉成PE/COFF格式的image。
- 如果是在Linux的環境,我們可以使用GCC來取代。
- Build Tool會將標準的header置換成UEFI header。
- Physical Memory Map
- 從下圖我們可以看到各個層級之間的關係。Firmware Device被load進system memory之後,它包含了firmware volume。而firmware volume又包含了許多Firmware File System,Firmware File System又放置著許多Firmware File。
2012年5月25日 星期五
UEFI/PI (7) UEFI Firmware Hierarchy
UEFI/PI (6) UEFI Drivers
- Driver's Location
- UEFI Driver run在DXE Phase中,在platform 初始化的過程中可能重複的被active。
- 同時,UEFI Driver是green H的其中一部份,如下圖所示。
- UEFI Driver's Attributes
- UEFI Driver是system driven的image。在DXE Phase中由UEFI Loader到系統中。UEFI Driver能提供protocols同時也可能使用其他Driver提供的protocol。我們可以使用UEFI Driver去支援特定硬體或override 已經存在的Driver。
- Supportive
- UEFI Driver支援複雜的bus hierachies。UEFI Driver可以與bus interface溝通來將device連接到bus。
- Independent
- UEFI Driver可以存放在任意的storage 中 包含flash。
- Flexible
- Extensible
- UEFI Driver被設計成可以支援未知的bus或device的種類。
- Supportive
- UEFI Driver's Functions
- UEFI Driver是firmware的延伸
- 可以支援新的硬體,與HW、OS無關。
- Portability
- 因為與Platform Arch.無關,因此可以跨平台。
- UEFI SPEC.提供許多API
- 因此可以加速開發。
- UEFI Driver是firmware的延伸
- UEFI Driver's Contents
- UEFI Driver包含了四大部分,
- 1.會有一個Entry Point作為Driver的進入點。
- 2.會提供Published Function 供其他的Driver使用。
- 3.Consumed Function,參考別的Driver提供出來的功能。
- 4.Data Structure,用來滿足Driver所需要的資料存放。
- UEFI Driver's Entry Point
- 如果前面所提到的,DXE Dispatcher會Load Driver,UEFI Driver透過UEFI Loader將Driver Load到記憶體中。Loader 會先進入Driver的Entry Point,接著Driver會建立Published Protocol。以下圖為例,他提供了Binding Protocol( supported, Start, Stop),最後離開。
- Drivers v.s. Applications
- UEFI Application 與 UEFI Driver本質上非常的類似,下表列出他們的比較。
- UEFI Protocols
- 一個UEFI protocol定義在SPEC中,可能是一塊function pointer、data structure或是API。
下面分成三個部份來解釋。
- Confused with Drivers
- UEFI Driver是一個可執行的UEFI Image。它包含了許多的protocol而每一個protcol也包含了多個handle。因此,Protocl是Driver建立的。
我們可以把UEFI protocl想像成interface。它包含了許多function pointer, data structure或APIs。 - Produced by Driver
- UEFI Driver可以建立許多protocol。
- Consumed by Anyone
- UEFI protocol可能被任一的Driver使用。例如UEFI platform Driver可能在其他的Driver啟動時使用。
- Confused with Drivers
- Example A: EFI_PCI_IO_PROTOCOL
- 下面的例子是PCI I/O Protocol。這一個Driver run在UEFI boot services/environment來存取memory及PCI controler的I/O。另外,與PCI相關的SPEC也定義在此protocol中。這一個Protocol的目的是要將對PCI device的讀寫抽象化。EFI_PCI_IO_PROTOCOL抽象化了對PCI 裝置的memory,I/O, PCI configuration及DMA interface的操作。每一個PCI Bus的PCI control都有對應的一個EFI_PCI_IO_PROTOCOL instance。對操作PCI裝置的Driver都必須透過對應的instance來操作。PCI controler的handle至少會有EFI_PATH_PROTOCOL及EFI_PCI_IO_PROTOCOL的instance。
- Example B
- EFI_DISK_IO_PROTOCOL是對block device存取抽象化。File System等等的code都需要依賴這個protocol。
- Example C
- 這個protocl的解釋如下:UEFI Image may use the device path to match its own device Drivers to the particular device. Note that the executing UEFI OS loader and UEFI application images must access all physical devices via Boot Services device handles until ExitBootServices() is successfully called.
- Design Process Steps
- Driver Types
- 在撰寫Driver之前,必須先知道我們要寫的是哪一種Driver。在UEFI Image中可以分成兩種,Driver及Application。
- Service Driver
- a. 不管理hardware。
- b.提供service給其他Driver。
- c.不支援Driver binding protocol。
- d. 在entry point裡install protocol。
- e. 建立一個或多個 service handlers。
- f. 產生service-specific protocols。
- 例如: UEFI Decompress Protocol、UEFI Byte Code Virtual Machine、Boot Integrity Service(BIS)。
- Initialization Drivers
- a. 與hardware會有溝通。
- b. one-time initialization。
- c. 不會建立handle及protocol。
- d. 結束後就會unload。
- Root Bridge Driver
- a. 管理部分的core chipset。
- b. 直接與HW溝通。
- c. 建立一個或多個 root bridge handle。
- d. 建立 root bridge I/O protocols,安裝在新的root bridge handle。
例如:PCI Host Bridge。
- Bus Driver
- 他是UEFI Driver Model的Driver。用來管理Bus controller。
- start()會建立一個或多個child handles及Bus Specific I/O protocols。例如:PCI NIC card、UART controllers。
- Device Driver
- 管理controller或peripheral device。
- start()不會建立child handle但會建立一個或多個protocols。
- 例如:PCI Video Adapter、USB Host Controller、USB keyboard/Mice。
- Hybrid Driver
- 結合Bus Driver及device Driver。
- 例如:PCI SCSI Host Controller、PCI Fiber Channel Controller。
UEFI Applications中有一種特殊的application叫做OS Loader。與一般的Application不同的是OS Loader會呼叫 ExitBootService然後就將control pass到OS kernel了。
接著我們來了解Driver中的幾種類型。 - Service Driver
- Consumed Protocols
- 什麼時候會使用那些Protocl呢?例如 PCI Adapter需要PCI I/O Protocol或加上也許Device Path protocol。 而像USB keyboard/mice, DVD rom這類的裝置就需要USB I/O protocol及device path protocol。
- Produces Protocols
- 那我們可能會產生什麼protocol呢?例如,假設是在寫keyboard Driver,我們可能會建立simple input protocol;滑鼠可能會有simple pointer protocol;USB flash disk可能會有block I/O protocol。Depends on 你寫的裝置。
- Writing UEFI Drivers
- 接下來,我們寫一個Driver需要那些protocol呢?參考下表:
- Initialized
- 當UEFI Driver被dispatch時,首先會進入entry point然後初始化。在初始化的過程中會宣告此Driver會提供那些protocol。UEFI Driver 是relocatable pickup image,所以可以load在記憶體的任意位置。在Driver initialize的過程中是不會touch HW的,在過程中會呼叫Driver binding protocol,在初始化後,service就被註冊了,這也是會什麼可以快速開機的原因。
- Supported
- 在初始化後,Binding Protocol會開始define Supported、Start及Stop function。
- 接下來以PCI Driver為例。
首先Open PCI Protocol( EFI_PCI_IO_PROTOCOL),然後check這個Driver是否支援這個controller( EFI_DEVICE_PATH_PROTOCOL)再來關閉PCI Protcol並return 是否支援。
- Start
- Start()會產生EFI_Block_IO_Protocol 建立child protocol(functions)。
- Stop
- Stop不會產生任何的Protocol,反而他會移除Start()所產生的Protocol。
- Recommended Protocols
- Driver Guideline
- 主要有四個原則
- 在Driver entry的地方不要touch HW
- 在Support()保持簡單。
- Start()對應Stop();Driver Entry對應Unload
- 把複雜的事情放到Start()和Stop()去做。
- Design Checklist
- Recommendations
- 在實作Test/Debug的時候有幾點注意的事情如下:
- Start() Code
- 這個範例是儲存PCI的Attributes。
- Stop() Code
- 將Attribute reset回原本的值。
- Library Functions
- 我們應該多利用既有的function來將code size降低,如下:
- Other Helpful Suggestions
- 這裡分成兩大塊。
- 使用UEFI支援的Compression來降低ROM Size。
- Compile with EFI Byte Code Compiler(EBC)
- 不要假設max number of children。
- 不要寫死memory address或使用assembly。
- 不要使用floating point arithmetic
- Dome minor ebc point considerations
- Bus Driver應該支援一次產生一個child。(可以加速開機)
Reducing Option ROM Size
Improving Protability
訂閱:
文章 (Atom)