UEFI.源码分析.DXE的异步事件服务.第一部分.事件驱动

  • 源代码:EDK2
  • 版本:UDK2017
  • UEFI源码分析第二篇,异步事件服务
  • 第一部分,事件驱动
  • 优先级的讨论将在另一篇,即第二部分。
  • 定时器类型EVT_TIMER将在第三部分

事件

每一个事件都是一个IEvent类型

/** /Dxe/Event/Event.h **/
 45 #define EVENT_SIGNATURE         SIGNATURE_32('e','v','n','t')
 46 typedef struct {                                             
 47   UINTN                   Signature;                         
 48   UINT32                  Type;                              
 49   UINT32                  SignalCount;                       
 53   LIST_ENTRY              SignalLink;                       
 57   EFI_TPL                 NotifyTpl;                         
 58   EFI_EVENT_NOTIFY        NotifyFunction;                    
 59   VOID                    *NotifyContext;                    
 60   EFI_GUID                EventGroup;                        
 61   LIST_ENTRY              NotifyLink;                        
 62   UINT8                   ExFlag;                             
 66   EFI_RUNTIME_EVENT_ENTRY RuntimeData;                       
 67   TIMER_EVENT_INFO        Timer;                             
 68 } IEVENT;                                                    

可以看到有多个链表

  • SignalLink
  • NotifyLink

这是提供给不同事件类型所使用。事件有以下几种类型。

/** MdePkg/Include/Uefi/UefiSpec.h **/
 384 //                                                          
 385 // These types can be ORed together as needed - for example,
 386 // EVT_TIMER might be Ored with EVT_NOTIFY_WAIT or          
 387 // EVT_NOTIFY_SIGNAL.                                       
 388 //                                                          
 389 #define EVT_TIMER                         0x80000000        
 390 #define EVT_RUNTIME                       0x40000000        
 391 #define EVT_NOTIFY_WAIT                   0x00000100        
 392 #define EVT_NOTIFY_SIGNAL                 0x00000200        
 393                                                             
 394 #define EVT_SIGNAL_EXIT_BOOT_SERVICES     0x00000201        
 395 #define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202        

大致有如下特性
- Notify意味着有NotifyFunction在事件发生的时候被调用,也就是回调函数
- Wait意味着可以使用WaitForEvent来等待事件的发生,其阻塞直到事件被Signal
- Signal意味着事件可以被唤醒
- Timer意味着该事件是一个定时器,IEventTimer域会被填充,其中包含一个Link来链接所有的定时器
- 这些特性是可以被OR来组合到一起的,即运算符|

两个类型只在此提一下,不详述
- EVT_SIGNAL_EXIT_BOOT_SERVICES是在UEFI系统退出(ExitBootServices())的时候调用,通常用来回收资源
- EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE在操作系统加载器调用运行时服务RuntimeServices的虚拟地址服务来进行虚拟地址转换的时候调用。

主要关注两个类型
- EVT_NOTIFY_WAIT可等待事件
- EVT_NOTIFY_SIGNAL可唤醒事件


重要的全局变量

  • gEventSignalQueue保存所有未被唤醒、类型为EVT_NOTIFY_SIGNAL的事件
  • gEventQueue保存已经被唤醒、需要执行回调函数的事件,根据优先级分为多个链表
  • gEventPending使用位图来保存gEventQueue是否含有某个优先级的链表
  • mEventTable包含了所有合法的事件类型

相关接口

创建事件CreateEvent
/** /Dxe/Event/Event.c **/
 378 EFI_STATUS                                              
 379 EFIAPI                                                  
 380 CoreCreateEventInternal (                               
 381   IN UINT32                   Type,                     
 382   IN EFI_TPL                  NotifyTpl,                
 383   IN EFI_EVENT_NOTIFY         NotifyFunction, OPTIONAL  
 384   IN CONST VOID               *NotifyContext, OPTIONAL  
 385   IN CONST EFI_GUID           *EventGroup,    OPTIONAL  
 386   OUT EFI_EVENT               *Event                    
 387   )                                                     
 388 {                                                       

Type域即事件的类型

NotifyTpl是回调函数的优先级,在本系列的第二部分会介绍,NorifyFunction即回调函数本身,NofityContext即传递给回调函数的参数。

EventGroup是事件组特性,其使用一个GUID来标识该事件属于一个事件组,同组内的事件均含有相同的GUID,不同事件组的GUID必然不同。

Event是返回的、创建完成的事件,EFI_EVENT类型本质上是IEvent*类型。


1、检查事件的类型

 401   Status = EFI_INVALID_PARAMETER;                                              
 402   for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) { 
 403      if (Type == mEventTable[Index]) {                                         
 404        Status = EFI_SUCCESS;                                                   
 405        break;                                                                  
 406      }                                                                         
 407   }                                                                            
 408   if(EFI_ERROR (Status)) {                                                     
 409     return EFI_INVALID_PARAMETER;                                        
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值