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 get_plugins(cls, ptype): """Get dictionary of <plugin_name>:<class> pairs.""" if ptype not in PLUGIN_TYPES: raise WicError('%s is not valid plugin type' % ptype) # collect plugin directories if not cls._plugin_dirs: cls._plugin_dirs = [os.path.join(os.path.dirname(__file__), 'plugins')] layers = get_bitbake_var("BBLAYERS") or '' for layer_path in layers.split(): path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR) path = os.path.abspath(os.path.expanduser(path)) if path not in cls._plugin_dirs and os.path.isdir(path): cls._plugin_dirs.insert(0, path) if ptype not in PLUGINS: # load all ptype plugins for pdir in cls._plugin_dirs: ppath = os.path.join(pdir, ptype) if os.path.isdir(ppath): for fname in os.listdir(ppath): if fname.endswith('.py'): mname = fname[:-3] mpath = os.path.join(ppath, fname) logger.debug("loading plugin module %s", mpath) SourceFileLoader(mname, mpath).load_module() return PLUGINS.get(ptype)
def create(self): """ For 'wic', we already have our build artifacts - we just create filesystems from the artifacts directly and combine them into a partitioned image. """ if self.no_fstab_update: new_rootfs = None else: new_rootfs = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR")) if new_rootfs: # rootfs was copied to update fstab self.rootfs_dir['ROOTFS_DIR'] = new_rootfs for part in self.parts: # get rootfs size from bitbake variable if it's not set in .ks file if not part.size: # and if rootfs name is specified for the partition image_name = self.rootfs_dir.get(part.rootfs_dir) if image_name and os.path.sep not in image_name: # 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', image_name) if rsize_bb: part.size = int(round(float(rsize_bb))) self._image.prepare(self) self._image.layout_partitions() self._image.create()
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_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(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_bootimg_dir(cls, bootimg_dir, dirname): """ Check if dirname exists in default bootimg_dir or in STAGING_DIR. """ for result in (bootimg_dir, get_bitbake_var("STAGING_DATADIR")): if os.path.exists("%s/%s" % (result, dirname)): return result raise WicError("Couldn't find correct bootimg_dir, exiting")
def __get_rootfs_dir(rootfs_dir): if os.path.isdir(rootfs_dir): return rootfs_dir image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir) if not os.path.isdir(image_rootfs_dir): raise WicError("No valid artifact IMAGE_ROOTFS from image " "named %s has been found at %s, exiting." % (rootfs_dir, image_rootfs_dir)) return image_rootfs_dir
def expand_line(line): while True: m = __expand_var_regexp__.search(line) if not m: return line key = m.group()[2:-1] val = get_bitbake_var(key) if val is None: logger.warning("cannot expand variable %s" % key) return line line = line[:m.start()] + val + line[m.end():]
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 build_canned_image_list(path): layers_path = get_bitbake_var("BBLAYERS") canned_wks_layer_dirs = [] if layers_path is not None: for layer_path in layers_path.split(): for wks_path in (WIC_DIR, SCRIPTS_CANNED_IMAGE_DIR): cpath = os.path.join(layer_path, wks_path) if os.path.isdir(cpath): canned_wks_layer_dirs.append(cpath) cpath = os.path.join(path, CANNED_IMAGE_DIR) canned_wks_layer_dirs.append(cpath) return canned_wks_layer_dirs
def _get_bootimg_dir(cls, bootimg_dir, dirname): """ Check if dirname exists in default bootimg_dir or in STAGING_DIR. """ staging_datadir = get_bitbake_var("STAGING_DATADIR") for result in (bootimg_dir, staging_datadir): if os.path.exists("%s/%s" % (result, dirname)): return result # STAGING_DATADIR is expanded with MLPREFIX if multilib is enabled # but dependency syslinux is still populated to original STAGING_DATADIR nonarch_datadir = re.sub('/[^/]*recipe-sysroot', '/recipe-sysroot', staging_datadir) if os.path.exists(os.path.join(nonarch_datadir, dirname)): return nonarch_datadir raise WicError("Couldn't find correct bootimg_dir, exiting")
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_stage_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, native_sysroot): # We rely on the --label parameter and the naming convention # in partition.py prepare_rootfs() here to find the already # prepared rootfs partition image. for partition in creator._image.partitions: if partition.source == 'bootimg-partition': boot_partition = partition break else: raise WicError("Could not find partition with source bootimg-partition !") boot_partition_dir = "%s/boot.%d" % (cr_workdir, boot_partition.lineno) hashimg = '%s/dm-verity_%s.img' % (cr_workdir, part.label) if get_bitbake_var("DM_VERITY") == "true": pattern = '%s/rootfs_%s.*' % (cr_workdir, source_params['target_root']) rootfs = glob.glob(pattern) if len(rootfs) != 1: raise WicError("%s shell pattern does not match exactly one rootfs image (missing --sourceparams=\"target_root=\" parameter?): %s" % (pattern, rootfs)) else: rootfs = rootfs[0] logger.debug("Calculating dm-verity hash for rootfs %s (native %s)." % (rootfs, native_sysroot)) ret, out = exec_native_cmd("veritysetup format --hash=sha384 '%s' '%s'" % (rootfs, hashimg), native_sysroot) m = re.search(r'^Root hash:\s*(\S+)$', out, re.MULTILINE) if ret or not m: raise WicError('veritysetup failed: %s' % out) root_hash = m.group(1) data_bytes = os.stat(rootfs).st_size hash_bytes = os.stat(hashimg).st_size logger.debug("dm-verity data partition %d bytes, hash partition %d bytes, ratio %f." % (data_bytes, hash_bytes, data_bytes/hash_bytes)) part.size = hash_bytes // 1024 part.source_file = hashimg # Step 1/3: Append 'DMVerity' in hex. IMPORTANT: "Image" was the # name for the kernel that was specified in machine's conf. ret, out = exec_native_cmd("echo -n -e '\x44\x4d\x56\x65\x72\x69\x74\x79' >> %s/Image" % (boot_partition_dir), native_sysroot) if ret: raise WicError('Append DMVerity failed: %s' % out) # Step 2/3: Append root_hash in hex. root_hash_in_hex = r'\x' + r'\x'.join(a+b for a,b in zip(root_hash[::2], root_hash[1::2])) ret, out = exec_native_cmd("echo -n -e '%s' >> %s/Image" %(root_hash_in_hex, boot_partition_dir), native_sysroot) if ret: raise WicError('Append roothash failed: %s' % out) # Step 3/3: Append padding bytes for 64-byte alignment. ret, out = exec_native_cmd("dd if=/dev/zero bs=1 count=8 >> %s/Image" % (boot_partition_dir), native_sysroot) if ret: raise WicError('Append padding bytes failed: %s' % out) logger.debug("Appending bytes to kernel completed.") else: exec_native_cmd("dd if=/dev/zero bs=1 count=1 >> %s" % hashimg, native_sysroot) # Set the kernel image path in the .its file for use with mkimage later. shutil.copyfile("%s" % (get_bitbake_var("ITS_FILE")), "%s/temp_kmb_os_image.its" % (cr_workdir)) out = exec_cmd("sed -i s:kmb-kernel:%s/Image: %s/temp_kmb_os_image.its" % (boot_partition_dir, cr_workdir)) # ":" as delimiter is safer # Sign the kernel with keys in KEYS_DIR to generate a signed FIT image. ret, out = exec_native_cmd("uboot-mkimage -f %s/temp_kmb_os_image.its -k %s sign-fit-img.itb" % (cr_workdir, get_bitbake_var("KEYS_DIR")), native_sysroot) if ret: raise WicError('Create FIT image failed: %s' % out) else: logger.debug("Create FIT image SUCCEEDED: %s" % out) # Copy the signed FIT image to the boot partition. shutil.copyfile("sign-fit-img.itb", "%s/Image" % boot_partition_dir) # Re-prepare boot partition to include the signed FIT image. logger.debug('Re-prepare boot partition using rootfs in %s', boot_partition_dir) boot_partition.prepare_rootfs(cr_workdir, oe_builddir, boot_partition_dir, native_sysroot, False)
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 label = part.label if part.label else "ESP" dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \ (label, 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_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 found') # 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_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params): """ Create grub.cfg """ configfile = creator.ks.bootloader.configfile custom_cfg = None if configfile: custom_cfg = get_custom_config(configfile) if custom_cfg: # Use a custom configuration 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") initrds = initrd.split(';') for rd in initrds: cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, 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='ACRN (Yocto)'\n" grubefi_conf += "timeout=%s\n" % bootloader.timeout grubefi_conf += "menuentry '%s'{\n" % (title if title else "boot") kernel = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) label = source_params.get('label') label_conf = "root=%s" % creator.rootdev if label: label_conf = "LABEL=%s" % label grubefi_conf += "linux /%s %s rootwait %s\n" \ % (kernel, label_conf, bootloader.append) if initrd: initrds = initrd.split(';') grubefi_conf += "initrd" for rd in initrds: grubefi_conf += " /%s" % rd grubefi_conf += "\n" grubefi_conf += "}\n" grubefi_conf += "menuentry 'ACRN (Yocto)'{\n" aux_modules = get_bitbake_var("ACRN_EFI_GRUB2_MOD_CFG") if aux_modules: aux_modules = aux_modules.split(";") for aux_module in aux_modules: if not aux_module: continue grubefi_conf += "%s\n" % aux_module grubefi_conf += "\nmultiboot2 /acrn.bin %s %s \n" % \ (label_conf, bootloader.append) boot_confs = get_bitbake_var("ACRN_EFI_BOOT_CONF").split(";") for boot_conf in boot_confs: if not boot_conf: continue conf = boot_conf.split(":") if len(conf) == 2: grubefi_conf += "module2 /%s %s\n" % (conf[0], conf[1]) elif len(conf) == 3: grubefi_conf += "module2 /%s %s %s\n" % (conf[0], conf[1], conf[2]) else: raise WicError("unable to parse ACRN_EFI_BOOT_CONF, in \"%s\" exiting" \ % boot_conf ) 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 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: initrd_search = source_params.get('initrd_search') if initrd_search: bootimg_dir = initrd_search else: bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not bootimg_dir: raise WicError("Couldn't find image search dir, exiting") initrds = initrd.split(';') for rd in initrds: cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, 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 = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) label = source_params.get('label') label_conf = "root=%s" % creator.rootdev if label: label_conf = "LABEL=%s" % label grubefi_conf += "linux /%s %s rootwait %s\n" \ % (kernel, label_conf, bootloader.append) if initrd: initrds = initrd.split(';') grubefi_conf += "initrd" for rd in initrds: grubefi_conf += " /%s" % rd grubefi_conf += "\n" 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 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") initrds = initrd.split(';') for rd in initrds: cp_cmd = "cp %s/%s %s" % (bootimg_dir, rd, 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 = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) title = source_params.get('title') boot_conf = "" boot_conf += "title %s\n" % (title if title else "boot") boot_conf += "linux /%s\n" % kernel label = source_params.get('label') label_conf = "LABEL=Boot root=%s" % creator.rootdev if label: label_conf = "LABEL=%s" % label boot_conf += "options %s %s\n" % \ (label_conf, bootloader.append) if initrd: initrds = initrd.split(';') for rd in initrds: boot_conf += "initrd /%s\n" % rd 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, 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) 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") logger.debug('Kernel dir: %s', bootimg_dir) 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) for deploy_entry in deploy_files: src, dst = deploy_entry install_task = [] 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: entry_dst_name = entry_name_fn(entry) install_task.append((entry, os.path.join(hdddir, entry_dst_name))) else: install_task = [(os.path.join(kernel_dir, src), os.path.join(hdddir, dst))] for task in install_task: src_path, dst_path = task logger.debug('Install %s as %s', os.path.basename(src_path), dst_path) install_cmd = "install -m 0644 -D %s %s" \ % (src_path, 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)
if os.path.isfile(initramfs_full_path) == False: raise Exception("initramfs file not found [%s]" % initramfs_full_path) do_gluing(firmware_full_path, yocto_full_path) do_grub_and_kernel_install(firmware_full_path, kernel_full_path, initramfs_full_path) print_hints(firmware_full_path) if __name__ == "__main__": # TODO: find a yocto way to import the vars as sudo instead if len(sys.argv) == 1: # first execution in bitbake env, get paths deploy_dir_image = get_bitbake_var("DEPLOY_DIR_IMAGE") yocto_full_path = os.path.join(deploy_dir_image, "core-image-minimal-qemux86-64.ext4") kernel_full_path = os.path.join(deploy_dir_image, "bzImage") work_dir = get_bitbake_var("WORKDIR") initramfs_full_path = os.path.join( work_dir, "../../../firmwareupdater/initramfs.igz") os.execvp("sudo", [ "python3", __file__, yocto_full_path, kernel_full_path, initramfs_full_path ]) elif len(sys.argv) == 4: # second execution in sudo context _, yocto_full_path, kernel_full_path, initramfs_full_path = sys.argv do_glue_image(FIRMWARE_FILE_FULL_PATH, yocto_full_path, kernel_full_path, initramfs_full_path)
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 kernel = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) cmds = ("install -m 0644 %s/%s %s/vmlinuz" % (staging_kernel_dir, kernel, 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) label = part.label if part.label else "boot" dosfs_cmd = "mkdosfs -n %s -i %s -S 512 -C %s %d" % \ (label, 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, 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 os.makedirs("%s/EFI/BOOT" % hdddir) try: if source_params['loader'] != 'grub-efi': raise WicError("unrecognized %s loader: %s" % (cls.name % source_params['loader'])) except KeyError: raise WicError("%s requires a loader, none specified" % cls.name) deploydir = get_bitbake_var("DEPLOY_DIR_IMAGE") if not deploydir: raise WicError("DEPLOY_DIR_IMAGE is unset!") if (not 'db_key' in source_params) or (not 'db_cert' in source_params): raise WicError('shim db_key/db_cert unset!') # TODO: verify initramfs image checksum # TODO: verify grub.cfg checksum cls.do_copy_shim(deploydir, cr_workdir, hdddir, source_params) cls.do_copy_mender_env(deploydir, cr_workdir, hdddir, source_params) cls.do_copy_grub(deploydir, cr_workdir, hdddir, creator, source_params) cls.do_copy_fwupdate(deploydir, cr_workdir, hdddir, source_params) cls.do_copy_ptcm(deploydir, cr_workdir, hdddir, source_params) 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) getSize = source_params['WKS_BOOT_SIZE_MB'] if getSize: logger.debug("Overriding block count with WKS_BOOT_SIZE_MB value") blocks = 1024 * int(getSize) # 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 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 kernel = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) install_cmd = "install -m 0644 %s/%s %s/%s" % \ (staging_kernel_dir, kernel, hdddir, kernel) exec_cmd(install_cmd) install_cmd = "install -m 0644 %s/acrn.bin %s/acrn.bin" % \ (staging_kernel_dir, hdddir) exec_cmd(install_cmd) if get_bitbake_var("IMAGE_EFI_BOOT_FILES"): for src_path, dst_path in cls.install_task: 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) 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) 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 label = part.label if part.label else "ESP" dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \ (label, 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_configure_partition(cls, part, source_params, cr, cr_workdir, oe_builddir, dataimg_dir, kernel_dir, native_sysroot): """ Called before do_prepare_partition() """ hdddir = "%s/data.%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") data_files = None for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)): if fmt: var = fmt % id else: var = "" data_files = get_bitbake_var("IMAGE_DATA_FILES" + var) if data_files is not None: break if data_files is None: cls.install_task = [] return logger.debug('Data files: %s', data_files) # list of tuples (src_name, dst_name) deploy_files = [] for src_entry in re.findall(r'[\w;\-\./\*]+', data_files): if ';' in src_entry: dst_entry = tuple(src_entry.split(';')) if not dst_entry[0] or not dst_entry[1]: raise WicError('Malformed data 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))
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") os.exit(1) staging_kernel_dir = kernel_dir hdddir = "%s/hdd/%s.%s" % (cr_workdir, part.label, part.lineno) install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ (staging_kernel_dir, hdddir) exec_cmd(install_cmd) # Write label as utf-16le to EFILABEL file fd = open("%s/EFILABEL" % hdddir, 'wb') fd.write(part.label.upper().encode("utf-16le")) fd.close() du_cmd = "du -bks %s" % hdddir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) # Calculate number of extra blocks to be sure that the resulting # partition image has the wanted size. 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 bootimg = "%s/%s.%s.img" % (cr_workdir, part.label, part.lineno) dosfs_cmd = "mkdosfs -F 16 -n %s -C %s %d" % (part.label.upper(), \ 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, 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" % cr_workdir 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") logger.debug('Kernel dir: %s', bootimg_dir) boot_files = get_bitbake_var("IMAGE_BOOT_FILES") if not boot_files: raise WicError('No boot files defined, IMAGE_BOOT_FILES unset') 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) for deploy_entry in deploy_files: src, dst = deploy_entry install_task = [] 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: entry_dst_name = entry_name_fn(entry) install_task.append( (entry, os.path.join(hdddir, entry_dst_name))) else: install_task = [(os.path.join(kernel_dir, src), os.path.join(hdddir, dst))] for task in install_task: src_path, dst_path = task logger.debug('Install %s as %s', os.path.basename(src_path), dst_path) install_cmd = "install -m 0644 -D %s %s" \ % (src_path, 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)
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 deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") img_iso_dir = get_bitbake_var("ISODIR") # 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) kernel = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) install_cmd = "install -m 0644 %s/%s %s/%s" % \ (kernel_dir, kernel, isodir, kernel) 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_src_image = "grub-efi-bootx64.efi" grub_dest_image = "bootx64.efi" elif re.match('i.86', target_arch): grub_src_image = "grub-efi-bootia32.efi" grub_dest_image = "bootia32.efi" else: raise WicError("grub-efi is incompatible with target %s" % target_arch) grub_target = os.path.join(target_dir, grub_dest_image) if not os.path.isfile(grub_target): grub_src = os.path.join(deploy_dir, grub_src_image) if not os.path.exists(grub_src): raise WicError("Grub loader %s is not found in %s. " "Please build grub-efi first" % (grub_src_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: # Default to 100 blocks of extra space for file system overhead esp_extra_blocks = int(source_params.get('esp_extra_blocks', '100')) du_cmd = "du -bks %s/EFI" % isodir out = exec_cmd(du_cmd) blocks = int(out.split()[0]) blocks += esp_extra_blocks 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 esp_label = source_params.get('esp_label', 'EFIimg') dosfs_cmd = 'mkfs.vfat -n \'%s\' -S 512 -C %s %d' \ % (esp_label, 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
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. """ rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label, self.lineno, self.fstype) if os.path.isfile(rootfs): os.remove(rootfs) p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) if (pseudo_dir): # Canonicalize the ignore paths. This corresponds to # calling oe.path.canonicalize(), which is used in bitbake.conf. ignore_paths = [rootfs] + (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "").split(",") canonical_paths = [] for path in ignore_paths: if "$" not in path: trailing_slash = path.endswith("/") and "/" or "" canonical_paths.append( os.path.realpath(path) + trailing_slash) ignore_paths = ",".join(canonical_paths) 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 += "export PSEUDO_IGNORE_PATHS=%s;" % ignore_paths pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") else: pseudo = None 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, cr_workdir, 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_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 boot partition. """ hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -d %s" % hdddir exec_cmd(install_cmd) # ROOTFS_DIR same # image_rootfs: /work/build/tmp/work/srg52-buster-armhf/srg52-image-srg-3352c-wic-targz-img/1.0-r0/rootfs image_rootfs = get_bitbake_var("IMAGE_ROOTFS") kernel_file = "vmlinuz" kernel = os.path.basename( os.path.realpath(os.path.join(image_rootfs, kernel_file))) staging_kernel_dir = "%s/boot" % image_rootfs kernel_version = kernel.strip(kernel_file + '-') cls.gen_ubootscript(part, source_params, creator, image_rootfs, hdddir) initrd = "initrd.img-%s" % (kernel_version) config = "config-%s" % (kernel_version) mapfile = "System.map-%s" % (kernel_version) bootscript = "boot.scr" cmds = ("install -m 0644 %s/%s %s/%s" % (staging_kernel_dir, kernel, hdddir, kernel), "install -m 0644 %s/%s %s/%s" % (staging_kernel_dir, initrd, hdddir, initrd), "install -m 0644 %s/%s %s/%s" % (staging_kernel_dir, config, hdddir, config), "install -m 0644 %s/%s %s/%s" % (staging_kernel_dir, mapfile, hdddir, mapfile), "install -m 0644 %s/%s %s/%s" % (staging_kernel_dir, bootscript, hdddir, bootscript)) for install_cmd in cmds: exec_cmd(install_cmd) dtbs_path = "%s/usr/lib/linux-image-%s" % (image_rootfs, kernel_version) dtbsdir = "%s/dtbs" % hdddir overlaydir = "%s/overlay" % dtbsdir cmds = (("install -d %s" % dtbsdir), ("install -d %s" % overlaydir)) for install_cmd in cmds: exec_cmd(install_cmd) # logger.info("dtbs_path:%s", dtbs_path) for root, dir, files in os.walk(dtbs_path): for f in files: if len(dir) > 0: install_cmd = "install -m 0644 %s/%s %s/%s" % (root, f, dtbsdir, f) else: install_cmd = "install -m 0644 %s/%s %s/%s" % ( root, f, overlaydir, f) # logger.info("dir:%s, f:%s", dir, f) # logger.info("dtb:%s", install_cmd) 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) bootimg = "%s/boot.img" % cr_workdir genimg_cmd = "dd if=/dev/zero of=%s bs=512 count=%d" % (bootimg, blocks) exec_native_cmd(genimg_cmd, native_sysroot) extraopts = "-F -i 8192" fstype = "ext4" mkfs_cmd = "mkfs.%s %s %s -L boot -d %s" % \ (fstype, extraopts, bootimg, hdddir) exec_native_cmd(mkfs_cmd, native_sysroot) mkfs_cmd = "fsck.%s -pvfD %s" % (fstype, bootimg) exec_native_cmd(mkfs_cmd, native_sysroot) 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, cr, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, krootfs_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 data partition that mounts to a specific directory in rootfs. """ # Passed in Parameters (from Partition(object).prepare() entry point) # part => Partition(object).instance # source_params => srcparams_dict # cr => creator # cr_workdir => cr_workdir # oe_builddir => oe_builddir # bootimg_dir => bootimg_dir # kernel_dir => kernel_dir # krootfs_dir => krootfs_dir # native_sysroot => native_sysroot # # original wic do_create command entry point: DirectPlugin(ImagerPlugin).do_create()-> # try: # self.create() # self.assemble() # self.finalize() # self.print_info() # finally: # self.cleanup() # # direct.py's PartitionedImage(object).create()-> # self._image.prepare(...) i.e. loop all partitions in wks file and prepare the partition # self._image.layout_partitions(...) i.e. calculate positions of all partitions # self._image.create() -> exec_native_cmd() i.e. call parted cmd to generate partition # # partition.py's class Partition(object).prepare()-> # plugin.do_configure_partition(...) # plugin.do_stage_partition(...) # plugin.do_prepare_partition(...) # plugin.do_post_partition(...) # # must find the datafs partition image specified by --sourceparams from deployed directory 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") if 'file' not in source_params: raise WicError("No file specified") # Note: We only care about TN_PARTITION_IMAGE (from image_type_tn.bbclass) # or TN_DOCKER_PARTITION_IMAGE (from docker-disk.inc/pico-imx8mm.conf) # or anyother PARTITION_IMAGE that we want to write to the additional data partition # which is used in wic/tn-imx8-imxboot-rootfs-container.wks.in # and this src image was created with mkfs command: # mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 -i 8192 -d ${DATA_VOLUME}/docker -F ${BUILD}/${PARTITION_IMAGE} src = os.path.join(kernel_dir, source_params['file']) # prepare the dst partition image first dst = os.path.join( cr_workdir, "fs_{}.{}.{}".format(part.label, part.lineno, part.fstype)) logger.info("datafs src: {}\ndatafs dst: {}\n".format(src, dst)) if os.path.isfile(dst): os.remove(dst) # copy src to dst in binary if 'skip' in source_params: sparse_copy(src, dst, skip=int(source_params['skip'])) else: sparse_copy(src, dst) # check the ext4 file system on the dst file mkfs_cmd = "fsck.{} -pvfD {}".format(part.fstype, dst) exec_native_cmd(mkfs_cmd, native_sysroot) # get the size in the right units for kickstart (kB) du_cmd = "du -Lbks {}".format(dst) out = exec_cmd(du_cmd) filesize = int(out.split()[0]) if filesize > part.size: part.size = filesize # update the partition label if part.label: DatafsPlugin.do_image_label(part.fstype, dst, part.label) part.source_file = dst
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") xen_gz_dir = "%s/%s" % (deploy_dir, "xen.gz") if os.path.exists(grub_cfg_dir): shutil.copyfile(grub_cfg_dir, "%s/grub.cfg" % hdddir) elif os.path.exists(xen_gz_dir): initrd = source_params.get('initrd') 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-xen' {\n" xen = "/xen" kernel = "/bzImage" bootdev = "(hd0,msdos1)" dom0_conf = "dom0_mem=2G loglvl=all guest_loglvl=all" dom0_serial = "com1=115200,8n1 console=com1 no-real-mode" rootdev = "/dev/sda2" kernel_params = "console=hvc0 earlyprintk=xen nomodeset" grub_conf += " insmod part_msdos\n" grub_conf += " set root=%s\n" % bootdev grub_conf += " multiboot2 %s %s %s\n" \ % (xen, dom0_conf, dom0_serial) grub_conf += " module2 %s root=%s %s\n" \ % (kernel, rootdev, kernel_params) if initrd: grub_conf += " module2 initrd /%s\n" % initrd grub_conf += "}\n" # Secure launch grub_conf += "\n" grub_conf += "menuentry 'secure-boot-xen' {\n" grub_conf += " insmod part_msdos\n" grub_conf += " set root=%s\n" % bootdev grub_conf += " slaunch skinit\n" grub_conf += " slaunch_module %s/lz_header.bin\n" % bootdev grub_conf += " multiboot2 %s %s %s\n" \ % (xen, dom0_conf, dom0_serial) grub_conf += " module2 %s root=%s %s\n" \ % (kernel, rootdev, kernel_params) if initrd: grub_conf += " module2 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() else: initrd = source_params.get('initrd') 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" bootdev = "(hd0,msdos1)" rootdev = "/dev/sda2" serial = "console=ttyS0,115200 earlyprintk=serial,ttyS0,115200" grub_conf += " linux %s root=%s %s\n" \ % (kernel, rootdev, serial) if initrd: grub_conf += " initrd /%s\n" % initrd grub_conf += "}\n" # Secure launch grub_conf += "\n" grub_conf += "menuentry 'secure-boot' {\n" grub_conf += " slaunch skinit\n" grub_conf += " slaunch_module %s/lz_header.bin\n" % bootdev grub_conf += " linux %s root=%s %s\n" \ % (kernel, rootdev, serial) 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_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 grub legacy 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 # Copying kernel hdddir = "%s/hdd/boot" % cr_workdir install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ (staging_kernel_dir, hdddir) exec_cmd(install_cmd) # Copying lz_header install_cmd = "install -m 0600 %s/lz_header.bin %s/lz_header.bin" % \ (staging_kernel_dir, hdddir) exec_cmd(install_cmd) # Copying grub modules grub_dir_native = get_bitbake_var( "IMAGE_ROOTFS") + "/usr/lib64/grub-tb" shutil.copytree("%s/i386-pc" % (grub_dir_native), "%s/grub/i386-pc" % hdddir) # Copying xen module if exists if os.path.exists("%s/xen.gz" % staging_kernel_dir): install_cmd = "install -m 0644 %s/xen.gz %s/xen.gz" % \ (staging_kernel_dir, hdddir) exec_cmd(install_cmd) # Uncompressing xen with gzip.open('%s/xen.gz' % hdddir, 'rb') as f_in: with open('%s/xen' % hdddir, 'wb') as f_out: shutil.copyfileobj(f_in, f_out) # Creating core.img grub_dir_hdd = "%s/grub" % hdddir cls.do_install_core_image(grub_dir_hdd, native_sysroot) # Counting 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 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 label = part.label if part.label else "ESP" dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \ (label, 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 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 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) distro_arch = get_bitbake_var("DISTRO_ARCH") if not distro_arch: raise WicError("Couldn't find target architecture") if distro_arch == "amd64": grub_target = 'x86_64-efi' grub_image = "bootx64.efi" grub_modules = "multiboot efi_uga iorw ata " elif distro_arch == "i386": grub_target = 'i386-efi' grub_image = "bootia32.efi" grub_modules = "multiboot efi_uga iorw ata " elif distro_arch == "arm64": grub_target = 'arm64-efi' grub_image = "bootaa64.efi" grub_modules = "" else: raise WicError("grub-efi is incompatible with target %s" % distro_arch) bootimg_dir = "%s/hdd/boot" % cr_workdir if not os.path.isfile("%s/EFI/BOOT/%s" \ % (bootimg_dir, grub_image)): # TODO: check that grub-mkimage is available grub_cmd = "grub-mkimage -p /EFI/BOOT " grub_cmd += "-O %s -o %s/EFI/BOOT/%s " \ % (grub_target, bootimg_dir, grub_image) grub_cmd += "part_gpt part_msdos ntfs ntfscomp fat ext2 " grub_cmd += "normal chain boot configfile linux " grub_cmd += "search efi_gop font gfxterm gfxmenu " grub_cmd += "terminal minicmd test loadenv echo help " grub_cmd += "reboot serial terminfo iso9660 loopback tar " grub_cmd += "memdisk ls search_fs_uuid udf btrfs xfs lvm " grub_cmd += "reiserfs regexp " + grub_modules exec_cmd(grub_cmd) 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-isar loader: %s" % source_params['loader']) except KeyError: raise WicError( "bootimg-efi-isar 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_cmd(dosfs_cmd) mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) exec_cmd(mcopy_cmd, True) 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 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 kernel = get_bitbake_var("KERNEL_IMAGETYPE") if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1": if get_bitbake_var("INITRAMFS_IMAGE"): kernel = "%s-%s.bin" % \ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME")) if source_params.get('create-unified-kernel-image') == "true": initrd = source_params.get('initrd') if not initrd: raise WicError("initrd= must be specified when create-unified-kernel-image=true, exiting") deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") efi_stub = glob("%s/%s" % (deploy_dir, "linux*.efi.stub")) if len(efi_stub) == 0: raise WicError("Unified Kernel Image EFI stub not found, exiting") efi_stub = efi_stub[0] with tempfile.TemporaryDirectory() as tmp_dir: label = source_params.get('label') label_conf = "root=%s" % creator.rootdev if label: label_conf = "LABEL=%s" % label bootloader = creator.ks.bootloader cmdline = open("%s/cmdline" % tmp_dir, "w") cmdline.write("%s %s" % (label_conf, bootloader.append)) cmdline.close() initrds = initrd.split(';') initrd = open("%s/initrd" % tmp_dir, "wb") for f in initrds: with open("%s/%s" % (deploy_dir, f), 'rb') as in_file: shutil.copyfileobj(in_file, initrd) initrd.close() # Searched by systemd-boot: # https://systemd.io/BOOT_LOADER_SPECIFICATION/#type-2-efi-unified-kernel-images install_cmd = "install -d %s/EFI/Linux" % hdddir exec_cmd(install_cmd) staging_dir_host = get_bitbake_var("STAGING_DIR_HOST") # https://www.freedesktop.org/software/systemd/man/systemd-stub.html objcopy_cmd = "objcopy \ --add-section .osrel=%s --change-section-vma .osrel=0x20000 \ --add-section .cmdline=%s --change-section-vma .cmdline=0x30000 \ --add-section .linux=%s --change-section-vma .linux=0x2000000 \ --add-section .initrd=%s --change-section-vma .initrd=0x3000000 \ %s %s" % \ ("%s/usr/lib/os-release" % staging_dir_host, cmdline.name, "%s/%s" % (staging_kernel_dir, kernel), initrd.name, efi_stub, "%s/EFI/Linux/linux.efi" % hdddir) exec_cmd(objcopy_cmd) else: install_cmd = "install -m 0644 %s/%s %s/%s" % \ (staging_kernel_dir, kernel, hdddir, kernel) exec_cmd(install_cmd) if get_bitbake_var("IMAGE_EFI_BOOT_FILES"): for src_path, dst_path in cls.install_task: 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) 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 label = part.label if part.label else "ESP" dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \ (label, 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 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_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) cls.do_configure_grubefi(hdddir, creator, cr_workdir, source_params) if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None: logger.debug('No boot files defined in IMAGE_EFI_BOOT_FILES') else: 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_EFI_BOOT_FILES" + var) if boot_files: break 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))
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. """ syslinux_dir = cls._get_syslinux_dir(bootimg_dir) staging_kernel_dir = kernel_dir kernel_file = get_bitbake_var("KERNEL_FILE") kernel_name = get_bitbake_var("KERNEL_NAME") rootfs_dir = rootfs_dir['ROOTFS_DIR'] kernel = os.path.basename( os.path.realpath(os.path.join(rootfs_dir, kernel_file))) kernel_version = kernel[len(kernel_file) + 1:-(len(kernel_name) + 1)] initrd = "initrd.img-%s-%s" % (kernel_version, kernel_name) config = "config-%s-%s" % (kernel_version, kernel_name) mapfile = "System.map-%s-%s" % (kernel_version, kernel_name) hdddir = "%s/hdd/boot" % cr_workdir cmds = ("install -m 0644 %s/%s/%s %s/%s" % (rootfs_dir, "boot", kernel, hdddir, kernel), "install -m 0644 %s/%s/%s %s/%s" % (rootfs_dir, "boot", initrd, hdddir, initrd), "install -m 0644 %s/%s/%s %s/%s" % (rootfs_dir, "boot", config, hdddir, config), "install -m 0644 %s/%s/%s %s/%s" % (rootfs_dir, "boot", mapfile, hdddir, mapfile), "install -m 444 %s/modules/bios/ldlinux.c32 %s/ldlinux.c32" % (syslinux_dir, hdddir), "install -m 0644 %s/modules/bios/vesamenu.c32 %s/vesamenu.c32" % (syslinux_dir, hdddir), "install -m 444 %s/modules/bios/libcom32.c32 %s/libcom32.c32" % (syslinux_dir, hdddir), "install -m 444 %s/modules/bios/libutil.c32 %s/libutil.c32" % (syslinux_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.img" % cr_workdir 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_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_grub_cfg(cls, hdddir, creator, cr_workdir, source_params): """ Prepare grub.cfg """ bootloader = creator.ks.bootloader # search for partitions grubefi_conf = "search -l efi --no-floppy --set root\nset prefix=($root)/EFI/BOOT\n" grubefi_conf += "search -l primary --no-floppy --set rootfs2\n" grubefi_conf += "search -l secondary --no-floppy --set rootfs3\n" # Partition UUIDs partnum = 1 for part in creator.parts: grubefi_conf += "disk_partuuid%s=\"%s\"\n" % (partnum, part.uuid) partnum += 1 # default settings 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 # mender assumptions grubefi_conf += "mender_efi_uuid=${disk_partuuid1}\n" grubefi_conf += "mender_rootfsa_part=2\n" grubefi_conf += "mender_rootfsb_part=3\n" grubefi_conf += "mender_rootfsa_uuid=${disk_partuuid2}\n" grubefi_conf += "mender_rootfsb_uuid=${disk_partuuid3}\n" grubefi_conf += "mender_data_uuid=${disk_partuuid4}\n" # mender settings grubefi_conf += """ function maybe_pause { # By default we do nothing. debug-pause PACKAGECONFIG replaces this so we # can pause at strategic places. echo } MENDER_ENV1=${prefix}/mender_grubenv1/env MENDER_ENVPREFIX1=${prefix}/mender_grubenv1/ MENDER_LOCK1=${prefix}/mender_grubenv1/lock MENDER_LOCKSUM1=${prefix}/mender_grubenv1/lock.sha256sum MENDER_ENV2=${prefix}/mender_grubenv2/env MENDER_ENVPREFIX2=${prefix}/mender_grubenv2/ MENDER_LOCK2=${prefix}/mender_grubenv2/lock MENDER_LOCKSUM2=${prefix}/mender_grubenv2/lock.sha256sum function mender_check_and_restore_env { if ! hashsum --hash sha256 --prefix ${MENDER_ENVPREFIX2} --check ${MENDER_LOCKSUM2}; then load_env --skip-sig --file ${MENDER_ENV1} bootcount mender_boot_part upgrade_available save_env --file ${MENDER_ENV2} bootcount mender_boot_part upgrade_available editing=0 save_env --file ${MENDER_LOCK2} editing if ! hashsum --hash sha256 --prefix ${MENDER_ENVPREFIX2} --check ${MENDER_LOCKSUM2}; then echo "Environment 2 still corrupt after attempted restore. Halting." halt fi elif ! hashsum --hash sha256 --prefix ${MENDER_ENVPREFIX1} --check ${MENDER_LOCKSUM1}; then load_env --skip-sig --file ${MENDER_ENV2} bootcount mender_boot_part upgrade_available save_env --file ${MENDER_ENV1} bootcount mender_boot_part upgrade_available editing=0 save_env --file ${MENDER_LOCK1} editing if ! hashsum --hash sha256 --prefix ${MENDER_ENVPREFIX1} --check ${MENDER_LOCKSUM1}; then echo "Environment 1 still corrupt after attempted restore. Halting." halt fi fi } function mender_save_env { # Save redundant environment. editing=1 save_env --file ${MENDER_LOCK2} editing save_env --file ${MENDER_ENV2} bootcount mender_boot_part upgrade_available editing=0 save_env --file ${MENDER_LOCK2} editing editing=1 save_env --file ${MENDER_LOCK1} editing save_env --file ${MENDER_ENV1} bootcount mender_boot_part upgrade_available editing=0 save_env --file ${MENDER_LOCK1} editing } function mender_check_grubenv_valid { if [ "${mender_boot_part}" != "${mender_rootfsa_part}" -a "${mender_boot_part}" != "${mender_rootfsb_part}" ]; then return 1 fi if [ "${bootcount}" != "0" -a "${bootcount}" != "1" ]; then return 1 fi if [ "${upgrade_available}" != "0" -a "${upgrade_available}" != "1" ]; then return 1 fi return 0 } """ # mender setup grubefi_conf += """ mender_check_and_restore_env # Now load environment. # Skipping signatures?? Yes, because these values will change over time, so they # cannot be signed. There is also no checksum facility that will work for # changing values. Instead we check their content for validity. load_env --skip-sig --file ${MENDER_ENV1} bootcount mender_boot_part upgrade_available if ! mender_check_grubenv_valid; then if [ "${check_signatures}" == "enforce" ]; then echo "Unverified environment and signatures enabled. Halting." halt fi fi if [ "${upgrade_available}" = "1" ]; then if [ "${bootcount}" != "0" ]; then echo "Rolling back..." if [ "${mender_boot_part}" = "${mender_rootfsa_part}" ]; then mender_boot_part="${mender_rootfsb_part}" else mender_boot_part="${mender_rootfsa_part}" fi upgrade_available=0 bootcount=0 else echo "Booting new update..." bootcount=1 fi mender_save_env fi if [ "${mender_boot_part}" = "${mender_rootfsa_part}" ]; then mender_root="PARTLABEL=primary" elif [ "${mender_boot_part}" = "${mender_rootfsb_part}" ]; then mender_root="PARTLABEL=secondary" fi mender_info="" eval kernelroot=('${'rootfs${mender_boot_part}'}') """ # build date build_date = "echo 'Image built on %u (%s)'\n" % ( time.time(), datetime.datetime.utcnow()) # menu entries grubefi_conf += "menuentry 'boot %s' {\n" % source_params['boot_name'] # directly get the "$APPEND" variable from get_bitbake_var("APPEND") because there is concatenate # strings set in APPEND on bootloader.append from OE-Core which causing the string duplication. kernel = "bzImage-kernel" kernels = source_params['extra_kernels'] initrd = source_params['initrd'] var_append = get_bitbake_var("APPEND") grubefi_conf += " echo Using ${kernelroot}\n" grubefi_conf += " echo 'Loading kernel %s'\n" % kernel grubefi_conf += " linuxefi ${kernelroot}/boot/%s root=${mender_root} ${mender_info} %s\n" \ % (kernel, var_append) if initrd: grubefi_conf += " echo 'Loading initial ramdisk %s'\n" % initrd grubefi_conf += " initrdefi ${kernelroot}/boot/%s\n" % initrd grubefi_conf += build_date grubefi_conf += "}\n" if kernels: for k in re.compile("\s+").split(kernels.strip()): grubefi_conf += "menuentry 'boot %s' {\n" % k grubefi_conf += " echo Using ${kernelroot}\n" grubefi_conf += " echo 'Loading kernel %s'\n" % k grubefi_conf += " linuxefi ${kernelroot}/boot/bzImage-%s root=${mender_root} ${mender_info} %s\n" \ % (k, var_append) if 'initrd-' + k in source_params: initrd_spec = source_params['initrd-' + k] else: initrd_spec = initrd if initrd_spec: grubefi_conf += " echo 'Loading initial ramdisk %s'\n" % initrd_spec grubefi_conf += " initrdefi ${kernelroot}/boot/%s\n" % initrd_spec grubefi_conf += build_date grubefi_conf += "}\n" # fwsetup grubefi_conf += "menuentry 'Firmware Setup' {\n" grubefi_conf += " echo 'Rebooting into setup'\n" grubefi_conf += " fwsetup\n" grubefi_conf += "}\n" os.makedirs("%s/cpio/EFI/BOOT" % cr_workdir) cfg = open("%s/cpio/EFI/BOOT/grub.cfg" % cr_workdir, "w") cfg.write(grubefi_conf) cfg.close() # for embedding into grub image cpiofile = open("%s/grub.cpio" % cr_workdir, "wb") cpio = subprocess.Popen( ["cpio", "-o", "-H", "newc", "-D", "%s/cpio" % cr_workdir], stdin=subprocess.PIPE, stdout=cpiofile) cpio.communicate(b'.\n./EFI/BOOT/grub.cfg\n') cpio.wait() cpiofile.close() if cpio.returncode: raise WicError("cpio died with %d" % cpio.returncode)
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_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_file = get_bitbake_var("KERNEL_FILE") kernel_name = get_bitbake_var("KERNEL_NAME") rootfs_dir = get_bitbake_var("IMAGE_ROOTFS") kernel = os.path.basename( os.path.realpath(os.path.join(rootfs_dir, kernel_file))) kernel_version = kernel[len(kernel_file) + 1:-(len(kernel_name) + 1)] initrd = "initrd.img-%s-%s" % (kernel_version, kernel_name) syslinux_conf += "KERNEL " + kernel + "\n" syslinux_conf += "APPEND label=boot root=%s initrd=%s %s\n" % \ (creator.rootdev, initrd, 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_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
def do_prepare_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): 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") hdddir = "%s/hdd/" % cr_workdir machine_translated = get_bitbake_var('MACHINE_ARCH') #underscores in MACHINE_ARCH are replaced by - in filenames machine_translated = machine_translated.replace("_","-") kernel_stagingdir = get_bitbake_var("STAGING_KERNEL_BUILDDIR") rootfs = get_bitbake_var("IMAGE_ROOTFS") versionfile = open(kernel_stagingdir + "/kernel-abiversion", "r") kernelversion = versionfile.read().rstrip() versionfile.close() modulesname = "{0}/modules-{1}.tgz".format(kernel_dir, machine_translated) modulesname = os.readlink(modulesname) try: cp_cmd = "tar -xzf {0}/{1} --directory {2}".format(kernel_dir, modulesname, hdddir) exec_cmd(cp_cmd, True) except KeyError: raise WicError("error while copying kernel modules") try: cp_cmd = "/sbin/depmod --basedir \"{1}\" --config \"{0}/etc/depmod.d\" {2}".format(rootfs, hdddir, kernelversion) exec_cmd(cp_cmd, True) except KeyError: raise WicError("Failed to execute depmod on modules") du_cmd = "du -B 1 -s %s" % hdddir out = exec_cmd(du_cmd) size_bytes = int(out.split()[0]) size_bytes += 2**20 logger.debug("out: %s, final size: %d", out, size_bytes) # create filesystem image modulesimg = "%s/modules.img" % cr_workdir dosfs_cmd = "mksquashfs \"{0}/lib/modules/{1}\" {2} -b {3} -noI -noD -noF -noX -all-root ".format(hdddir, kernelversion, modulesimg, "4096") logger.debug("Executing: %s" % dosfs_cmd) exec_native_cmd(dosfs_cmd, native_sysroot) chmod_cmd = "chmod 644 %s" % modulesimg exec_cmd(chmod_cmd) du_cmd = "du -Lbks %s" % modulesimg out = exec_cmd(du_cmd) modulesimg_size = out.split()[0] part.size = int(modulesimg_size) part.source_file = modulesimg
def _parse(self, parser, confpath): """ Parse file in .wks format using provided parser. """ with open(confpath) as conf: lineno = 0 for line in conf: line = line.strip() lineno += 1 if line and line[0] != '#': line = expand_line(line) try: line_args = shlex.split(line) parsed = parser.parse_args(line_args) except ArgumentError as err: raise KickStartError('%s:%d: %s' % \ (confpath, lineno, err)) if line.startswith('part'): # SquashFS does not support filesystem UUID if parsed.fstype == 'squashfs': if parsed.fsuuid: err = "%s:%d: SquashFS does not support UUID" \ % (confpath, lineno) raise KickStartError(err) if parsed.label: err = "%s:%d: SquashFS does not support LABEL" \ % (confpath, lineno) raise KickStartError(err) if parsed.use_label and not parsed.label: err = "%s:%d: Must set the label with --label" \ % (confpath, lineno) raise KickStartError(err) # using ArgumentParser one cannot easily tell if option # was passed as argument, if said option has a default # value; --overhead-factor/--extra-space cannot be used # with --fixed-size, so at least detect when these were # passed with non-0 values ... if parsed.fixed_size: if parsed.overhead_factor or parsed.extra_space: err = "%s:%d: arguments --overhead-factor and --extra-space not "\ "allowed with argument --fixed-size" \ % (confpath, lineno) raise KickStartError(err) else: # ... and provide defaults if not using # --fixed-size iff given option was not used # (again, one cannot tell if option was passed but # with value equal to 0) if '--overhead-factor' not in line_args: parsed.overhead_factor = self.DEFAULT_OVERHEAD_FACTOR if '--extra-space' not in line_args: parsed.extra_space = self.DEFAULT_EXTRA_SPACE self.partnum += 1 self.partitions.append(Partition(parsed, self.partnum)) elif line.startswith('include'): self._parse(parser, parsed.path) elif line.startswith('bootloader'): if not self.bootloader: self.bootloader = parsed # Concatenate the strings set in APPEND append_var = get_bitbake_var("APPEND") if append_var: self.bootloader.append = ' '.join(filter(None, \ (self.bootloader.append, append_var))) else: err = "%s:%d: more than one bootloader specified" \ % (confpath, lineno) raise KickStartError(err)
def do_prepare_partition(cls, part, source_params, creator, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, native_sysroot): 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") hdddir = "%s/hdd/boot/" % cr_workdir machine = get_bitbake_var("MACHINE_ARCH") machine = machine.replace("_", "-") topdir = get_bitbake_var("TOPDIR") deploy_dir_image = get_bitbake_var("DEPLOY_DIR_IMAGE") sbsign_sysroot = get_bitbake_var("RECIPE_SYSROOT_NATIVE") sbsign_cmd = "{0}/usr/bin/sbsign".format(sbsign_sysroot) test_cert_dir = "{0}/test_certificates".format(topdir) secure_boot_signing_key = "{0}/ssig_subca.key".format(test_cert_dir) secure_boot_signing_cert = "{0}/ssig_subca.cert".format(test_cert_dir) kernelbin_link = "{0}/bzImage-initramfs-{1}.bin".format( deploy_dir_image, machine) kernelbin_path = "{0}/{1}".format(deploy_dir_image, os.readlink(kernelbin_link)) try: os.symlink("{0}.signed".format(kernelbin_path), "{0}.signed".format(kernelbin_link)) sign_cmd = '{0} --key "{1}" --cert "{2}" --output "{3}.signed" "{3}"'.format( sbsign_cmd, secure_boot_signing_key, secure_boot_signing_cert, kernelbin_path) exec_cmd(sign_cmd) try: cp_cmd = "cp {0} {1}/EFI/BOOT/BOOTX64.EFI".format( kernelbin_path, hdddir) exec_cmd(cp_cmd, True) except KeyError: raise WicError("error while copying kernel") except FileExistsError as e: bb.warn("Signed binary symlink already existing, skipping signing") 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 -C %s %d" % (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