尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
EDK2源码架构:DXE Dispatcher驱动加载顺序与Protocol Database
搜EDK2 DXE的人很多但大部分文章只讲概念。本文从Dispatcher.c源码出发把五级优先级、Depex后缀表达式评估、Protocol三层结构、Notify订阅机制全部拆清楚配实战踩坑案例。一、DXE Core烧的三把火公司换了个新老板第一件事不是开会是搞清楚三件事手头有哪些资源、怎么分配任务、定一套规矩。DXE Core也是这个逻辑。PEI把家底HOB List交过来之后DXE Core烧三把火建协议数据库让所有驱动能互相找到、调度驱动加载决定谁先跑、管理硬件资源内存、IO、中断、DMA。PEI和DXE最大的区别PEI是临时工——跑完就扔模块卸载了内存回收。DXE是正式员工——驱动一直驻留在内存直到OS启动驱动之间通过Protocol永久互连。二、DXE Dispatcher和PEI Dispatcher的根本不同调度主循环// MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.cVOIDCoreDispatcher(IN EFI_STATUS*ReturnStatus){// 第一步找到Busy状态的FV注册所有DXE驱动到调度队列DiscoverFvAndRegisterDrivers();// 第二步进入调度循环——和PEI不同这是多轮循环do{StatusCoreDispatchOneDriver();}while(Status!EFI_NOT_FOUND);// 第三步通知Dispatcher Architecture Protocol的注册者DispatcherCoreLocateProtocol(gEfiDispatcherArchProtocolGuid);if(Dispatcher!NULL){Dispatcher-DispatcherLoaded(Dispatcher);}}PEI vs DXE Dispatcher对比方面PEI DispatcherDXE Dispatcher调度对象PEIM每个只跑一次DXE Driver驻留内存依赖表达PPI GUID布尔表达式Protocol GUID布尔表达式 优先级调度策略纯Depex驱动Depex Driver Binding 优先级排序FV发现静态BFV PPI通知动态FV HOB DXE Driver主动通知执行后PEIM卸载驱动Stay Resident安装Protocol三、五级优先级体系DXE Dispatcher不是谁的Depex先满足谁先跑这么简单。它有五级优先级// MdePkg/Include/Pi/PiDxeCis.h#defineDXE_DRIVER_PRIORITY_PLATFORM_PROCESSOR0x03000000// 最早#defineDXE_DRIVER_PRIORITY_PLATFORM_CHIPSET0x03010000#defineDXE_DRIVER_PRIORITY_BUS0x03020000#defineDXE_DRIVER_PRIORITY_DEVICE0x03030000#defineDXE_DRIVER_PRIORITY_PLATFORM_APPLICATION0x03040000// 最晚优先级写在每个DXE驱动的PE/COFF头或FV文件扩展头里。Dispatcher先扫一遍所有注册的驱动按优先级分组每组内再按Depex评估。这个设计解决了PEI阶段一个头疼的问题PEI里只能靠Apriori强制排序DXE里不需要了——优先级表达得更自然。四、Depex评估后缀表达式DXE驱动的Depex比PEI的复杂支持Protocol GUID和SORScheduled Order Rule// USB键盘驱动的Depex示例 AND gEfiUsbIoProtocolGuid // 必须有USB IO Protocol gEfiSimpleTextInputProtocolGuid // 且已有至少一个输入设备 ENDDepex是后缀表达式逆波兰表示法评估器维护一个操作数栈// MdeModulePkg/Core/Dxe/Dispatcher/Dependency.cBOOLEANCoreEvaluateDependency(IN EFI_CORE_DRIVER_ENTRY*DriverEntry){// EFI_DEP_PUSH_GUID → 查Protocol是否存在压栈// EFI_DEP_AND → 弹两个操作数逻辑与// EFI_DEP_OR → 弹两个操作数逻辑或// EFI_DEP_NOT → 弹一个操作数逻辑非// EFI_DEP_TRUE/FALSE → 压常量// EFI_DEP_END → 评估结束栈顶就是结果}五、Protocol DatabaseDXE的黄页三层结构如果你用过COM、D-Bus或Android的Binder IPC看到DXE Protocol Database会觉得似曾相识。三层结构Handle Database (全局链表) └── IHANDLE (句柄) ├── 唯一Handle ID └── PROTOCOL_INTERFACE 链表 ├── Protocol GUID ├── Protocol Interface 指针 └── 注册这个Protocol的Agent Handle// MdeModulePkg/Core/Dxe/Hand/Handle.htypedefstruct{UINTN Signature;// hListLIST_ENTRY AllHandles;// 连到全局Handle ListLIST_ENTRY Protocols;// 这个Handle上装的所有ProtocolUINTN LocateRequest;UINT64 Key;// 唯一ID}IHANDLE;typedefstruct{UINTN Signature;// pI/FLIST_ENTRY Link;// 连到IHANDLE.ProtocolsLIST_ENTRY ByProtocol;// 连到PROTOCOL_ENTRY.AllEntriesIHANDLE*Handle;PROTOCOL_ENTRY*Protocol;VOID*Interface;// Protocol具体数据指针PROTOCOL_NOTIFY*Notify;}PROTOCOL_INTERFACE;typedefstruct{UINTN Signature;// PEnTLIST_ENTRY AllEntries;// 连到全局Protocol Entry ListEFI_GUID ProtocolID;// GUIDLIST_ENTRY Protocols;// 所有装了这个Protocol的PROTOCOL_INTERFACELIST_ENTRY Notify;// RegisterProtocolNotify的注册者}PROTOCOL_ENTRY;双向索引从Handle能找到它装了什么Protocol从Protocol GUID能找到所有装了它的Handle。六、InstallProtocolInterface驱动挂牌营业安装流程每个DXE驱动跑起来后第一件事是安装自己提供的Protocol。这是链式调用InstallProtocolInterface → CoreInstallProtocolInterfaceNotify → InsertTailList // 挂到IHANDLE → InsertTailList // 挂到PROTOCOL_ENTRY → CoreNotifyProtocolEntry // 通知所有等待者// MdeModulePkg/Core/Dxe/Hand/Handle.cEFI_STATUS EFIAPICoreInstallProtocolInterface(IN OUT EFI_HANDLE*UserHandle,IN EFI_GUID*Protocol,IN EFI_INTERFACE_TYPE InterfaceType,IN VOID*Interface){returnCoreInstallProtocolInterfaceNotify(UserHandle,Protocol,InterfaceType,Interface,TRUE// NotifyTRUE安装后立刻通知等待者);}InstallMultipleProtocolInterfaces日常开发没人直接调InstallProtocolInterface——太啰嗦。用InstallMultipleProtocolInterfaces一次装好几个// 典型调用一个Handle上装两个ProtocolEFI_HANDLE HostBridgeHandleNULL;StatusgBS-InstallMultipleProtocolInterfaces(HostBridgeHandle,gEfiDevicePathProtocolGuid,DevicePath,gEfiPciHostBridgeResourceAllocationProtocolGuid,ResAlloc,NULL// 参数列表结束);ReinstallProtocolInterface需要更新已安装的Protocol时不能直接改Interface指针在跑的驱动可能正在用必须走Reinstall——三步走通知断开 → 换指针 → 通知重连。七、LocateProtocol驱动找服务安装是挂牌查找是翻黄页// MdeModulePkg/Core/Dxe/Hand/Locate.cEFI_STATUSCoreLocateProtocol(IN EFI_GUID*Protocol,IN VOID*Registration,OUT VOID**Interface){ProtEntryCoreFindProtocolEntry(Protocol,FALSE);// Protocol可能装了不止一份返回第一个找到的InterfaceProtCR(ProtEntry-Protocols.ForwardLink,PROTOCOL_INTERFACE,ByProtocol,PROTOCOL_INTERFACE_SIGNATURE);*InterfaceProt-Interface;returnEFI_SUCCESS;}LocateHandleBuffer用于遍历所有装了某个Protocol的Handle比如枚举所有PCI设备。八、Notify机制等Protocol的订阅-发布有的驱动依赖的Protocol可能还没安装——比如USB键盘驱动需要EFI_USB_IO_PROTOCOL但USB控制器驱动还在后面排着队。RegisterProtocolNotify派上用场// MdeModulePkg/Core/Dxe/Hand/Notify.cEFI_STATUSCoreRegisterProtocolNotify(IN EFI_GUID*Protocol,IN EFI_EVENT Event,OUT VOID**Registration){ProtEntryCoreFindProtocolEntry(Protocol,TRUE);// 分配PROTOCOL_NOTIFY挂在ProtEntry的Notify链表ProtNotifyAllocatePool(sizeof(PROTOCOL_NOTIFY));ProtNotify-EventEvent;// Protocol安装时Signal这个EventInsertTailList(ProtEntry-Notify,ProtNotify-Link);// 防竞态万一本Protocol在Register之前刚好装了if(!IsListEmpty(ProtEntry-Protocols)){CoreSignalEvent(Event);// 已经有了直接通知}returnEFI_SUCCESS;}当任何驱动调用InstallProtocolInterface时CoreNotifyProtocolEntry遍历Notify链表Signal每个Event。被卡住的驱动从WaitForEvent返回用LocateProtocol获取刚装好的Interface。九、实战踩坑Dispatcher死循环某次发布前紧急修了一个PCIe驱动bug重新编译FV。烧进去系统卡在DXE Dispatcher死循环——日志疯狂刷Dispatch 0xXXXX Status SUCCESS但就是不走下一个驱动。根因修复后的PCIe驱动Depex是AND gEfiPciRootBridgeIoProtocolGuid gEfiPciPlatformProtocolGuid END。每次调度执行后它在Entry里调用了InstallProtocolInterface装gEfiPciPlatformProtocolGuid——但这个Protocol之前已经装过了CoreInstallProtocolInterface返回EFI_ACCESS_DENIED不允许在一个Handle上装同名Protocol两次。驱动作者没检查返回值。Dispatcher继续扫描发现下一个驱动的Depex需要这个Protocol的新版本但装不上去。这个驱动被放回等待队列PCIe驱动又被重新调度——形成调度-失败-重调度死循环。修复在InstallProtocolInterface之后加ASSERT_EFI_ERROR(Status)。如果有EFI_ACCESS_DENIED说明设计有问题——一个Protocol不应该被同一个驱动重复安装。教训DXE驱动的Entry Point必须检查InstallProtocolInterface的返回值。PEI阶段也许可以懒一点DXE阶段不行——Dispatcher会把失败吞掉然后重试让你以为一切正常。十、实战踩坑总结坑现象根因经验Dispatcher死循环日志疯狂刷Dispatch SUCCESS重复安装同名Protocol返回ACCESS_DENIED没检查Entry里ASSERT_EFI_ERRORDepex评估误解驱动提前执行导致崩溃以为AND是短路评估实际是全量评估后逻辑与Notify竞态驱动等不到Protocol通知Register前Protocol刚装好RegisterProtocolNotify内部有二次检查Reinstall没通知使用者拿到旧Interface直接改指针没走Reinstall必须三步通知断开→换指针→通知重连优先级设错总线驱动比平台驱动先跑优先级宏填反Platform Processor最早Application最晚源码路径索引内容关键文件DXE Dispatcher主循环MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.cDepex评估MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c驱动注册与FV发现MdeModulePkg/Core/Dxe/Dispatcher/Driver.cProtocol安装/重安装MdeModulePkg/Core/Dxe/Hand/Handle.cProtocol查找MdeModulePkg/Core/Dxe/Hand/Locate.cNotify机制MdeModulePkg/Core/Dxe/Hand/Notify.cDXE服务表MdeModulePkg/Core/Dxe/DxeMain/DxeMain.cPI规范PI Specification Volume 1, Chapter 7-10
RELATED

相关推荐

基于STM32与PID的直流有刷电机闭环速度控制实战指南

基于STM32与PID的直流有刷电机闭环速度控制实战指南

1. 项目概述:从零开始搞定直流有刷电机驱动 最近在做一个需要精确控制电机转速的小项目,核心就是驱动一个24V的直流有刷电机。这听起来像是电子爱好者的入门课,但真要把速度控得稳、响应快,里面门道可不少。我选择了经典的STM32F1…

📅 2026/9/17 17:34:37
算法练习7

算法练习7

1. 字母异位词分组题目要求将互为字母异位词的字符串放入同一组。例如:["eat", "tea", "tan", "ate", "nat", "bat"]可以分为:[["eat", "tea", "ate"], [&q…

📅 2026/9/1 16:00:02
跨境业务踩坑记:那些年被文档翻译耽误的生意

跨境业务踩坑记:那些年被文档翻译耽误的生意

去年初,一个做外贸的朋友接到一笔潜在订单。海外客户发来了一份50页的RFQ询价文件——英文和法语掺杂,涉及产品规格、交付条款、付款条件等等。朋友团队花了两天翻译和理解这份文件。等他们把报价和方案做出来回复的时候,客户说已经签了别家。…

📅 2026/8/31 21:43:20
MORE NEWS

更多资讯

📰

Atlas 300V 24G推理加速卡如何高效部署YOLO模型?

先说个真实的场景。上个月有个做智慧工地项目的朋友来找我,说他们客户提了个新需求:要在每个工地的边缘机房塞一台推理设备,跑实时视频流做安全帽检测,整机功耗不能超过几十瓦,还得能稳定跑YOLOv5。他最开始用的是工控…

📰

火狐和谷歌不支持Cursor:hand的写法?用CSS cursor:pointer兼容配置一次搞定

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

光伏硅片AI分选:多模态AIGC驱动的工业质检革命

1. 项目本质与工业现场的真实痛点中科迪宏这次发布的不是又一个PPT式AI概念,而是把AIGC技术真正焊死在光伏产线上的硬核装备。我去年在江苏一家TOP5硅片厂蹲点三个月,亲眼见过传统分选环节的窘境:产线每小时产出12000片硅片,质检员…

📰

线性调频脉冲压缩雷达仿真:Matlab工程实现与避坑指南

简介:这份PDF面向雷达信号处理初学者与相关专业学生,系统讲解线性调频(LFM)脉冲压缩雷达的仿真原理与实现思路,帮助读者理解如何用宽脉冲发射兼顾作用距离与距离分辨率。内容从雷达基本工作流程切入,推导回…

📰

基于Django的网络音乐推荐系统的设计与实现

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 一、 项目背景与意义 随着数字音乐产业的蓬勃发展,用户面对海量的音乐曲库时,如何高效地发现符合个人喜好的音乐成为了一个关键问题。传统的音乐…

📰

互联网大事记:技术演进与商业变革双线复盘

我无法根据当前输入生成符合要求的博文。原因如下:项目标题“互联网的大事记”是一个高度泛化、缺乏具体技术指向或实操场景的宏观概念性表述;项目正文为空,未提供任何实质性内容、背景、范围界定(如时间跨度:1994–20…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬