当前位置: 首页 > ds >正文

uefi协议设计目的

在EDK2的术语体系中,GUID定义的是协议的标识符,而具体实现的函数集合称为协议的实现。它们是同一协议的不同抽象层次,以下是详细解释:

1. 协议(Protocol)的两层含义

(1) 协议规范(接口定义)
  • 用GUID标识:每个协议有唯一的GUID,如gEfiSimpleTextOutProtocolGuid
  • 定义接口函数:通过结构体定义一组函数指针,规定协议的功能。
// 协议规范定义(示例)
typedef struct _EFI_SIMPLE_TEXT_OUT_PROTOCOL {EFI_STATUS (*Reset)(EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, BOOLEAN ExtendedVerification);EFI_STATUS (*OutputString)(EFI_SIMPLE_TEXT_OUT_PROTOCOL *This, CHAR16 *String);// 其他函数...
} EFI_SIMPLE_TEXT_OUT_PROTOCOL;
(2) 协议实现(具体代码)
  • 实现接口函数:驱动开发者编写具体的函数实现。
  • 通过GUID注册:将实现绑定到对应的GUID上。
// 协议实现示例
EFI_STATUS
EFIAPI
MyOutputString (IN EFI_SIMPLE_TEXT_OUT_PROTOCOL  *This,IN CHAR16                         *String)
{// 实际输出字符串的代码return EFI_SUCCESS;
}// 协议实例
EFI_SIMPLE_TEXT_OUT_PROTOCOL gMySimpleTextOut = {.Reset       = MyReset,.OutputString = MyOutputString,// 其他函数实现...
};

2. 关键区别

概念描述关联
协议GUID唯一标识符,用于在运行时查找协议接口。一个GUID对应一个协议规范
协议规范定义协议的函数接口(结构体),不包含具体实现。由GUID和结构体共同定义
协议实现具体的函数代码,实现协议规范中定义的接口。多个实现可共享同一GUID

3. 同一GUID的多实现示例

同一个GUID的协议可以有多个实现:

// 协议规范(唯一GUID)
#define EFI_MY_PROTOCOL_GUID \{ 0x12345678, 0x9abc, 0xdef0, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } }typedef struct _EFI_MY_PROTOCOL {EFI_STATUS (*DoWork)(VOID);
} EFI_MY_PROTOCOL;// 实现1:控制台输出
EFI_STATUS EFIAPI ConsoleDoWork(VOID) { Print(L"Console Implementation\n"); return EFI_SUCCESS; }
EFI_MY_PROTOCOL gConsoleImpl = { .DoWork = ConsoleDoWork };// 实现2:文件输出
EFI_STATUS EFIAPI FileDoWork(VOID) { WriteFile(L"output.txt", L"File Implementation\n"); return EFI_SUCCESS; }
EFI_MY_PROTOCOL gFileImpl = { .DoWork = FileDoWork };// 注册两个实现(使用相同GUID)
gBS->InstallProtocolInterface(&h1, &gEfiMyProtocolGuid, EFI_NATIVE_INTERFACE, &gConsoleImpl);
gBS->InstallProtocolInterface(&h2, &gEfiMyProtocolGuid, EFI_NATIVE_INTERFACE, &gFileImpl);

4. 如何调用特定实现

通过句柄(Handle)区分同一协议的不同实现:

// 获取所有实现的句柄
EFI_HANDLE *Handles;
UINTN HandleCount;
gBS->LocateHandleBuffer(ByProtocol, &gEfiMyProtocolGuid, NULL, &HandleCount, &Handles);// 遍历并调用每个实现
for (UINTN i = 0; i < HandleCount; i++) {EFI_MY_PROTOCOL *Protocol;gBS->HandleProtocol(Handles[i], &gEfiMyProtocolGuid, (VOID**)&Protocol);Protocol->DoWork();  // 调用不同实现的函数
}

总结

  • GUID和协议:GUID是协议的唯一标识符,协议规范定义了接口。
  • 实现:具体的函数代码称为协议的实现,多个实现可共享同一GUID。
  • 调用方式:通过GUID查找协议,通过句柄区分不同实现。

这种设计使得EDK2能够实现灵活的插件架构和多态机制。

在EDK2(UEFI开发工具包)中,.dec.dsc.inf是三种核心配置文件,分别用于不同层次的组件定义和构建配置。以下是它们的主要区别和作用:

1. DEC文件(定义文件,.dec)

作用
  • 声明全局可用的元数据(如GUID、PPI、Protocol、PCD等)
  • 定义跨模块共享的常量和类型
  • 不包含具体实现代码
关键内容
  • GUID定义:唯一标识协议、PPI、驱动等
  • PPI/Protocol声明:定义接口规范
  • PCD(平台配置数据)声明:定义可配置参数
  • 库类声明:定义库接口
示例
[Defines]DEC_SPECIFICATION_VERSION = 0x00010005  # DEC文件规范版本[Guids]gEfiSimpleTextOutProtocolGuid = { 0x387477c2, 0x69c7, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } }[Ppis]gEfiPeiReadOnlyVariable2PpiGuidgEfiPeiServicesTablePointerPpiGuid[Protocols]gEfiDevicePathProtocolGuidgEfiSimpleNetworkProtocolGuid[PcdsFeatureFlag]gEfiMdeModulePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000FFFF

2. DSC文件(描述文件,.dsc)

作用
  • 定义完整的UEFI固件或应用程序
  • 指定要构建的组件(驱动、应用、库)
  • 配置构建选项和平台特性
  • 控制模块之间的依赖关系
关键内容
  • 平台定义:描述目标平台特性
  • 组件列表:指定要包含的模块(.inf文件)
  • PCD值设置:为特定平台定制PCD参数
  • 构建选项:编译器、链接器参数等
示例
[Defines]PLATFORM_NAME           = MyPlatformPLATFORM_GUID           = { 0x12345678, 0x9abc, 0xdef0, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } }PLATFORM_VERSION        = 1.0DSC_SPECIFICATION       = 0x00010005[Components]# 包含的驱动组件MdeModulePkg/Bus/Usb/Host/UsbUhciDxe/UsbUhciDxe.infMdeModulePkg/Bus/Usb/Host/UsbEhcxDxe/UsbEhcxDxe.inf# 包含的应用组件MdeModulePkg/Application/HelloWorld/HelloWorld.inf[PcdsFixedAtBuild]gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"Contoso"gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersion|0x10000

3. INF文件(信息文件,.inf)

作用
  • 描述单个模块(驱动、应用、库)的元数据
  • 指定源文件、依赖项、库类和构建选项
  • 是构建系统的最小单元
关键内容
  • 模块基本信息:类型(驱动/应用/库)、名称、GUID
  • 源文件列表:包含的C/ASM等源文件
  • 库依赖:使用的库类
  • 协议/PPI依赖:模块需要的接口
  • 构建选项:特定于模块的编译参数
示例
[Defines]INF_VERSION             = 0x00010005BASE_NAME               = MyDriverFILE_GUID               = { 0x12345678, 0x9abc, 0xdef0, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } }MODULE_TYPE             = UEFI_DRIVERVERSION_STRING          = 1.0[Sources]MyDriver.cMyHelper.c[Packages]MdePkg/MdePkg.decMdeModulePkg/MdeModulePkg.dec[LibraryClasses]UefiDriverEntryPointUefiLibDebugLib[Protocols]gEfiDevicePathProtocolGuidgEfiSimpleTextOutProtocolGuid

4. 三者关系总结

文件类型作用核心内容示例用途
DEC全局声明元数据GUID、PPI、Protocol、PCD定义定义标准UEFI协议的GUID
DSC定义整个平台或应用组件列表、平台PCD值、构建选项配置UEFI固件包含的所有驱动
INF描述单个模块源文件、库依赖、模块特性定义一个USB驱动的构建参数

5. 构建流程中的协作

  1. DEC文件:提供全局符号和类型定义,被DSC和INF引用
  2. DSC文件:指定要构建的INF列表,并为它们提供平台级配置
  3. INF文件:指导具体模块的编译和链接,依赖DEC中定义的符号

例如,当构建一个UEFI驱动时:

  • INF文件列出驱动的源文件和依赖库
  • DSC文件决定该驱动是否被包含在最终固件中
  • DEC文件提供驱动所需的协议和PPI定义

6. 最佳实践

  • 模块化设计:每个组件应有独立的INF,避免过大的模块
  • 避免重复:公共定义放在DEC中,避免在多个INF/DSC中重复
  • 配置分离:通过PCD在DSC中定制平台特性,避免硬编码
  • 版本控制:保持DEC/DSC/INF版本同步,避免兼容性问题

理解这三种文件的区别和协作方式,是EDK2开发的基础。

http://www.xdnf.cn/news/12309.html

相关文章:

  • linux——磁盘和文件系统管理
  • python打卡训练营打卡记录day45
  • 数学运算在 OpenCV 中的核心作用与视觉效果演示
  • 本地部署大模型实战:使用AIStarter一键安装Ollama+OpenWeb教程(含最新版本更新指南)
  • 【图像处理3D】:焦距的像素单位标定
  • 使用API有效率地管理Dynadot域名,查看域名市场中所售域名的详细信息
  • 宠物车载安全座椅市场报告:解读行业趋势与投资前景
  • MyBatis-Plus深度全解:从入门到企业级实战
  • 旋转字符串的解题思路与算法分享
  • Offline Transition Modeling via Contrastive Energy Learning
  • 【iSAQB软件架构】软件架构中构建块的视图:黑箱、灰箱和白箱及其交互机制
  • vue和uniapp聊天页面右侧滚动条自动到底部
  • 计算机网络领域所有CCF-A/B/C类期刊汇总!
  • 低代码逻辑引擎配置化实战:三步穿透审批记录查询
  • 鞋内测量新方案:Moticon传感器鞋垫OpenGo在运动科学中的平衡测试应用
  • BIM Revit教程(十一)如何使用机器学习实现 MEP 布局自动化?
  • NumPy数组操作完全指南:从入门到精通
  • 【Zephyr 系列 9】Zephyr 与设备树机制详解:如何为你的板子编写 Devicetree
  • open3d:使用彩色图和深度图生成点云
  • 拆解实战案例:电商ERP管理系统从需求到原型全流程设计
  • 深度学习习题3
  • IDEA 包分层显示设置
  • Postgresql字符串操作函数
  • 《前端面试题:CSS3新特性》
  • 结合PDE反应扩散方程与物理信息神经网络(PINN)进行稀疏数据预测的技术方案
  • 【VLAs篇】02:Impromptu VLA—用于驱动视觉-语言-动作模型的开放权重和开放数据
  • reverse笔记
  • 深度学习在非线性场景中的核心应用领域及向量/张量数据处理案例,结合工业、金融等领域的实际落地场景分析
  • 比特币:固若金汤的数字堡垒与它的四道防线
  • 【Redis】笔记|第9节|Redis Stack扩展功能