[elbe-devel] [PATCH v2 2/4] grubinstaller: enable UEFI (secure) boot with shim

bage at linutronix.de bage at linutronix.de
Fri Aug 23 11:03:30 CEST 2019


From: Bastian Germann <bage at linutronix.de>

This is a workaround for grub-installer being dependent on the system
where it is executed. When shim and the signed grub-efi variants are
installed, it fails to create a usable installation on the loop device.

Fix the installation by creating a debian boot environment (the name
does not matter but has to be different from BOOT) and copying the
signed shim to it.

The signed grub-efi is also available for other systems than amd64.
Enable installing them as well.

Signed-off-by: Bastian Germann <bage at linutronix.de>
---
 elbepack/efilesystem.py |  2 +-
 elbepack/elbeproject.py | 33 ++++++++++++++++++---------------
 elbepack/hdimg.py       | 33 +++++++++++++++++++--------------
 3 files changed, 38 insertions(+), 30 deletions(-)

diff --git a/elbepack/efilesystem.py b/elbepack/efilesystem.py
index faa2a183..29ef4526 100644
--- a/elbepack/efilesystem.py
+++ b/elbepack/efilesystem.py
@@ -352,7 +352,7 @@ class TargetFs(ChRootFilesystem):
                     f.write(fstab.get_str())
             f.close()
 
-    def part_target(self, targetdir, grub_version, grub_fw_type=None):
+    def part_target(self, targetdir, grub_version, grub_fw_type=[]):
 
         # create target images and copy the rfs into them
         self.images = do_hdimg(
diff --git a/elbepack/elbeproject.py b/elbepack/elbeproject.py
index df8a7981..d9690321 100644
--- a/elbepack/elbeproject.py
+++ b/elbepack/elbeproject.py
@@ -615,26 +615,29 @@ class ElbeProject (object):
         # Use some handwaving to determine grub version
         #
         # We might also want support for legacy grub
-        if (self.get_rpcaptcache().is_installed('grub-pc') and
-                self.get_rpcaptcache().is_installed('grub-efi-amd64-bin')):
+        grub_arch = "ia32" if self.arch == "i386" else self.arch
+        grub_fw_type = []
+        grub_version = 0
+        if self.get_rpcaptcache().is_installed('grub-pc'):
             grub_version = 202
-            grub_fw_type = "hybrid"
-        elif self.get_rpcaptcache().is_installed('grub-pc'):
+            grub_fw_type.append("bios")
+        if self.get_rpcaptcache().is_installed('grub-efi-%s-bin' % grub_arch):
             grub_version = 202
-            grub_fw_type = "bios"
-        elif self.get_rpcaptcache().is_installed('grub-efi-amd64'):
+            grub_tgt = "x86_64" if self.arch == "amd64" else self.arch
+            grub_fw_type.extend(["efi", grub_tgt + "-efi"])
+        if (self.get_rpcaptcache().is_installed('shim-signed') and
+                self.get_rpcaptcache().is_installed(
+                    'grub-efi-%s-signed' % grub_arch)):
             grub_version = 202
-            grub_fw_type = "efi"
-        elif self.get_rpcaptcache().is_installed('grub-legacy'):
+            grub_fw_type.append("shimfix")
+        if self.get_rpcaptcache().is_installed('grub-legacy'):
             self.log.printo("package grub-legacy is installed, "
                             "this is obsolete, skipping grub")
-            grub_version = 0
-            grub_fw_type = ""
-        else:
-            self.log.printo("package grub-pc is not installed, skipping grub")
-            # version 0 == skip_grub
-            grub_version = 0
-            grub_fw_type = ""
+            grub_fw_type = []
+        elif not grub_fw_type:
+            self.log.printo("neither package grub-pc nor grub-efi-%s-bin "
+                            "are installed, skipping grub" % grub_arch)
+
         self.targetfs.part_target(self.builddir, grub_version, grub_fw_type)
 
         self.build_cdroms(build_bin, build_sources, cdrom_size)
diff --git a/elbepack/hdimg.py b/elbepack/hdimg.py
index 98ae5f2b..29dd132e 100644
--- a/elbepack/hdimg.py
+++ b/elbepack/hdimg.py
@@ -144,7 +144,7 @@ def build_image_mtd(outf, mtd, target):
 
 
 class grubinstaller_base(object):
-    def __init__(self, outf, fw_type=None):
+    def __init__(self, outf, fw_type=[]):
         self.outf = outf
         self.root = None
         self.boot = None
@@ -218,13 +218,22 @@ class grubinstaller202(grubinstaller_base):
             self.outf.do("chroot %s  update-initramfs -u -k all" % imagemnt)
             self.outf.do("chroot %s  update-grub2" % imagemnt)
 
-            if self.fw_type == "efi" or self.fw_type == "hybrid":
+            if "efi" in self.fw_type:
+                grub_tgt = next(t for t in self.fw_type if t.endswith("-efi"))
                 self.outf.do(
-                    "chroot %s grub-install --target=x86_64-efi --removable "
+                    "chroot %s grub-install --target=%s --removable "
                     "--no-floppy /dev/poop0" %
-                    (imagemnt))
-            if self.fw_type == "hybrid" or self.fw_type is None:
-                # when we are in hybrid mode, install grub also into MBR
+                    (imagemnt, grub_tgt))
+            if "shimfix" in self.fw_type:
+                # grub-install is heavily dependent on the running system having
+                # a BIOS or EFI.  The initvm is BIOS-based, so fix the resulting
+                # shim installation.
+                self.outf.do("chroot %s  /bin/bash -c '"
+                             "cp -r /boot/efi/EFI/BOOT /boot/efi/EFI/debian && "
+                             "cd /usr/lib/shim && f=( shim*.efi.signed ) && cp "
+                             "${f[0]} /boot/efi/EFI/debian/${f[0]%%.signed}'"  %
+                             imagemnt)
+            if not self.fw_type or "bios" in self.fw_type:
                 self.outf.do(
                     "chroot %s grub-install --no-floppy /dev/poop0" %
                     (imagemnt))
@@ -381,7 +390,7 @@ def create_logical_partitions(
         current_sector += lpart.getLength()
 
 
-def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type=None):
+def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type=[]):
 
     # pylint: disable=too-many-arguments
     # pylint: disable=too-many-locals
@@ -403,12 +412,8 @@ def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type=None):
     else:
         disk = parted.freshDisk(imag, "msdos")
 
-    if grub_version == 202 and grub_fw_type == "efi":
-        grub = grubinstaller202(outf, "efi")
-    elif grub_version == 202 and grub_fw_type == "hybrid":
-        grub = grubinstaller202(outf, "hybrid")
-    elif grub_version == 202:
-        grub = grubinstaller202(outf)
+    if grub_version == 202:
+        grub = grubinstaller202(outf, grub_fw_type)
     else:
         grub = grubinstaller_base(outf)
 
@@ -481,7 +486,7 @@ def add_binary_blob(outf, hd, target):
             bs))
 
 
-def do_hdimg(outf, xml, target, rfs, grub_version, grub_fw_type=None):
+def do_hdimg(outf, xml, target, rfs, grub_version, grub_fw_type=[]):
 
     # pylint: disable=too-many-arguments
     # pylint: disable=too-many-locals
-- 
2.20.1




More information about the elbe-devel mailing list