UEFI中的Protocol
一、Protocol是什么
Protocol是服务器端和客户端之间的一种约定,在软件编程上称为接口,服务器端和客户端通过这个约定信息的互通。服务器端和客户端在UEFI中都是可执行的二进制文件,为了实现这些二进制文件之间的互通,C/S双方共同作出的让步,使用Protocol进行双方的交互。
二、Protocol是干什么的,为什么要有Protocol
UEFI的中文含义是“可扩展固件接口”,所谓可扩展的含义就是可以在系统完成后(编译为binary)之后,再次为系统增加新的功能,而不用重新rebuild整个系统。为了支持不同二进制组件运行时相互通信,不同组件可以相互调用之间的功能,同时各个组件相互之间调用时的统一编程接口以便方便组件厂商对于组件的开发等要求。Protocol用以实现这些功能的同时满足服务器端和客户端之间的通信。而通信至少要具备以下几种功能:
(1)互操作。A组件自由可以调用B组件实现的函数。反过来也一样。
(2)数据传递。双方可以通过某种方法(sharedmemory, pipes and etc)互相交换数据。
(3)可探测。某组件必须具备探测另一个组件是否存在的能力。
(4)组件的开发必须是独立的。开发A组件不需要B组件的源代码,反之亦然。
三、Protocol的组成
Protocol其实就是一个大的结构类型,它包含有很多数据信息。最主要的是GUID,每一个Protocol都有一个定义好的、唯一的标识符,这个标识符用GUID来表达。这样程序员可以方便的通过指明不同的GUID来得到不同的Protocol。其次是一个指向GUID的全局指针变量,比如EFI_BLOCK_IO_PROTOCOL,就有一个gEfiBlockIoProtocolGuid的全局指针,他是EFI_GUID *结构的。这样做事实上完全是为了方便,他的变量名的命名规则是统一的,即g + Efi + Protocol 名称 + ProtocolGuid。这样一来,程序员就不需记住相应GUID具体的值,而只在需要GUID作为参数的时候,使用这个全局变量就行了。如果要在应用程序或者驱动中使用这个GUID(如gEfiBlockIoProtocolGuid),那么必须要在.inf文件的[Protocols]中什么以便预处理时将其包含在生成的AutoGen.c中供全局使用。以下是以块设备的Protocol为例描述protocol的数据结构中的成员变量,通过这个Protocol可以控制块设备。
struct _EFI_BLOCK_IO_PROTOCOL {
UINT64 Revision; //必须保证向后兼容的Protocol版本号,若木有向后兼容的话就必须给未来的版本号定义一个新的GUID,相当于定义了一个新的Protoco