diff options
author | Kristian Klausen <kristian@klausen.dk> | 2021-09-28 14:44:16 +0200 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2021-10-04 15:03:53 +0100 |
commit | b8c0f073f6a282f89fba7711ec168d0638749300 (patch) | |
tree | e5ab029e59753092968248f5d339d3b0dda83f1f /scripts | |
parent | 75b79d5c056b5abb44c546af773e3431d4c09476 (diff) | |
download | poky-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')
-rw-r--r-- | scripts/lib/wic/plugins/source/bootimg-efi.py | 74 |
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 | ||
13 | import logging | 13 | import logging |
14 | import os | 14 | import os |
15 | import tempfile | ||
15 | import shutil | 16 | import shutil |
16 | import re | 17 | import 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: |