All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] wic/bootimg-efi: Add Unified Kernel Image option
@ 2021-09-09 17:53 Kristian Klausen
  2021-09-10  8:31 ` [OE-core] " Richard Purdie
  0 siblings, 1 reply; 3+ messages in thread
From: Kristian Klausen @ 2021-09-09 17:53 UTC (permalink / raw)
  To: openembedded-core; +Cc: 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>
---

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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [OE-core] [PATCH] wic/bootimg-efi: Add Unified Kernel Image option
  2021-09-09 17:53 [PATCH] wic/bootimg-efi: Add Unified Kernel Image option Kristian Klausen
@ 2021-09-10  8:31 ` Richard Purdie
  2021-09-12 16:09   ` Kristian Klausen
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Purdie @ 2021-09-10  8:31 UTC (permalink / raw)
  To: kristian, openembedded-core

On Thu, 2021-09-09 at 17:53 +0000, Kristian Klausen via lists.openembedded.org
wrote:
> "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>
> ---
> 
> 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(-)

Do we need to add a test for this into meta/lib/oeqa/selftest/cases/wic.py?

Cheers,

Richard


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [OE-core] [PATCH] wic/bootimg-efi: Add Unified Kernel Image option
  2021-09-10  8:31 ` [OE-core] " Richard Purdie
@ 2021-09-12 16:09   ` Kristian Klausen
  0 siblings, 0 replies; 3+ messages in thread
From: Kristian Klausen @ 2021-09-12 16:09 UTC (permalink / raw)
  To: Richard Purdie; +Cc: kristian, openembedded-core

Den Fri, Sep 10, 2021 at 09:31:18 +0100 skrev Richard Purdie:
> On Thu, 2021-09-09 at 17:53 +0000, Kristian Klausen via lists.openembedded.org
> wrote:
> > "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>
> > ---
> > 
> > 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(-)
> 
> Do we need to add a test for this into meta/lib/oeqa/selftest/cases/wic.py?
> 
> Cheers,
> 
> Richard
> 

A simple test wouldn't hurt :)
I will add a simple test checking the EFI binary is created in the 
expected location and a bootloader confing isn't created.

- Kristian

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-09-12 16:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-09 17:53 [PATCH] wic/bootimg-efi: Add Unified Kernel Image option Kristian Klausen
2021-09-10  8:31 ` [OE-core] " Richard Purdie
2021-09-12 16:09   ` Kristian Klausen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.