1# 2# Copyright OpenEmbedded Contributors 3# 4# SPDX-License-Identifier: GPL-2.0-only 5# 6# DESCRIPTION 7# This implements the 'bootimg-partition' source plugin class for 8# 'wic'. The plugin creates an image of boot partition, copying over 9# files listed in IMAGE_BOOT_FILES bitbake variable. 10# 11# AUTHORS 12# Maciej Borzecki <maciej.borzecki (at] open-rnd.pl> 13# 14 15import logging 16import os 17import re 18 19from oe.bootfiles import get_boot_files 20 21from wic import WicError 22from wic.engine import get_custom_config 23from wic.pluginbase import SourcePlugin 24from wic.misc import exec_cmd, get_bitbake_var 25 26logger = logging.getLogger('wic') 27 28class BootimgPartitionPlugin(SourcePlugin): 29 """ 30 Create an image of boot partition, copying over files 31 listed in IMAGE_BOOT_FILES bitbake variable. 32 """ 33 34 name = 'bootimg-partition' 35 image_boot_files_var_name = 'IMAGE_BOOT_FILES' 36 37 @classmethod 38 def do_configure_partition(cls, part, source_params, cr, cr_workdir, 39 oe_builddir, bootimg_dir, kernel_dir, 40 native_sysroot): 41 """ 42 Called before do_prepare_partition(), create u-boot specific boot config 43 """ 44 hdddir = "%s/boot.%d" % (cr_workdir, part.lineno) 45 install_cmd = "install -d %s" % hdddir 46 exec_cmd(install_cmd) 47 48 if not kernel_dir: 49 kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 50 if not kernel_dir: 51 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") 52 53 boot_files = None 54 for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)): 55 if fmt: 56 var = fmt % id 57 else: 58 var = "" 59 60 boot_files = get_bitbake_var(cls.image_boot_files_var_name + var) 61 if boot_files is not None: 62 break 63 64 if boot_files is None: 65 raise WicError('No boot files defined, %s unset for entry #%d' % (cls.image_boot_files_var_name, part.lineno)) 66 67 logger.debug('Boot files: %s', boot_files) 68 69 cls.install_task = get_boot_files(kernel_dir, boot_files) 70 if source_params.get('loader') != "u-boot": 71 return 72 73 configfile = cr.ks.bootloader.configfile 74 custom_cfg = None 75 if configfile: 76 custom_cfg = get_custom_config(configfile) 77 if custom_cfg: 78 # Use a custom configuration for extlinux.conf 79 extlinux_conf = custom_cfg 80 logger.debug("Using custom configuration file " 81 "%s for extlinux.conf", configfile) 82 else: 83 raise WicError("configfile is specified but failed to " 84 "get it from %s." % configfile) 85 86 if not custom_cfg: 87 # The kernel types supported by the sysboot of u-boot 88 kernel_types = ["zImage", "Image", "fitImage", "uImage", "vmlinux"] 89 has_dtb = False 90 fdt_dir = '/' 91 kernel_name = None 92 93 # Find the kernel image name, from the highest precedence to lowest 94 for image in kernel_types: 95 for task in cls.install_task: 96 src, dst = task 97 if re.match(image, src): 98 kernel_name = os.path.join('/', dst) 99 break 100 if kernel_name: 101 break 102 103 for task in cls.install_task: 104 src, dst = task 105 # We suppose that all the dtb are in the same directory 106 if re.search(r'\.dtb', src) and fdt_dir == '/': 107 has_dtb = True 108 fdt_dir = os.path.join(fdt_dir, os.path.dirname(dst)) 109 break 110 111 if not kernel_name: 112 raise WicError('No kernel file found') 113 114 # Compose the extlinux.conf 115 extlinux_conf = "default Yocto\n" 116 extlinux_conf += "label Yocto\n" 117 extlinux_conf += " kernel %s\n" % kernel_name 118 if has_dtb: 119 extlinux_conf += " fdtdir %s\n" % fdt_dir 120 bootloader = cr.ks.bootloader 121 extlinux_conf += "append root=%s rootwait %s\n" \ 122 % (cr.rootdev, bootloader.append if bootloader.append else '') 123 124 install_cmd = "install -d %s/extlinux/" % hdddir 125 exec_cmd(install_cmd) 126 cfg = open("%s/extlinux/extlinux.conf" % hdddir, "w") 127 cfg.write(extlinux_conf) 128 cfg.close() 129 130 131 @classmethod 132 def do_prepare_partition(cls, part, source_params, cr, cr_workdir, 133 oe_builddir, bootimg_dir, kernel_dir, 134 rootfs_dir, native_sysroot): 135 """ 136 Called to do the actual content population for a partition i.e. it 137 'prepares' the partition to be incorporated into the image. 138 In this case, does the following: 139 - sets up a vfat partition 140 - copies all files listed in IMAGE_BOOT_FILES variable 141 """ 142 hdddir = "%s/boot.%d" % (cr_workdir, part.lineno) 143 144 if not kernel_dir: 145 kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") 146 if not kernel_dir: 147 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") 148 149 logger.debug('Kernel dir: %s', bootimg_dir) 150 151 152 for task in cls.install_task: 153 src_path, dst_path = task 154 logger.debug('Install %s as %s', src_path, dst_path) 155 install_cmd = "install -m 0644 -D %s %s" \ 156 % (os.path.join(kernel_dir, src_path), 157 os.path.join(hdddir, dst_path)) 158 exec_cmd(install_cmd) 159 160 logger.debug('Prepare boot partition using rootfs in %s', hdddir) 161 part.prepare_rootfs(cr_workdir, oe_builddir, hdddir, 162 native_sysroot, False) 163