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