[elbe-devel] [PATCH 2/3] Add support for UEFI boot with grub

Torben Hohn torben.hohn at linutronix.de
Wed Mar 28 10:52:24 CEST 2018


Comments inline.

On Mon, Mar 26, 2018 at 10:10:57AM +0200, Martin Kaistra wrote:
> If the package grub-efi-amd64 is installed and <grub-install/> is
> used in the xml, try to install grub on the boot partition
> to the default fallback location \EFI\boot\bootx64.efi
> 
> Use grub_fw_type to differentiate between "bios" and "efi", so we can
> call a seperate grub installer function for efi (class grubinstaller202efi)
> which is based on the version for bios (class grubinstaller202)
> 
> This is currently specific to amd64, but it shouldn't be too difficult
> to expand it to other target platforms which support uefi.
> 
> Signed-off-by: Martin Kaistra <martin.kaistra at linutronix.de>
> ---
>  elbepack/efilesystem.py |   5 ++-
>  elbepack/elbeproject.py |   8 +++-
>  elbepack/hdimg.py       | 108 ++++++++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 114 insertions(+), 7 deletions(-)
> 
> diff --git a/elbepack/efilesystem.py b/elbepack/efilesystem.py
> index e1bab181..a2781b5f 100644
> --- a/elbepack/efilesystem.py
> +++ b/elbepack/efilesystem.py
> @@ -309,7 +309,7 @@ class TargetFs(ChRootFilesystem):
>                      f.write(fstab.get_str())
>              f.close()
>  
> -    def part_target(self, targetdir, grub_version):
> +    def part_target(self, targetdir, grub_version, grub_fw_type):
>  
>          # create target images and copy the rfs into them
>          self.images = do_hdimg(
> @@ -317,7 +317,8 @@ class TargetFs(ChRootFilesystem):
>              self.xml,
>              targetdir,
>              self,
> -            grub_version)
> +            grub_version,
> +            grub_fw_type)
>  
>          if self.xml.has("target/package/tar"):
>              targz_name = self.xml.text("target/package/tar/name")
> diff --git a/elbepack/elbeproject.py b/elbepack/elbeproject.py
> index be2b25f5..047020bc 100644
> --- a/elbepack/elbeproject.py
> +++ b/elbepack/elbeproject.py
> @@ -471,15 +471,21 @@ class ElbeProject (object):
>                  grub_version = 199
>              else:
>                  grub_version = 202
> +                grub_fw_type = "bios"
> +        elif self.get_rpcaptcache().is_installed('grub-efi-amd64'):
> +            grub_version = 202
> +            grub_fw_type = "efi"
>          elif 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
> -        self.targetfs.part_target(self.builddir, grub_version)
> +            grub_fw_type = ""
> +        self.targetfs.part_target(self.builddir, grub_version, grub_fw_type)
>  
>          # Build cdrom images
>          self.repo_images = []
> diff --git a/elbepack/hdimg.py b/elbepack/hdimg.py
> index e1dc2aae..ead4c923 100644
> --- a/elbepack/hdimg.py
> +++ b/elbepack/hdimg.py
> @@ -287,6 +287,92 @@ class grubinstaller202(grubinstaller_base):
>              self.outf.do("losetup -d /dev/poop0", allow_fail=True)
>  
>  

grubinstaller202efi is basically identical with grubinstaller202.
Do not duplicate such a big lump of code.

In the next patch you change /boot mountpoint to /boot/efi. This
removes the feature for a separate /boot partition, when efi is used.

please add self.boot_efi to grubinstaller_base and use additional
code to mount that, when it exists. (in grubinstaller202)

then you only need one if statement for the grub commandline.


> +class grubinstaller202efi(grubinstaller_base):
> +
> +    def install(self, target):
> +        if not self.root:
> +            return
> +
> +        imagemnt = os.path.join(target, "imagemnt")
> +        try:
> +            self.outf.do('cp -a /dev/loop0 /dev/poop0')
> +
> +            self.outf.do('losetup /dev/poop0 "%s"' % self.root.filename)
> +            self.outf.do('kpartx -as /dev/poop0')
> +            self.outf.do(
> +                'mount /dev/mapper/poop0p%d %s' %
> +                (self.root.partnum, imagemnt))
> +
> +            if self.boot:
> +                self.outf.do(
> +                    'mount /dev/mapper/poop0p%d %s' %
> +                    (self.boot.partnum, os.path.join(
> +                        imagemnt, "boot")))
> +
> +            self.outf.do(
> +                "mount --bind /dev %s" %
> +                os.path.join(
> +                    imagemnt,
> +                    "dev"))
> +            self.outf.do(
> +                "mount --bind /proc %s" %
> +                os.path.join(
> +                    imagemnt,
> +                    "proc"))
> +            self.outf.do(
> +                "mount --bind /sys %s" %
> +                os.path.join(
> +                    imagemnt,
> +                    "sys"))
> +
> +            self.outf.do('mkdir -p "%s"' % os.path.join(imagemnt, "boot/grub"))
> +
> +            devmap = open(os.path.join(imagemnt, "boot/grub/device.map"), "w")
> +            devmap.write("(hd0) /dev/poop0\n")
> +            devmap.close()
> +
> +            self.outf.do("chroot %s  update-initramfs -u -k all" % imagemnt)
> +            self.outf.do("chroot %s  update-grub2" % imagemnt)
> +
> +            self.outf.do(
> +                "chroot %s grub-install --target=x86_64-efi "
> +                "--efi-directory=/boot --removable --no-floppy /dev/poop0" %
> +                (imagemnt))

this is basically the only place, where efi shall be different.
seems like we only want to specify the --target ? 

what is the --target for bios ?


> +
> +        finally:
> +            os.unlink(os.path.join(imagemnt, "boot/grub/device.map"))
> +            self.outf.do(
> +                "umount %s" %
> +                os.path.join(
> +                    imagemnt,
> +                    "dev"),
> +                allow_fail=True)
> +            self.outf.do(
> +                "umount %s" %
> +                os.path.join(
> +                    imagemnt,
> +                    "proc"),
> +                allow_fail=True)
> +            self.outf.do(
> +                "umount %s" %
> +                os.path.join(
> +                    imagemnt,
> +                    "sys"),
> +                allow_fail=True)
> +
> +            if self.boot:
> +                self.outf.do(
> +                    'umount /dev/mapper/poop0p%d' %
> +                    self.boot.partnum, allow_fail=True)
> +
> +            self.outf.do(
> +                'umount /dev/mapper/poop0p%d' %
> +                self.root.partnum, allow_fail=True)
> +
> +            self.outf.do('kpartx -d /dev/poop0', allow_fail=True)
> +            self.outf.do("losetup -d /dev/poop0", allow_fail=True)
> +
> +
>  class grubinstaller199(grubinstaller_base):
>  
>      def install(self, target):
> @@ -480,7 +566,7 @@ def create_logical_partitions(
>          current_sector += lpart.getLength()
>  
>  
> -def do_image_hd(outf, hd, fslabel, target, grub_version):
> +def do_image_hd(outf, hd, fslabel, target, grub_version, grub_fw_type):
>  
>      sector_size = 512
>      s = size_to_int(hd.text("size"))
> @@ -500,6 +586,8 @@ def do_image_hd(outf, hd, fslabel, target, grub_version):
>  
>      if grub_version == 199:
>          grub = grubinstaller199(outf)
> +    elif grub_version == 202 and grub_fw_type == "efi":
> +        grub = grubinstaller202efi(outf)
>      elif grub_version == 202:
>          grub = grubinstaller202(outf)
>      else:
> @@ -574,7 +662,7 @@ def add_binary_blob(outf, hd, target):
>              bs))
>  
>  
> -def do_hdimg(outf, xml, target, rfs, grub_version):
> +def do_hdimg(outf, xml, target, rfs, grub_version, grub_fw_type):
>      # list of created files
>      img_files = []
>  
> @@ -623,11 +711,23 @@ def do_hdimg(outf, xml, target, rfs, grub_version):
>          # Now iterate over all images and create filesystems and partitions
>          for i in xml.tgt.node("images"):
>              if i.tag == "msdoshd":
> -                img = do_image_hd(outf, i, fslabel, target, grub_version)
> +                img = do_image_hd(
> +                    outf,
> +                    i,
> +                    fslabel,
> +                    target,
> +                    grub_version,
> +                    grub_fw_type)
>                  img_files.append(img)
>  
>              if i.tag == "gpthd":
> -                img = do_image_hd(outf, i, fslabel, target, grub_version)
> +                img = do_image_hd(
> +                    outf,
> +                    i,
> +                    fslabel,
> +                    target,
> +                    grub_version,
> +                    grub_fw_type)
>                  img_files.append(img)
>  
>              if i.tag == "mtd":
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> elbe-devel mailing list
> elbe-devel at linutronix.de
> https://lists.linutronix.de/mailman/listinfo/elbe-devel

-- 
Mit freundlichen Grüßen
Torben Hohn

Linutronix GmbH

Standort: Bremen

Phone: +49 7556 25 999 18; Fax.: +49 7556 25 999 99

Firmensitz / Registered Office: D-88690 Uhldingen, Bahnhofstr. 3
Registergericht / Local District Court: Amtsgericht Freiburg i. Br.; HRB
Nr. / Trade register no.: 700 806

Geschäftsführer / Managing Directors: Heinz Egger, Thomas Gleixner

Eine Bitte von uns: Sollten Sie diese E-Mail irrtümlich erhalten haben,
benachrichtigen Sie uns in diesem Falle bitte sobald wie es Ihnen
möglich ist, durch Antwort-Mail. Vielen Dank!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.linutronix.de/pipermail/elbe-devel/attachments/20180328/ce44e7ca/attachment.sig>


More information about the elbe-devel mailing list