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().