Search code examples
linux-kerneluefi

How could 32bit kernel read efivars from 64bit UEFI?


I'm booting a GRUB EFI application compiled to x86_64-efi, on a x86_64 firwmare in UEFI only mode.

This GRUB app launches a 32bit Linux v3.18.48, with CONFIG_EFIVAR_FS=y and CONFIG_EFI_VARS=y.

Now I want to read some efivars, but I cannot even mount the efivarfs:

mount -t efivarfs efivarfs /sys/firmware/efi/efivars

which returns "No such device" (ENODEV).

It was expected since dmesg says:

No EFI runtime due to 32/64-bit mismatch with kernel

Looking at the Linux source:

     if (!efi_runtime_supported())
         pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
     else {
         if (efi_runtime_disabled() || efi_runtime_init())
             return;
     }

and

static inline bool efi_is_native(void)
{
    return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT);
}

static inline bool efi_runtime_supported(void)
{
    if (efi_is_native())
        return true;

    if (IS_ENABLED(CONFIG_EFI_MIXED) && !efi_enabled(EFI_OLD_MEMMAP))
        return true;

    return false;
}

seems that efi_runtime_supported() will always return false to me, since CONFIG_X86_64=n and CONFIG_EFI_MIXED depends on CONFIG_X86_64=y.

Is there any workaround that could allow me to read the efivars, under these conditions?

Constraints:

  • x86_64 firmware with UEFI only mode;
  • GRUB x86_64-efi will launch Linux;
  • Linux kernel v3.18.48 (may be patched), 32bits.

Solution

  • No, the 32-bit OS can't make 64-bit UEFI calls.

    I hesitate to say anything can't be done in software, but this is about as close to impossible as you can get. You can't make 64-bit UEFI calls without switching to 64-bit mode, which would be extremely difficult to do the after the 32-bit OS boots.

    One possible approach would be to change GRUB to read the variables and save them and provide a 32-bit interface for the OS to retrieve them. Since GRUB doesn't generally persist after the OS boots, this would be a significant change.