UEFI源码解析之PROTOCOL&HANDLE

本文详细介绍了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的管理和交互机制。

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;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值