- UEFI Drivers and Overview
- 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本質上非常的類似,下表列出他們的比較。
- Driver's Location
- UEFI Protocols
- 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.
- UEFI Protocols
- Driver Design
- Design Process Steps
- Driver Types
- 在撰寫Driver之前,必須先知道我們要寫的是哪一種Driver。在UEFI Image中可以分成兩種,Driver及Application。
- UEFI Applications中有一種特殊的application叫做OS Loader。與一般的Application不同的是OS Loader會呼叫 ExitBootService然後就將control pass到OS kernel了。
- 接著我們來了解Driver中的幾種類型。
- 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。
- 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 Drivers
- 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
- Writing UEFI Drivers
- Tips and Techniques
-
- 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)
- Reducing Option ROM Size
- Improving Protability
- 不要假設max number of children。
- 不要寫死memory address或使用assembly。
- 不要使用floating point arithmetic
- Dome minor ebc point considerations
- Bus Driver應該支援一次產生一個child。(可以加速開機)
- Driver Guideline
資料來源:http://clhjoe.blogspot.tw/2012/05/uefipi-5-uefi-drivers.html