Den Mon, Sep 13, 2021 at 10:13:04 +0200 skrev Kristian Klausen:
> "A unified kernel image is a single EFI PE executable combining an EFI
> stub loader, a kernel image, an initramfs image, and the kernel command
> line.
> 
> [...]
> 
> Images of this type have the advantage that all metadata and payload
> that makes up the boot entry is monopolized in a single PE file that can
> be signed cryptographically as one for the purpose of EFI
> SecureBoot."[1]
> 
> This commit adds a create-unified-kernel-image=true option to the
> bootimg-efi plugin for creating a Unified Kernel Image[1] and installing
> it into $BOOT/EFI/Linux/ with a .efi extension per the the Boot Loader
> Specification[1][2]. This is useful for implementing Secure Boot.
> 
> systemd-boot is the only mainstream bootloader implementing the
> specification, but GRUB should be able to boot the EFI binary, this
> commit however doesn't implement the necessary changes to the GRUB
> config generation logic to boot the Unified Kernel Image.
> 
> [1] 
> https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
> [2] https://systemd.io/BOOT_LOADER_SPECIFICATION/
> 
> Signed-off-by: Kristian Klausen <krist...@klausen.dk>

Any update on getting this merged?

Cheers,
Kristian

> ---
> V2:
> Add os-release as dependency
> Pull os-release file from STAGING_DIR_HOST, so it doesn't need to be
> installed into the rootfs
> Add selftest
> 
>  meta-selftest/wic/test_efi_plugin.wks         |  6 ++
>  meta/classes/image_types_wic.bbclass          |  5 +-
>  meta/lib/oeqa/selftest/cases/wic.py           | 29 ++++++++
>  scripts/lib/wic/plugins/source/bootimg-efi.py | 71 ++++++++++++++++---
>  4 files changed, 99 insertions(+), 12 deletions(-)
>  create mode 100644 meta-selftest/wic/test_efi_plugin.wks
> 
> diff --git a/meta-selftest/wic/test_efi_plugin.wks 
> b/meta-selftest/wic/test_efi_plugin.wks
> new file mode 100644
> index 0000000000..1603d6c4bb
> --- /dev/null
> +++ b/meta-selftest/wic/test_efi_plugin.wks
> @@ -0,0 +1,6 @@
> +# short-description: This file is used in oe-selftest wic module to test efi 
> plugin
> +
> +part /boot --source bootimg-efi 
> --sourceparams="loader=systemd-boot,create-unified-kernel-image=true,initrd=${INITRAMFS_IMAGE}-${MACHINE}.${INITRAMFS_FSTYPES}"
>  --active --align 1024 --use-uuid
> +part / --source rootfs --fstype=ext4 --align 1024 --use-uuid
> +
> +bootloader  --timeout=0 --append="console=ttyS0,115200n8"
> diff --git a/meta/classes/image_types_wic.bbclass 
> b/meta/classes/image_types_wic.bbclass
> index d561fb2636..e3863c88a9 100644
> --- a/meta/classes/image_types_wic.bbclass
> +++ b/meta/classes/image_types_wic.bbclass
> @@ -27,6 +27,7 @@ WICVARS ?= "\
>       ROOTFS_SIZE \
>       STAGING_DATADIR \
>       STAGING_DIR \
> +     STAGING_DIR_HOST \
>       STAGING_LIBDIR \
>       TARGET_SYS \
>  "
> @@ -84,8 +85,8 @@ do_image_wic[deptask] += "do_image_complete"
>  WKS_FILE_DEPENDS_DEFAULT = '${@bb.utils.contains_any("BUILD_ARCH", [ 
> 'x86_64', 'i686' ], "syslinux-native", "",d)}'
>  WKS_FILE_DEPENDS_DEFAULT += "bmap-tools-native cdrtools-native 
> btrfs-tools-native squashfs-tools-native e2fsprogs-native"
>  WKS_FILE_DEPENDS_BOOTLOADERS = ""
> -WKS_FILE_DEPENDS_BOOTLOADERS:x86 = "syslinux grub-efi systemd-boot"
> -WKS_FILE_DEPENDS_BOOTLOADERS:x86-64 = "syslinux grub-efi systemd-boot"
> +WKS_FILE_DEPENDS_BOOTLOADERS:x86 = "syslinux grub-efi systemd-boot 
> os-release"
> +WKS_FILE_DEPENDS_BOOTLOADERS:x86-64 = "syslinux grub-efi systemd-boot 
> os-release"
>  WKS_FILE_DEPENDS_BOOTLOADERS:x86-x32 = "syslinux grub-efi"
>  
>  WKS_FILE_DEPENDS ??= "${WKS_FILE_DEPENDS_DEFAULT} 
> ${WKS_FILE_DEPENDS_BOOTLOADERS}"
> diff --git a/meta/lib/oeqa/selftest/cases/wic.py 
> b/meta/lib/oeqa/selftest/cases/wic.py
> index dc7b9e637e..5fc8e65142 100644
> --- a/meta/lib/oeqa/selftest/cases/wic.py
> +++ b/meta/lib/oeqa/selftest/cases/wic.py
> @@ -1158,6 +1158,35 @@ class Wic2(WicTestCase):
>              out = glob(self.resultdir + "%s-*.direct" % wksname)
>              self.assertEqual(1, len(out))
>  
> +    @only_for_arch(['i586', 'i686', 'x86_64'])
> +    def test_efi_plugin_unified_kernel_image_qemu(self):
> +        """Test efi plugin's Unified Kernel Image feature in qemu"""
> +        config = 'IMAGE_FSTYPES = "wic"\n'\
> +                 'INITRAMFS_IMAGE = "core-image-minimal-initramfs"\n'\
> +                 'WKS_FILE = "test_efi_plugin.wks"\n'\
> +                 'MACHINE_FEATURES:append = " efi"\n'
> +        self.append_config(config)
> +        self.assertEqual(0, bitbake('core-image-minimal 
> core-image-minimal-initramfs ovmf').status)
> +        self.remove_config(config)
> +
> +        with runqemu('core-image-minimal', ssh=False,
> +                     runqemuparams='ovmf', image_fstype='wic') as qemu:
> +            # Check that /boot has EFI bootx64.efi (required for EFI)
> +            cmd = "ls /boot/EFI/BOOT/bootx64.efi | wc -l"
> +            status, output = qemu.run_serial(cmd)
> +            self.assertEqual(1, status, 'Failed to run command "%s": %s' % 
> (cmd, output))
> +            self.assertEqual(output, '1')
> +            # Check that /boot has EFI/Linux/linux.efi (required for Unified 
> Kernel Images auto detection)
> +            cmd = "ls /boot/EFI/Linux/linux.efi | wc -l"
> +            status, output = qemu.run_serial(cmd)
> +            self.assertEqual(1, status, 'Failed to run command "%s": %s' % 
> (cmd, output))
> +            self.assertEqual(output, '1')
> +            # Check that /boot doesn't have loader/entries/boot.conf 
> (Unified Kernel Images are auto detected by the bootloader)
> +            cmd = "ls /boot/loader/entries/boot.conf 2&>/dev/null | wc -l"
> +            status, output = qemu.run_serial(cmd)
> +            self.assertEqual(1, status, 'Failed to run command "%s": %s' % 
> (cmd, output))
> +            self.assertEqual(output, '0')
> +
>      def test_fs_types(self):
>          """Test filesystem types for empty and not empty partitions"""
>          img = 'core-image-minimal'
> diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py 
> b/scripts/lib/wic/plugins/source/bootimg-efi.py
> index cdc72543c2..cc6f5cf063 100644
> --- a/scripts/lib/wic/plugins/source/bootimg-efi.py
> +++ b/scripts/lib/wic/plugins/source/bootimg-efi.py
> @@ -12,6 +12,7 @@
>  
>  import logging
>  import os
> +import tempfile
>  import shutil
>  import re
>  
> @@ -119,12 +120,13 @@ class BootimgEFIPlugin(SourcePlugin):
>          bootloader = creator.ks.bootloader
>  
>          loader_conf = ""
> -        loader_conf += "default boot\n"
> +        if source_params.get('create-unified-kernel-image') != "true":
> +            loader_conf += "default boot\n"
>          loader_conf += "timeout %d\n" % bootloader.timeout
>  
>          initrd = source_params.get('initrd')
>  
> -        if initrd:
> +        if initrd and source_params.get('create-unified-kernel-image') != 
> "true":
>              # obviously we need to have a common common deploy var
>              bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
>              if not bootimg_dir:
> @@ -183,11 +185,12 @@ class BootimgEFIPlugin(SourcePlugin):
>                  for rd in initrds:
>                      boot_conf += "initrd /%s\n" % rd
>  
> -        logger.debug("Writing systemd-boot config "
> -                     "%s/hdd/boot/loader/entries/boot.conf", cr_workdir)
> -        cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w")
> -        cfg.write(boot_conf)
> -        cfg.close()
> +        if source_params.get('create-unified-kernel-image') != "true":
> +            logger.debug("Writing systemd-boot config "
> +                         "%s/hdd/boot/loader/entries/boot.conf", cr_workdir)
> +            cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, 
> "w")
> +            cfg.write(boot_conf)
> +            cfg.close()
>  
>  
>      @classmethod
> @@ -288,9 +291,57 @@ class BootimgEFIPlugin(SourcePlugin):
>                  kernel = "%s-%s.bin" % \
>                      (get_bitbake_var("KERNEL_IMAGETYPE"), 
> get_bitbake_var("INITRAMFS_LINK_NAME"))
>  
> -        install_cmd = "install -m 0644 %s/%s %s/%s" % \
> -            (staging_kernel_dir, kernel, hdddir, kernel)
> -        exec_cmd(install_cmd)
> +        if source_params.get('create-unified-kernel-image') == "true":
> +            initrd = source_params.get('initrd')
> +            if initrd:
> +                initrds = initrd.split(';')
> +                if len(initrds) != 1:
> +                    raise WicError("initrd= must only referer a single 
> initrd, exiting")
> +                initrd = initrds[0]
> +            else:
> +                raise WicError("initrd= must be specified when 
> create-unified-kernel-image=true, exiting")
> +
> +            deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
> +            efi_stub = glob("%s/%s" % (deploy_dir, "linux*.efi.stub"))
> +            if len(efi_stub) == 0:
> +                raise WicError("Unified Kernel Image EFI stub not found, 
> exiting")
> +            efi_stub = efi_stub[0]
> +
> +            with tempfile.NamedTemporaryFile(mode="w+") as cmdline:
> +                label = source_params.get('label')
> +                label_conf = "root=%s" % creator.rootdev
> +                if label:
> +                    label_conf = "LABEL=%s" % label
> +
> +                bootloader = creator.ks.bootloader
> +                cmdline.write("%s %s" % (label_conf, bootloader.append))
> +                cmdline.flush()
> +
> +                # Searched by systemd-boot:
> +                # 
> https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
> +                install_cmd = "install -d %s/EFI/Linux" % hdddir
> +                exec_cmd(install_cmd)
> +
> +                staging_dir_host = get_bitbake_var("STAGING_DIR_HOST")
> +
> +                # 
> https://github.com/systemd/systemd/blob/7728f6aa812f1af563821505d9f377a7f4f727d9/test/test-efi-create-disk.sh#L32-L38
> +                objcopy_cmd = "objcopy \
> +                    --add-section .osrel=%s --change-section-vma 
> .osrel=0x20000 \
> +                    --add-section .cmdline=%s --change-section-vma 
> .cmdline=0x30000 \
> +                    --add-section .linux=%s --change-section-vma 
> .linux=0x2000000 \
> +                    --add-section .initrd=%s --change-section-vma 
> .initrd=0x3000000 \
> +                    %s %s" % \
> +                    ("%s/usr/lib/os-release" % staging_dir_host,
> +                    cmdline.name,
> +                    "%s/%s" % (staging_kernel_dir, kernel),
> +                    "%s/%s" % (deploy_dir, initrd),
> +                    efi_stub,
> +                    "%s/EFI/Linux/linux.efi" % hdddir)
> +                exec_cmd(objcopy_cmd)
> +        else:
> +            install_cmd = "install -m 0644 %s/%s %s/%s" % \
> +                (staging_kernel_dir, kernel, hdddir, kernel)
> +            exec_cmd(install_cmd)
>  
>          if get_bitbake_var("IMAGE_EFI_BOOT_FILES"):
>              for src_path, dst_path in cls.install_task:
> -- 
> 2.25.1
> 
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#156384): 
https://lists.openembedded.org/g/openembedded-core/message/156384
Mute This Topic: https://lists.openembedded.org/mt/85570082/21656
Group Owner: openembedded-core+ow...@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to