blob: 8956162205663c46b70d44b7a8881ba19c0cacdf [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#
Patrick Williams92b42cb2022-09-03 06:53:57 -05002# Copyright OpenEmbedded Contributors
3#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -05005#
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
Brad Bishop6e60e8b2018-02-01 10:27:11 -050015import logging
Patrick Williamsc124f4f2015-09-15 14:41:29 -050016import os
17import re
18
Patrick Williamsc124f4f2015-09-15 14:41:29 -050019from glob import glob
20
Brad Bishop6e60e8b2018-02-01 10:27:11 -050021from wic import WicError
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080022from wic.engine import get_custom_config
Brad Bishop6e60e8b2018-02-01 10:27:11 -050023from wic.pluginbase import SourcePlugin
Brad Bishopd7bf8c12018-02-25 22:55:05 -050024from wic.misc import exec_cmd, get_bitbake_var
Brad Bishop6e60e8b2018-02-01 10:27:11 -050025
26logger = logging.getLogger('wic')
27
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028class 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
36 @classmethod
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080037 def do_configure_partition(cls, part, source_params, cr, cr_workdir,
Patrick Williamsc124f4f2015-09-15 14:41:29 -050038 oe_builddir, bootimg_dir, kernel_dir,
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080039 native_sysroot):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050040 """
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080041 Called before do_prepare_partition(), create u-boot specific boot config
Patrick Williamsc124f4f2015-09-15 14:41:29 -050042 """
Brad Bishopd7bf8c12018-02-25 22:55:05 -050043 hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050044 install_cmd = "install -d %s" % hdddir
45 exec_cmd(install_cmd)
46
Brad Bishop6e60e8b2018-02-01 10:27:11 -050047 if not kernel_dir:
48 kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
49 if not kernel_dir:
50 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050051
Brad Bishopd7bf8c12018-02-25 22:55:05 -050052 boot_files = None
53 for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)):
54 if fmt:
55 var = fmt % id
56 else:
57 var = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058
Brad Bishopd7bf8c12018-02-25 22:55:05 -050059 boot_files = get_bitbake_var("IMAGE_BOOT_FILES" + var)
60 if boot_files is not None:
61 break
62
63 if boot_files is None:
64 raise WicError('No boot files defined, IMAGE_BOOT_FILES unset for entry #%d' % part.lineno)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065
Brad Bishop6e60e8b2018-02-01 10:27:11 -050066 logger.debug('Boot files: %s', boot_files)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050067
68 # list of tuples (src_name, dst_name)
69 deploy_files = []
70 for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files):
71 if ';' in src_entry:
72 dst_entry = tuple(src_entry.split(';'))
73 if not dst_entry[0] or not dst_entry[1]:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050074 raise WicError('Malformed boot file entry: %s' % src_entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075 else:
76 dst_entry = (src_entry, src_entry)
77
Brad Bishop6e60e8b2018-02-01 10:27:11 -050078 logger.debug('Destination entry: %r', dst_entry)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050079 deploy_files.append(dst_entry)
80
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080081 cls.install_task = [];
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082 for deploy_entry in deploy_files:
83 src, dst = deploy_entry
Patrick Williamsc124f4f2015-09-15 14:41:29 -050084 if '*' in src:
85 # by default install files under their basename
86 entry_name_fn = os.path.basename
87 if dst != src:
88 # unless a target name was given, then treat name
89 # as a directory and append a basename
90 entry_name_fn = lambda name: \
91 os.path.join(dst,
92 os.path.basename(name))
93
Brad Bishop6e60e8b2018-02-01 10:27:11 -050094 srcs = glob(os.path.join(kernel_dir, src))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095
Brad Bishop6e60e8b2018-02-01 10:27:11 -050096 logger.debug('Globbed sources: %s', ', '.join(srcs))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 for entry in srcs:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080098 src = os.path.relpath(entry, kernel_dir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050099 entry_dst_name = entry_name_fn(entry)
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800100 cls.install_task.append((src, entry_dst_name))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500101 else:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800102 cls.install_task.append((src, dst))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500103
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800104 if source_params.get('loader') != "u-boot":
105 return
106
107 configfile = cr.ks.bootloader.configfile
108 custom_cfg = None
109 if configfile:
110 custom_cfg = get_custom_config(configfile)
111 if custom_cfg:
112 # Use a custom configuration for extlinux.conf
113 extlinux_conf = custom_cfg
114 logger.debug("Using custom configuration file "
115 "%s for extlinux.cfg", configfile)
116 else:
117 raise WicError("configfile is specified but failed to "
118 "get it from %s." % configfile)
119
120 if not custom_cfg:
121 # The kernel types supported by the sysboot of u-boot
122 kernel_types = ["zImage", "Image", "fitImage", "uImage", "vmlinux"]
123 has_dtb = False
124 fdt_dir = '/'
125 kernel_name = None
126
127 # Find the kernel image name, from the highest precedence to lowest
128 for image in kernel_types:
129 for task in cls.install_task:
130 src, dst = task
131 if re.match(image, src):
132 kernel_name = os.path.join('/', dst)
133 break
134 if kernel_name:
135 break
136
137 for task in cls.install_task:
138 src, dst = task
139 # We suppose that all the dtb are in the same directory
140 if re.search(r'\.dtb', src) and fdt_dir == '/':
141 has_dtb = True
142 fdt_dir = os.path.join(fdt_dir, os.path.dirname(dst))
143 break
144
145 if not kernel_name:
Andrew Geissler635e0e42020-08-21 15:58:33 -0500146 raise WicError('No kernel file found')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800147
148 # Compose the extlinux.conf
149 extlinux_conf = "default Yocto\n"
150 extlinux_conf += "label Yocto\n"
151 extlinux_conf += " kernel %s\n" % kernel_name
152 if has_dtb:
153 extlinux_conf += " fdtdir %s\n" % fdt_dir
154 bootloader = cr.ks.bootloader
155 extlinux_conf += "append root=%s rootwait %s\n" \
156 % (cr.rootdev, bootloader.append if bootloader.append else '')
157
158 install_cmd = "install -d %s/extlinux/" % hdddir
159 exec_cmd(install_cmd)
160 cfg = open("%s/extlinux/extlinux.conf" % hdddir, "w")
161 cfg.write(extlinux_conf)
162 cfg.close()
163
164
165 @classmethod
166 def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
167 oe_builddir, bootimg_dir, kernel_dir,
168 rootfs_dir, native_sysroot):
169 """
170 Called to do the actual content population for a partition i.e. it
171 'prepares' the partition to be incorporated into the image.
172 In this case, does the following:
173 - sets up a vfat partition
174 - copies all files listed in IMAGE_BOOT_FILES variable
175 """
176 hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
177
178 if not kernel_dir:
179 kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
180 if not kernel_dir:
181 raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
182
183 logger.debug('Kernel dir: %s', bootimg_dir)
184
185
186 for task in cls.install_task:
187 src_path, dst_path = task
188 logger.debug('Install %s as %s', src_path, dst_path)
189 install_cmd = "install -m 0644 -D %s %s" \
190 % (os.path.join(kernel_dir, src_path),
191 os.path.join(hdddir, dst_path))
192 exec_cmd(install_cmd)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500193
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500194 logger.debug('Prepare boot partition using rootfs in %s', hdddir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 part.prepare_rootfs(cr_workdir, oe_builddir, hdddir,
Brad Bishop316dfdd2018-06-25 12:45:53 -0400196 native_sysroot, False)