UEFI open protocol详解

本文详细解析了UEFI驱动中的OpenProtocol实现方法,包括如何打开、关闭协议,创建子设备,初始化设备,以及安装协议接口等关键步骤。通过深入分析OpenProtocol的原型及其参数,阐述了其在驱动开发中的应用。

 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: 释放协议数据库锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值