Protocol用于UEFI在DXE及之后各阶段中各模块之间的通信,作用与PI阶段的PPI类似;Protocol与Handle一起使用,实现了C++中的面向对象的编程方式,且能达到类似数组或map中的访问方式,通过一个输入数值Handle/GUID等获取数据结构信息或操作接口等;
以下介绍Protocol/Handle在UEFI内核中的实现以及各接口的使用;主要代码在MdeModulePkg\Core\Dxe\Hand\Handle.c中,DxeMain阶段的mBootDevice中指向了各与Protocol/Handle相关的接口。
几个重要的全局变量,用于保存Protocol/Handle的全貌;
//整个系统所有Protocol构成的链表
LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
//整个系统所有Handle构成的链表
LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
// Protocol/Handle操作的互斥保护锁
EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);
UINT64 gHandleDatabaseKey = 0;
重要的数据结构及相互之间的连接关系:
Protocol对应一个PROTOCOL_ENTRY,通过AllEntries连入mProtocolDatabase全局链表中;
通过给定的Protocol GUID可以在链表中找到该Entry:
PROTOCOL_ENTRY *CoreFindProtocolEntry (IN EFI_GUID *Protocol, IN BOOLEAN Create)
{
//遍历mProtocolDatabase的节点,节点的guid与输入guid一直则认为找到
ProtEntry = NULL;
for (Link = mProtocolDatabase.ForwardLink; Link != &mProtocolDatabase;
Link = Link->ForwardLink) {
Item = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
if (CompareGuid (&Item->ProtocolID, Protocol)) {
ProtEntry = Item;
break;
}
}
// 没有找到guid对应的protocol entry,且指定了新建标志,则新建entry
if ((ProtEntry == NULL) && Create) {
ProtEntry = AllocatePool (sizeof(PROTOCOL_ENTRY));
CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol); //初始化guid
InitializeListHead (&ProtEntry->Protocols); //连接该protocol相关的Interface
InitializeListHead (&ProtEntry->Notify); //连接该protocol相关的Notify
InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries); //全局管理
}
}
return ProtEntry;
}
所有安装在Handle上的Protocol中实际内容用PROTOCOL_INTERFACE表示,
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
IHANDLE *Handle;
LIST_ENTRY ByProtocol;
PROTOCOL_ENTRY *Protocol;
VOID *Interface;

本文详细介绍了UEFI(统一可扩展固件接口)内核中Protocol和Handle机制的工作原理。Protocol用于不同模块间的通信,类似于PI阶段的PPI,与Handle结合实现面向对象编程。全局变量mProtocolDatabase和gHandleList维护所有Protocol和Handle的链表,通过EFI_LOCK gProtocolDatabaseLock确保同步。CoreFindProtocolEntry函数用于查找Protocol Entry,而CoreInstallProtocolInterface实现Protocol的安装。CoreHandleProtocol和CoreOpenProtocol分别用于查询Handle支持的Protocol及获取Interface。CoreLocateHandle和CoreLocateHandleBuffer则根据Protocol查找Handle。此外,CoreRegisterProtocolNotify用于注册Protocol通知。这些接口共同构建了UEFI内核中Protocol和Handle的管理和交互机制。
最低0.47元/天 解锁文章
1758

被折叠的 条评论
为什么被折叠?



