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
Example #2
0
    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)
Example #3
0
    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)
Example #5
0
    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
Example #6
0
    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])
Example #7
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")
Example #8
0
    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():]
Example #10
0
    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()
Example #11
0
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")
Example #13
0
    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)
Example #15
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 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()
Example #17
0
    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)
Example #21
0
    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)
Example #22
0
    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()
Example #23
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 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
Example #24
0
    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
                               oe_builddir, bootimg_dir, kernel_dir,
                               native_sysroot):
        """
        Called before do_prepare_partition(), creates loader-specific config
        """
        hdddir = "%s/hdd/boot" % cr_workdir

        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
Example #25
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 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
Example #26
0
    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
Example #28
0
    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)
Example #29
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 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
Example #30
0
    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])
Example #31
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
Example #32
0
    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
Example #33
0
    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)
Example #34
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 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
Example #35
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 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
Example #36
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 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
Example #37
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 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
Example #38
0
    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
                               oe_builddir, bootimg_dir, kernel_dir,
                               native_sysroot):
        """
        Called before do_prepare_partition(), creates loader-specific config
        """
        hdddir = "%s/hdd/boot" % cr_workdir

        install_cmd = "install -d %s/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))
Example #39
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 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
Example #40
0
    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()
Example #42
0
    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
                               oe_builddir, bootimg_dir, kernel_dir,
                               native_sysroot):
        """
        Called before do_prepare_partition(), creates 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
Example #44
0
    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
Example #45
0
    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)
Example #46
0
    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