在drivers/firmware/efi/runtime-wrappers.c 中会建立kernel调用uefi的runtime service
static int __init arm64_enable_runtime_services(void)
{
/* Set up runtime services function pointers */
efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
}
early_initcall(arm64_enable_runtime_services);
可见是通过early_initcall自动调用arm64_enable_runtime_services
void efi_native_runtime_setup(void)
{
efi.get_time = virt_efi_get_time;
efi.set_time = virt_efi_set_time;
efi.get_wakeup_time = virt_efi_get_wakeup_time;
efi.set_wakeup_time = virt_efi_set_wakeup_time;
efi.get_variable = virt_efi_get_variable;
efi.get_next_variable = virt_efi_get_next_variable;
}
我们以virt_efi_get_time为例
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
{
unsigned long flags;
efi_status_t status;
spin_lock_irqsave(&rtc_lock, flags);
spin_lock(&efi_runtime_lock);
status = efi_call_virt(get_time, tm, tc);
spin_unlock(&efi_runtime_lock);
spin_unlock_irqrestore(&rtc_lock, flags);
return status;
}
efi_call_virt 定义如下:
#define efi_call_virt(f, ...) \
({ \
efi_##f##_t *__f; \
efi_status_t __s; \
\
kernel_neon_begin(); \
efi_virtmap_load(); \
__f = efi.systab->runtime->f; \
__s = __f(__VA_ARGS__); \
efi_virtmap_unload(); \
kernel_neon_end(); \
__s; \
})
替换掉宏定义最终还是调用efi.systab->runtime->get_time(tm,tc)
static int __init arm64_enable_runtime_services(void)
{
/* Set up runtime services function pointers */
efi_native_runtime_setup();
set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
}
early_initcall(arm64_enable_runtime_services);
可见是通过early_initcall自动调用arm64_enable_runtime_services
void efi_native_runtime_setup(void)
{
efi.get_time = virt_efi_get_time;
efi.set_time = virt_efi_set_time;
efi.get_wakeup_time = virt_efi_get_wakeup_time;
efi.set_wakeup_time = virt_efi_set_wakeup_time;
efi.get_variable = virt_efi_get_variable;
efi.get_next_variable = virt_efi_get_next_variable;
}
我们以virt_efi_get_time为例
static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
{
unsigned long flags;
efi_status_t status;
spin_lock_irqsave(&rtc_lock, flags);
spin_lock(&efi_runtime_lock);
status = efi_call_virt(get_time, tm, tc);
spin_unlock(&efi_runtime_lock);
spin_unlock_irqrestore(&rtc_lock, flags);
return status;
}
efi_call_virt 定义如下:
#define efi_call_virt(f, ...) \
({ \
efi_##f##_t *__f; \
efi_status_t __s; \
\
kernel_neon_begin(); \
efi_virtmap_load(); \
__f = efi.systab->runtime->f; \
__s = __f(__VA_ARGS__); \
efi_virtmap_unload(); \
kernel_neon_end(); \
__s; \
})
替换掉宏定义最终还是调用efi.systab->runtime->get_time(tm,tc)