UEFI-Driver_框架
基础函数介绍
1. EfiLibInstallDriverBindingComponentName2
用来安装 EFI_DRIVER_BINDING_PROTOCOL gDeviceDriverBinding.
以UsbBus层驱动实例注册为例:
34 EFI_DRIVER_BINDING_PROTOCOL mUsbBusDriverBinding = {
35 UsbBusControllerDriverSupported,
36 UsbBusControllerDriverStart,
37 UsbBusControllerDriverStop,
38 0xa,
39 NULL,
40 NULL
41 };
EfiLibInstallDriverBindingComponentName2 : 该函数通过InstallMultipleProtocolInterfaces将上述标准实例框架绑定到ImageHandle中, 并与gEfiDriverBindingProtocolGuid关联.
附EfiLibInstallDriverBindingComponentName2函数:
229 EFI_STATUS
230 EFIAPI 内
231 EfiLibInstallDriverBindingComponentName2 (
232 IN CONST EFI_HANDLE ImageHandle,
233 IN CONST EFI_SYSTEM_TABLE *SystemTable,
234 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
235 IN EFI_HANDLE DriverBindingHandle,
236 IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL
237 IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL
238 )
239 {
240 EFI_STATUS Status;
241
242 ASSERT (DriverBinding != NULL);
243
244 //
245 // Update the ImageHandle and DriverBindingHandle fields of the Driver Binding Protocol
246 //
247 DriverBinding->ImageHandle = ImageHandle;
248 DriverBinding->DriverBindingHandle = DriverBindingHandle;
249
250 if (ComponentName == NULL || FeaturePcdGet(PcdComponentNameDisable)) {
251 if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {
252 Status = gBS->InstallMultipleProtocolInterfaces (
253 &DriverBinding->DriverBindingHandle,
254 &gEfiDriverBindingProtocolGuid, DriverBinding,
255 NULL
256 );
257 } else {
258 Status = gBS->InstallMultipleProtocolInterfaces (
259 &DriverBinding->DriverBindingHandle,
260 &gEfiDriverBindingProtocolGuid, DriverBinding,
261 &gEfiComponentName2ProtocolGuid, ComponentName2,
262 NULL
263 );
264 }
265 } else {
266 if (ComponentName2 == NULL || FeaturePcdGet(PcdComponentName2Disable)) {
267 Status = gBS->InstallMultipleProtocolInterfaces (
268 &DriverBinding->DriverBindingHandle,
269 &gEfiDriverBindingProtocolGuid, DriverBinding,
270 &gEfiComponentNameProtocolGuid, ComponentName,
271 NULL
272 );
273 } else {
274 Status = gBS->InstallMultipleProtocolInterfaces (
275 &DriverBinding->DriverBindingHandle,
276 &gEfiDriverBindingProtocolGuid, DriverBinding,
277 &gEfiComponentNameProtocolGuid, ComponentName,
278 &gEfiComponentName2ProtocolGuid, ComponentName2,
279 NULL
280 );
281 }
282 }
283
284 //
285 // ASSERT if the call to InstallMultipleProtocolInterfaces() failed
286 //
287 ASSERT_EFI_ERROR (Status);
288
289 return Status;
290 }
2. InstallMultipleProtocolInterfaces
简述 InstallMultipleProtocolInterfaces : 用来安装一一对应的多对Guid的Protocol, 明确注意的是Guid首先与Handle进行绑定, Protocol再与Guid进行绑定, 所以我们正常使用Protocol时首先HandleProtocol再LocateProtocol, 即是为了找到我们需要的Image中对应的真正Protocol:
实例驱动注册
INF文件
以UsbBusDxe为例, 我们正常编写的UEFI驱动都会指定入口点(当然这是个相对地址的函数调用),当Core执行到这个Image就会找到对应的该EntryPoint函数:
17 [Defines]
18 INF_VERSION = 0x00010005
19 BASE_NAME = UsbBusDxe
20 MODULE_UNI_FILE = UsbBusDxe.uni
21 FILE_GUID = 240612B7-A063-11d4-9A3A-0090273FC14D
22 MODULE_TYPE = UEFI_DRIVER
23 VERSION_STRING = 1.0
24
25 ENTRY_POINT = UsbBusDriverEntryPoint
MODULE_TYPE = UEFI_DRIVER; ENTRY_POINT = UsbBusDriverEntryPoint;
EntryPoint实例
1102 /**
1103 The USB bus driver entry pointer.
1104
1105 @param ImageHandle The driver image handle.
1106 @param SystemTable The system table.
1107
1108 @return EFI_SUCCESS The component name protocol is installed.
1109 @return Others Failed to init the usb driver.
1110
1111 **/
1112 EFI_STATUS
1113 EFIAPI
1114 UsbBusDriverEntryPoint (
1115 IN EFI_HANDLE ImageHandle,
1116 IN EFI_SYSTEM_TABLE *SystemTable
1117 )
1118 {
1119 return EfiLibInstallDriverBindingComponentName2 (
1120 ImageHandle,
1121 SystemTable,
1122 &mUsbBusDriverBinding,
1123 ImageHandle,
1124 &mUsbBusComponentName,
1125 &mUsbBusComponentName2
1126 );
1127 }
UsbBusDriverEntryPoint: 调用了我们基础函数EfiLibInstallDriverBindingComponentName2将mUsbBusDriverBinding注册到Handle内, 并绑定特定的gEfiDriverBindingProtocolGuid(该GUID是EDK内部本身唯一确定的).
简述DriverBinding如何被trigger?
- EHCI(Enhanced Host Controller Interface)增强型主机控制器接口规范描述了一个通用串行总线(USB)2.0版的主机控制器的寄存器级接口.
- OHCI (Open Host Controller Interface) 开放式主机控制接口协议 一个不仅仅是usb用的主控制器接口标准.
- XHCI (eXtensible Host Controller Interface) 是一种可扩展的主机控制器接口,是Intel开发的USB主机控制器。
还是以mUsbBusDriverBinding为例:
基础函数内简述的UsbBus层驱动实例内包含 Support, Start, Stop 三个标准回调接口;
假设我们IO上存在一个EHCI的控制器, 首先我们已经注册了EHCI的驱动, 然后EFI_CORE当查询该控制器是否属于一个USB接口的时候(即 Support查看是否安装了gEfiUsb2HcProtocolGuid(EHCI驱动内注册)), Support成功确认为USB接口开始调用Image.Start即(Start)UsbBus开始工作.
本章节主要是以UEFI_DRIVER的视角来阐述工作原理, USB只是为了举例说明, 就不详细深入了, 总之Support是为了确认该驱动是否可以被装载到对应的设备上, Start是真正驱动工作机制.
天若有情天亦老,人间正道是沧桑。