1eb8dc403SDave Cobbley# 2*92b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors 3*92b42cb3SPatrick Williams# 4c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only 5eb8dc403SDave Cobbley# 6eb8dc403SDave Cobbley# DESCRIPTION 7eb8dc403SDave Cobbley# This implements the 'isoimage-isohybrid' source plugin class for 'wic' 8eb8dc403SDave Cobbley# 9eb8dc403SDave Cobbley# AUTHORS 10eb8dc403SDave Cobbley# Mihaly Varga <mihaly.varga (at] ni.com> 11eb8dc403SDave Cobbley 12eb8dc403SDave Cobbleyimport glob 13eb8dc403SDave Cobbleyimport logging 14eb8dc403SDave Cobbleyimport os 15eb8dc403SDave Cobbleyimport re 16eb8dc403SDave Cobbleyimport shutil 17eb8dc403SDave Cobbley 18eb8dc403SDave Cobbleyfrom wic import WicError 19eb8dc403SDave Cobbleyfrom wic.engine import get_custom_config 20eb8dc403SDave Cobbleyfrom wic.pluginbase import SourcePlugin 21eb8dc403SDave Cobbleyfrom wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var 22eb8dc403SDave Cobbley 23eb8dc403SDave Cobbleylogger = logging.getLogger('wic') 24eb8dc403SDave Cobbley 25eb8dc403SDave Cobbleyclass IsoImagePlugin(SourcePlugin): 26eb8dc403SDave Cobbley """ 27eb8dc403SDave Cobbley Create a bootable ISO image 28eb8dc403SDave Cobbley 29eb8dc403SDave Cobbley This plugin creates a hybrid, legacy and EFI bootable ISO image. The 30eb8dc403SDave Cobbley generated image can be used on optical media as well as USB media. 31eb8dc403SDave Cobbley 32eb8dc403SDave Cobbley Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not 33eb8dc403SDave Cobbley implemented yet) as bootloader. The plugin creates the directories required 34eb8dc403SDave Cobbley by bootloaders and populates them by creating and configuring the 35eb8dc403SDave Cobbley bootloader files. 36eb8dc403SDave Cobbley 37eb8dc403SDave Cobbley Example kickstart file: 38eb8dc403SDave Cobbley part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\ 391a4b7ee2SBrad Bishop image_name= IsoImage" --ondisk cd --label LIVECD 40eb8dc403SDave Cobbley bootloader --timeout=10 --append=" " 41eb8dc403SDave Cobbley 42eb8dc403SDave Cobbley In --sourceparams "loader" specifies the bootloader used for booting in EFI 43eb8dc403SDave Cobbley mode, while "image_name" specifies the name of the generated image. In the 44eb8dc403SDave Cobbley example above, wic creates an ISO image named IsoImage-cd.direct (default 45eb8dc403SDave Cobbley extension added by direct imeger plugin) and a file named IsoImage-cd.iso 46eb8dc403SDave Cobbley """ 47eb8dc403SDave Cobbley 48eb8dc403SDave Cobbley name = 'isoimage-isohybrid' 49eb8dc403SDave Cobbley 50eb8dc403SDave Cobbley @classmethod 51eb8dc403SDave Cobbley def do_configure_syslinux(cls, creator, cr_workdir): 52eb8dc403SDave Cobbley """ 53eb8dc403SDave Cobbley Create loader-specific (syslinux) config 54eb8dc403SDave Cobbley """ 55eb8dc403SDave Cobbley splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg") 56eb8dc403SDave Cobbley if os.path.exists(splash): 57eb8dc403SDave Cobbley splashline = "menu background splash.jpg" 58eb8dc403SDave Cobbley else: 59eb8dc403SDave Cobbley splashline = "" 60eb8dc403SDave Cobbley 61eb8dc403SDave Cobbley bootloader = creator.ks.bootloader 62eb8dc403SDave Cobbley 63eb8dc403SDave Cobbley syslinux_conf = "" 64eb8dc403SDave Cobbley syslinux_conf += "PROMPT 0\n" 65eb8dc403SDave Cobbley syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10) 66eb8dc403SDave Cobbley syslinux_conf += "\n" 67eb8dc403SDave Cobbley syslinux_conf += "ALLOWOPTIONS 1\n" 68eb8dc403SDave Cobbley syslinux_conf += "SERIAL 0 115200\n" 69eb8dc403SDave Cobbley syslinux_conf += "\n" 70eb8dc403SDave Cobbley if splashline: 71eb8dc403SDave Cobbley syslinux_conf += "%s\n" % splashline 72eb8dc403SDave Cobbley syslinux_conf += "DEFAULT boot\n" 73eb8dc403SDave Cobbley syslinux_conf += "LABEL boot\n" 74eb8dc403SDave Cobbley 7515ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 7696ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 7796ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 7896ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 7996ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 8096ff1984SBrad Bishop 8115ae2509SBrad Bishop syslinux_conf += "KERNEL /" + kernel + "\n" 82eb8dc403SDave Cobbley syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \ 83eb8dc403SDave Cobbley % bootloader.append 84eb8dc403SDave Cobbley 85eb8dc403SDave Cobbley logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg", 86eb8dc403SDave Cobbley cr_workdir) 87eb8dc403SDave Cobbley 88eb8dc403SDave Cobbley with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg: 89eb8dc403SDave Cobbley cfg.write(syslinux_conf) 90eb8dc403SDave Cobbley 91eb8dc403SDave Cobbley @classmethod 92eb8dc403SDave Cobbley def do_configure_grubefi(cls, part, creator, target_dir): 93eb8dc403SDave Cobbley """ 94eb8dc403SDave Cobbley Create loader-specific (grub-efi) config 95eb8dc403SDave Cobbley """ 96eb8dc403SDave Cobbley configfile = creator.ks.bootloader.configfile 97eb8dc403SDave Cobbley if configfile: 98eb8dc403SDave Cobbley grubefi_conf = get_custom_config(configfile) 99eb8dc403SDave Cobbley if grubefi_conf: 100eb8dc403SDave Cobbley logger.debug("Using custom configuration file %s for grub.cfg", 101eb8dc403SDave Cobbley configfile) 102eb8dc403SDave Cobbley else: 103eb8dc403SDave Cobbley raise WicError("configfile is specified " 104eb8dc403SDave Cobbley "but failed to get it from %s", configfile) 105eb8dc403SDave Cobbley else: 106eb8dc403SDave Cobbley splash = os.path.join(target_dir, "splash.jpg") 107eb8dc403SDave Cobbley if os.path.exists(splash): 108eb8dc403SDave Cobbley splashline = "menu background splash.jpg" 109eb8dc403SDave Cobbley else: 110eb8dc403SDave Cobbley splashline = "" 111eb8dc403SDave Cobbley 112eb8dc403SDave Cobbley bootloader = creator.ks.bootloader 113eb8dc403SDave Cobbley 114eb8dc403SDave Cobbley grubefi_conf = "" 115eb8dc403SDave Cobbley grubefi_conf += "serial --unit=0 --speed=115200 --word=8 " 116eb8dc403SDave Cobbley grubefi_conf += "--parity=no --stop=1\n" 117eb8dc403SDave Cobbley grubefi_conf += "default=boot\n" 118eb8dc403SDave Cobbley grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10) 119eb8dc403SDave Cobbley grubefi_conf += "\n" 120eb8dc403SDave Cobbley grubefi_conf += "search --set=root --label %s " % part.label 121eb8dc403SDave Cobbley grubefi_conf += "\n" 122eb8dc403SDave Cobbley grubefi_conf += "menuentry 'boot'{\n" 123eb8dc403SDave Cobbley 12415ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 12596ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 12696ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 12796ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 12896ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 129eb8dc403SDave Cobbley 13015ae2509SBrad Bishop grubefi_conf += "linux /%s rootwait %s\n" \ 131eb8dc403SDave Cobbley % (kernel, bootloader.append) 132eb8dc403SDave Cobbley grubefi_conf += "initrd /initrd \n" 133eb8dc403SDave Cobbley grubefi_conf += "}\n" 134eb8dc403SDave Cobbley 135eb8dc403SDave Cobbley if splashline: 136eb8dc403SDave Cobbley grubefi_conf += "%s\n" % splashline 137eb8dc403SDave Cobbley 138eb8dc403SDave Cobbley cfg_path = os.path.join(target_dir, "grub.cfg") 139eb8dc403SDave Cobbley logger.debug("Writing grubefi config %s", cfg_path) 140eb8dc403SDave Cobbley 141eb8dc403SDave Cobbley with open(cfg_path, "w") as cfg: 142eb8dc403SDave Cobbley cfg.write(grubefi_conf) 143eb8dc403SDave Cobbley 144eb8dc403SDave Cobbley @staticmethod 145eb8dc403SDave Cobbley def _build_initramfs_path(rootfs_dir, cr_workdir): 146eb8dc403SDave Cobbley """ 147eb8dc403SDave Cobbley Create path for initramfs image 148eb8dc403SDave Cobbley """ 149eb8dc403SDave Cobbley 150eb8dc403SDave Cobbley initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD") 151eb8dc403SDave Cobbley if not initrd: 152eb8dc403SDave Cobbley initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 153eb8dc403SDave Cobbley if not initrd_dir: 154eb8dc403SDave Cobbley raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.") 155eb8dc403SDave Cobbley 156eb8dc403SDave Cobbley image_name = get_bitbake_var("IMAGE_BASENAME") 157eb8dc403SDave Cobbley if not image_name: 158eb8dc403SDave Cobbley raise WicError("Couldn't find IMAGE_BASENAME, exiting.") 159eb8dc403SDave Cobbley 160eb8dc403SDave Cobbley image_type = get_bitbake_var("INITRAMFS_FSTYPES") 161eb8dc403SDave Cobbley if not image_type: 162eb8dc403SDave Cobbley raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.") 163eb8dc403SDave Cobbley 164eb8dc403SDave Cobbley machine = os.path.basename(initrd_dir) 165eb8dc403SDave Cobbley 166eb8dc403SDave Cobbley pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type) 167eb8dc403SDave Cobbley files = glob.glob(pattern) 168eb8dc403SDave Cobbley if files: 169eb8dc403SDave Cobbley initrd = files[0] 170eb8dc403SDave Cobbley 171eb8dc403SDave Cobbley if not initrd or not os.path.exists(initrd): 172eb8dc403SDave Cobbley # Create initrd from rootfs directory 173eb8dc403SDave Cobbley initrd = "%s/initrd.cpio.gz" % cr_workdir 174eb8dc403SDave Cobbley initrd_dir = "%s/INITRD" % cr_workdir 175eb8dc403SDave Cobbley shutil.copytree("%s" % rootfs_dir, \ 176eb8dc403SDave Cobbley "%s" % initrd_dir, symlinks=True) 177eb8dc403SDave Cobbley 178eb8dc403SDave Cobbley if os.path.isfile("%s/init" % rootfs_dir): 179eb8dc403SDave Cobbley shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir) 180eb8dc403SDave Cobbley elif os.path.lexists("%s/init" % rootfs_dir): 181eb8dc403SDave Cobbley os.symlink(os.readlink("%s/init" % rootfs_dir), \ 182eb8dc403SDave Cobbley "%s/init" % initrd_dir) 183eb8dc403SDave Cobbley elif os.path.isfile("%s/sbin/init" % rootfs_dir): 184eb8dc403SDave Cobbley shutil.copy2("%s/sbin/init" % rootfs_dir, \ 185eb8dc403SDave Cobbley "%s" % initrd_dir) 186eb8dc403SDave Cobbley elif os.path.lexists("%s/sbin/init" % rootfs_dir): 187eb8dc403SDave Cobbley os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \ 188eb8dc403SDave Cobbley "%s/init" % initrd_dir) 189eb8dc403SDave Cobbley else: 190eb8dc403SDave Cobbley raise WicError("Couldn't find or build initrd, exiting.") 191eb8dc403SDave Cobbley 1921a4b7ee2SBrad Bishop exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \ 1931a4b7ee2SBrad Bishop % (initrd_dir, cr_workdir), as_shell=True) 1941a4b7ee2SBrad Bishop exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True) 195eb8dc403SDave Cobbley shutil.rmtree(initrd_dir) 196eb8dc403SDave Cobbley 197eb8dc403SDave Cobbley return initrd 198eb8dc403SDave Cobbley 199eb8dc403SDave Cobbley @classmethod 200eb8dc403SDave Cobbley def do_configure_partition(cls, part, source_params, creator, cr_workdir, 201eb8dc403SDave Cobbley oe_builddir, bootimg_dir, kernel_dir, 202eb8dc403SDave Cobbley native_sysroot): 203eb8dc403SDave Cobbley """ 204eb8dc403SDave Cobbley Called before do_prepare_partition(), creates loader-specific config 205eb8dc403SDave Cobbley """ 206eb8dc403SDave Cobbley isodir = "%s/ISO/" % cr_workdir 207eb8dc403SDave Cobbley 208eb8dc403SDave Cobbley if os.path.exists(isodir): 209eb8dc403SDave Cobbley shutil.rmtree(isodir) 210eb8dc403SDave Cobbley 211eb8dc403SDave Cobbley install_cmd = "install -d %s " % isodir 212eb8dc403SDave Cobbley exec_cmd(install_cmd) 213eb8dc403SDave Cobbley 214eb8dc403SDave Cobbley # Overwrite the name of the created image 215eb8dc403SDave Cobbley logger.debug(source_params) 216eb8dc403SDave Cobbley if 'image_name' in source_params and \ 217eb8dc403SDave Cobbley source_params['image_name'].strip(): 218eb8dc403SDave Cobbley creator.name = source_params['image_name'].strip() 219eb8dc403SDave Cobbley logger.debug("The name of the image is: %s", creator.name) 220eb8dc403SDave Cobbley 2216ce62a20SAndrew Geissler @staticmethod 2226ce62a20SAndrew Geissler def _install_payload(source_params, iso_dir): 2236ce62a20SAndrew Geissler """ 2246ce62a20SAndrew Geissler Copies contents of payload directory (as specified in 'payload_dir' param) into iso_dir 2256ce62a20SAndrew Geissler """ 2266ce62a20SAndrew Geissler 2276ce62a20SAndrew Geissler if source_params.get('payload_dir'): 2286ce62a20SAndrew Geissler payload_dir = source_params['payload_dir'] 2296ce62a20SAndrew Geissler 2306ce62a20SAndrew Geissler logger.debug("Payload directory: %s", payload_dir) 2316ce62a20SAndrew Geissler shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True) 2326ce62a20SAndrew Geissler 233eb8dc403SDave Cobbley @classmethod 234eb8dc403SDave Cobbley def do_prepare_partition(cls, part, source_params, creator, cr_workdir, 235eb8dc403SDave Cobbley oe_builddir, bootimg_dir, kernel_dir, 236eb8dc403SDave Cobbley rootfs_dir, native_sysroot): 237eb8dc403SDave Cobbley """ 238eb8dc403SDave Cobbley Called to do the actual content population for a partition i.e. it 239eb8dc403SDave Cobbley 'prepares' the partition to be incorporated into the image. 240eb8dc403SDave Cobbley In this case, prepare content for a bootable ISO image. 241eb8dc403SDave Cobbley """ 242eb8dc403SDave Cobbley 243eb8dc403SDave Cobbley isodir = "%s/ISO" % cr_workdir 244eb8dc403SDave Cobbley 2456ce62a20SAndrew Geissler cls._install_payload(source_params, isodir) 2466ce62a20SAndrew Geissler 247eb8dc403SDave Cobbley if part.rootfs_dir is None: 248eb8dc403SDave Cobbley if not 'ROOTFS_DIR' in rootfs_dir: 249eb8dc403SDave Cobbley raise WicError("Couldn't find --rootfs-dir, exiting.") 250eb8dc403SDave Cobbley rootfs_dir = rootfs_dir['ROOTFS_DIR'] 251eb8dc403SDave Cobbley else: 252eb8dc403SDave Cobbley if part.rootfs_dir in rootfs_dir: 253eb8dc403SDave Cobbley rootfs_dir = rootfs_dir[part.rootfs_dir] 254eb8dc403SDave Cobbley elif part.rootfs_dir: 255eb8dc403SDave Cobbley rootfs_dir = part.rootfs_dir 256eb8dc403SDave Cobbley else: 257eb8dc403SDave Cobbley raise WicError("Couldn't find --rootfs-dir=%s connection " 258eb8dc403SDave Cobbley "or it is not a valid path, exiting." % 259eb8dc403SDave Cobbley part.rootfs_dir) 260eb8dc403SDave Cobbley 261eb8dc403SDave Cobbley if not os.path.isdir(rootfs_dir): 262eb8dc403SDave Cobbley rootfs_dir = get_bitbake_var("IMAGE_ROOTFS") 263eb8dc403SDave Cobbley if not os.path.isdir(rootfs_dir): 264eb8dc403SDave Cobbley raise WicError("Couldn't find IMAGE_ROOTFS, exiting.") 265eb8dc403SDave Cobbley 266eb8dc403SDave Cobbley part.rootfs_dir = rootfs_dir 267eb8dc403SDave Cobbley deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 268eb8dc403SDave Cobbley img_iso_dir = get_bitbake_var("ISODIR") 269eb8dc403SDave Cobbley 270eb8dc403SDave Cobbley # Remove the temporary file created by part.prepare_rootfs() 271eb8dc403SDave Cobbley if os.path.isfile(part.source_file): 272eb8dc403SDave Cobbley os.remove(part.source_file) 273eb8dc403SDave Cobbley 274eb8dc403SDave Cobbley # Support using a different initrd other than default 275eb8dc403SDave Cobbley if source_params.get('initrd'): 276eb8dc403SDave Cobbley initrd = source_params['initrd'] 277eb8dc403SDave Cobbley if not deploy_dir: 278eb8dc403SDave Cobbley raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") 279eb8dc403SDave Cobbley cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir) 280eb8dc403SDave Cobbley exec_cmd(cp_cmd) 281eb8dc403SDave Cobbley else: 282eb8dc403SDave Cobbley # Prepare initial ramdisk 283eb8dc403SDave Cobbley initrd = "%s/initrd" % deploy_dir 284eb8dc403SDave Cobbley if not os.path.isfile(initrd): 285eb8dc403SDave Cobbley initrd = "%s/initrd" % img_iso_dir 286eb8dc403SDave Cobbley if not os.path.isfile(initrd): 287eb8dc403SDave Cobbley initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir) 288eb8dc403SDave Cobbley 289eb8dc403SDave Cobbley install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir) 290eb8dc403SDave Cobbley exec_cmd(install_cmd) 291eb8dc403SDave Cobbley 292eb8dc403SDave Cobbley # Remove the temporary file created by _build_initramfs_path function 293eb8dc403SDave Cobbley if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir): 294eb8dc403SDave Cobbley os.remove("%s/initrd.cpio.gz" % cr_workdir) 295eb8dc403SDave Cobbley 29615ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 29796ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 29896ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 29996ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 30096ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 30115ae2509SBrad Bishop 30215ae2509SBrad Bishop install_cmd = "install -m 0644 %s/%s %s/%s" % \ 30315ae2509SBrad Bishop (kernel_dir, kernel, isodir, kernel) 304eb8dc403SDave Cobbley exec_cmd(install_cmd) 305eb8dc403SDave Cobbley 306eb8dc403SDave Cobbley #Create bootloader for efi boot 307eb8dc403SDave Cobbley try: 308eb8dc403SDave Cobbley target_dir = "%s/EFI/BOOT" % isodir 309eb8dc403SDave Cobbley if os.path.exists(target_dir): 310eb8dc403SDave Cobbley shutil.rmtree(target_dir) 311eb8dc403SDave Cobbley 312eb8dc403SDave Cobbley os.makedirs(target_dir) 313eb8dc403SDave Cobbley 314eb8dc403SDave Cobbley if source_params['loader'] == 'grub-efi': 315eb8dc403SDave Cobbley # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or 316eb8dc403SDave Cobbley # didn't contains it 317eb8dc403SDave Cobbley target_arch = get_bitbake_var("TARGET_SYS") 318eb8dc403SDave Cobbley if not target_arch: 319eb8dc403SDave Cobbley raise WicError("Coludn't find target architecture") 320eb8dc403SDave Cobbley 321eb8dc403SDave Cobbley if re.match("x86_64", target_arch): 322c4ea075dSBrad Bishop grub_src_image = "grub-efi-bootx64.efi" 323c4ea075dSBrad Bishop grub_dest_image = "bootx64.efi" 324eb8dc403SDave Cobbley elif re.match('i.86', target_arch): 325c4ea075dSBrad Bishop grub_src_image = "grub-efi-bootia32.efi" 326c4ea075dSBrad Bishop grub_dest_image = "bootia32.efi" 327eb8dc403SDave Cobbley else: 328eb8dc403SDave Cobbley raise WicError("grub-efi is incompatible with target %s" % 329eb8dc403SDave Cobbley target_arch) 330eb8dc403SDave Cobbley 331c4ea075dSBrad Bishop grub_target = os.path.join(target_dir, grub_dest_image) 332eb8dc403SDave Cobbley if not os.path.isfile(grub_target): 333c4ea075dSBrad Bishop grub_src = os.path.join(deploy_dir, grub_src_image) 334eb8dc403SDave Cobbley if not os.path.exists(grub_src): 335eb8dc403SDave Cobbley raise WicError("Grub loader %s is not found in %s. " 3361a4b7ee2SBrad Bishop "Please build grub-efi first" % (grub_src_image, deploy_dir)) 337eb8dc403SDave Cobbley shutil.copy(grub_src, grub_target) 338eb8dc403SDave Cobbley 339eb8dc403SDave Cobbley if not os.path.isfile(os.path.join(target_dir, "boot.cfg")): 340eb8dc403SDave Cobbley cls.do_configure_grubefi(part, creator, target_dir) 341eb8dc403SDave Cobbley 342eb8dc403SDave Cobbley else: 343eb8dc403SDave Cobbley raise WicError("unrecognized bootimg-efi loader: %s" % 344eb8dc403SDave Cobbley source_params['loader']) 345eb8dc403SDave Cobbley except KeyError: 346eb8dc403SDave Cobbley raise WicError("bootimg-efi requires a loader, none specified") 347eb8dc403SDave Cobbley 348eb8dc403SDave Cobbley # Create efi.img that contains bootloader files for EFI booting 349eb8dc403SDave Cobbley # if ISODIR didn't exist or didn't contains it 350eb8dc403SDave Cobbley if os.path.isfile("%s/efi.img" % img_iso_dir): 351eb8dc403SDave Cobbley install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \ 352eb8dc403SDave Cobbley (img_iso_dir, isodir) 353eb8dc403SDave Cobbley exec_cmd(install_cmd) 354eb8dc403SDave Cobbley else: 3551d80a2eaSBrad Bishop # Default to 100 blocks of extra space for file system overhead 3561d80a2eaSBrad Bishop esp_extra_blocks = int(source_params.get('esp_extra_blocks', '100')) 3571d80a2eaSBrad Bishop 358eb8dc403SDave Cobbley du_cmd = "du -bks %s/EFI" % isodir 359eb8dc403SDave Cobbley out = exec_cmd(du_cmd) 360eb8dc403SDave Cobbley blocks = int(out.split()[0]) 3611d80a2eaSBrad Bishop blocks += esp_extra_blocks 362eb8dc403SDave Cobbley logger.debug("Added 100 extra blocks to %s to get to %d " 363eb8dc403SDave Cobbley "total blocks", part.mountpoint, blocks) 364eb8dc403SDave Cobbley 365eb8dc403SDave Cobbley # dosfs image for EFI boot 366eb8dc403SDave Cobbley bootimg = "%s/efi.img" % isodir 367eb8dc403SDave Cobbley 3681d80a2eaSBrad Bishop esp_label = source_params.get('esp_label', 'EFIimg') 3691d80a2eaSBrad Bishop 3701d80a2eaSBrad Bishop dosfs_cmd = 'mkfs.vfat -n \'%s\' -S 512 -C %s %d' \ 3711d80a2eaSBrad Bishop % (esp_label, bootimg, blocks) 372eb8dc403SDave Cobbley exec_native_cmd(dosfs_cmd, native_sysroot) 373eb8dc403SDave Cobbley 374eb8dc403SDave Cobbley mmd_cmd = "mmd -i %s ::/EFI" % bootimg 375eb8dc403SDave Cobbley exec_native_cmd(mmd_cmd, native_sysroot) 376eb8dc403SDave Cobbley 377eb8dc403SDave Cobbley mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \ 378eb8dc403SDave Cobbley % (bootimg, isodir) 379eb8dc403SDave Cobbley exec_native_cmd(mcopy_cmd, native_sysroot) 380eb8dc403SDave Cobbley 381eb8dc403SDave Cobbley chmod_cmd = "chmod 644 %s" % bootimg 382eb8dc403SDave Cobbley exec_cmd(chmod_cmd) 383eb8dc403SDave Cobbley 384eb8dc403SDave Cobbley # Prepare files for legacy boot 385eb8dc403SDave Cobbley syslinux_dir = get_bitbake_var("STAGING_DATADIR") 386eb8dc403SDave Cobbley if not syslinux_dir: 387eb8dc403SDave Cobbley raise WicError("Couldn't find STAGING_DATADIR, exiting.") 388eb8dc403SDave Cobbley 389eb8dc403SDave Cobbley if os.path.exists("%s/isolinux" % isodir): 390eb8dc403SDave Cobbley shutil.rmtree("%s/isolinux" % isodir) 391eb8dc403SDave Cobbley 392eb8dc403SDave Cobbley install_cmd = "install -d %s/isolinux" % isodir 393eb8dc403SDave Cobbley exec_cmd(install_cmd) 394eb8dc403SDave Cobbley 395eb8dc403SDave Cobbley cls.do_configure_syslinux(creator, cr_workdir) 396eb8dc403SDave Cobbley 397eb8dc403SDave Cobbley install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir 398eb8dc403SDave Cobbley install_cmd += "%s/isolinux/ldlinux.sys" % isodir 399eb8dc403SDave Cobbley exec_cmd(install_cmd) 400eb8dc403SDave Cobbley 401eb8dc403SDave Cobbley install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir 402eb8dc403SDave Cobbley install_cmd += "%s/isolinux/isohdpfx.bin" % isodir 403eb8dc403SDave Cobbley exec_cmd(install_cmd) 404eb8dc403SDave Cobbley 405eb8dc403SDave Cobbley install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir 406eb8dc403SDave Cobbley install_cmd += "%s/isolinux/isolinux.bin" % isodir 407eb8dc403SDave Cobbley exec_cmd(install_cmd) 408eb8dc403SDave Cobbley 409eb8dc403SDave Cobbley install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir 410eb8dc403SDave Cobbley install_cmd += "%s/isolinux/ldlinux.c32" % isodir 411eb8dc403SDave Cobbley exec_cmd(install_cmd) 412eb8dc403SDave Cobbley 413eb8dc403SDave Cobbley #create ISO image 414eb8dc403SDave Cobbley iso_img = "%s/tempiso_img.iso" % cr_workdir 415eb8dc403SDave Cobbley iso_bootimg = "isolinux/isolinux.bin" 416eb8dc403SDave Cobbley iso_bootcat = "isolinux/boot.cat" 417eb8dc403SDave Cobbley efi_img = "efi.img" 418eb8dc403SDave Cobbley 419eb8dc403SDave Cobbley mkisofs_cmd = "mkisofs -V %s " % part.label 420eb8dc403SDave Cobbley mkisofs_cmd += "-o %s -U " % iso_img 421eb8dc403SDave Cobbley mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg 422eb8dc403SDave Cobbley mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat 423eb8dc403SDave Cobbley mkisofs_cmd += "-boot-info-table -eltorito-alt-boot " 424eb8dc403SDave Cobbley mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img 425eb8dc403SDave Cobbley mkisofs_cmd += "-no-emul-boot %s " % isodir 426eb8dc403SDave Cobbley 427eb8dc403SDave Cobbley logger.debug("running command: %s", mkisofs_cmd) 428eb8dc403SDave Cobbley exec_native_cmd(mkisofs_cmd, native_sysroot) 429eb8dc403SDave Cobbley 430eb8dc403SDave Cobbley shutil.rmtree(isodir) 431eb8dc403SDave Cobbley 432eb8dc403SDave Cobbley du_cmd = "du -Lbks %s" % iso_img 433eb8dc403SDave Cobbley out = exec_cmd(du_cmd) 434eb8dc403SDave Cobbley isoimg_size = int(out.split()[0]) 435eb8dc403SDave Cobbley 436eb8dc403SDave Cobbley part.size = isoimg_size 437eb8dc403SDave Cobbley part.source_file = iso_img 438eb8dc403SDave Cobbley 439eb8dc403SDave Cobbley @classmethod 440eb8dc403SDave Cobbley def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, 441eb8dc403SDave Cobbley bootimg_dir, kernel_dir, native_sysroot): 442eb8dc403SDave Cobbley """ 443eb8dc403SDave Cobbley Called after all partitions have been prepared and assembled into a 444eb8dc403SDave Cobbley disk image. In this case, we insert/modify the MBR using isohybrid 445eb8dc403SDave Cobbley utility for booting via BIOS from disk storage devices. 446eb8dc403SDave Cobbley """ 447eb8dc403SDave Cobbley 448eb8dc403SDave Cobbley iso_img = "%s.p1" % disk.path 449eb8dc403SDave Cobbley full_path = creator._full_path(workdir, disk_name, "direct") 450eb8dc403SDave Cobbley full_path_iso = creator._full_path(workdir, disk_name, "iso") 451eb8dc403SDave Cobbley 452eb8dc403SDave Cobbley isohybrid_cmd = "isohybrid -u %s" % iso_img 453eb8dc403SDave Cobbley logger.debug("running command: %s", isohybrid_cmd) 454eb8dc403SDave Cobbley exec_native_cmd(isohybrid_cmd, native_sysroot) 455eb8dc403SDave Cobbley 456eb8dc403SDave Cobbley # Replace the image created by direct plugin with the one created by 457eb8dc403SDave Cobbley # mkisofs command. This is necessary because the iso image created by 458eb8dc403SDave Cobbley # mkisofs has a very specific MBR is system area of the ISO image, and 459eb8dc403SDave Cobbley # direct plugin adds and configures an another MBR. 460eb8dc403SDave Cobbley logger.debug("Replaceing the image created by direct plugin\n") 461eb8dc403SDave Cobbley os.remove(disk.path) 462eb8dc403SDave Cobbley shutil.copy2(iso_img, full_path_iso) 463eb8dc403SDave Cobbley shutil.copy2(full_path_iso, full_path) 464