当前位置: 代码迷 >> 综合 >> UEFI open protocol详解
  详细解决方案

UEFI open protocol详解

热度:12   发布时间:2023-12-14 22:41:24.0

 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 

接下来,是一系列的参数(合法性)检查:


997-1002: 如果想要查找的protocol 为空,则返回 EFI_INVALID_PARAMETER
1004-1013: 如果Attribute 为 EFI_OPEN_PROTOCOL_TEST_PROTOCOL , 那么仅仅只要检查UserHandle上是否有安装有我们想要的protocol.
1015-1021:  对UserHandle 合法性进行检查。就是看 Handle的Signature 是否为 EFI_HANDLE_SIGNATURE
接下来,还是参数检查,不过这回根据不同的Attribute会作简单的区分。
??
1065-1068 : 锁住protocol 数据库
1070-1083 : 在Userhandle 上面去找由guid 所指定的protocol.通过compareGuid .个人认为,这几行是openprotocol 的核心部分。前半部分是在UserHandle 上面找到了    Protocol, 后半部分将找到的Protocol 赋值给Interface。
1089-1093 : 遍历openlist, 为每一个OpenData 赋值。
1094-1095: 如果打开请求为BY_DRIVER , 将ByDriver 置1.
1096-1099: 表示同一个 AgentHandle 和ControllerHandle 被第二次打开,返回 EFI_ALREADY_STARTED;
1101-1108:如果已经存在Exclusive的打开请求,将Exclusive 置1. 如果不是,将OpenCount 加1

断开已经存在的链接。

1160-1175: 分配一个entry, 并往其结构中填充相应的值,最后插入到Openlist中。
1181: 释放协议数据库锁。??
  相关解决方案