UEFI抢占机制
来源:互联网 发布:av淘宝在线获取网址 编辑:程序博客网 时间:2024/06/06 15:31
本文件纯属个人理解,如有错误,欢迎指出
1. Task Priority Level, 任务优先级
任务优先级, 数值越大,优先级越高。优先级高于当前任务优先级的任务可能抢占当前中断当前任务的执行。在UEFI标准中,只有4个优先级
表格 1 任务优先级
Task Priority Level
Value
中断
使用经典场景
TPL_APPLICATION
4
启用
.efi文件运行时的默认优先级;调用WaitForEvent时必须处于TPL_APPLICATION优先级
TPL_CALLBACK
8
启用
中间优先级
TPL_NOTIFY
16
启用
中间优先级
TPL_HIGH_LEVEL
31
禁用
最高优先级,处于此优先级时
可调用BootService的RiseTPL/RestoreTPL提升或降低任务优先级。在RestoreTPL时,会调用处于等调用事件处理函数队列中高于当前任务优先级的事件处理函数。
2. Event, 事件
用于同步事件,如,定时器到达指定点后,定时器中断程序会通过调用事件中指定的回调函数及参数完成指定定时任务。
事件共有如下几种类型
表格 2 Event类型
Type
值
功能
EVT_TIMER
0x80000000
定时器
EVT_RUNTIME
0x40000000
运行时事件
EVT_NOTIFY_WAIT
0x00000100
等待事件,checkEvent时会被移入Notify_Callback待调用队列,在RestoreTPL时调用notify_callback函数
EVT_NOTIFY_SIGNAL
0x00000200
通知事件,创建时增加进signal队列,如果
EVT_SIGNAL_EXITBOOT_SERVICES
0x00000201
退出BOOT_SERVICES时通知事件,只在进OS才发生
EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
0x60000202
UNKOWN
表格 3 有效Event类型组合
Type组合
有效TPL
Notify Function
Notify Context
略注
EVT_TIMER | EVT_NOTIFY_SIGNAL
TPL_CALLBACK
TPL_NOTIFY
必须有
Timer到达后,会将此Event移入signaled事件队列,在RestoreTPL时如果当前TPL为CreateEvent时指定的TPL则调用通知函数
EVT_TIMER
Ignore
Ignore
Ignore
EVT_NOTIFY_WAIT
TPL_CALLBACK
TPL_NOTIFY
必须有
CheckEvent会通过RestoreTPL调用notify_callback
EVT_NOTIFY_SIGNAL
TPL_CALLBACK
TPL_NOTIFY
必须有
当有程序调用SignalEvent时,Event会被移入signaled事件队列, 在RestoreTPL时如果当前TPL为CreateEvent时指定的TPL则调用通知函数
EVT_SIGNAL_EXIT_BOOT_SERVICES
TPL_CALLBACK
TPL_NOTIFY
必须有
退出BOOT_SERVICES时通知事件,只在进OS才发生
EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
TPL_CALLBACK
TPL_NOTIFY
必须有
0x00000000
Ignore
Ignore
Ignore
EVT_TIMER | EVT_NOTIFY_WAIT
TPL_CALLBACK
TPL_NOTIFY
必须有
到时间自动转成Signaled状态,CoreSignalEvent ,但checkevent不会调用通知函数
3. Timer, 定时器
定时器在UEFI中有着关重要的地位:1. 任务时间片切换, 2.定时功能
UEFI通常来讲只会启用BSP一个CPU内核;UEFI不但没有实现多任务机制,中断也除了定时器外全部禁用(SMI在这不涉及,不多提)。当进入时间中断处理函数时,会将TPL提升至TPL_HIGH_LEVEL,此时中断被关闭,然后将定时器事件队列中的已经抵达时间点的事件状态转为signaled。然后调用RestoreTPL函数逐级调用所有已被signaled的事件处理函数;中断在处理TPL_HIGH_LEVEL之下的事件时被打开。如果有低等级事件耗时过长,时间中断有可能再次进入。
4. 情景分析
① DXE驱动程序启动,后台Timer1已超时,事件1,事件2已经转成signaled状态
② 定时器中断触发,驱动程序强行被暂停,中断程序将任务优先级直接提到TPL_HIGH_LEVEL,中断被关闭,然后检查定时器队列中所有Timer Event是否超时,如有超时,移到signaled事件队列,在本情景中,Timer1 Event被移到signaled队列
③ 定时器队列检查程序完成,RestoreTPL到TPL_APPLICATION:降至TPL_NOTIFY,然后开启中断;接着查看此任务优先级signaled队列,发现Timer1需要处理,将Timer1 Event从signaled队列断开,调用Timer1处理程序
④ 继续降至TPL_CALLBACK, 发现事件1需要处理,将事件1 Event从signaled队列断开, 调用其处理程序
⑤ 事件1处理完成后,发现事件2需要处理,将事件2 Event从signaled队列断开, 调用事件2处理程序
⑥ 事件2处理程序还未完成,但时间中断再次降临,事件2处理程序被中断,任务优先级再次被提到TPL_HIGH_LEVEL,中断关闭, 执行定时器队列检查程序,发现Timer2已经超时,将其移到signaled队列
⑦ 定时器队列检查完成,Restore TPL到TPL_CALLBACK(在跳回TPL_NOTIFY时开启中断),TPL_HIGH_LEVEL及TPL_NOTIFY上没有signaled状态的事件。中断返回,继续执行事件2处理程序
⑧ 执行完事件2处理程序后,发现Timer2的Event处于signaled状态,帮执行Timer2的处理程序
事件2处理程序完成。Restore TPL在signaled队列中未找到其它节点,返回,第一次中断返回,继续DXE驱动执行
5.SpinLock机制
SpinLock的数据结构体是EFI_LOCK,内含三个变量
- Tpl 锁的TPL等级;上锁时TPL被提升至此等级,释放时还原TPL等级
- OwnerTpl 记录上锁之前程序的等级
- EFI_LOCK_STATE 锁的状态 共三种状态(uninitialized, Released, Acquired)
SpinLock相关函数有三个:
- EfiAcquireLock 先将当前任务优先级提升到Tpl,然后状态转换成Acquired
- EfiAcquireLockOrFail 先检查锁的状态,如果为Acquired,则返回Fail, 然后执行EfiAcquireLock逻辑
- EfiReleaseLock 先将状态转换成Released,然后将当前任务优先级还原
其实函数EfiAcquireLockOrFail的作用只是防止高优先级的任务异步获取低等级的锁。
SpinLock工作的基础是只有高于当前优先级的任务才能抢占当前的任务。
- UEFI抢占机制
- linux抢占机制
- Linux内核抢占机制(preempt)
- Linux内核抢占机制(preempt)
- Linux内核抢占机制 - 简介
- Linux内核抢占机制 - 实现
- Linux内核抢占实现机制
- Linux内核抢占机制(preempt)
- Linux内核抢占机制(preempt)
- Linux内核抢占实现机制分析
- Linux内核抢占实现机制分析
- Linux内核抢占实现机制分析
- Linux内核抢占实现机制分析
- Linux内核态抢占机制分析
- Linux内核抢占实现机制分析
- Linux内核抢占实现机制分析
- 2.6内核的内核抢占机制
- Linux内核态抢占机制分析
- n的阶乘末尾含0的个数
- JQuery中的基本筛选选择器
- 图片压缩到指定大小范围内KB、MB
- ORM, ormlite和sqlite
- 使用Python写一个小小的项目监控
- UEFI抢占机制
- 一些关于深度学习资料和教程分享
- 09扩展 青蛙跳台阶(高效解法)
- java 内存泄露 内存溢出
- poj3094 Quicksum
- 15 个 Android 通用流行框架大全
- 一定要看
- Swift - 网络请求报App Transport Security has blocked a cleartext错
- 百度坐标(经纬度坐标,米制坐标)与wgs84,火星坐标的互转