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-pcbios' 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 151a4b7ee2SBrad Bishopimport re 16eb8dc403SDave Cobbley 17eb8dc403SDave Cobbleyfrom wic import WicError 18eb8dc403SDave Cobbleyfrom wic.engine import get_custom_config 19eb8dc403SDave Cobbleyfrom wic.pluginbase import SourcePlugin 20eb8dc403SDave Cobbleyfrom wic.misc import (exec_cmd, exec_native_cmd, 21eb8dc403SDave Cobbley get_bitbake_var, BOOTDD_EXTRA_SPACE) 22eb8dc403SDave Cobbley 23eb8dc403SDave Cobbleylogger = logging.getLogger('wic') 24eb8dc403SDave Cobbley 25eb8dc403SDave Cobbleyclass BootimgPcbiosPlugin(SourcePlugin): 26eb8dc403SDave Cobbley """ 27eb8dc403SDave Cobbley Create MBR boot partition and install syslinux on it. 28eb8dc403SDave Cobbley """ 29eb8dc403SDave Cobbley 30eb8dc403SDave Cobbley name = 'bootimg-pcbios' 31eb8dc403SDave Cobbley 32eb8dc403SDave Cobbley @classmethod 33eb8dc403SDave Cobbley def _get_bootimg_dir(cls, bootimg_dir, dirname): 34eb8dc403SDave Cobbley """ 35eb8dc403SDave Cobbley Check if dirname exists in default bootimg_dir or in STAGING_DIR. 36eb8dc403SDave Cobbley """ 371a4b7ee2SBrad Bishop staging_datadir = get_bitbake_var("STAGING_DATADIR") 381a4b7ee2SBrad Bishop for result in (bootimg_dir, staging_datadir): 39eb8dc403SDave Cobbley if os.path.exists("%s/%s" % (result, dirname)): 40eb8dc403SDave Cobbley return result 41eb8dc403SDave Cobbley 421a4b7ee2SBrad Bishop # STAGING_DATADIR is expanded with MLPREFIX if multilib is enabled 431a4b7ee2SBrad Bishop # but dependency syslinux is still populated to original STAGING_DATADIR 441a4b7ee2SBrad Bishop nonarch_datadir = re.sub('/[^/]*recipe-sysroot', '/recipe-sysroot', staging_datadir) 451a4b7ee2SBrad Bishop if os.path.exists(os.path.join(nonarch_datadir, dirname)): 461a4b7ee2SBrad Bishop return nonarch_datadir 471a4b7ee2SBrad Bishop 48eb8dc403SDave Cobbley raise WicError("Couldn't find correct bootimg_dir, exiting") 49eb8dc403SDave Cobbley 50eb8dc403SDave Cobbley @classmethod 51eb8dc403SDave Cobbley def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, 52eb8dc403SDave Cobbley bootimg_dir, kernel_dir, native_sysroot): 53eb8dc403SDave Cobbley """ 54eb8dc403SDave Cobbley Called after all partitions have been prepared and assembled into a 55eb8dc403SDave Cobbley disk image. In this case, we install the MBR. 56eb8dc403SDave Cobbley """ 57eb8dc403SDave Cobbley bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') 58eb8dc403SDave Cobbley mbrfile = "%s/syslinux/" % bootimg_dir 59eb8dc403SDave Cobbley if creator.ptable_format == 'msdos': 60eb8dc403SDave Cobbley mbrfile += "mbr.bin" 61eb8dc403SDave Cobbley elif creator.ptable_format == 'gpt': 62eb8dc403SDave Cobbley mbrfile += "gptmbr.bin" 63eb8dc403SDave Cobbley else: 64eb8dc403SDave Cobbley raise WicError("Unsupported partition table: %s" % 65eb8dc403SDave Cobbley creator.ptable_format) 66eb8dc403SDave Cobbley 67eb8dc403SDave Cobbley if not os.path.exists(mbrfile): 68eb8dc403SDave Cobbley raise WicError("Couldn't find %s. If using the -e option, do you " 69eb8dc403SDave Cobbley "have the right MACHINE set in local.conf? If not, " 70eb8dc403SDave Cobbley "is the bootimg_dir path correct?" % mbrfile) 71eb8dc403SDave Cobbley 72eb8dc403SDave Cobbley full_path = creator._full_path(workdir, disk_name, "direct") 73eb8dc403SDave Cobbley logger.debug("Installing MBR on disk %s as %s with size %s bytes", 74eb8dc403SDave Cobbley disk_name, full_path, disk.min_size) 75eb8dc403SDave Cobbley 76eb8dc403SDave Cobbley dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path) 77eb8dc403SDave Cobbley exec_cmd(dd_cmd, native_sysroot) 78eb8dc403SDave Cobbley 79eb8dc403SDave Cobbley @classmethod 80eb8dc403SDave Cobbley def do_configure_partition(cls, part, source_params, creator, cr_workdir, 81eb8dc403SDave Cobbley oe_builddir, bootimg_dir, kernel_dir, 82eb8dc403SDave Cobbley native_sysroot): 83eb8dc403SDave Cobbley """ 84eb8dc403SDave Cobbley Called before do_prepare_partition(), creates syslinux config 85eb8dc403SDave Cobbley """ 86eb8dc403SDave Cobbley hdddir = "%s/hdd/boot" % cr_workdir 87eb8dc403SDave Cobbley 88eb8dc403SDave Cobbley install_cmd = "install -d %s" % hdddir 89eb8dc403SDave Cobbley exec_cmd(install_cmd) 90eb8dc403SDave Cobbley 91eb8dc403SDave Cobbley bootloader = creator.ks.bootloader 92eb8dc403SDave Cobbley 93eb8dc403SDave Cobbley custom_cfg = None 94eb8dc403SDave Cobbley if bootloader.configfile: 95eb8dc403SDave Cobbley custom_cfg = get_custom_config(bootloader.configfile) 96eb8dc403SDave Cobbley if custom_cfg: 97eb8dc403SDave Cobbley # Use a custom configuration for grub 98eb8dc403SDave Cobbley syslinux_conf = custom_cfg 99eb8dc403SDave Cobbley logger.debug("Using custom configuration file %s " 100eb8dc403SDave Cobbley "for syslinux.cfg", bootloader.configfile) 101eb8dc403SDave Cobbley else: 102eb8dc403SDave Cobbley raise WicError("configfile is specified but failed to " 103eb8dc403SDave Cobbley "get it from %s." % bootloader.configfile) 104eb8dc403SDave Cobbley 105eb8dc403SDave Cobbley if not custom_cfg: 106eb8dc403SDave Cobbley # Create syslinux configuration using parameters from wks file 107eb8dc403SDave Cobbley splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg") 108eb8dc403SDave Cobbley if os.path.exists(splash): 109eb8dc403SDave Cobbley splashline = "menu background splash.jpg" 110eb8dc403SDave Cobbley else: 111eb8dc403SDave Cobbley splashline = "" 112eb8dc403SDave Cobbley 113eb8dc403SDave Cobbley syslinux_conf = "" 114eb8dc403SDave Cobbley syslinux_conf += "PROMPT 0\n" 115eb8dc403SDave Cobbley syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n" 116eb8dc403SDave Cobbley syslinux_conf += "\n" 117eb8dc403SDave Cobbley syslinux_conf += "ALLOWOPTIONS 1\n" 118eb8dc403SDave Cobbley syslinux_conf += "SERIAL 0 115200\n" 119eb8dc403SDave Cobbley syslinux_conf += "\n" 120eb8dc403SDave Cobbley if splashline: 121eb8dc403SDave Cobbley syslinux_conf += "%s\n" % splashline 122eb8dc403SDave Cobbley syslinux_conf += "DEFAULT boot\n" 123eb8dc403SDave Cobbley syslinux_conf += "LABEL boot\n" 124eb8dc403SDave Cobbley 125*028142bdSAndrew Geissler kernel = "/" + get_bitbake_var("KERNEL_IMAGETYPE") 126eb8dc403SDave Cobbley syslinux_conf += "KERNEL " + kernel + "\n" 127eb8dc403SDave Cobbley 128eb8dc403SDave Cobbley syslinux_conf += "APPEND label=boot root=%s %s\n" % \ 129eb8dc403SDave Cobbley (creator.rootdev, bootloader.append) 130eb8dc403SDave Cobbley 131eb8dc403SDave Cobbley logger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg", 132eb8dc403SDave Cobbley cr_workdir) 133eb8dc403SDave Cobbley cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w") 134eb8dc403SDave Cobbley cfg.write(syslinux_conf) 135eb8dc403SDave Cobbley cfg.close() 136eb8dc403SDave Cobbley 137eb8dc403SDave Cobbley @classmethod 138eb8dc403SDave Cobbley def do_prepare_partition(cls, part, source_params, creator, cr_workdir, 139eb8dc403SDave Cobbley oe_builddir, bootimg_dir, kernel_dir, 140eb8dc403SDave Cobbley rootfs_dir, native_sysroot): 141eb8dc403SDave Cobbley """ 142eb8dc403SDave Cobbley Called to do the actual content population for a partition i.e. it 143eb8dc403SDave Cobbley 'prepares' the partition to be incorporated into the image. 144eb8dc403SDave Cobbley In this case, prepare content for legacy bios boot partition. 145eb8dc403SDave Cobbley """ 146eb8dc403SDave Cobbley bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') 147eb8dc403SDave Cobbley 148eb8dc403SDave Cobbley staging_kernel_dir = kernel_dir 149eb8dc403SDave Cobbley 150eb8dc403SDave Cobbley hdddir = "%s/hdd/boot" % cr_workdir 151eb8dc403SDave Cobbley 15215ae2509SBrad Bishop kernel = get_bitbake_var("KERNEL_IMAGETYPE") 15396ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": 15496ff1984SBrad Bishop if get_bitbake_var("INITRAMFS_IMAGE"): 15596ff1984SBrad Bishop kernel = "%s-%s.bin" % \ 15696ff1984SBrad Bishop (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) 15715ae2509SBrad Bishop 158*028142bdSAndrew Geissler cmds = ("install -m 0644 %s/%s %s/%s" % 159*028142bdSAndrew Geissler (staging_kernel_dir, kernel, hdddir, get_bitbake_var("KERNEL_IMAGETYPE")), 160eb8dc403SDave Cobbley "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" % 161eb8dc403SDave Cobbley (bootimg_dir, hdddir), 162eb8dc403SDave Cobbley "install -m 0644 %s/syslinux/vesamenu.c32 %s/vesamenu.c32" % 163eb8dc403SDave Cobbley (bootimg_dir, hdddir), 164eb8dc403SDave Cobbley "install -m 444 %s/syslinux/libcom32.c32 %s/libcom32.c32" % 165eb8dc403SDave Cobbley (bootimg_dir, hdddir), 166eb8dc403SDave Cobbley "install -m 444 %s/syslinux/libutil.c32 %s/libutil.c32" % 167eb8dc403SDave Cobbley (bootimg_dir, hdddir)) 168eb8dc403SDave Cobbley 169eb8dc403SDave Cobbley for install_cmd in cmds: 170eb8dc403SDave Cobbley exec_cmd(install_cmd) 171eb8dc403SDave Cobbley 172eb8dc403SDave Cobbley du_cmd = "du -bks %s" % hdddir 173eb8dc403SDave Cobbley out = exec_cmd(du_cmd) 174eb8dc403SDave Cobbley blocks = int(out.split()[0]) 175eb8dc403SDave Cobbley 176eb8dc403SDave Cobbley extra_blocks = part.get_extra_block_count(blocks) 177eb8dc403SDave Cobbley 178eb8dc403SDave Cobbley if extra_blocks < BOOTDD_EXTRA_SPACE: 179eb8dc403SDave Cobbley extra_blocks = BOOTDD_EXTRA_SPACE 180eb8dc403SDave Cobbley 181eb8dc403SDave Cobbley blocks += extra_blocks 182eb8dc403SDave Cobbley 183eb8dc403SDave Cobbley logger.debug("Added %d extra blocks to %s to get to %d total blocks", 184eb8dc403SDave Cobbley extra_blocks, part.mountpoint, blocks) 185eb8dc403SDave Cobbley 186eb8dc403SDave Cobbley # dosfs image, created by mkdosfs 187eb8dc403SDave Cobbley bootimg = "%s/boot%s.img" % (cr_workdir, part.lineno) 188eb8dc403SDave Cobbley 1895f35090dSAndrew Geissler label = part.label if part.label else "boot" 1905f35090dSAndrew Geissler 1915f35090dSAndrew Geissler dosfs_cmd = "mkdosfs -n %s -i %s -S 512 -C %s %d" % \ 1925f35090dSAndrew Geissler (label, part.fsuuid, bootimg, blocks) 193eb8dc403SDave Cobbley exec_native_cmd(dosfs_cmd, native_sysroot) 194eb8dc403SDave Cobbley 195eb8dc403SDave Cobbley mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) 196eb8dc403SDave Cobbley exec_native_cmd(mcopy_cmd, native_sysroot) 197eb8dc403SDave Cobbley 198eb8dc403SDave Cobbley syslinux_cmd = "syslinux %s" % bootimg 199eb8dc403SDave Cobbley exec_native_cmd(syslinux_cmd, native_sysroot) 200eb8dc403SDave Cobbley 201eb8dc403SDave Cobbley chmod_cmd = "chmod 644 %s" % bootimg 202eb8dc403SDave Cobbley exec_cmd(chmod_cmd) 203eb8dc403SDave Cobbley 204eb8dc403SDave Cobbley du_cmd = "du -Lbks %s" % bootimg 205eb8dc403SDave Cobbley out = exec_cmd(du_cmd) 206eb8dc403SDave Cobbley bootimg_size = out.split()[0] 207eb8dc403SDave Cobbley 208eb8dc403SDave Cobbley part.size = int(bootimg_size) 209eb8dc403SDave Cobbley part.source_file = bootimg 210