11.UEFI Driver Model
遵循 UEFI model 的 EFI driver 是不允許去遍歷所有的 controller 來識別需要安裝到哪個 controller 上的,而是通過 EFI_BOOT_SERVICES 的 ConnectController 和調用 Binding Driver 來實現;
具體實現如下:
CoreConnectController--->CoreConnectSingleController
CoreConnectSingleController::
CoreConnectSingleController 中會一個個 handle 來輪詢所有支持的 BindingDriver ,直到 support 返回 success,然后執行 start 函數。
然后 controller 被EFI_BOOT_SERVICES.DisconnectController() 執行 stop 釋放。
UEFI驅動程序的驅動初始化例程不允許觸及任何設備硬件。相反,它 只是在UEFI 驅動程序的ImageHandle上安裝一個EFI_DRIVER_BINDING_PROTOCOL的實例。確定驅動程序是否支持給定控制器的測試必須在盡可能短的時間內( )執行,而不會對正在測試的任何控制器造成任何副作用。因此,大部分 控制器初始化代碼都出現在 EFI_DRIVER_BINDING_PROTOCOL的 start 和 stop 中。
11.1 EFI Driver Binding Protocol
本節提供EFI_DRIVER_BINDING_PROTOCOL的詳細描述。該協議是由遵循UEFI驅動程序模型的每個驅動程序產生的,它是允許 驅動程序和控制器被管理的中心組件。它提供了一個服務來測試一個特定的控制器是否被驅動程序支持,一個服務來開始管理一個控制器,一個服務來停止管理一個控制器。這些服務同樣適用于總線控制器和設備控制器的驅動程序。
提供確定驅動程序是否支持給定控制器所需的服務。如果控制器是支持的,那么它還提供了啟動和停止控制器的例程;
struct _EFI_DRIVER_BINDING_PROTOCOL {EFI_DRIVER_BINDING_SUPPORTED Supported;EFI_DRIVER_BINDING_START Start;EFI_DRIVER_BINDING_STOP Stop;////// The version number of the UEFI driver that produced the/// EFI_DRIVER_BINDING_PROTOCOL. This field is used by/// the EFI boot service ConnectController() to determine/// the order that driver's Supported() service will be used when/// a controller needs to be started. EFI Driver Binding Protocol/// instances with higher Version values will be used before ones/// with lower Version values. The Version values of 0x0-/// 0x0f and 0xfffffff0-0xffffffff are reserved for/// platform/OEM specific drivers. The Version values of 0x10-/// 0xffffffef are reserved for IHV-developed drivers.///UINT32 Version;////// The image handle of the UEFI driver that produced this instance/// of the EFI_DRIVER_BINDING_PROTOCOL.///EFI_HANDLE ImageHandle;////// The handle on which this instance of the/// EFI_DRIVER_BINDING_PROTOCOL is installed. In most/// cases, this is the same handle as ImageHandle. However, for/// UEFI drivers that produce more than one instance of the/// EFI_DRIVER_BINDING_PROTOCOL, this value may not be/// the same as ImageHandle.///EFI_HANDLE DriverBindingHandle;
};
EFI_DRIVER_BINDING_PROTOCOL.Supported()
測試此驅動程序是否支持給定的控制器。如果提供了子設備,它將進一步測試 此驅動程序是否支持為指定的子設備創建句柄。
EFI_SUCCESS | 設備的 controller 以及剩下的 device 支持,(比如 bus driver 的下級 controller 也是支持這個 driver 的) |
EFI_ALREADY_STARTED | 這個 device 已經被這個 driver 管理了 |
EFI_ACCESS_DENIED | 這個 device 已經被不同的 driver 管理了,或者需要獨立訪問的空間 |
EFI_UNSUPPORTED | 這個 device 不支持這個 driver |
EFI_DRIVER_BINDING_PROTOCOL.Start()
此函數使用This指定的驅動程序啟動Controller指定的設備。在Start()中分配的 資源必須在Stop()中釋放。
EFI_DRIVER_BINDING_PROTOCOL.Stop()
停止設備控制器或總線控制器。 EFI_DRIVER_BINDING_PROTOCOL的Start()和Stop()服務互為鏡像
- Uninstall all the protocols that were installed onto ControllerHandle in Start().
- Close all the protocols that were opened on behalf of ControllerHandle in Start().
- Free all the structures that were allocated on behalf of ControllerHandle in Start().