3.UEFI中的Protocol

1.UEFI中的Protocol引入了面向对象的思想:

--用struct来模拟class

--用函数指针(Protocol的成员变量)模拟成员函数,此种函数的第一个参数必须指向Protocol的指针,用来模拟this。

(通常,计算机中有很多的块设备,每个块设备都有一个EFI_BLOCK_IO_PROTOCOL的实例,This指针就是指向这个实例,用于告诉成员函数我们正在操作哪个设备。This指针是Protocol成员函数的一个重要特征。)

2.Protocol在UEFI内核中的表示:

使用Protocol之前,我们需要知道Protocol位于什么地方。首先,我们要来认识一下EFI_HANDLE

typedef VOID * EFI_HANDLE;

EFI_HANDLE是指向某种对象的指针,UEFI用它来指向某个对象。UEFI扫描总线后,会为总线上的每个设备创立一个Controller对象,用于控制设备,所有该设备的驱动以protocol的形式安装到这个Controller中,这个Controller就是一个EFI_HANDLE对象。当我们将一个.efi文件加载到内存中时,UEFI也会为该文件创建一个image对象。在UEFI内部,EFI_HANDLE被理解为IHANDLE,IHANDLE的数据结构代码如下所示:

typedef struct{

UINTN Signature;//表明Handle的类别

LIST_ENTRY AllHandles;//所有Handle组成的链表

LIST_ENTRY Protocols;//此Handle的Protocols链表

UINTN LocateRequest;

UINT64 Key;

}IHANDLE;

每个IHANDLE都有一个protocols链表(双向链表),存放属于自己的protocol。所有的IHANDLE通过AllHandles连接起来。

3.如何使用protocol

Boot Services提供了对Protocol进行操作的services,如OpenProtocol()、HandleProtocol()、LocateProtocol()三种服务用于找出指定的protocol:OpenProtocol()用于打开指定句柄上的Protocol;HandleProtocol()是OpenProtocol()的简化版;LocateProtocol()用于找出指定protocol在系统中的第一个实例。使用完Protocol后还要通过CloseProtocol()关闭打开的protocol,否则可能造成内存泄露,由于HandleProtocol和OpenProtocol没有指定AgentHandle,所以无法关闭,如果一定要关闭,需要调用OpenProtocolInformation()获得AgentHandle和ControllerHandle,然后关闭它。

除了打开和关闭protocol,有时候还有能找出支持某个Protocol的所有设备。例如要找出支持BlockIos的所有设备(即找出所有块设备),这时候就要使用LocateHandleBuffer()服务;如果想知道某个Protocol被哪些设备打开了,那么可以使用OpenProtocolInformation()服务;ProtocolPerHandle()用于获得指定设备所支持的所有Protocol。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,363评论 0 6
  • 从我们按下开机键到进入到操作系统之前的系统初始化动作,即是BIOS run的过程。如今操作系统已经从枯燥的文本时代...
    NickHe阅读 4,204评论 0 10
  • SEC--PEI--DXE--BDS 【SEC阶段】 1.SEC的功能: SEC阶段是平台初始化的第一个阶段,计算...
    NickHe阅读 11,058评论 1 10
  • 理论部分 镜像 一、镜像的百科定义 1、维基百科 ISO映像是一种光盘的存档文件(英语:archive file)...
    幻影翔阅读 1,955评论 4 3
  • 原本以为画正方体很容易,但在缠绕画的第二堂素描课里,发现以前画的那么多正方体竟然都是错的,至少在素描领域是错的。实...
    好吃的芒果饭阅读 773评论 0 0