1eb8dc403SDave Cobbley# 2eb8dc403SDave Cobbley# Copyright (c) 2014, Intel Corporation. 3eb8dc403SDave Cobbley# 4c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only 5eb8dc403SDave Cobbley# 6eb8dc403SDave Cobbley# DESCRIPTION 7eb8dc403SDave Cobbley# This implements the 'bootimg-efi' source plugin class for 'wic' 8eb8dc403SDave Cobbley# 9eb8dc403SDave Cobbley# AUTHORS 10eb8dc403SDave Cobbley# Tom Zanussi <tom.zanussi (at] linux.intel.com> 11eb8dc403SDave Cobbley# 12eb8dc403SDave Cobbley 13eb8dc403SDave Cobbleyimport logging 14eb8dc403SDave Cobbleyimport os 1593c203f3SPatrick Williamsimport tempfile 16eb8dc403SDave Cobbleyimport shutil 17635e0e46SAndrew Geisslerimport re 18635e0e46SAndrew Geissler 19635e0e46SAndrew Geisslerfrom glob import glob 20eb8dc403SDave Cobbley 21eb8dc403SDave Cobbleyfrom wic import WicError 22eb8dc403SDave Cobbleyfrom wic.engine import get_custom_config 23eb8dc403SDave Cobbleyfrom wic.pluginbase import SourcePlugin 24eb8dc403SDave Cobbleyfrom wic.misc import (exec_cmd, exec_native_cmd, 25eb8dc403SDave Cobbley get_bitbake_var, BOOTDD_EXTRA_SPACE) 26eb8dc403SDave Cobbley 27eb8dc403SDave Cobbleylogger = logging.getLogger('wic') 28eb8dc403SDave Cobbley 29eb8dc403SDave Cobbleyclass BootimgEFIPlugin(SourcePlugin): 30eb8dc403SDave Cobbley """ 31eb8dc403SDave Cobbley Create EFI boot partition. 32eb8dc403SDave Cobbley This plugin supports GRUB 2 and systemd-boot bootloaders. 33eb8dc403SDave Cobbley """ 34eb8dc403SDave Cobbley 35eb8dc403SDave Cobbley name = 'bootimg-efi' 36eb8dc403SDave Cobbley 37eb8dc403SDave Cobbley @classmethod 38db4c27eeSPatrick Williams def _copy_additional_files(cls, hdddir, initrd, dtb): 39db4c27eeSPatrick Williams bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 40db4c27eeSPatrick Williams if not bootimg_dir: 41db4c27eeSPatrick Williams raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") 42db4c27eeSPatrick Williams 43db4c27eeSPatrick Williams if initrd: 44db4c27eeSPatrick Williams initrds = initrd.split(';') 45db4c27eeSPatrick Williams for rd in initrds: 46db4c27eeSPatrick Williams cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, hdddir) 47db4c27eeSPatrick Williams exec_cmd(cp_cmd, True) 48db4c27eeSPatrick Williams else: 49db4c27eeSPatrick Williams logger.debug("Ignoring missing initrd") 50db4c27eeSPatrick Williams 51db4c27eeSPatrick Williams if dtb: 52db4c27eeSPatrick Williams if ';' in dtb: 53db4c27eeSPatrick Williams raise WicError("Only one DTB supported, exiting") 54db4c27eeSPatrick Williams cp_cmd = "cp %s/%s %s" % (bootimg_dir, dtb, hdddir) 55db4c27eeSPatrick Williams exec_cmd(cp_cmd, True) 56db4c27eeSPatrick Williams 57db4c27eeSPatrick Williams @classmethod 58d5ae7d90SBrad Bishop def do_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params): 59eb8dc403SDave Cobbley """ 60eb8dc403SDave Cobbley Create loader-specific (grub-efi) config 61eb8dc403SDave Cobbley """ 62eb8dc403SDave Cobbley configfile = creator.ks.bootloader.configfile 63eb8dc403SDave Cobbley custom_cfg = None 64eb8dc403SDave Cobbley if configfile: 65eb8dc403SDave Cobbley custom_cfg = get_custom_config(configfile) 66eb8dc403SDave Cobbley if custom_cfg: 67eb8dc403SDave Cobbley # Use a custom configuration for grub 68eb8dc403SDave Cobbley grubefi_conf = custom_cfg 69eb8dc403SDave Cobbley logger.debug("Using custom configuration file " 70eb8dc403SDave Cobbley "%s for grub.cfg", configfile) 71eb8dc403SDave Cobbley else: 72eb8dc403SDave Cobbley raise WicError("configfile is specified but failed to " 73eb8dc403SDave Cobbley "get it from %s." % configfile) 74eb8dc403SDave Cobbley 75d5ae7d90SBrad Bishop initrd = source_params.get('initrd') 76db4c27eeSPatrick Williams dtb = source_params.get('dtb') 77d5ae7d90SBrad Bishop 78db4c27eeSPatrick Williams cls._copy_additional_files(hdddir, initrd, dtb) 79d5ae7d90SBrad Bishop 80eb8dc403SDave Cobbley if not custom_cfg: 81eb8dc403SDave Cobbley # Create grub configuration using parameters from wks file 82eb8dc403SDave Cobbley bootloader = creator.ks.bootloader 8319323693SBrad Bishop title = source_params.get('title') 84eb8dc403SDave Cobbley 85eb8dc403SDave Cobbley grubefi_conf = "" 86eb8dc403SDave Cobbley grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" 87eb8dc403SDave Cobbley grubefi_conf += "default=boot\n" 88eb8dc403SDave Cobbley grubefi_conf += "timeout=%s\n" % bootloader.timeout 8919323693SBrad Bishop grubefi_conf += "menuentry '%s'{\n" % (title if title else "boot") 90eb8dc403SDave Cobbley 9115ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 9296ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 9396ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 9496ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 9596ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 96eb8dc403SDave Cobbley 9715ae2509SBrad Bishop label = source_params.get('label') 9815ae2509SBrad Bishop label_conf = "root=%s" % creator.rootdev 9915ae2509SBrad Bishop if label: 10015ae2509SBrad Bishop label_conf = "LABEL=%s" % label 10115ae2509SBrad Bishop 10215ae2509SBrad Bishop grubefi_conf += "linux /%s %s rootwait %s\n" \ 10315ae2509SBrad Bishop % (kernel, label_conf, bootloader.append) 104d5ae7d90SBrad Bishop 105d5ae7d90SBrad Bishop if initrd: 106f3fd288eSBrad Bishop initrds = initrd.split(';') 107f3fd288eSBrad Bishop grubefi_conf += "initrd" 108f3fd288eSBrad Bishop for rd in initrds: 109f3fd288eSBrad Bishop grubefi_conf += " /%s" % rd 110f3fd288eSBrad Bishop grubefi_conf += "\n" 111d5ae7d90SBrad Bishop 112db4c27eeSPatrick Williams if dtb: 113db4c27eeSPatrick Williams grubefi_conf += "devicetree /%s\n" % dtb 114db4c27eeSPatrick Williams 115eb8dc403SDave Cobbley grubefi_conf += "}\n" 116eb8dc403SDave Cobbley 117eb8dc403SDave Cobbley logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg", 118eb8dc403SDave Cobbley cr_workdir) 119eb8dc403SDave Cobbley cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") 120eb8dc403SDave Cobbley cfg.write(grubefi_conf) 121eb8dc403SDave Cobbley cfg.close() 122eb8dc403SDave Cobbley 123eb8dc403SDave Cobbley @classmethod 124eb8dc403SDave Cobbley def do_configure_systemdboot(cls, hdddir, creator, cr_workdir, source_params): 125eb8dc403SDave Cobbley """ 126eb8dc403SDave Cobbley Create loader-specific systemd-boot/gummiboot config 127eb8dc403SDave Cobbley """ 128eb8dc403SDave Cobbley install_cmd = "install -d %s/loader" % hdddir 129eb8dc403SDave Cobbley exec_cmd(install_cmd) 130eb8dc403SDave Cobbley 131eb8dc403SDave Cobbley install_cmd = "install -d %s/loader/entries" % hdddir 132eb8dc403SDave Cobbley exec_cmd(install_cmd) 133eb8dc403SDave Cobbley 134eb8dc403SDave Cobbley bootloader = creator.ks.bootloader 135eb8dc403SDave Cobbley 136db4c27eeSPatrick Williams unified_image = source_params.get('create-unified-kernel-image') == "true" 137db4c27eeSPatrick Williams 138eb8dc403SDave Cobbley loader_conf = "" 139db4c27eeSPatrick Williams if not unified_image: 140eb8dc403SDave Cobbley loader_conf += "default boot\n" 141eb8dc403SDave Cobbley loader_conf += "timeout %d\n" % bootloader.timeout 142eb8dc403SDave Cobbley 143eb8dc403SDave Cobbley initrd = source_params.get('initrd') 144db4c27eeSPatrick Williams dtb = source_params.get('dtb') 145eb8dc403SDave Cobbley 146db4c27eeSPatrick Williams if not unified_image: 147db4c27eeSPatrick Williams cls._copy_additional_files(hdddir, initrd, dtb) 148eb8dc403SDave Cobbley 149eb8dc403SDave Cobbley logger.debug("Writing systemd-boot config " 150eb8dc403SDave Cobbley "%s/hdd/boot/loader/loader.conf", cr_workdir) 151eb8dc403SDave Cobbley cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w") 152eb8dc403SDave Cobbley cfg.write(loader_conf) 153eb8dc403SDave Cobbley cfg.close() 154eb8dc403SDave Cobbley 155eb8dc403SDave Cobbley configfile = creator.ks.bootloader.configfile 156eb8dc403SDave Cobbley custom_cfg = None 157eb8dc403SDave Cobbley if configfile: 158eb8dc403SDave Cobbley custom_cfg = get_custom_config(configfile) 159eb8dc403SDave Cobbley if custom_cfg: 160eb8dc403SDave Cobbley # Use a custom configuration for systemd-boot 161eb8dc403SDave Cobbley boot_conf = custom_cfg 162eb8dc403SDave Cobbley logger.debug("Using custom configuration file " 163eb8dc403SDave Cobbley "%s for systemd-boots's boot.conf", configfile) 164eb8dc403SDave Cobbley else: 165eb8dc403SDave Cobbley raise WicError("configfile is specified but failed to " 166eb8dc403SDave Cobbley "get it from %s.", configfile) 167eb8dc403SDave Cobbley 168eb8dc403SDave Cobbley if not custom_cfg: 169eb8dc403SDave Cobbley # Create systemd-boot configuration using parameters from wks file 17015ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 17196ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 17296ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 17396ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 17496ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 17515ae2509SBrad Bishop 17619323693SBrad Bishop title = source_params.get('title') 177eb8dc403SDave Cobbley 178eb8dc403SDave Cobbley boot_conf = "" 17919323693SBrad Bishop boot_conf += "title %s\n" % (title if title else "boot") 18015ae2509SBrad Bishop boot_conf += "linux /%s\n" % kernel 18115ae2509SBrad Bishop 18215ae2509SBrad Bishop label = source_params.get('label') 18315ae2509SBrad Bishop label_conf = "LABEL=Boot root=%s" % creator.rootdev 18415ae2509SBrad Bishop if label: 18515ae2509SBrad Bishop label_conf = "LABEL=%s" % label 18615ae2509SBrad Bishop 18715ae2509SBrad Bishop boot_conf += "options %s %s\n" % \ 18815ae2509SBrad Bishop (label_conf, bootloader.append) 189eb8dc403SDave Cobbley 190eb8dc403SDave Cobbley if initrd: 191f3fd288eSBrad Bishop initrds = initrd.split(';') 192f3fd288eSBrad Bishop for rd in initrds: 193f3fd288eSBrad Bishop boot_conf += "initrd /%s\n" % rd 194eb8dc403SDave Cobbley 195db4c27eeSPatrick Williams if dtb: 196db4c27eeSPatrick Williams boot_conf += "devicetree /%s\n" % dtb 197db4c27eeSPatrick Williams 198db4c27eeSPatrick Williams if not unified_image: 199eb8dc403SDave Cobbley logger.debug("Writing systemd-boot config " 200eb8dc403SDave Cobbley "%s/hdd/boot/loader/entries/boot.conf", cr_workdir) 201eb8dc403SDave Cobbley cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w") 202eb8dc403SDave Cobbley cfg.write(boot_conf) 203eb8dc403SDave Cobbley cfg.close() 204eb8dc403SDave Cobbley 205eb8dc403SDave Cobbley 206eb8dc403SDave Cobbley @classmethod 207eb8dc403SDave Cobbley def do_configure_partition(cls, part, source_params, creator, cr_workdir, 208eb8dc403SDave Cobbley oe_builddir, bootimg_dir, kernel_dir, 209eb8dc403SDave Cobbley native_sysroot): 210eb8dc403SDave Cobbley """ 211eb8dc403SDave Cobbley Called before do_prepare_partition(), creates loader-specific config 212eb8dc403SDave Cobbley """ 213eb8dc403SDave Cobbley hdddir = "%s/hdd/boot" % cr_workdir 214eb8dc403SDave Cobbley 215eb8dc403SDave Cobbley install_cmd = "install -d %s/EFI/BOOT" % hdddir 216eb8dc403SDave Cobbley exec_cmd(install_cmd) 217eb8dc403SDave Cobbley 218eb8dc403SDave Cobbley try: 219eb8dc403SDave Cobbley if source_params['loader'] == 'grub-efi': 220d5ae7d90SBrad Bishop cls.do_configure_grubefi(hdddir, creator, cr_workdir, source_params) 221eb8dc403SDave Cobbley elif source_params['loader'] == 'systemd-boot': 222eb8dc403SDave Cobbley cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params) 2232390b1b6SPatrick Williams elif source_params['loader'] == 'uefi-kernel': 2246aa7eec5SAndrew Geissler pass 225eb8dc403SDave Cobbley else: 226eb8dc403SDave Cobbley raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) 227eb8dc403SDave Cobbley except KeyError: 228eb8dc403SDave Cobbley raise WicError("bootimg-efi requires a loader, none specified") 229eb8dc403SDave Cobbley 230c9f7865aSAndrew Geissler if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None: 231c9f7865aSAndrew Geissler logger.debug('No boot files defined in IMAGE_EFI_BOOT_FILES') 232635e0e46SAndrew Geissler else: 233635e0e46SAndrew Geissler boot_files = None 234635e0e46SAndrew Geissler for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)): 235635e0e46SAndrew Geissler if fmt: 236635e0e46SAndrew Geissler var = fmt % id 237635e0e46SAndrew Geissler else: 238635e0e46SAndrew Geissler var = "" 239635e0e46SAndrew Geissler 240c9f7865aSAndrew Geissler boot_files = get_bitbake_var("IMAGE_EFI_BOOT_FILES" + var) 241635e0e46SAndrew Geissler if boot_files: 242635e0e46SAndrew Geissler break 243635e0e46SAndrew Geissler 244635e0e46SAndrew Geissler logger.debug('Boot files: %s', boot_files) 245635e0e46SAndrew Geissler 246635e0e46SAndrew Geissler # list of tuples (src_name, dst_name) 247635e0e46SAndrew Geissler deploy_files = [] 248635e0e46SAndrew Geissler for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files): 249635e0e46SAndrew Geissler if ';' in src_entry: 250635e0e46SAndrew Geissler dst_entry = tuple(src_entry.split(';')) 251635e0e46SAndrew Geissler if not dst_entry[0] or not dst_entry[1]: 252635e0e46SAndrew Geissler raise WicError('Malformed boot file entry: %s' % src_entry) 253635e0e46SAndrew Geissler else: 254635e0e46SAndrew Geissler dst_entry = (src_entry, src_entry) 255635e0e46SAndrew Geissler 256635e0e46SAndrew Geissler logger.debug('Destination entry: %r', dst_entry) 257635e0e46SAndrew Geissler deploy_files.append(dst_entry) 258635e0e46SAndrew Geissler 259635e0e46SAndrew Geissler cls.install_task = []; 260635e0e46SAndrew Geissler for deploy_entry in deploy_files: 261635e0e46SAndrew Geissler src, dst = deploy_entry 262635e0e46SAndrew Geissler if '*' in src: 263635e0e46SAndrew Geissler # by default install files under their basename 264635e0e46SAndrew Geissler entry_name_fn = os.path.basename 265635e0e46SAndrew Geissler if dst != src: 266635e0e46SAndrew Geissler # unless a target name was given, then treat name 267635e0e46SAndrew Geissler # as a directory and append a basename 268635e0e46SAndrew Geissler entry_name_fn = lambda name: \ 269635e0e46SAndrew Geissler os.path.join(dst, 270635e0e46SAndrew Geissler os.path.basename(name)) 271635e0e46SAndrew Geissler 272635e0e46SAndrew Geissler srcs = glob(os.path.join(kernel_dir, src)) 273635e0e46SAndrew Geissler 274635e0e46SAndrew Geissler logger.debug('Globbed sources: %s', ', '.join(srcs)) 275635e0e46SAndrew Geissler for entry in srcs: 276635e0e46SAndrew Geissler src = os.path.relpath(entry, kernel_dir) 277635e0e46SAndrew Geissler entry_dst_name = entry_name_fn(entry) 278635e0e46SAndrew Geissler cls.install_task.append((src, entry_dst_name)) 279635e0e46SAndrew Geissler else: 280635e0e46SAndrew Geissler cls.install_task.append((src, dst)) 281eb8dc403SDave Cobbley 282eb8dc403SDave Cobbley @classmethod 283eb8dc403SDave Cobbley def do_prepare_partition(cls, part, source_params, creator, cr_workdir, 284eb8dc403SDave Cobbley oe_builddir, bootimg_dir, kernel_dir, 285eb8dc403SDave Cobbley rootfs_dir, native_sysroot): 286eb8dc403SDave Cobbley """ 287eb8dc403SDave Cobbley Called to do the actual content population for a partition i.e. it 288eb8dc403SDave Cobbley 'prepares' the partition to be incorporated into the image. 289eb8dc403SDave Cobbley In this case, prepare content for an EFI (grub) boot partition. 290eb8dc403SDave Cobbley """ 291eb8dc403SDave Cobbley if not kernel_dir: 292eb8dc403SDave Cobbley kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 293eb8dc403SDave Cobbley if not kernel_dir: 294eb8dc403SDave Cobbley raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") 295eb8dc403SDave Cobbley 296eb8dc403SDave Cobbley staging_kernel_dir = kernel_dir 297eb8dc403SDave Cobbley 298eb8dc403SDave Cobbley hdddir = "%s/hdd/boot" % cr_workdir 299eb8dc403SDave Cobbley 30015ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 30196ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 30296ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 30396ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 30496ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 30515ae2509SBrad Bishop 30693c203f3SPatrick Williams if source_params.get('create-unified-kernel-image') == "true": 30793c203f3SPatrick Williams initrd = source_params.get('initrd') 30893c203f3SPatrick Williams if not initrd: 30993c203f3SPatrick Williams raise WicError("initrd= must be specified when create-unified-kernel-image=true, exiting") 31093c203f3SPatrick Williams 31193c203f3SPatrick Williams deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 31293c203f3SPatrick Williams efi_stub = glob("%s/%s" % (deploy_dir, "linux*.efi.stub")) 31393c203f3SPatrick Williams if len(efi_stub) == 0: 31493c203f3SPatrick Williams raise WicError("Unified Kernel Image EFI stub not found, exiting") 31593c203f3SPatrick Williams efi_stub = efi_stub[0] 31693c203f3SPatrick Williams 31793c203f3SPatrick Williams with tempfile.TemporaryDirectory() as tmp_dir: 31893c203f3SPatrick Williams label = source_params.get('label') 31993c203f3SPatrick Williams label_conf = "root=%s" % creator.rootdev 32093c203f3SPatrick Williams if label: 32193c203f3SPatrick Williams label_conf = "LABEL=%s" % label 32293c203f3SPatrick Williams 32393c203f3SPatrick Williams bootloader = creator.ks.bootloader 32493c203f3SPatrick Williams cmdline = open("%s/cmdline" % tmp_dir, "w") 32593c203f3SPatrick Williams cmdline.write("%s %s" % (label_conf, bootloader.append)) 32693c203f3SPatrick Williams cmdline.close() 32793c203f3SPatrick Williams 32893c203f3SPatrick Williams initrds = initrd.split(';') 32993c203f3SPatrick Williams initrd = open("%s/initrd" % tmp_dir, "wb") 33093c203f3SPatrick Williams for f in initrds: 33193c203f3SPatrick Williams with open("%s/%s" % (deploy_dir, f), 'rb') as in_file: 33293c203f3SPatrick Williams shutil.copyfileobj(in_file, initrd) 33393c203f3SPatrick Williams initrd.close() 33493c203f3SPatrick Williams 33593c203f3SPatrick Williams # Searched by systemd-boot: 33693c203f3SPatrick Williams # https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images 33793c203f3SPatrick Williams install_cmd = "install -d %s/EFI/Linux" % hdddir 33893c203f3SPatrick Williams exec_cmd(install_cmd) 33993c203f3SPatrick Williams 34093c203f3SPatrick Williams staging_dir_host = get_bitbake_var("STAGING_DIR_HOST") 341db4c27eeSPatrick Williams target_sys = get_bitbake_var("TARGET_SYS") 34293c203f3SPatrick Williams 3432a25492cSPatrick Williams objdump_cmd = "%s-objdump" % target_sys 3442a25492cSPatrick Williams objdump_cmd += " -p %s" % efi_stub 3452a25492cSPatrick Williams objdump_cmd += " | awk '{ if ($1 == \"SectionAlignment\"){print $2} }'" 3462a25492cSPatrick Williams 3472a25492cSPatrick Williams ret, align_str = exec_native_cmd(objdump_cmd, native_sysroot) 3482a25492cSPatrick Williams align = int(align_str, 16) 3492a25492cSPatrick Williams 3502a25492cSPatrick Williams objdump_cmd = "%s-objdump" % target_sys 3512a25492cSPatrick Williams objdump_cmd += " -h %s | tail -2" % efi_stub 3522a25492cSPatrick Williams ret, output = exec_native_cmd(objdump_cmd, native_sysroot) 3532a25492cSPatrick Williams 3542a25492cSPatrick Williams offset = int(output.split()[2], 16) + int(output.split()[3], 16) 3552a25492cSPatrick Williams 3562a25492cSPatrick Williams osrel_off = offset + align - offset % align 3572a25492cSPatrick Williams osrel_path = "%s/usr/lib/os-release" % staging_dir_host 3582a25492cSPatrick Williams osrel_sz = os.stat(osrel_path).st_size 3592a25492cSPatrick Williams 3602a25492cSPatrick Williams cmdline_off = osrel_off + osrel_sz 3612a25492cSPatrick Williams cmdline_off = cmdline_off + align - cmdline_off % align 3622a25492cSPatrick Williams cmdline_sz = os.stat(cmdline.name).st_size 3632a25492cSPatrick Williams 3642a25492cSPatrick Williams dtb_off = cmdline_off + cmdline_sz 3652a25492cSPatrick Williams dtb_off = dtb_off + align - dtb_off % align 3662a25492cSPatrick Williams 3672a25492cSPatrick Williams dtb = source_params.get('dtb') 3682a25492cSPatrick Williams if dtb: 3692a25492cSPatrick Williams if ';' in dtb: 3702a25492cSPatrick Williams raise WicError("Only one DTB supported, exiting") 3712a25492cSPatrick Williams dtb_path = "%s/%s" % (deploy_dir, dtb) 3722a25492cSPatrick Williams dtb_params = '--add-section .dtb=%s --change-section-vma .dtb=0x%x' % \ 3732a25492cSPatrick Williams (dtb_path, dtb_off) 3742a25492cSPatrick Williams linux_off = dtb_off + os.stat(dtb_path).st_size 3752a25492cSPatrick Williams linux_off = linux_off + align - linux_off % align 3762a25492cSPatrick Williams else: 3772a25492cSPatrick Williams dtb_params = '' 3782a25492cSPatrick Williams linux_off = dtb_off 3792a25492cSPatrick Williams 3802a25492cSPatrick Williams linux_path = "%s/%s" % (staging_kernel_dir, kernel) 3812a25492cSPatrick Williams linux_sz = os.stat(linux_path).st_size 3822a25492cSPatrick Williams 3832a25492cSPatrick Williams initrd_off = linux_off + linux_sz 3842a25492cSPatrick Williams initrd_off = initrd_off + align - initrd_off % align 3852a25492cSPatrick Williams 38693c203f3SPatrick Williams # https://www.freedesktop.org/software/systemd/man/systemd-stub.html 387db4c27eeSPatrick Williams objcopy_cmd = "%s-objcopy" % target_sys 388b542dec1SPatrick Williams objcopy_cmd += " --enable-deterministic-archives" 389b542dec1SPatrick Williams objcopy_cmd += " --preserve-dates" 3902a25492cSPatrick Williams objcopy_cmd += " --add-section .osrel=%s" % osrel_path 3912a25492cSPatrick Williams objcopy_cmd += " --change-section-vma .osrel=0x%x" % osrel_off 392db4c27eeSPatrick Williams objcopy_cmd += " --add-section .cmdline=%s" % cmdline.name 3932a25492cSPatrick Williams objcopy_cmd += " --change-section-vma .cmdline=0x%x" % cmdline_off 394db4c27eeSPatrick Williams objcopy_cmd += dtb_params 3952a25492cSPatrick Williams objcopy_cmd += " --add-section .linux=%s" % linux_path 3962a25492cSPatrick Williams objcopy_cmd += " --change-section-vma .linux=0x%x" % linux_off 397db4c27eeSPatrick Williams objcopy_cmd += " --add-section .initrd=%s" % initrd.name 3982a25492cSPatrick Williams objcopy_cmd += " --change-section-vma .initrd=0x%x" % initrd_off 399db4c27eeSPatrick Williams objcopy_cmd += " %s %s/EFI/Linux/linux.efi" % (efi_stub, hdddir) 4002a25492cSPatrick Williams 401db4c27eeSPatrick Williams exec_native_cmd(objcopy_cmd, native_sysroot) 40293c203f3SPatrick Williams else: 403*da295319SPatrick Williams if source_params.get('install-kernel-into-boot-dir') != 'false': 40415ae2509SBrad Bishop install_cmd = "install -m 0644 %s/%s %s/%s" % \ 40515ae2509SBrad Bishop (staging_kernel_dir, kernel, hdddir, kernel) 406eb8dc403SDave Cobbley exec_cmd(install_cmd) 407eb8dc403SDave Cobbley 408c9f7865aSAndrew Geissler if get_bitbake_var("IMAGE_EFI_BOOT_FILES"): 409635e0e46SAndrew Geissler for src_path, dst_path in cls.install_task: 410635e0e46SAndrew Geissler install_cmd = "install -m 0644 -D %s %s" \ 411635e0e46SAndrew Geissler % (os.path.join(kernel_dir, src_path), 412635e0e46SAndrew Geissler os.path.join(hdddir, dst_path)) 413635e0e46SAndrew Geissler exec_cmd(install_cmd) 414eb8dc403SDave Cobbley 415eb8dc403SDave Cobbley try: 416eb8dc403SDave Cobbley if source_params['loader'] == 'grub-efi': 417eb8dc403SDave Cobbley shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, 418eb8dc403SDave Cobbley "%s/grub.cfg" % cr_workdir) 419eb8dc403SDave Cobbley for mod in [x for x in os.listdir(kernel_dir) if x.startswith("grub-efi-")]: 420eb8dc403SDave Cobbley cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[9:]) 421eb8dc403SDave Cobbley exec_cmd(cp_cmd, True) 422eb8dc403SDave Cobbley shutil.move("%s/grub.cfg" % cr_workdir, 423eb8dc403SDave Cobbley "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir) 424eb8dc403SDave Cobbley elif source_params['loader'] == 'systemd-boot': 425eb8dc403SDave Cobbley for mod in [x for x in os.listdir(kernel_dir) if x.startswith("systemd-")]: 426eb8dc403SDave Cobbley cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[8:]) 427eb8dc403SDave Cobbley exec_cmd(cp_cmd, True) 4282390b1b6SPatrick Williams elif source_params['loader'] == 'uefi-kernel': 4292390b1b6SPatrick Williams kernel = get_bitbake_var("KERNEL_IMAGETYPE") 4302390b1b6SPatrick Williams if not kernel: 4312390b1b6SPatrick Williams raise WicError("Empty KERNEL_IMAGETYPE %s\n" % target) 4322390b1b6SPatrick Williams target = get_bitbake_var("TARGET_SYS") 4332390b1b6SPatrick Williams if not target: 4342390b1b6SPatrick Williams raise WicError("Unknown arch (TARGET_SYS) %s\n" % target) 4352390b1b6SPatrick Williams 4362390b1b6SPatrick Williams if re.match("x86_64", target): 4372390b1b6SPatrick Williams kernel_efi_image = "bootx64.efi" 4382390b1b6SPatrick Williams elif re.match('i.86', target): 4392390b1b6SPatrick Williams kernel_efi_image = "bootia32.efi" 4402390b1b6SPatrick Williams elif re.match('aarch64', target): 4412390b1b6SPatrick Williams kernel_efi_image = "bootaa64.efi" 4422390b1b6SPatrick Williams elif re.match('arm', target): 4432390b1b6SPatrick Williams kernel_efi_image = "bootarm.efi" 4442390b1b6SPatrick Williams else: 4452390b1b6SPatrick Williams raise WicError("UEFI stub kernel is incompatible with target %s" % target) 4462390b1b6SPatrick Williams 4472390b1b6SPatrick Williams for mod in [x for x in os.listdir(kernel_dir) if x.startswith(kernel)]: 4482390b1b6SPatrick Williams cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, kernel_efi_image) 4492390b1b6SPatrick Williams exec_cmd(cp_cmd, True) 450eb8dc403SDave Cobbley else: 451eb8dc403SDave Cobbley raise WicError("unrecognized bootimg-efi loader: %s" % 452eb8dc403SDave Cobbley source_params['loader']) 453eb8dc403SDave Cobbley except KeyError: 454eb8dc403SDave Cobbley raise WicError("bootimg-efi requires a loader, none specified") 455eb8dc403SDave Cobbley 456eb8dc403SDave Cobbley startup = os.path.join(kernel_dir, "startup.nsh") 457eb8dc403SDave Cobbley if os.path.exists(startup): 458eb8dc403SDave Cobbley cp_cmd = "cp %s %s/" % (startup, hdddir) 459eb8dc403SDave Cobbley exec_cmd(cp_cmd, True) 460eb8dc403SDave Cobbley 4612390b1b6SPatrick Williams for paths in part.include_path or []: 4622390b1b6SPatrick Williams for path in paths: 4632390b1b6SPatrick Williams cp_cmd = "cp -r %s %s/" % (path, hdddir) 4642390b1b6SPatrick Williams exec_cmd(cp_cmd, True) 4652390b1b6SPatrick Williams 466eb8dc403SDave Cobbley du_cmd = "du -bks %s" % hdddir 467eb8dc403SDave Cobbley out = exec_cmd(du_cmd) 468eb8dc403SDave Cobbley blocks = int(out.split()[0]) 469eb8dc403SDave Cobbley 470eb8dc403SDave Cobbley extra_blocks = part.get_extra_block_count(blocks) 471eb8dc403SDave Cobbley 472eb8dc403SDave Cobbley if extra_blocks < BOOTDD_EXTRA_SPACE: 473eb8dc403SDave Cobbley extra_blocks = BOOTDD_EXTRA_SPACE 474eb8dc403SDave Cobbley 475eb8dc403SDave Cobbley blocks += extra_blocks 476eb8dc403SDave Cobbley 477eb8dc403SDave Cobbley logger.debug("Added %d extra blocks to %s to get to %d total blocks", 478eb8dc403SDave Cobbley extra_blocks, part.mountpoint, blocks) 479eb8dc403SDave Cobbley 4808e7b46e2SPatrick Williams # required for compatibility with certain devices expecting file system 4818e7b46e2SPatrick Williams # block count to be equal to partition block count 4828e7b46e2SPatrick Williams if blocks < part.fixed_size: 4838e7b46e2SPatrick Williams blocks = part.fixed_size 4848e7b46e2SPatrick Williams logger.debug("Overriding %s to %d total blocks for compatibility", 4858e7b46e2SPatrick Williams part.mountpoint, blocks) 4868e7b46e2SPatrick Williams 487eb8dc403SDave Cobbley # dosfs image, created by mkdosfs 488eb8dc403SDave Cobbley bootimg = "%s/boot.img" % cr_workdir 489eb8dc403SDave Cobbley 490c342db35SBrad Bishop label = part.label if part.label else "ESP" 491c342db35SBrad Bishop 492c342db35SBrad Bishop dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \ 493c342db35SBrad Bishop (label, part.fsuuid, bootimg, blocks) 494eb8dc403SDave Cobbley exec_native_cmd(dosfs_cmd, native_sysroot) 495eb8dc403SDave Cobbley 496eb8dc403SDave Cobbley mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) 497eb8dc403SDave Cobbley exec_native_cmd(mcopy_cmd, native_sysroot) 498eb8dc403SDave Cobbley 499eb8dc403SDave Cobbley chmod_cmd = "chmod 644 %s" % bootimg 500eb8dc403SDave Cobbley exec_cmd(chmod_cmd) 501eb8dc403SDave Cobbley 502eb8dc403SDave Cobbley du_cmd = "du -Lbks %s" % bootimg 503eb8dc403SDave Cobbley out = exec_cmd(du_cmd) 504eb8dc403SDave Cobbley bootimg_size = out.split()[0] 505eb8dc403SDave Cobbley 506eb8dc403SDave Cobbley part.size = int(bootimg_size) 507eb8dc403SDave Cobbley part.source_file = bootimg 508