Driver基本上是被動的,需要等System通知Driver需要管理的Controller有誰。
如果有 Linux or Windows Driver 的撰寫經驗的話,應該會對這一點比較有感覺。
在這篇文章中可以看到相關的code
為什麼需要在 OS Boot 之前有 EFI Driver Model ?
- 因為BIOS INT 19H 無法得知在那個Device中有 OS Loader
- EFI Driver Model 只要啟動開機時需要的Device 就可以。
(# int 19h 負責載入啟動程式磁區,再移交控職權給 boot code的服務常式.)
在這篇文章中有提到Driver的分類
以Driver 的 LifeCycle角度來看
- EFI Boot Service drivers: 在Boot的時後會存在的 Driver,一樣會有自己的Memory及status,在 ExitBootServices後會Release。
- EFI Runtime Drivers:自己本身的Memory及status會一直存在。
如果以這張圖來看,可以分出
- UEFI Driver Model Driver:需要符合下面提到的 EFI Driver Model 規範。(也就是上面圖中的EFI Driver Model Drivers)
- UEFI Non Driver Model Driver:如果有不符合的則為此類Driver。
UEFI Driver Model Driver
Device Driver (EX: USB KB Driver)
- 控制Controller或是Device
- Start() 不會Create 任何的Child Handle
- Start() 會Produce 一個或多個Protocol (安裝在Device's Controller Handle)
Bus Driver(EX: PCI Bus Driver)
- 控制及列舉Bus Controller
- Start()會Create一或多個Child Handle
- Start()會Produce Bus特定的 I/O Protocol(安裝在Bus Child Controller)
Hybrid Driver (EX: PCI SCSI Host Controller)
- 控制及列舉Bus Controller
- Start()會Create一或多個Child Handle
- Start()會Produce Bus特定的 I/O Protocol (安裝在Bus 本身 Controller Handle或Child Handle)
UEFI Non Driver Model Driver
Service Driver (EX : Boot Integrity Service)
- 不會控制到Hardware
- 提供Service到其它的Driver
- 不會Support Driver Binding Protocol
- 通常會在Driver Entry Point 的地方安裝Protocol
- Create 一個或多個 Service Handles
- 會Produce Service特定的Protocol (安裝進Service Handle)
Initializing Driver (EX:SBDXE_Init)
- 通常會接觸到Hardware
- 執行一次性的Initialization 運作
- 不會Produce任何的Protocol
- 當Finished的時後會Unload
Root Bridge Driver (PCI Host Bridge) # 可參考下面的 Host Bug Controller
- 通常會控制部份的Core Chipset
- 直接碰觸到硬體
- 會Create 一個或多個 Root Bridge Handle
- Produce Root Bridge I/O Protocol
EFI Driver Model 規範
- EFI Driver Module不允許碰到任何HardWard,從別一個方面來說,它允許的只有install protocol instance 到 image 的 Handle中。
- 一個包含Driver Binding Protocol的Image Handle就稱為Driver Image Handle。
- Driver可以選擇性地決定要不要安裝其他Protocol
- 允許做自己的Unload() function, 這是optional的function
- 如果需要一些特別的操作,可以實作Notification function,在ExitBootServices()時會被觸發到。
下面是optional的protocol
EFI_DRIVER_CONFIGURATION_PROTOCOL
EFI_DRIVER_DIAGNOSTICS_PROTOCOL
EFI_COMPONENT_NAME_PROTOCOL
Driver
Initialization
Driver Image 需要從下面列出的Media中load。
ROM,
flash, hard drives, floppy drives, CD-ROM, or even a network connection.
Driver Image 可以透過BootService 的 LoadImage() Load PE/COFF 格式的image到System
Memory中。
例如: gBS->LoadImage (
TRUE,
ImageHandle,
DevicePath,
NULL,
0,
&FileImageHandle);
TRUE,
ImageHandle,
DevicePath,
NULL,
0,
&FileImageHandle);
將DevicePath上的Driver Image載入到System Memory之後, 取得Handle並存放在FileImageHandle裡。
而FileImageHandle會被掛上一個LOADED_IMAGE_PROTOCOL。
如下圖所示:
在這個時後,Image 還沒被啟動,
需要透過BootService的StartImage()來啟動它。
Host Bus Controller ( Root Bridge Driver )
Firmware Component不會受到 EFI Driver Model規則的影響
像是如下圖的CPU 及 Core Chipset Component
Core Chipset components 產生 m host bridges (Host Bus Controller)
Host Bridges (Host Bus Controller)
- 不屬於EFI Driver Model的任何一種。
- 會提供I/O Interface
- 包含了DEVICE_PATH_PROTOCOL (如果有對應到實體的Device ex:PCI Bus)
- 另一個PROTOCOL會提供I/O的Operation (像下圖的PCI Host Bridge)
下圖是當Device Driver 連結到Device Handle(Host Bridges)的狀態
原本的Device Handle是由XYZ Bus Driver所Create出的Child Handle,
連到Device Handle的Device Driver必需要在自己的Image Handle上安裝Driver Binding Protocol。而Drive Binding Protocol包含下面三個function
- Support() :用來檢查Driver是否有支援Controller,以上面的例子而言的話,會檢查Device Handle 有沒有支援DEVICE_PATH_PROTOCOL。
- Start() :如果Support的檢查有通過,就可以使用Start()連結Controller
- Stop():使Driver停止管理Controller
Protocol Interface,不用的時後可以用CloseProtocol() Release。
可以透過 System Firmware 管理的 Handle Database取得Controller的資訊
OpenProtocolInformation可以取得使用這個Protocol Interface的component list
Bus Driver 跟 Device Driver只有在概念上的定義有不同,唯一的不同只在於Bus Driver會建立Device Handle 給自己在Bus 上找到的child controller使用。
Bus Driver有兩種不同的分類
- first call to Start():會呼叫Start()給所有找到的Child Controller,每個Child Controller都會有一個Handle。
- multiple calls to Start():多次呼叫 Start()建立 一個個 Child Controller 的Handle 。這個方法對於Fast Boot很有用,可以建立少量的Handle甚至是一個Handle。
在下圖是Bus Controller在呼叫 Start()及 Stop()之前的狀態。
虛線代表Bus Controller的Parent Controller。
如果是Host Bus Controller就不會有Parent Controller。
節點A B C D E代表Bus Controller的Child Controller
當呼叫Start()時,Bus Driver可以選擇只建立其中一個Child,且可以選擇先建立某一個Child。
Driver Binding Protocol的Supported(), Start()以及Stop() function有足夠的彈性能夠這樣做。
Bus Driver必需要install 可操作Bus Service的I/O protocol到各個Child Controller。
像下圖XYZ Bus Driver 建立了一個 XYZ的 Child Device Handle,它support 了DEVICE_PATH_PROTOCOL、IO_PROTOCOL及OVERRIDE_PROTOCOL。
Bus Driver可以選擇性地安裝Bus Specific Driver Override Protocol到每一個Child Handle. 這個Protocol會使用在Driver連接到Child Handle時, 呼叫Boot Service ConnectController(),
從原本有定義好的一些優先權規則, 找到最適合的Driver安裝到Controller上.
Bus Specific Driver Override Protocol比一般的Driver搜尋演算法有更高的優先權, 但比Platform Override低.
ConnectController以及DisconnectController可以用來讓Platform Firmware決定那個Controller要被Start那個不要。
Platform也會決定是否要產生Platform
Driver Override Protocol。
這個方式也讓EFI能夠支援HotPlug Events。
UEFI Driver與DXE Driver的區別
UEFI Driver與DXE Driver的區別
在這邊指的UEFI Driver也就是符合EFI Driver規範的Driver
也就是上面圖中的(UEFI Driver Model Driver)
而DXE Driver通常指得是上圖中的(Initializing Driver)
不過明確的定義,還是需要看那隻Driver的運作而定
- 不需要依赖Dependency决定執行的顺序
- 必需可以被重覆執行
- 不需要即時啟動
- 支援硬體的熱插拔(Hot-Plug)
- 支持軟體的熱插拔(Unload)
- 所有的Function都是Device(Handle)结合Driver(Protocol)所達成
留言
張貼留言