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