uefi driver 大致实现方法
1. 使用OpenProtocol() 打开所有需要用到的protocol, OpenProtoco参数列表里面有一个 Attribute。 如果这个driver 允许打开的 protocol 和其他的driver 共用,这时候,就用EFI_OPEN_PROTOCOL_BY_DRIVER 作为Attribute, 反之,如果这个driver 不允许其他的 driver 共享打开的protocol, 就用 OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE.
2. 如果第一步OpenProtocol 执行出现了任何差错,要用CloseProtocol 关掉所有已经打开的Protocol, 并返回错误代码。
3. 创建RemaingDevicePath 指定的子设备。
4. 初始化ControllerHandle 指定的device.
5. 按 ControllerHandle 分配并初始化所有的数据结构(结构体)。
6. 使用InstallProtocolInterface() 向ControllerHandle 上安装相应的protocol.
7. 返回 EFI_SUCCESS
在符合EFI driver 模型的驱动里,不可避免的要用到 gBS->OpenProtocol. 这篇文章就详细说说Open protocol 的实现。
OpenProtocol 的原型是 CoreOpenProtocol , 它的实现在Handle.c 里面。
函数原型及参数解释:
首先: 多个protocol 构成的handle, 如果handle的protocol 链表里面有想要找的Protocol, 则Protocol 对象的指针写到*Interface。从handle 上去找到想要的Protocol,利用(invoke) 它去获得相应的interface. 最后将相关信息注册到 protocol 数据库里面(通过向链表插入的方法InsertTailList (&Prot->OpenList, &OpenData->Link);)
962: 获得protocol 的handle.我们将要在这个handle 上面去找我们想要的protocol.
963: Protocl 的guid.
964: 得到的interface 的位置(应该是在内存中的地址) 963 和 964 搭配起来,一般长成这个样子: 09576E91-6D3F-11D2-8E39-00A0C969723B 8A60B918 后面是 interface 的位置。
965:打开此protocol 的Image。
966: 需要这个interface 的controller handle.
970 : 打开模式(方式),一共有六个取值。
独占这个protocol, 不与其它driver 共享,如果Protocol已经打开,则再次打开时将失败#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 #define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010独占这个protocol, 不与其它driver 共享,如果Protocol已经打开,则再次打开时将失败
#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
接下来,是一系列的参数(合法性)检查: