def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called after all partitions have been prepared and assembled into a disk image. In this case, we install the MBR. """ bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') mbrfile = "%s/syslinux/" % bootimg_dir mbrfile += "mbr.bin" full_path = creator._full_path(workdir, disk_name, "direct") logger.debug("Installing MBR on disk %s as %s with size %s bytes", disk_name, full_path, disk.min_size) device_map_path = "%s/device.map" % workdir device_map_content = "(hd0) %s" % full_path with open(device_map_path, 'w') as file: file.write(device_map_content) dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path) exec_cmd(dd_cmd, native_sysroot) grub_dir = "%s/hdd/boot/grub/i386-pc" % workdir cmd_bios_setup = 'grub-bios-setup -v --device-map=%s -r "hd0,msdos1" -d %s %s' % ( device_map_path, grub_dir, full_path ) exec_cmd(cmd_bios_setup, native_sysroot)
def finalize(self): """ Finalize the disk image. For example, prepare the image to be bootable by e.g. creating and installing a bootloader configuration. """ source_plugin = self.ks.bootloader.source disk_name = self.parts[0].disk if source_plugin: plugin = PluginMgr.get_plugins('source')[source_plugin] plugin.do_install_disk(self._image, disk_name, self, self.workdir, self.oe_builddir, self.bootimg_dir, self.kernel_dir, self.native_sysroot) full_path = self._image.path # Generate .bmap if self.bmap: logger.debug("Generating bmap file for %s", disk_name) python = os.path.join(self.native_sysroot, 'usr/bin/python3-native/python3') bmaptool = os.path.join(self.native_sysroot, 'usr/bin/bmaptool') exec_native_cmd("%s %s create %s -o %s.bmap" % \ (python, bmaptool, full_path, full_path), self.native_sysroot) # Compress the image if self.compressor: logger.debug("Compressing disk %s with %s", disk_name, self.compressor) exec_cmd("%s %s" % (self.compressor, full_path))
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): hdddir = "%s/hdd/modules" % cr_workdir install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd)
def copy(self, src, pnum, path): """Copy partition image into wic image.""" cmd = "{} -i {} -snop {} ::{}".format(self.mcopy, self._get_part_image(pnum), src, path) exec_cmd(cmd) self._put_part_image(pnum)
def prepare_rootfs_msdos(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, native_sysroot, pseudo): """ Prepare content for a msdos/vfat rootfs partition. """ du_cmd = "du -bks %s" % rootfs_dir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) rootfs_size = self.get_rootfs_size(blocks) label_str = "-n boot" if self.label: label_str = "-n %s" % self.label size_str = "" extraopts = self.mkfs_extraopts or '-S 512' dosfs_cmd = "mkdosfs %s -i %s %s %s -C %s %d" % \ (label_str, self.fsuuid, size_str, extraopts, rootfs, rootfs_size) exec_native_cmd(dosfs_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) exec_native_cmd(mcopy_cmd, native_sysroot) if self.updated_fstab_path and self.has_fstab and not self.no_fstab_update: mcopy_cmd = "mcopy -i %s %s ::/etc/fstab" % ( rootfs, self.updated_fstab_path) exec_native_cmd(mcopy_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % rootfs exec_cmd(chmod_cmd)
def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo): """ Prepare content for a msdos/vfat rootfs partition. """ du_cmd = "du -bks %s" % rootfs_dir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) rootfs_size = self.get_rootfs_size(blocks) label_str = "-n boot" if self.label: label_str = "-n %s" % self.label size_str = "" if self.fstype == 'msdos': size_str = "-F 16" # FAT 16 extraopts = self.mkfs_extraopts or '-S 512' dosfs_cmd = "mkdosfs %s %s %s -C %s %d" % \ (label_str, size_str, extraopts, rootfs, rootfs_size) exec_native_cmd(dosfs_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) exec_native_cmd(mcopy_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % rootfs exec_cmd(chmod_cmd)
def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called after all partitions have been prepared and assembled into a disk image. In this case, we install the MBR. """ bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') mbrfile = "%s/syslinux/" % bootimg_dir if creator.ptable_format == 'msdos': mbrfile += "mbr.bin" elif creator.ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: raise WicError("Unsupported partition table: %s" % creator.ptable_format) if not os.path.exists(mbrfile): raise WicError("Couldn't find %s. If using the -e option, do you " "have the right MACHINE set in local.conf? If not, " "is the bootimg_dir path correct?" % mbrfile) full_path = creator._full_path(workdir, disk_name, "direct") logger.debug("Installing MBR on disk %s as %s with size %s bytes", disk_name, full_path, disk.min_size) dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path) exec_cmd(dd_cmd, native_sysroot)
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates loader-specific config """ hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -d %s/EFI/BOOT" % hdddir exec_cmd(install_cmd) try: if source_params['loader'] == 'grub-efi': cls.do_configure_grubefi(hdddir, creator, cr_workdir, source_params) elif source_params['loader'] == 'systemd-boot': cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params) else: raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) except KeyError: raise WicError("bootimg-efi requires a loader, none specified") if source_params['version']: install_cmd = "install -d %s/aos" % hdddir exec_cmd(install_cmd) version = open("%s/hdd/boot/aos/version" % cr_workdir, "w") version.write('VERSION = "%s"\n' % source_params['version']) version.close()
def write_ptable(parts, target): with tempfile.NamedTemporaryFile(prefix="wic-sfdisk-", mode='w') as outf: write_sfdisk_script(outf, parts) cmd = "{} --no-reread {} < {} ".format(self.sfdisk, target, outf.name) exec_cmd(cmd, as_shell=True)
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates loader-specific config """ hdddir = "%s/hdd/%s.%s" % (cr_workdir, part.label, part.lineno) install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) bootloader = creator.ks.bootloader cmdline = "root=%s %s\n" % \ (creator.rootdev, bootloader.append) cwd = os.getcwd() os.chdir(hdddir) config_cmd = 'bg_setenv -f . -k "C:%s:bzImage" -a "%s" -r %s -w %s' % \ (part.label.upper(), \ cmdline.strip(), \ source_params.get("revision", 1), \ source_params.get("watchdog", 5)) exec_native_cmd(config_cmd, native_sysroot) os.chdir(cwd)
def copy(self, src, dest): """Copy partition image into wic image.""" pnum = dest.part if isinstance(src, str) else src.part if self.partitions[pnum].fstype.startswith('ext'): if isinstance(src, str): cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\ format(os.path.dirname(dest.path), src, os.path.basename(src), self.debugfs, self._get_part_image(pnum)) else: # copy from wic # run both dump and rdump to support both files and directory cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | {} {}".\ format(os.path.dirname(src.path), src.path, dest, src.path, dest, self.debugfs, self._get_part_image(pnum)) else: # fat if isinstance(src, str): cmd = "{} -i {} -snop {} ::{}".format( self.mcopy, self._get_part_image(pnum), src, dest.path) else: cmd = "{} -i {} -snop ::{} {}".format( self.mcopy, self._get_part_image(pnum), src.path, dest) exec_cmd(cmd, as_shell=True) self._put_part_image(pnum)
def do_prepare_partition(cls, part, source_params, cr, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): """ Called to do the actual content population for a partition i.e. it 'prepares' the partition to be incorporated into the image. In this case, does the following: - sets up a vfat partition - copies all files listed in IMAGE_BOOT_FILES variable """ hdddir = "%s/boot.%d" % (cr_workdir, part.lineno) if not kernel_dir: kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not kernel_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") logger.debug('Kernel dir: %s', bootimg_dir) for task in cls.install_task: src_path, dst_path = task logger.debug('Install %s as %s', src_path, dst_path) install_cmd = "install -m 0644 -D %s %s" \ % (os.path.join(kernel_dir, src_path), os.path.join(hdddir, dst_path)) exec_cmd(install_cmd) logger.debug('Prepare boot partition using rootfs in %s', hdddir) part.prepare_rootfs(cr_workdir, oe_builddir, hdddir, native_sysroot, False)
def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called after all partitions have been prepared and assembled into a disk image. In this case, we install the MBR. """ syslinux_dir = cls._get_syslinux_dir(bootimg_dir) if creator.ptable_format == 'msdos': mbrfile = os.path.join(syslinux_dir, "mbr/mbr.bin") elif creator.ptable_format == 'gpt': mbrfile = os.path.join(syslinux_dir, "mbr/gptmbr.bin") else: raise WicError("Unsupported partition table: %s" % creator.ptable_format) if not os.path.exists(mbrfile): raise WicError( "Couldn't find %s. If using the -e option, do you " "have the right MACHINE set in local.conf? If not, " "is the bootimg_dir path correct?" % mbrfile) full_path = creator._full_path(workdir, disk_name, "direct") logger.debug("Installing MBR on disk %s as %s with size %s bytes", disk_name, full_path, disk.min_size) dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path) exec_cmd(dd_cmd, native_sysroot)
def prepare_empty_partition_msdos(self, rootfs, oe_builddir, native_sysroot): """ Prepare an empty vfat partition. """ blocks = self.disk_size label_str = "-n boot" if self.label: label_str = "-n %s" % self.label size_str = "" if self.fstype == 'msdos': size_str = "-F 16" # FAT 16 extraopts = self.mkfs_extraopts or '-S 512' dosfs_cmd = "mkdosfs %s -i %s %s %s -C %s %d" % \ (label_str, self.fsuuid, extraopts, size_str, rootfs, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % rootfs exec_cmd(chmod_cmd)
def dir(self, pnum, path): if self.partitions[pnum].fstype.startswith('ext'): return exec_cmd("{} {} -R 'ls -l {}'".format(self.debugfs, self._get_part_image(pnum), path), as_shell=True) else: # fat return exec_cmd("{} -i {} ::{}".format(self.mdir, self._get_part_image(pnum), path))
def do_install_core_image(cls, grubdir, native_sysroot): """ Create the core image in the grub directory. """ grub_modules = "at_keyboard biosdisk boot chain configfile ext2 fat linux ls part_msdos reboot serial vga" cmd_mkimage = "grub-mkimage -p %s -d %s/i386-pc -o %s/i386-pc/core.img -O i386-pc %s" % ( "(hd0,msdos1)/grub", grubdir, grubdir, grub_modules) exec_cmd(cmd_mkimage)
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates syslinux config """ hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) bootloader = creator.ks.bootloader custom_cfg = None if bootloader.configfile: custom_cfg = get_custom_config(bootloader.configfile) if custom_cfg: # Use a custom configuration for grub syslinux_conf = custom_cfg logger.debug( "Using custom configuration file %s " "for syslinux.cfg", bootloader.configfile) else: raise WicError("configfile is specified but failed to " "get it from %s." % bootloader.configfile) if not custom_cfg: # Create syslinux configuration using parameters from wks file splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg") if os.path.exists(splash): splashline = "menu background splash.jpg" else: splashline = "" syslinux_conf = "" syslinux_conf += "PROMPT 0\n" syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n" syslinux_conf += "\n" syslinux_conf += "ALLOWOPTIONS 1\n" syslinux_conf += "SERIAL 0 115200\n" syslinux_conf += "\n" if splashline: syslinux_conf += "%s\n" % splashline syslinux_conf += "DEFAULT boot\n" syslinux_conf += "LABEL boot\n" kernel = "/vmlinuz" syslinux_conf += "KERNEL " + kernel + "\n" syslinux_conf += "APPEND label=boot root=%s %s\n" % \ (creator.rootdev, bootloader.append) logger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg", cr_workdir) cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w") cfg.write(syslinux_conf) cfg.close()
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates syslinux config """ hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) bootloader = creator.ks.bootloader custom_cfg = None if bootloader.configfile: custom_cfg = get_custom_config(bootloader.configfile) if custom_cfg: # Use a custom configuration for grub syslinux_conf = custom_cfg logger.debug("Using custom configuration file %s " "for syslinux.cfg", bootloader.configfile) else: raise WicError("configfile is specified but failed to " "get it from %s." % bootloader.configfile) if not custom_cfg: # Create syslinux configuration using parameters from wks file splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg") if os.path.exists(splash): splashline = "menu background splash.jpg" else: splashline = "" syslinux_conf = "" syslinux_conf += "PROMPT 0\n" syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n" syslinux_conf += "\n" syslinux_conf += "ALLOWOPTIONS 1\n" syslinux_conf += "SERIAL 0 115200\n" syslinux_conf += "\n" if splashline: syslinux_conf += "%s\n" % splashline syslinux_conf += "DEFAULT boot\n" syslinux_conf += "LABEL boot\n" kernel = "/vmlinuz" syslinux_conf += "KERNEL " + kernel + "\n" syslinux_conf += "APPEND label=boot root=%s %s\n" % \ (creator.rootdev, bootloader.append) logger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg", cr_workdir) cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w") cfg.write(syslinux_conf) cfg.close()
def do_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params): """ Create loader-specific (grub-efi) config """ configfile = creator.ks.bootloader.configfile custom_cfg = None if configfile: custom_cfg = get_custom_config(configfile) if custom_cfg: # Use a custom configuration for grub grubefi_conf = custom_cfg logger.debug( "Using custom configuration file " "%s for grub.cfg", configfile) else: raise WicError("configfile is specified but failed to " "get it from %s." % configfile) initrd = source_params.get('initrd') if initrd: bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not bootimg_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") cp_cmd = "cp %s/%s %s" % (bootimg_dir, initrd, hdddir) exec_cmd(cp_cmd, True) else: logger.debug("Ignoring missing initrd") if not custom_cfg: # Create grub configuration using parameters from wks file bootloader = creator.ks.bootloader title = source_params.get('title') grubefi_conf = "" grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" grubefi_conf += "default=boot\n" grubefi_conf += "timeout=%s\n" % bootloader.timeout grubefi_conf += "menuentry '%s'{\n" % (title if title else "boot") kernel = "/bzImage" grubefi_conf += "linux %s root=%s rootwait %s\n" \ % (kernel, creator.rootdev, bootloader.append) if initrd: grubefi_conf += "initrd /%s\n" % initrd grubefi_conf += "}\n" logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg", cr_workdir) cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") cfg.write(grubefi_conf) cfg.close()
def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, native_sysroot, real_rootfs=True, pseudo_dir=None): """ Prepare content for a rootfs partition i.e. create a partition and fill it from a /rootfs dir. Currently handles ext2/3/4, btrfs, vfat and squashfs. """ p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) if (pseudo_dir): pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir pseudo += "export PSEUDO_NOSYMLINKEXP=1;" pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") else: pseudo = None rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label, self.lineno, self.fstype) if os.path.isfile(rootfs): os.remove(rootfs) if not self.size and real_rootfs: # The rootfs size is not set in .ks file so try to get it # from bitbake variable rsize_bb = get_bitbake_var('ROOTFS_SIZE') rdir = get_bitbake_var('IMAGE_ROOTFS') if rsize_bb and rdir == rootfs_dir: # Bitbake variable ROOTFS_SIZE is calculated in # Image._get_rootfs_size method from meta/lib/oe/image.py # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT, # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE self.size = int(round(float(rsize_bb))) else: # Bitbake variable ROOTFS_SIZE is not defined so compute it # from the rootfs_dir size using the same logic found in # get_rootfs_size() from meta/classes/image.bbclass du_cmd = "du -ks %s" % rootfs_dir out = exec_cmd(du_cmd) self.size = int(out.split()[0]) prefix = "ext" if self.fstype.startswith("ext") else self.fstype method = getattr(self, "prepare_rootfs_" + prefix) method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo) self.source_file = rootfs # get the rootfs size in the right units for kickstart (kB) du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) self.size = int(out.split()[0])
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates loader specific config """ hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -d %s/grub" % hdddir exec_cmd(install_cmd) cls.do_configure_grub_legacy(hdddir, creator, cr_workdir, source_params)
def _build_initramfs_path(rootfs_dir, cr_workdir): """ Create path for initramfs image """ initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD") if not initrd: initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not initrd_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.") image_name = get_bitbake_var("IMAGE_BASENAME") if not image_name: raise WicError("Couldn't find IMAGE_BASENAME, exiting.") image_type = get_bitbake_var("INITRAMFS_FSTYPES") if not image_type: raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.") machine = os.path.basename(initrd_dir) pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type) files = glob.glob(pattern) if files: initrd = files[0] if not initrd or not os.path.exists(initrd): # Create initrd from rootfs directory initrd = "%s/initrd.cpio.gz" % cr_workdir initrd_dir = "%s/INITRD" % cr_workdir shutil.copytree("%s" % rootfs_dir, \ "%s" % initrd_dir, symlinks=True) if os.path.isfile("%s/init" % rootfs_dir): shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir) elif os.path.lexists("%s/init" % rootfs_dir): os.symlink(os.readlink("%s/init" % rootfs_dir), \ "%s/init" % initrd_dir) elif os.path.isfile("%s/sbin/init" % rootfs_dir): shutil.copy2("%s/sbin/init" % rootfs_dir, \ "%s" % initrd_dir) elif os.path.lexists("%s/sbin/init" % rootfs_dir): os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \ "%s/init" % initrd_dir) else: raise WicError("Couldn't find or build initrd, exiting.") exec_cmd("cd %s && find . | cpio -o -H newc -R +0:+0 >./initrd.cpio " \ % initrd_dir, as_shell=True) exec_cmd("gzip -f -9 -c %s/initrd.cpio > %s" \ % (cr_workdir, initrd), as_shell=True) shutil.rmtree(initrd_dir) return initrd
def do_configure_partition(cls, part, source_params, cr, cr_workdir, oe_builddir, bootimg_dir, deploy_dir_image, native_sysroot): """ Called before do_prepare_partition(), create u-boot specific boot config """ hdddir = "%s/boot.%d" % (cr_workdir, part.lineno) install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) if not deploy_dir_image: deploy_dir_image = get_bitbake_var("DEPLOY_DIR_IMAGE") if not deploy_dir_image: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") part_files = source_params.get("files") logger.debug('%s files files: %s', part, part_files) # list of tuples (src_name, dst_name) deploy_files = [] for src_entry in re.findall(r'[\w;\-\./\*]+', part_files): if ';' in src_entry: dst_entry = tuple(src_entry.split(';')) if not dst_entry[0] or not dst_entry[1]: raise WicError('Malformed boot file entry: %s' % src_entry) else: dst_entry = (src_entry, src_entry) logger.debug('Destination entry: %r', dst_entry) deploy_files.append(dst_entry) cls.install_task = [] for deploy_entry in deploy_files: src, dst = deploy_entry if '*' in src: # by default install files under their basename entry_name_fn = os.path.basename if dst != src: # unless a target name was given, then treat name # as a directory and append a basename entry_name_fn = lambda name: \ os.path.join(dst, os.path.basename(name)) srcs = glob(os.path.join(deploy_dir_image, src)) logger.debug('Globbed sources: %s', ', '.join(srcs)) for entry in srcs: src = os.path.relpath(entry, deploy_dir_image) entry_dst_name = entry_name_fn(entry) cls.install_task.append((src, entry_dst_name)) else: cls.install_task.append((src, dst))
def do_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params): """ Create loader-specific (grub-efi) config """ configfile = creator.ks.bootloader.configfile custom_cfg = None if configfile: custom_cfg = get_custom_config(configfile) if custom_cfg: # Use a custom configuration for grub grubefi_conf = custom_cfg logger.debug("Using custom configuration file " "%s for grub.cfg", configfile) else: raise WicError("configfile is specified but failed to " "get it from %s." % configfile) initrd = source_params.get('initrd') if initrd: bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not bootimg_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") cp_cmd = "cp %s/%s %s" % (bootimg_dir, initrd, hdddir) exec_cmd(cp_cmd, True) else: logger.debug("Ignoring missing initrd") if not custom_cfg: # Create grub configuration using parameters from wks file bootloader = creator.ks.bootloader grubefi_conf = "" grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" grubefi_conf += "default=boot\n" grubefi_conf += "timeout=%s\n" % bootloader.timeout grubefi_conf += "menuentry 'boot'{\n" kernel = "/bzImage" grubefi_conf += "linux %s root=%s rootwait %s\n" \ % (kernel, creator.rootdev, bootloader.append) if initrd: grubefi_conf += "initrd /%s\n" % initrd grubefi_conf += "}\n" logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg", cr_workdir) cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") cfg.write(grubefi_conf) cfg.close()
def copy(self, src, pnum, path): """Copy partition image into wic image.""" if self.partitions[pnum].fstype.startswith('ext'): cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\ format(path, src, os.path.basename(src), self.debugfs, self._get_part_image(pnum)) else: # fat cmd = "{} -i {} -snop {} ::{}".format(self.mcopy, self._get_part_image(pnum), src, path) exec_cmd(cmd, as_shell=True) self._put_part_image(pnum)
def dir(self, pnum, path): if pnum not in self.partitions: raise WicError("Partition %s is not in the image" % pnum) if self.partitions[pnum].fstype.startswith('ext'): return exec_cmd("{} {} -R 'ls -l {}'".format( self.debugfs, self._get_part_image(pnum), path), as_shell=True) else: # fat return exec_cmd("{} -i {} ::{}".format(self.mdir, self._get_part_image(pnum), path))
def copy(self, src, pnum, path): """Copy partition image into wic image.""" if self.partitions[pnum].fstype.startswith('ext'): cmd = "echo -e 'cd {}\nwrite {} {}' | {} -w {}".\ format(path, src, os.path.basename(src), self.debugfs, self._get_part_image(pnum)) else: # fat cmd = "{} -i {} -snop {} ::{}".format(self.mcopy, self._get_part_image(pnum), src, path) exec_cmd(cmd, as_shell=True) self._put_part_image(pnum)
def do_prepare_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): """ Called to do the actual content population for a partition i.e. it 'prepares' the partition to be incorporated into the image. In this case, prepare content for an EFI (grub) boot partition. """ if not bootimg_dir: bootimg_dir = get_bitbake_var("HDDDIR") if not bootimg_dir: msger.error("HDDDIR not set, exiting\n") staging_kernel_dir = kernel_dir hdddir = "%s/hdd/%s.%s" % (cr_workdir, part.label, part.lineno) install_cmd = "install -d %s/EFI/BOOT" % hdddir exec_cmd(install_cmd) cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir) exec_cmd(cp_cmd, True) # Calculate the number of extra blocks to be sure that the # resulting partition image is of the wanted size du_cmd = "du -bks %s" % hdddir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) extra_blocks = part.get_extra_block_count(blocks) if extra_blocks < BOOTDD_EXTRA_SPACE: extra_blocks = BOOTDD_EXTRA_SPACE blocks += extra_blocks msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \ (extra_blocks, part.mountpoint, blocks)) # dosfs image, created by mkdosfs efiimg = "%s/%s.%s.img" % (cr_workdir, part.label, part.lineno) dosfs_cmd = "mkdosfs -n %s -C %s %d" % (part.label.upper(), efiimg, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (efiimg, hdddir) exec_native_cmd(mcopy_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % efiimg exec_cmd(chmod_cmd) du_cmd = "du -Lbks %s" % efiimg out = exec_cmd(du_cmd) efiimg_size = out.split()[0] part.size = int(efiimg_size) part.source_file = efiimg
def remove(self, pnum, path): """Remove files/dirs from the partition.""" partimg = self._get_part_image(pnum) cmd = "{} -i {} ::{}".format(self.mdel, partimg, path) try: exec_cmd(cmd) except WicError as err: if "not found" in str(err) or "non empty" in str(err): # mdel outputs 'File ... not found' or 'directory .. non empty" # try to use mdeltree as path could be a directory cmd = "{} -i {} ::{}".format(self.mdeltree, partimg, path) exec_cmd(cmd) else: raise err self._put_part_image(pnum)
def do_configure_grub_legacy(cls, hdddir, creator, cr_workdir, source_params): """ Check if custom config exists in deploy dir, if not create config file. """ # Create config file bootloader = creator.ks.bootloader hdddir = "%s/hdd/boot/grub" % cr_workdir install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") grub_cfg_dir = "%s/%s" % (deploy_dir, "grub.cfg") if os.path.exists(grub_cfg_dir): shutil.copyfile(grub_cfg_dir, "%s/grub.cfg" % hdddir) else: grub_conf = "" grub_conf += "serial --unit=0 --speed=115200\n" grub_conf += "terminal --timeout=%s serial\n" % bootloader.timeout grub_conf += "default=boot\n" grub_conf += "menuentry 'boot' {\n" kernel = "/bzImage" rootdev = "/dev/sda2" serial = "console=ttyS0,115200 earlyprintk=serial,ttyS0,115200" grub_conf += "linux %s root=%s %s\n" \ % (kernel, rootdev, serial) initrd = source_params.get('initrd') if initrd: grub_conf += "initrd /%s\n" % initrd grub_conf += "}\n" logger.debug("Writing grub config %s/hdd/boot/grub/grub.cfg", cr_workdir) cfg = open("%s/hdd/boot/grub/grub.cfg" % cr_workdir, "w") cfg.write(grub_conf) cfg.close() # Check if custom grubenv file exists grubenv_dir = "%s/%s" % (deploy_dir, "grubenv") if os.path.exists(grubenv_dir): shutil.copyfile(grubenv_dir, "%s/grubenv" % hdddir)
def do_image_label(fstype, dst, label): if fstype.startswith('ext'): cmd = 'tune2fs -L %s %s' % (label, dst) elif fstype in ('msdos', 'vfat'): cmd = 'dosfslabel %s %s' % (dst, label) elif fstype == 'btrfs': cmd = 'btrfs filesystem label %s %s' % (dst, label) elif fstype == 'swap': cmd = 'mkswap -L %s %s' % (label, dst) elif fstype == 'squashfs': raise WicError("It's not possible to update a squashfs " "filesystem label '%s'" % (label)) else: raise WicError("Cannot update filesystem label: " "Unknown fstype: '%s'" % (fstype)) exec_cmd(cmd)
def prepare_rootfs_ext(self, rootfs, cr_workdir, oe_builddir, rootfs_dir, native_sysroot, pseudo): """ Prepare content for an ext2/3/4 rootfs partition. """ du_cmd = "du -ks %s" % rootfs_dir out = exec_cmd(du_cmd) actual_rootfs_size = int(out.split()[0]) rootfs_size = self.get_rootfs_size(actual_rootfs_size) with open(rootfs, 'w') as sparse: os.ftruncate(sparse.fileno(), rootfs_size * 1024) extraopts = self.mkfs_extraopts or "-F -i 8192" label_str = "" if self.label: label_str = "-L %s" % self.label mkfs_cmd = "mkfs.%s %s %s %s -U %s -d %s" % \ (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) if self.updated_fstab_path and self.has_fstab: debugfs_script_path = os.path.join(cr_workdir, "debugfs_script") with open(debugfs_script_path, "w") as f: f.write("cd etc\n") f.write("rm fstab\n") f.write("write %s fstab\n" % (self.updated_fstab_path)) debugfs_cmd = "debugfs -w -f %s %s" % (debugfs_script_path, rootfs) exec_native_cmd(debugfs_cmd, native_sysroot) mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
def do_prepare_partition(cls, part, source_params, cr, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): """ Called to do the actual content population for a partition i.e. it 'prepares' the partition to be incorporated into the image. """ if not kernel_dir: kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not kernel_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") logger.debug('Kernel dir: %s', kernel_dir) if 'file' not in source_params: raise WicError("No file specified") src = os.path.join(kernel_dir, source_params['file']) dst = os.path.join(cr_workdir, "%s.%s" % (source_params['file'], part.lineno)) if 'skip' in source_params: sparse_copy(src, dst, skip=int(source_params['skip'])) else: sparse_copy(src, dst) # get the size in the right units for kickstart (kB) du_cmd = "du -Lbks %s" % dst out = exec_cmd(du_cmd) filesize = int(out.split()[0]) if filesize > part.size: part.size = filesize part.source_file = dst
def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo): """ Prepare content for an ext2/3/4 rootfs partition. """ du_cmd = "du -ks %s" % rootfs_dir out = exec_cmd(du_cmd) actual_rootfs_size = int(out.split()[0]) rootfs_size = self.get_rootfs_size(actual_rootfs_size) with open(rootfs, 'w') as sparse: os.ftruncate(sparse.fileno(), rootfs_size * 1024) extraopts = self.mkfs_extraopts or "-F -i 8192" label_str = "" if self.label: label_str = "-L %s" % self.label mkfs_cmd = "mkfs.%s %s %s %s -d %s" % \ (self.fstype, extraopts, rootfs, label_str, rootfs_dir) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates loader-specific config """ isodir = "%s/ISO/" % cr_workdir if os.path.exists(isodir): shutil.rmtree(isodir) install_cmd = "install -d %s " % isodir exec_cmd(install_cmd) # Overwrite the name of the created image logger.debug(source_params) if 'image_name' in source_params and \ source_params['image_name'].strip(): creator.name = source_params['image_name'].strip() logger.debug("The name of the image is: %s", creator.name)
def do_configure_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), creates loader-specific config """ hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -d %s/EFI/BOOT" % hdddir exec_cmd(install_cmd) try: if source_params['loader'] == 'grub-efi': cls.do_configure_grubefi(creator, cr_workdir) elif source_params['loader'] == 'systemd-boot': cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params) else: raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) except KeyError: raise WicError("bootimg-efi requires a loader, none specified")
def partitions(self): if self._partitions is None: self._partitions = OrderedDict() out = exec_cmd("%s -sm %s unit B print" % (self.parted, self.imagepath)) parttype = namedtuple("Part", "pnum start end size fstype") for line in out.splitlines()[2:]: pnum, start, end, size, fstype = line.split(':')[:5] partition = parttype(pnum, int(start[:-1]), int(end[:-1]), int(size[:-1]), fstype) self._partitions[pnum] = partition return self._partitions
def remove(self, pnum, path): """Remove files/dirs from the partition.""" partimg = self._get_part_image(pnum) if self.partitions[pnum].fstype.startswith('ext'): cmd = "{} {} -wR 'rm {}'".format(self.debugfs, self._get_part_image(pnum), path) out = exec_cmd(cmd , as_shell=True) for line in out.splitlines(): if line.startswith("rm:"): if "file is a directory" in line: # Try rmdir to see if this is an empty directory. This won't delete # any non empty directory so let user know about any error that this might # generate. print(exec_cmd("{} {} -wR 'rmdir {}'".format(self.debugfs, self._get_part_image(pnum), path), as_shell=True)) else: raise WicError("Could not complete operation: wic %s" % str(line)) else: # fat cmd = "{} -i {} ::{}".format(self.mdel, partimg, path) try: exec_cmd(cmd) except WicError as err: if "not found" in str(err) or "non empty" in str(err): # mdel outputs 'File ... not found' or 'directory .. non empty" # try to use mdeltree as path could be a directory cmd = "{} -i {} ::{}".format(self.mdeltree, partimg, path) exec_cmd(cmd) else: raise err self._put_part_image(pnum)
def get_partitions(self): if self._partitions is None: self._partitions = OrderedDict() out = exec_cmd("%s -sm %s unit B print" % (self.parted, self.imagepath)) parttype = namedtuple("Part", "pnum start end size fstype") splitted = out.splitlines() lsector_size, psector_size, self._ptable_format = splitted[1].split(":")[3:6] self._lsector_size = int(lsector_size) self._psector_size = int(psector_size) for line in splitted[2:]: pnum, start, end, size, fstype = line.split(':')[:5] partition = parttype(int(pnum), int(start[:-1]), int(end[:-1]), int(size[:-1]), fstype) self._partitions[pnum] = partition return self._partitions
def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, native_sysroot): """ Prepare content for a rootfs partition i.e. create a partition and fill it from a /rootfs dir. Currently handles ext2/3/4, btrfs and vfat. """ p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", "%s/../pseudo" % get_bitbake_var("IMAGE_ROOTFS")) p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % p_localstatedir pseudo += "export PSEUDO_PASSWD=%s;" % p_passwd pseudo += "export PSEUDO_NOSYMLINKEXP=%s;" % p_nosymlinkexp pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label, self.lineno, self.fstype) if os.path.isfile(rootfs): os.remove(rootfs) # Get rootfs size from bitbake variable if it's not set in .ks file if not self.size: # Bitbake variable ROOTFS_SIZE is calculated in # Image._get_rootfs_size method from meta/lib/oe/image.py # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT, # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE rsize_bb = get_bitbake_var('ROOTFS_SIZE') if rsize_bb: logger.warning('overhead-factor was specified, but size was not,' ' so bitbake variables will be used for the size.' ' In this case both IMAGE_OVERHEAD_FACTOR and ' '--overhead-factor will be applied') self.size = int(round(float(rsize_bb))) prefix = "ext" if self.fstype.startswith("ext") else self.fstype method = getattr(self, "prepare_rootfs_" + prefix) method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo) self.source_file = rootfs # get the rootfs size in the right units for kickstart (kB) du_cmd = "du -Lbks %s" % rootfs out = exec_cmd(du_cmd) self.size = int(out.split()[0])
def get_partitions(self): if self._partitions is None: self._partitions = OrderedDict() out = exec_cmd("%s -sm %s unit B print" % (self.parted, self.imagepath)) parttype = namedtuple("Part", "pnum start end size fstype") splitted = out.splitlines() # skip over possible errors in exec_cmd output try: idx =splitted.index("BYT;") except ValueError: raise WicError("Error getting partition information from %s" % (self.parted)) lsector_size, psector_size, self._ptable_format = splitted[idx + 1].split(":")[3:6] self._lsector_size = int(lsector_size) self._psector_size = int(psector_size) for line in splitted[idx + 2:]: pnum, start, end, size, fstype = line.split(':')[:5] partition = parttype(int(pnum), int(start[:-1]), int(end[:-1]), int(size[:-1]), fstype) self._partitions[pnum] = partition return self._partitions
def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo): """ Prepare content for a btrfs rootfs partition. """ du_cmd = "du -ks %s" % rootfs_dir out = exec_cmd(du_cmd) actual_rootfs_size = int(out.split()[0]) rootfs_size = self.get_rootfs_size(actual_rootfs_size) with open(rootfs, 'w') as sparse: os.ftruncate(sparse.fileno(), rootfs_size * 1024) label_str = "" if self.label: label_str = "-L %s" % self.label mkfs_cmd = "mkfs.%s -b %d -r %s %s %s -U %s %s" % \ (self.fstype, rootfs_size * 1024, rootfs_dir, label_str, self.mkfs_extraopts, self.fsuuid, rootfs) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
def remove(self, pnum, path): """Remove files/dirs from the partition.""" partimg = self._get_part_image(pnum) if self.partitions[pnum].fstype.startswith('ext'): exec_cmd("{} {} -wR 'rm {}'".format(self.debugfs, self._get_part_image(pnum), path), as_shell=True) else: # fat cmd = "{} -i {} ::{}".format(self.mdel, partimg, path) try: exec_cmd(cmd) except WicError as err: if "not found" in str(err) or "non empty" in str(err): # mdel outputs 'File ... not found' or 'directory .. non empty" # try to use mdeltree as path could be a directory cmd = "{} -i {} ::{}".format(self.mdeltree, partimg, path) exec_cmd(cmd) else: raise err self._put_part_image(pnum)
def do_configure_systemdboot(cls, hdddir, creator, cr_workdir, source_params): """ Create loader-specific systemd-boot/gummiboot config """ install_cmd = "install -d %s/loader" % hdddir exec_cmd(install_cmd) install_cmd = "install -d %s/loader/entries" % hdddir exec_cmd(install_cmd) bootloader = creator.ks.bootloader loader_conf = "" loader_conf += "default boot\n" loader_conf += "timeout %d\n" % bootloader.timeout initrd = source_params.get('initrd') if initrd: # obviously we need to have a common common deploy var bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not bootimg_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") cp_cmd = "cp %s/%s %s" % (bootimg_dir, initrd, hdddir) exec_cmd(cp_cmd, True) else: logger.debug("Ignoring missing initrd") logger.debug("Writing systemd-boot config " "%s/hdd/boot/loader/loader.conf", cr_workdir) cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w") cfg.write(loader_conf) cfg.close() configfile = creator.ks.bootloader.configfile custom_cfg = None if configfile: custom_cfg = get_custom_config(configfile) if custom_cfg: # Use a custom configuration for systemd-boot boot_conf = custom_cfg logger.debug("Using custom configuration file " "%s for systemd-boots's boot.conf", configfile) else: raise WicError("configfile is specified but failed to " "get it from %s.", configfile) if not custom_cfg: # Create systemd-boot configuration using parameters from wks file kernel = "/bzImage" boot_conf = "" boot_conf += "title boot\n" boot_conf += "linux %s\n" % kernel boot_conf += "options LABEL=Boot root=%s %s\n" % \ (creator.rootdev, bootloader.append) if initrd: boot_conf += "initrd /%s\n" % initrd logger.debug("Writing systemd-boot config " "%s/hdd/boot/loader/entries/boot.conf", cr_workdir) cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w") cfg.write(boot_conf) cfg.close()
def do_prepare_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): """ Called to do the actual content population for a partition i.e. it 'prepares' the partition to be incorporated into the image. In this case, prepare content for legacy bios boot partition. """ bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') staging_kernel_dir = kernel_dir hdddir = "%s/hdd/boot" % cr_workdir cmds = ("install -m 0644 %s/bzImage %s/vmlinuz" % (staging_kernel_dir, hdddir), "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" % (bootimg_dir, hdddir), "install -m 0644 %s/syslinux/vesamenu.c32 %s/vesamenu.c32" % (bootimg_dir, hdddir), "install -m 444 %s/syslinux/libcom32.c32 %s/libcom32.c32" % (bootimg_dir, hdddir), "install -m 444 %s/syslinux/libutil.c32 %s/libutil.c32" % (bootimg_dir, hdddir)) for install_cmd in cmds: exec_cmd(install_cmd) du_cmd = "du -bks %s" % hdddir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) extra_blocks = part.get_extra_block_count(blocks) if extra_blocks < BOOTDD_EXTRA_SPACE: extra_blocks = BOOTDD_EXTRA_SPACE blocks += extra_blocks logger.debug("Added %d extra blocks to %s to get to %d total blocks", extra_blocks, part.mountpoint, blocks) # dosfs image, created by mkdosfs bootimg = "%s/boot%s.img" % (cr_workdir, part.lineno) dosfs_cmd = "mkdosfs -n boot -i %s -S 512 -C %s %d" % \ (part.fsuuid, bootimg, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) exec_native_cmd(mcopy_cmd, native_sysroot) syslinux_cmd = "syslinux %s" % bootimg exec_native_cmd(syslinux_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % bootimg exec_cmd(chmod_cmd) du_cmd = "du -Lbks %s" % bootimg out = exec_cmd(du_cmd) bootimg_size = out.split()[0] part.size = int(bootimg_size) part.source_file = bootimg
def do_configure_partition(cls, part, source_params, cr, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition(), create u-boot specific boot config """ hdddir = "%s/boot.%d" % (cr_workdir, part.lineno) install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) if not kernel_dir: kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not kernel_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") boot_files = None for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)): if fmt: var = fmt % id else: var = "" boot_files = get_bitbake_var("IMAGE_BOOT_FILES" + var) if boot_files is not None: break if boot_files is None: raise WicError('No boot files defined, IMAGE_BOOT_FILES unset for entry #%d' % part.lineno) logger.debug('Boot files: %s', boot_files) # list of tuples (src_name, dst_name) deploy_files = [] for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files): if ';' in src_entry: dst_entry = tuple(src_entry.split(';')) if not dst_entry[0] or not dst_entry[1]: raise WicError('Malformed boot file entry: %s' % src_entry) else: dst_entry = (src_entry, src_entry) logger.debug('Destination entry: %r', dst_entry) deploy_files.append(dst_entry) cls.install_task = []; for deploy_entry in deploy_files: src, dst = deploy_entry if '*' in src: # by default install files under their basename entry_name_fn = os.path.basename if dst != src: # unless a target name was given, then treat name # as a directory and append a basename entry_name_fn = lambda name: \ os.path.join(dst, os.path.basename(name)) srcs = glob(os.path.join(kernel_dir, src)) logger.debug('Globbed sources: %s', ', '.join(srcs)) for entry in srcs: src = os.path.relpath(entry, kernel_dir) entry_dst_name = entry_name_fn(entry) cls.install_task.append((src, entry_dst_name)) else: cls.install_task.append((src, dst)) if source_params.get('loader') != "u-boot": return configfile = cr.ks.bootloader.configfile custom_cfg = None if configfile: custom_cfg = get_custom_config(configfile) if custom_cfg: # Use a custom configuration for extlinux.conf extlinux_conf = custom_cfg logger.debug("Using custom configuration file " "%s for extlinux.cfg", configfile) else: raise WicError("configfile is specified but failed to " "get it from %s." % configfile) if not custom_cfg: # The kernel types supported by the sysboot of u-boot kernel_types = ["zImage", "Image", "fitImage", "uImage", "vmlinux"] has_dtb = False fdt_dir = '/' kernel_name = None # Find the kernel image name, from the highest precedence to lowest for image in kernel_types: for task in cls.install_task: src, dst = task if re.match(image, src): kernel_name = os.path.join('/', dst) break if kernel_name: break for task in cls.install_task: src, dst = task # We suppose that all the dtb are in the same directory if re.search(r'\.dtb', src) and fdt_dir == '/': has_dtb = True fdt_dir = os.path.join(fdt_dir, os.path.dirname(dst)) break if not kernel_name: raise WicError('No kernel file founded') # Compose the extlinux.conf extlinux_conf = "default Yocto\n" extlinux_conf += "label Yocto\n" extlinux_conf += " kernel %s\n" % kernel_name if has_dtb: extlinux_conf += " fdtdir %s\n" % fdt_dir bootloader = cr.ks.bootloader extlinux_conf += "append root=%s rootwait %s\n" \ % (cr.rootdev, bootloader.append if bootloader.append else '') install_cmd = "install -d %s/extlinux/" % hdddir exec_cmd(install_cmd) cfg = open("%s/extlinux/extlinux.conf" % hdddir, "w") cfg.write(extlinux_conf) cfg.close()
def do_prepare_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): """ Called to do the actual content population for a partition i.e. it 'prepares' the partition to be incorporated into the image. In this case, prepare content for an EFI (grub) boot partition. """ if not kernel_dir: kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not kernel_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") staging_kernel_dir = kernel_dir hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ (staging_kernel_dir, hdddir) exec_cmd(install_cmd) try: if source_params['loader'] == 'grub-efi': shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "%s/grub.cfg" % cr_workdir) for mod in [x for x in os.listdir(kernel_dir) if x.startswith("grub-efi-")]: cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[9:]) exec_cmd(cp_cmd, True) shutil.move("%s/grub.cfg" % cr_workdir, "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir) elif source_params['loader'] == 'systemd-boot': for mod in [x for x in os.listdir(kernel_dir) if x.startswith("systemd-")]: cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[8:]) exec_cmd(cp_cmd, True) else: raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) except KeyError: raise WicError("bootimg-efi requires a loader, none specified") startup = os.path.join(kernel_dir, "startup.nsh") if os.path.exists(startup): cp_cmd = "cp %s %s/" % (startup, hdddir) exec_cmd(cp_cmd, True) du_cmd = "du -bks %s" % hdddir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) extra_blocks = part.get_extra_block_count(blocks) if extra_blocks < BOOTDD_EXTRA_SPACE: extra_blocks = BOOTDD_EXTRA_SPACE blocks += extra_blocks logger.debug("Added %d extra blocks to %s to get to %d total blocks", extra_blocks, part.mountpoint, blocks) # dosfs image, created by mkdosfs bootimg = "%s/boot.img" % cr_workdir dosfs_cmd = "mkdosfs -n efi -i %s -C %s %d" % \ (part.fsuuid, bootimg, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) exec_native_cmd(mcopy_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % bootimg exec_cmd(chmod_cmd) du_cmd = "du -Lbks %s" % bootimg out = exec_cmd(du_cmd) bootimg_size = out.split()[0] part.size = int(bootimg_size) part.source_file = bootimg
def do_prepare_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): """ Called to do the actual content population for a partition i.e. it 'prepares' the partition to be incorporated into the image. In this case, prepare content for a bootable ISO image. """ isodir = "%s/ISO" % cr_workdir if part.rootfs_dir is None: if not 'ROOTFS_DIR' in rootfs_dir: raise WicError("Couldn't find --rootfs-dir, exiting.") rootfs_dir = rootfs_dir['ROOTFS_DIR'] else: if part.rootfs_dir in rootfs_dir: rootfs_dir = rootfs_dir[part.rootfs_dir] elif part.rootfs_dir: rootfs_dir = part.rootfs_dir else: raise WicError("Couldn't find --rootfs-dir=%s connection " "or it is not a valid path, exiting." % part.rootfs_dir) if not os.path.isdir(rootfs_dir): rootfs_dir = get_bitbake_var("IMAGE_ROOTFS") if not os.path.isdir(rootfs_dir): raise WicError("Couldn't find IMAGE_ROOTFS, exiting.") part.rootfs_dir = rootfs_dir # Prepare rootfs.img deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") img_iso_dir = get_bitbake_var("ISODIR") rootfs_img = "%s/rootfs.img" % img_iso_dir if not os.path.isfile(rootfs_img): # check if rootfs.img is in deploydir deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") image_name = get_bitbake_var("IMAGE_LINK_NAME") rootfs_img = "%s/%s.%s" \ % (deploy_dir, image_name, part.fstype) if not os.path.isfile(rootfs_img): # create image file with type specified by --fstype # which contains rootfs du_cmd = "du -bks %s" % rootfs_dir out = exec_cmd(du_cmd) part.size = int(out.split()[0]) part.extra_space = 0 part.overhead_factor = 1.2 part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, \ native_sysroot) rootfs_img = part.source_file install_cmd = "install -m 0644 %s %s/rootfs.img" \ % (rootfs_img, isodir) exec_cmd(install_cmd) # Remove the temporary file created by part.prepare_rootfs() if os.path.isfile(part.source_file): os.remove(part.source_file) # Support using a different initrd other than default if source_params.get('initrd'): initrd = source_params['initrd'] if not deploy_dir: raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir) exec_cmd(cp_cmd) else: # Prepare initial ramdisk initrd = "%s/initrd" % deploy_dir if not os.path.isfile(initrd): initrd = "%s/initrd" % img_iso_dir if not os.path.isfile(initrd): initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir) install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir) exec_cmd(install_cmd) # Remove the temporary file created by _build_initramfs_path function if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir): os.remove("%s/initrd.cpio.gz" % cr_workdir) # Install bzImage install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ (kernel_dir, isodir) exec_cmd(install_cmd) #Create bootloader for efi boot try: target_dir = "%s/EFI/BOOT" % isodir if os.path.exists(target_dir): shutil.rmtree(target_dir) os.makedirs(target_dir) if source_params['loader'] == 'grub-efi': # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or # didn't contains it target_arch = get_bitbake_var("TARGET_SYS") if not target_arch: raise WicError("Coludn't find target architecture") if re.match("x86_64", target_arch): grub_image = "grub-efi-bootx64.efi" elif re.match('i.86', target_arch): grub_image = "grub-efi-bootia32.efi" else: raise WicError("grub-efi is incompatible with target %s" % target_arch) grub_target = os.path.join(target_dir, grub_image) if not os.path.isfile(grub_target): grub_src = os.path.join(deploy_dir, grub_image) if not os.path.exists(grub_src): raise WicError("Grub loader %s is not found in %s. " "Please build grub-efi first" % (grub_image, deploy_dir)) shutil.copy(grub_src, grub_target) if not os.path.isfile(os.path.join(target_dir, "boot.cfg")): cls.do_configure_grubefi(part, creator, target_dir) else: raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) except KeyError: raise WicError("bootimg-efi requires a loader, none specified") # Create efi.img that contains bootloader files for EFI booting # if ISODIR didn't exist or didn't contains it if os.path.isfile("%s/efi.img" % img_iso_dir): install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \ (img_iso_dir, isodir) exec_cmd(install_cmd) else: du_cmd = "du -bks %s/EFI" % isodir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) # Add some extra space for file system overhead blocks += 100 logger.debug("Added 100 extra blocks to %s to get to %d " "total blocks", part.mountpoint, blocks) # dosfs image for EFI boot bootimg = "%s/efi.img" % isodir dosfs_cmd = 'mkfs.vfat -n "EFIimg" -S 512 -C %s %d' \ % (bootimg, blocks) exec_native_cmd(dosfs_cmd, native_sysroot) mmd_cmd = "mmd -i %s ::/EFI" % bootimg exec_native_cmd(mmd_cmd, native_sysroot) mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \ % (bootimg, isodir) exec_native_cmd(mcopy_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % bootimg exec_cmd(chmod_cmd) # Prepare files for legacy boot syslinux_dir = get_bitbake_var("STAGING_DATADIR") if not syslinux_dir: raise WicError("Couldn't find STAGING_DATADIR, exiting.") if os.path.exists("%s/isolinux" % isodir): shutil.rmtree("%s/isolinux" % isodir) install_cmd = "install -d %s/isolinux" % isodir exec_cmd(install_cmd) cls.do_configure_syslinux(creator, cr_workdir) install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir install_cmd += "%s/isolinux/ldlinux.sys" % isodir exec_cmd(install_cmd) install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir install_cmd += "%s/isolinux/isohdpfx.bin" % isodir exec_cmd(install_cmd) install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir install_cmd += "%s/isolinux/isolinux.bin" % isodir exec_cmd(install_cmd) install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir install_cmd += "%s/isolinux/ldlinux.c32" % isodir exec_cmd(install_cmd) #create ISO image iso_img = "%s/tempiso_img.iso" % cr_workdir iso_bootimg = "isolinux/isolinux.bin" iso_bootcat = "isolinux/boot.cat" efi_img = "efi.img" mkisofs_cmd = "mkisofs -V %s " % part.label mkisofs_cmd += "-o %s -U " % iso_img mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat mkisofs_cmd += "-boot-info-table -eltorito-alt-boot " mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img mkisofs_cmd += "-no-emul-boot %s " % isodir logger.debug("running command: %s", mkisofs_cmd) exec_native_cmd(mkisofs_cmd, native_sysroot) shutil.rmtree(isodir) du_cmd = "du -Lbks %s" % iso_img out = exec_cmd(du_cmd) isoimg_size = int(out.split()[0]) part.size = isoimg_size part.source_file = iso_img