summaryrefslogtreecommitdiffstats
path: root/scripts/lib/wic/plugins/source/bootimg-efi.py
diff options
context:
space:
mode:
authorKristian Klausen <kristian@klausen.dk>2021-09-28 14:44:16 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2021-10-04 15:03:53 +0100
commitb8c0f073f6a282f89fba7711ec168d0638749300 (patch)
treee5ab029e59753092968248f5d339d3b0dda83f1f /scripts/lib/wic/plugins/source/bootimg-efi.py
parent75b79d5c056b5abb44c546af773e3431d4c09476 (diff)
downloadpoky-b8c0f073f6a282f89fba7711ec168d0638749300.tar.gz
wic/bootimg-efi: Add Unified Kernel Image option
"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/ (From OE-Core rev: b0573f240525df561ddef6e47cb285b217d38487) Signed-off-by: Kristian Klausen <kristian@klausen.dk> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/wic/plugins/source/bootimg-efi.py')
-rw-r--r--scripts/lib/wic/plugins/source/bootimg-efi.py74
1 files changed, 64 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..0391aebdc8 100644
--- a/scripts/lib/wic/plugins/source/bootimg-efi.py
+++ b/scripts/lib/wic/plugins/source/bootimg-efi.py
@@ -12,6 +12,7 @@
12 12
13import logging 13import logging
14import os 14import os
15import tempfile
15import shutil 16import shutil
16import re 17import re
17 18
@@ -119,12 +120,13 @@ class BootimgEFIPlugin(SourcePlugin):
119 bootloader = creator.ks.bootloader 120 bootloader = creator.ks.bootloader
120 121
121 loader_conf = "" 122 loader_conf = ""
122 loader_conf += "default boot\n" 123 if source_params.get('create-unified-kernel-image') != "true":
124 loader_conf += "default boot\n"
123 loader_conf += "timeout %d\n" % bootloader.timeout 125 loader_conf += "timeout %d\n" % bootloader.timeout
124 126
125 initrd = source_params.get('initrd') 127 initrd = source_params.get('initrd')
126 128
127 if initrd: 129 if initrd and source_params.get('create-unified-kernel-image') != "true":
128 # obviously we need to have a common common deploy var 130 # obviously we need to have a common common deploy var
129 bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 131 bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
130 if not bootimg_dir: 132 if not bootimg_dir:
@@ -183,11 +185,12 @@ class BootimgEFIPlugin(SourcePlugin):
183 for rd in initrds: 185 for rd in initrds:
184 boot_conf += "initrd /%s\n" % rd 186 boot_conf += "initrd /%s\n" % rd
185 187
186 logger.debug("Writing systemd-boot config " 188 if source_params.get('create-unified-kernel-image') != "true":
187 "%s/hdd/boot/loader/entries/boot.conf", cr_workdir) 189 logger.debug("Writing systemd-boot config "
188 cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w") 190 "%s/hdd/boot/loader/entries/boot.conf", cr_workdir)
189 cfg.write(boot_conf) 191 cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w")
190 cfg.close() 192 cfg.write(boot_conf)
193 cfg.close()
191 194
192 195
193 @classmethod 196 @classmethod
@@ -288,9 +291,60 @@ class BootimgEFIPlugin(SourcePlugin):
288 kernel = "%s-%s.bin" % \ 291 kernel = "%s-%s.bin" % \
289 (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 292 (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
290 293
291 install_cmd = "install -m 0644 %s/%s %s/%s" % \ 294 if source_params.get('create-unified-kernel-image') == "true":
292 (staging_kernel_dir, kernel, hdddir, kernel) 295 initrd = source_params.get('initrd')
293 exec_cmd(install_cmd) 296 if not initrd:
297 raise WicError("initrd= must be specified when create-unified-kernel-image=true, exiting")
298
299 deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
300 efi_stub = glob("%s/%s" % (deploy_dir, "linux*.efi.stub"))
301 if len(efi_stub) == 0:
302 raise WicError("Unified Kernel Image EFI stub not found, exiting")
303 efi_stub = efi_stub[0]
304
305 with tempfile.TemporaryDirectory() as tmp_dir:
306 label = source_params.get('label')
307 label_conf = "root=%s" % creator.rootdev
308 if label:
309 label_conf = "LABEL=%s" % label
310
311 bootloader = creator.ks.bootloader
312 cmdline = open("%s/cmdline" % tmp_dir, "w")
313 cmdline.write("%s %s" % (label_conf, bootloader.append))
314 cmdline.close()
315
316 initrds = initrd.split(';')
317 initrd = open("%s/initrd" % tmp_dir, "wb")
318 for f in initrds:
319 with open("%s/%s" % (deploy_dir, f), 'rb') as in_file:
320 shutil.copyfileobj(in_file, initrd)
321 initrd.close()
322
323 # Searched by systemd-boot:
324 # https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images
325 install_cmd = "install -d %s/EFI/Linux" % hdddir
326 exec_cmd(install_cmd)
327
328 staging_dir_host = get_bitbake_var("STAGING_DIR_HOST")
329
330 # https://www.freedesktop.org/software/systemd/man/systemd-stub.html
331 objcopy_cmd = "objcopy \
332 --add-section .osrel=%s --change-section-vma .osrel=0x20000 \
333 --add-section .cmdline=%s --change-section-vma .cmdline=0x30000 \
334 --add-section .linux=%s --change-section-vma .linux=0x2000000 \
335 --add-section .initrd=%s --change-section-vma .initrd=0x3000000 \
336 %s %s" % \
337 ("%s/usr/lib/os-release" % staging_dir_host,
338 cmdline.name,
339 "%s/%s" % (staging_kernel_dir, kernel),
340 initrd.name,
341 efi_stub,
342 "%s/EFI/Linux/linux.efi" % hdddir)
343 exec_cmd(objcopy_cmd)
344 else:
345 install_cmd = "install -m 0644 %s/%s %s/%s" % \
346 (staging_kernel_dir, kernel, hdddir, kernel)
347 exec_cmd(install_cmd)
294 348
295 if get_bitbake_var("IMAGE_EFI_BOOT_FILES"): 349 if get_bitbake_var("IMAGE_EFI_BOOT_FILES"):
296 for src_path, dst_path in cls.install_task: 350 for src_path, dst_path in cls.install_task: