把UEFI当作一个类操作系统,则一定不会把该系统划分到实时操作系统范围中去。因为在UEFI的世界里,准确的讲,只有timer interrupt handler,而没有其他的中断服务程序。
那么,UEFI是如何处理多任务的呢?
我们从UEFI kernel的DXEMain和TimerDriverInitialize看起。
DXEMain服务初始化和回调函数的绑定
DXEMain中有两个关于定时器的重要函数:CoreInitializeEventServices和CoreNotifyOnProtocolInstallation。CoreInitializeEventServices做了如下3件事:
初始化每一个Event Queue的头节点,虽然UEFI SPEC中只规定了4种优先级的事件,但这里对0到31这32种优先级的Event Queue都做了初始化;
对有关timer的服务进行初始化;
创建了一个回调函数是空函数的gIdleLoopEvent。
在初始化有关timer的服务中,便建立了mEfiCheckTimerEvent和CoreCheckTimers函数的联系:
Status = CoreCreateEventInternal (
EVT_NOTIFY_SIGNAL,
TPL_HIGH_LEVEL - 1,
CoreCheckTimers,
NULL,
NULL,
&mEfiCheckTimerEvent
);
那么一旦有某个module去signal mEfiCheckTimerEvent,那么CoreCheckTimers函数就会被回调。而CoreCheckTimers主要做了:
这一部分用来处理定时器事件,这些事件都会放在mEfiTimerList中。首先获取当前系统时间,如果trigger timer小于或等于当前系统时间,那么触发该定时器事件,并且从timer Queue中删去。如果该事件是一个周期性的定时器事件,还需要再次更新下trigger time,并将该事件增加到mEfiTimerList中。
再看看CoreNotifyOnProtocolInstallation铺垫了哪些:
在CoreNotifyOnProtocolInstallation函数中只是为mArchProtocols和mOptionalProtocols创建了以下每个protocol所独有的event:
EFI_CORE_PROTOCOL_NOTIFY_ENTRY mArchProtocols[] = {
{
&gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE },
{
&gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE },
{
&gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE