"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> --- This patch supersedes: "[RFC][PATCH] kernel: Add Unified Kernel Image image type"[1] and: "[PATCH] wic/bootimg-efi: Add option for only installing the bootloader"[2] The latter is perhaps still useful, but with this patch it is no longer needed for using a Unified Kernel Image with systemd-boot. [1] https://lists.openembedded.org/g/openembedded-core/message/155801 [2] https://lists.openembedded.org/g/openembedded-core/message/155789 scripts/lib/wic/plugins/source/bootimg-efi.py | 69 ++++++++++++++++--- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py b/scripts/lib/wic/plugins/source/bootimg-efi.py index cdc72543c2..e3dc0604f5 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,55 @@ 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) + + # 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" % rootfs_dir.get("ROOTFS_DIR"), + 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 (#155866): https://lists.openembedded.org/g/openembedded-core/message/155866 Mute This Topic: https://lists.openembedded.org/mt/85490739/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-