栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

UEFI 原理与编程实战

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

UEFI 原理与编程实战

欢迎关注全是干货的技术号 JavaEdge

1 UEFI 内核下的 Protocol 1.1 EFI_HANDLE

指向某种对象的指针,UEFI用其表示某个对象。

  • UefibaseType.h
// 相关接口的集合.
typedef VOID *EFI_HANDLE;

UEFI 扫描总线后,为每个设备建立一个Controller对象,来控制该设备,
所有该设备的驱动以Protocol的形式安装到该Controller上,这个Controller就是一个EFI_HANDLE对象。

在UEFI内部,EFI_HANDLE被理解为IHANDLE,其结构如下:

  • edk2/MdeModulePkg/Core/Dxe/Hand/Handle.h
// IHANDLE -包含Protocol handle 链表
typedef struct {
  UINTN Signature;
  // 所有IHandle组成的链表
  LIST_ENTRY   AllHandles;
  // List of PROTOCOL_INTERFACE's for this handle 该Handle下的Protocol链表
  LIST_ENTRY   Protocols;
  UINTN LocateRequest;
  // The Handle Database Key value when this handle was last created or modified
  // 上次创建或修改此handle 时的Handle Database Key值
  UINT64Key;
} IHANDLE;

在该结构体中,重要的为

1.2 LIST_ENTRY
  • edk2/MdePkg/Include/base.h
// LIST_ENTRY 结构定义.
typedef struct _LIST_ENTRY LIST_ENTRY;

// _LIST_ENTRY 结构定义.
struct _LIST_ENTRY {
  LIST_ENTRY  *Forwardlink;
  LIST_ENTRY  *Backlink;
};

由此可见 IHANDLE 包含两个双向链表

  • 一条用于串联所有 IHANDLE 实例,因为串联的是两个 IHANDLE 结构体中 AllHandles 成员变量,因此会利用到 _CR
    宏主要利用成员在结构体中的偏移量得到结构体的基地址
    具体实现在./baseTools/Source/C/Include/Common/baseTypes.h
  • 另外一条用于串联该handle所有的 PROTOCOL_INTERFACE
1.3 PROTOCOL_INTERFACE

edk2/MdeModulePkg/Core/Dxe/Hand/Handle.h

// PROTOCOL_INTERFACE - 使用该结构跟踪安装在 handle 上的每个 protocol 
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的定义,在同文件内可以看到定义

// PROTOCOL_ENTRY - Each handler that supports this protocol is listed, along with a list of registered notifies.
// 每个不同的 protocol 在 protocol 数据库中都有1个 entry
// 列出了支持该 protocol 的每个处理程序以及已注册通知的链表
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的 GUID

GUID的三种形式
一:3a738b36-b9c5-4763-abbd-6cbd4b25f9ff
二:{ 0x36, 0x8b, 0x73, 0x3a, 0xc5, 0xb9, 0x63, 0x47, 0xab, 0xbd, 0x6c, 0xbd, 0x4b, 0x25, 0xf9, 0xff }
三:{ 0x368b733a, 0xc5b9, 0x630x47, { 0xab, 0xbd, 0x6c, 0xbd, 0x4b, 0x25, 0xf9, 0xff } }
生成GUID的网站
https://www.guidgen.com

1.4 小结 IHANDLE内的Protocol组织图

总体来说主要由三条链表将这些数据结构串在一起

  • 一条为所有Handle串成的链表Handle Database
  • 一条为Protocol串起的Protocol Database
  • 第三条为PROTOCOL_INTERFACE串起的链表
    如下图

参考

UEFI小结-Handle的来龙去脉
如何理解UEFI中handle和protocol的概念
UEFI原理与编程

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号