Bug#775202: Add support for running a 64-bit Linux kernel on a 32-bit EFI

Steve McIntyre steve at einval.com
Mon Jan 12 16:24:24 UTC 2015


On Mon, Jan 12, 2015 at 03:17:39PM +0000, Colin Watson wrote:
>On Mon, Jan 12, 2015 at 03:03:30PM +0000, Steve McIntyre wrote:
>> I've got a patch accepted for the kernel to expose the size of the
>> underlying UEFI firmware for x86, and Ben's happy to take it for the
>> Debian kernel (#775191). I've written and tested a grub patch to match
>> (see http://blog.einval.com/2015/01/11#Jessie-EFI_5) which adds
>> support for this extra interface. Here it is. I'd appreciate it if we
>> can get this in for Jessie, and and of course it'd be lovely if this
>> went upstream too as it's generic.
>
>It would be helpful if you could send this to grub-devel yourself.
>There'll probably be some minor differences to resolve, but nothing
>serious as far as I can see.

ACK, will do.

>> --- a/grub-core/osdep/linux/platform.c	2015-01-10 00:44:06.905703004 +0000
>> +++ b/grub-core/osdep/linux/platform.c	2015-01-10 01:25:11.742486599 +0000
>> @@ -63,2 +63,2 @@
>>    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;
>> +
>> +  fp = grub_util_fopen ("/sys/firmware/efi/fw_platform_size", "r");
>> +  if (! fp)
>> +    return 0; /* Can't read, fall through to other methods */
>
>This all looks reasonable enough, but why not "return is_64_kernel () ?
>64 : 32;" here?  Then you could simplify
>grub_install_get_default_x86_platform to just conditionalise on "if
>(read_platform_size () == 64)" and avoid duplication.

Could do, yes. I personally tend to shy away from ternary usage like
that, but meh. :-) OK, how about:

--- grub-core/osdep/linux/platform.c.org	2015-01-12 16:03:03.942786770 +0000
+++ grub-core/osdep/linux/platform.c	2015-01-12 16:23:12.367107511 +0000
@@ -63,6 +63,42 @@
   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 @@
       int found;
 
       grub_util_info ("...found");
-      if (is_64_kernel ())
+      if (read_platform_size() == 64)
 	platform = "x86_64-efi";
       else
 	platform = "i386-efi";


-- 
Steve McIntyre, Cambridge, UK.                                steve at einval.com
"I used to be the first kid on the block wanting a cranial implant,
 now I want to be the first with a cranial firewall. " -- Charlie Stross



More information about the Pkg-grub-devel mailing list