From: Kristian Klausen <kristian@klausen.dk>
To: openembedded-core@lists.openembedded.org
Cc: Kristian Klausen <kristian@klausen.dk>,
richard.purdie@linuxfoundation.org
Subject: Re: [PATCH v2] wic/bootimg-efi: Add Unified Kernel Image option
Date: Mon, 27 Sep 2021 13:18:58 +0200 [thread overview]
Message-ID: <YVGooo7LiUG3JQ0h@bob> (raw)
In-Reply-To: <20210913081304.10799-1-kristian@klausen.dk>
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 <kristian@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
>
next prev parent reply other threads:[~2021-09-27 11:19 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-13 8:13 [PATCH v2] wic/bootimg-efi: Add Unified Kernel Image option Kristian Klausen
2021-09-27 11:18 ` Kristian Klausen [this message]
2021-09-30 22:46 ` Richard Purdie
2021-10-01 7:13 ` Kristian Klausen
2021-10-01 8:41 ` Richard Purdie
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YVGooo7LiUG3JQ0h@bob \
--to=kristian@klausen.dk \
--cc=openembedded-core@lists.openembedded.org \
--cc=richard.purdie@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox