]> git.proxmox.com Git - grub2.git/commitdiff
Add support for running a 64-bit Linux kernel on a 32-bit EFI
authorSteve McIntyre <93sam@debian.org>
Tue, 27 Jan 2015 20:08:53 +0000 (20:08 +0000)
committerColin Watson <cjwatson@debian.org>
Thu, 14 May 2015 15:15:24 +0000 (16:15 +0100)
Some platforms might be capable of running a 64-bit Linux kernel but
only use a 32-bit EFI.  To support such systems, it is necessary to work
out the size of the firmware rather than just the size of the kernel.
To enable that, there is now an extra EFI sysfs file to describe the
underlying firmware.  Read that if possible, otherwise fall back to the
kernel type as before.

Signed-off-by: Steve McIntyre <93sam@debian.org>
Bug-Debian: https://bugs.debian.org/775202
Forwarded: Not yet
Last-Update: 2015-01-10

Patch-Name: mixed_size_efi.patch

grub-core/osdep/linux/platform.c

index 033afd8220ab4ec877dac412e38c7aad8dc0e4a4..3675b23628ad1976c7848f9e240d80ff74035edd 100644 (file)
@@ -63,6 +63,42 @@ is_64_kernel (void)
   return strcmp (un.machine, "x86_64") == 0;
 }
 
+static int
+read_platform_size (void)
+{
+  FILE *fp;
+  char *buf = NULL;
+  size_t len = 0;
+  int ret = 0;
+
+  /* Newer kernels can tell us directly about the size of the
+   * underlying firmware - let's see if that interface is there. */
+  fp = grub_util_fopen ("/sys/firmware/efi/fw_platform_size", "r");
+  if (fp != NULL)
+  {
+    if (getline (&buf, &len, fp) > 0)
+      {
+       if (strncmp (buf, "32", 2) == 0)
+         ret = 32;
+       else if (strncmp (buf, "64", 2) == 0)
+         ret = 64;
+      }
+    free (buf);
+    fclose (fp);
+  }
+
+  if (ret == 0)
+    /* Unrecognised - fall back to matching the kernel size instead */
+    {
+      if (is_64_kernel ())
+       ret = 64;
+      else
+       ret = 32;
+    }
+
+  return ret;
+}
+
 const char *
 grub_install_get_default_x86_platform (void)
 { 
@@ -85,7 +121,7 @@ grub_install_get_default_x86_platform (void)
       int found;
 
       grub_util_info ("...found");
-      if (is_64_kernel ())
+      if (read_platform_size() == 64)
        platform = "x86_64-efi";
       else
        platform = "i386-efi";