UEFI Framework - 3 [ EFI Driver Model ]

Driver基本上是被動的,需要等System通知Driver需要管理的Controller有誰。
如果有 Linux or Windows Driver 的撰寫經驗的話,應該會對這一點比較有感覺。
在這篇文章中可以看到相關的code


為什麼需要在 OS Boot 之前有 EFI Driver Model ?
  1. 因為BIOS INT 19H 無法得知在那個Device中有 OS Loader
  2. EFI Driver Model 只要啟動開機時需要的Device 就可以。
 (# int 19h 負責載入啟動程式磁區,再移交控職權給 boot code的服務常式.)




在這篇文章中有提到Driver的分類

以Driver 的 LifeCycle角度來看
  1. EFI Boot Service  drivers: 在Boot的時後會存在的 Driver,一樣會有自己的Memory及status,在 ExitBootServices後會Release。
  2. EFI Runtime Drivers:自己本身的Memory及status會一直存在。


如果以這張圖來看,可以分出

  1. UEFI Driver Model Driver:需要符合下面提到的 EFI Driver Model 規範。(也就是上面圖中的EFI Driver Model Drivers)
  2. UEFI Non Driver Model Driver:如果有不符合的則為此類Driver。

UEFI Driver Model Driver


Device Driver (EX: USB KB Driver)

  1. 控制Controller或是Device
  2. Start() 不會Create 任何的Child Handle
  3. Start() 會Produce 一個或多個Protocol   (安裝在Device's Controller Handle)                        


Bus Driver(EX: PCI Bus Driver)

  1. 控制及列舉Bus Controller
  2. Start()會Create一或多個Child Handle
  3. Start()會Produce Bus特定的 I/O Protocol(安裝在Bus Child Controller)
Hybrid Driver (EX: PCI SCSI Host Controller)

  1. 控制及列舉Bus Controller
  2. Start()會Create一或多個Child Handle
  3. Start()會Produce Bus特定的 I/O Protocol (安裝在Bus 本身 Controller Handle或Child Handle)

UEFI Non Driver Model Driver

Service Driver (EX : Boot Integrity Service)
  1. 不會控制到Hardware
  2. 提供Service到其它的Driver
  3. 不會Support Driver Binding Protocol
  4. 通常會在Driver Entry Point 的地方安裝Protocol
  5. Create 一個或多個 Service Handles
  6. 會Produce Service特定的Protocol (安裝進Service Handle)
Initializing Driver (EX:SBDXE_Init)
  1. 通常會接觸到Hardware
  2. 執行一次性的Initialization 運作
  3. 不會Produce任何的Protocol
  4. 當Finished的時後會Unload



Root Bridge Driver (PCI Host Bridge) # 可參考下面的 Host Bug Controller 

  1. 通常會控制部份的Core Chipset
  2. 直接碰觸到硬體
  3. 會Create 一個或多個 Root Bridge Handle
  4. Produce Root Bridge I/O Protocol


EFI Driver Model 規範 
  1. EFI Driver Module不允許碰到任何HardWard,從別一個方面來說,它允許的只有install protocol instance 到 image 的 Handle中。
  2. 一個包含Driver Binding Protocol的Image Handle就稱為Driver Image Handle。
  3. Driver可以選擇性地決定要不要安裝其他Protocol
  4. 允許做自己的Unload() function, 這是optional的function
  5. 如果需要一些特別的操作,可以實作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);

將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) 
  1. 不屬於EFI Driver Model的任何一種。
  2. 會提供I/O Interface
  3. 包含了DEVICE_PATH_PROTOCOL (如果有對應到實體的Device ex:PCI Bus)
  4. 另一個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
  1. Support() :用來檢查Driver是否有支援Controller,以上面的例子而言的話,會檢查Device Handle 有沒有支援DEVICE_PATH_PROTOCOL。
  2. Start() :如果Support的檢查有通過,就可以使用Start()連結Controller
  3. Stop():使Driver停止管理Controller
這三個Function需要透過BootService的 OpenProtocol()得到
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有兩種不同的分類
  1. first call to Start():會呼叫Start()給所有找到的Child Controller,每個Child Controller都會有一個Handle。
  2. 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也就是符合EFI Driver規範的Driver
也就是上面圖中的(UEFI Driver Model Driver)
而DXE Driver通常指得是上圖中的(Initializing Driver)
不過明確的定義,還是需要看那隻Driver的運作而定 
  1. 不需要依赖Dependency决定執行的顺序
  2. 必需可以被重覆執行
  3. 不需要即時啟動
  4. 支援硬體的熱插拔(Hot-Plug)
  5. 支持軟體的熱插拔(Unload)
  6. 所有的Function都是Device(Handle)结合Driver(Protocol)所達成

留言