以下内容为学习《UEFI原理与编程》(戴正华)第四章和第六章的摘要

UEFI是用C语言来实现的,但UEFI中Protocol是作为一种对象来设计和使用。例如:

// 通过这个protocol可以控制块设备

struct  _EFI_BLOCK_IO_PROTOCOL{

UINT64 Revision;

EFI_BLOCK_IO_MEDIA *Media;

EFI_BLOCK_RESET Reset;

EFI_BLOCK_READ ReadBlocks;

EFI_BLOCK_ERITE WriteBlocks;

EFI_BLOCK_FLUSH FlushBlocks;

};

extern EFI_GUID gEfiBlockIoProtocolGuid;

每个protocol必须有一个唯一的GUID, 例如:

///
/// Global ID for EFI_PEI_RECOVERY_BLOCK_IO_PPI
///
#define EFI_PEI_RECOVERY_BLOCK_IO_PPI_GUID \
  { \
    0x695d8aa1, 0x42ee, 0x4c46, { 0x80, 0x5c, 0x6e, 0xa6, 0xbc, 0xe7, 0x99, 0xe3 } \
  }

EFI_BLOCK_IO_PROTOCOL的ReadBlocks服务的函数原型

/*++
  Routine Description:
    Read BufferSize bytes from Lba into Buffer.

Arguments:
    This       - Protocol instance pointer.
    MediaId    - Id of the media, changes every time the media is replaced.
    Lba        - The starting Logical Block Address to read from
    BufferSize - Size of Buffer, must be a multiple of device block size.
    Buffer     - Buffer containing read data

Returns:
    EFI_SUCCESS           - The data was read correctly from the device.
    EFI_DEVICE_ERROR      - The device reported an error while performing the read.
    EFI_NO_MEDIA          - There is no media in the device.
    EFI_MEDIA_CHANGED     - The MediaId does not matched the current device.
    EFI_BAD_BUFFER_SIZE   - The Buffer was not a multiple of the block size of the device.
    EFI_INVALID_PARAMETER - The read request contains device addresses that are not  valid for the device.
--*/
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_READ) (
  IN EFI_BLOCK_IO_PROTOCOL          * This,
  IN UINT32                         MediaId,
  IN EFI_LBA                        Lba,
  IN UINTN                          BufferSize,
  OUT VOID                          *Buffer
  )

使用Protocol之前,要先弄清楚Protocol在UEFI内核中是怎样表示的。首先来认识EFI_HANDLE.

typedef  VOID  *EFI_HANDLE;

EFI_HANDLE 是指向某种对象的指针,UEFI用它来表示某个对象。UEFI扫描总线后,会为每个设备建立一个Controller对象,用于控制设备,所有该设备的驱动以Protocol的形式安装到这个Controller中,这个Controller就是一个EFI_HANDLE对象。当我们加载.efi文件到内存中时,UEFI也会为该文件建立一个Image对象,这个对象也是EFI_HANGDLE对象。在UEFI内部,EFI_HANDLE被理解为IHANDLE. 可查看Handle.h

///
/// IHANDLE - contains a list of protocol handles
///
typedef struct {
  UINTN               Signature;
  /// All handles list of IHANDLE
  LIST_ENTRY          AllHandles;
  /// List of PROTOCOL_INTERFACE's for this handle
  LIST_ENTRY          Protocols;      
  UINTN               LocateRequest;
  /// The Handle Database Key value when this handle was last created or modified
  UINT64              Key;
} IHANDLE;

所有IHANDLE通过AllHandles链接,而每个IHANDLE的Protocol通过Protocols链接。

IHANDLE的Protocols是一个双向链表,链表中的每一个元素是PROTOCOL_INTERFACE, 通过PROTOCOL_INTERFACE的Protocol指针可以得到这个Protocol的GUID,通过Interface指针可以得到这个Protocol的实例。

///
/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked
/// with a protocol interface structure
///
typedef struct {
  UINTN                       Signature;
  /// Link on IHANDLE.Protocols
  LIST_ENTRY                  Link;   
  /// Back pointer
  IHANDLE                     *Handle;  
  /// Link on PROTOCOL_ENTRY.Protocols
  LIST_ENTRY                  ByProtocol; 
  /// The protocol ID
  PROTOCOL_ENTRY              *Protocol;  
  /// The interface value
  VOID                        *Interface; 
  /// OPEN_PROTOCOL_DATA list
  LIST_ENTRY                  OpenList;       
  UINTN                       OpenListCount;

} PROTOCOL_INTERFACE;

///
/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol
/// database.  Each handler that supports this protocol is listed, along
/// with a list of registered notifies.
///
typedef struct {
  UINTN               Signature;
  /// Link Entry inserted to mProtocolDatabase
  LIST_ENTRY          AllEntries;  
  /// ID of the protocol
  EFI_GUID            ProtocolID;  
  /// All protocol interfaces
  LIST_ENTRY          Protocols;     
  /// Registerd notification handlers
  LIST_ENTRY          Notify;                 
} PROTOCOL_ENTRY;

所有的Protocol均放在mProtocolDatabase指向的PROTOCOL_ENTRY链表中。PROTOCOL_ENTRY包含三个链表。

AllEntries是PROTOCOL_ENTRY链。

Protocols指向此Protocol的所有实例。   例如:系统中可能有很多块设备,每个块设备都有一个EFI_BLOCK_IO_PROTOCOL实例,所有的EFI_BLOCK_IO_PROTOCOL实例都会插入到PROTOCOL_ENTRY.Protocols链表中。

Notify指向PROTOCOL_NOTIFY链表,当PROTOCOL_ENTRY,ProtocolID对应的Protocol安装时,Notify链表中所有Event都会触发。

UEFI中的Protocol相关推荐

  1. UEFI中的Protocol浅谈

    UEFI中的Protocol 一.Protocol是什么 Protocol是服务器端和客户端之间的一种约定,在软件编程上称为接口,服务器端和客户端通过这个约定信息的互通.服务器端和客户端在UEFI中都 ...

  2. 【UEFI基础】Protocol介绍

    简要说明 Protocol是UEFI中的一个重要概念(事实上<UEFI SPEC>中有超过70%的内容都是在讲Protocol),下面简单说明下: 1. 首先,非常重要的一点,Protoc ...

  3. PCI Option ROM 在UEFI中加载流程

    目录 一.UEFI Driver 是什么? 二.UEFI Driver 加载流程 1.EFI_DRIVER_BINDING_PROTOCOL 2. PCI扫描过程中是如何确定PCI设备是支持optio ...

  4. UEFI Handle与Protocol

    最近看了一些UEFI中handle和protocol的资料,这里做一个整理,写一点自己的理解,想了想还是搬运过来了,因为写得比较认真,但是放github 博客上除了我应该没人看吧. 主要参考文章 UE ...

  5. uefi中的Smbios实现

    需要了解的Smbios知识: (1)什么是Smbios: Smbios在百度百科中是这样解释的:Smbios(system management bios)是主板或者系统制造厂商以标准格式显示产品信息 ...

  6. UEFI中的PCI设备扫描及分配Mem/Io空间过程

    最近在调试解决PCI设备相关的问题,然后对UEFI下面的这部分实现有了初步的了解,为了防止后面慢慢的又忘记了,所以还是决定将最近的收获都记录起来,各位读者如果发现哪里记录或者总结的不对,欢迎留言指正. ...

  7. spring 项目中集成 Protocol Buffers 示例

    http://blog.csdn.net/fangzhangsc2006/article/details/8687388 本文适用于了解spring框架,同时想在spring项目中使用Protocol ...

  8. 在Android中使用Protocol Buffers

    网络性能优化的终极手法就是不通过网络传输,但这常常是不可能的.但我们还是可以通过对网络传输的数据本身做优化,来获得更好的性能,性能就应该从每一个可能的地方榨取.这里来看一下 Protocol Buff ...

  9. 在Java中使用Protocol Buffers

    这份教程为Java开发者提供了使用 Protocol Buffer 的基本介绍.通过创建一个简单的示例应用,它展示了 在 .proto 文件中定义消息格式. 使用 Protocol Buffer 编译 ...

  10. 在C++中使用Protocol Buffers

    下载并编译Protocol Buffer 这份教程为C++开发者提供了使用 Protocol Buffer 的基本介绍.通过创建一个简单应用,它展示了 在 .proto 文件中定义消息格式. 使用 P ...

最新文章

  1. 【建站系列教程】7、SEO优化之meta标签【最后一篇】
  2. Git安装教程(Windows安装)
  3. windows dos/cmd常用命令
  4. 为什么软件开发方法论让你觉得糟糕?Why Software Development Methodologies Suck?
  5. CentOS 7 安装nexus
  6. 【数学基础】一份非常适合人工智能学习的概率论基础材料中文版 (CS229概率论)...
  7. 中方:开展科技合作应秉持开放、合作、包容心态
  8. 记一次 Vue 移动端活动倒计时优化
  9. 图像识别:微信跳一跳机器人
  10. 天体运行动图,如此美妙,如此震撼!
  11. c#web页面显示弹窗_web页面实现PDF读取显示
  12. (转)Cesium教程系列汇总
  13. 用FileOutputStream将内容写入到文本
  14. 如何花式计算20的阶乘?
  15. 应用WSH、JavaScript和 bat 实现自动化构建工具改善工作中的代码部署流程!
  16. 【毕设狗】【单片机毕业设计】基于单片机的红外非接触测温设计-实物设计
  17. 解决Solidworks 2016 安装注册Activator.GUI.SSQ卡顿 闪退 崩溃等问题
  18. 游怎么用模拟器多开挂机不封号
  19. 量手知姓氏 :算命测姓氏 之 数学原理
  20. 出售计算机广告英文作文,17年6月大学英语四级作文参考范文—二手电脑广告

热门文章

  1. JFreeChart的简单使用
  2. 3维人体建模历史最全算法、论文、数据等资源整理分享
  3. ERStudio逆向工程生成ER模型
  4. 深度神经网络主要模型,深度神经网络预测模型
  5. INSAR学习(小白笔记一)
  6. RJ45与网络变压器脚位及网线线序的关系?
  7. Excel对于筛选后单元格进行“复制”与“粘贴”
  8. C语言:判断一个三位数是否为水仙花数
  9. vue 编写H5项目使用BScroll “better-scroll“;两边都滚动,并且联系
  10. MagicDraw-状态机图