summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Felsch <m.felsch@pengutronix.de>2024-01-26 14:16:31 +0100
committerKhem Raj <raj.khem@gmail.com>2024-10-09 15:47:23 -0700
commitb20be52a4ee5867cd0a21dc9891605e189c48219 (patch)
treec6489c23e3a5098ee68c44d08a2faa9254962bd8
parenta090cd3e0ef554d7171eb84488661599d72fa3e9 (diff)
downloadmeta-openembedded-b20be52a4ee5867cd0a21dc9891605e189c48219.tar.gz
fitimage: add support to build arbitrary FIT images
The FIT image support in OE is quite limited: 1) No support to build an arbitrary number of FIT images since the FIT image generation is tightly coupled to the kernel image. 2) A lot of U_BOOT-specific variables which may not be necessary for other bootloaders. 3) No usage of the meta-oe signing.bbclass for signed FIT images. This alternative class is added to solve the above-mentioned problems: 1) The class can be inherited by an arbitrary number of <fit-image-name>.bb recipes to generate FIT images 2) No U_BOOT-specific variables are used 3) <fit-image-name>.bb recipes can prepend the do_fitimage() to provide the key using the signing.bbclass e.g.: do_fitimage:prepend() { signing_prepare signing_use_role "${FITIMAGE_SIGNING_KEY_ROLE}" } Then enable and configure signing as follows: FITIMAGE_SIGN = "1" FITIMAGE_MKIMAGE_EXTRA_ARGS = "--engine pkcs11" FITIMAGE_SIGN_KEYDIR = "${PKCS11_URI} This class is inspired by the meta-phytec fitimage.bbclass [1]. [1] https://git.phytec.de/meta-phytec/tree/classes/fitimage.bbclass Signed-off-by: Marco Felsch <m.felsch@pengutronix.de> Signed-off-by: Enrico Jörns <ejo@pengutronix.de> Signed-off-by: Khem Raj <raj.khem@gmail.com>
-rw-r--r--meta-oe/classes/fitimage.bbclass530
1 files changed, 530 insertions, 0 deletions
diff --git a/meta-oe/classes/fitimage.bbclass b/meta-oe/classes/fitimage.bbclass
new file mode 100644
index 0000000000..78e30eca33
--- /dev/null
+++ b/meta-oe/classes/fitimage.bbclass
@@ -0,0 +1,530 @@
1# SPDX-License-Identifier: MIT
2#
3# Copyright PHYTEC Messtechnik GmbH
4# Copyright (C) 2024 Pengutronix, <yocto@pengutronix.de>
5#
6# Class for creating (signed) FIT images
7# Description:
8#
9# You have to define the 'images' to put in the FIT image in your recipe file
10# following this example:
11#
12# FITIMAGE_IMAGES ?= "kernel fdt fdto setup ramdisk bootscript"
13#
14# FITIMAGE_IMAGE_kernel ?= "virtual/kernel"
15# FITIMAGE_IMAGE_kernel[type] ?= "kernel"
16#
17# FITIMAGE_IMAGE_fdt ?= "virtual/dtb" # or "virtual/kernel"
18# FITIMAGE_IMAGE_fdt[type] ?= "fdt"
19# #FITIMAGE_IMAGE_fdt[file] ?= "hw-name.dtb"
20#
21# FITIMAGE_IMAGE_fdto ?= "virtual/kernel"
22# FITIMAGE_IMAGE_fdto[type] ?= "fdto"
23# FITIMAGE_IMAGE_fdto[file] ?= <list of all dtbo files from KERNEL_DEVICETREE>
24#
25# Add a devicetree created on-thy-fly of a base dtb and serveral dtbo's
26# FITIMAGE_IMAGE_fdtapply ?= "virtual/kernel"
27# FITIMAGE_IMAGE_fdtapply[type] ?= "fdtapply"
28# FITIMAGE_IMAGE_fdtapply[file] ?= "base.dtb overlay-1.dtbo overlay-2.dtbo"
29# FITIMAGE_IMAGE_fdtapply[name] ?= "<name for new generated fdt>"
30#
31# FITIMAGE_IMAGE_ramdisk ?= "core-image-minimal"
32# FITIMAGE_IMAGE_ramdisk[type] ?= "ramdisk"
33# FITIMAGE_IMAGE_ramdisk[fstype] ?= "cpio.gz"
34#
35# FITIMAGE_IMAGE_bootscript ?= "bootscript"
36# FITIMAGE_IMAGE_bootscript[type] ?= "bootscript"
37# FITIMAGE_IMAGE_bootscript[file] ?= "boot.scr"
38#
39# Valid options for the [type] varflag are: "kernel", "fdt", "fdto", "fdtapply", "ramdisk", "bootscript".
40#
41# To enable signing, set
42#
43# FITIMAGE_SIGN = "1"
44#
45# and configure FITIMAGE_SIGN_KEYDIR (and FITIMAGE_SIGN_KEYNAME) according to
46# your needs.
47#
48# For signing via PKCS#11 URIs provided by the meta-oe signing.bbclass, add:
49#
50# inherit signing
51#
52# FITIMAGE_SIGNING_KEY_ROLE = "fit"
53#
54# do_fitimage:prepend() {
55# signing_prepare
56# signing_use_role "${FITIMAGE_SIGNING_KEY_ROLE}"
57# }
58#
59# FITIMAGE_SIGN = "1"
60# FITIMAGE_MKIMAGE_EXTRA_ARGS = "--engine pkcs11"
61# FITIMAGE_SIGN_KEYDIR = "${PKCS11_URI}"
62
63
64LICENSE ?= "MIT"
65
66inherit deploy kernel-artifact-names image-artifact-names kernel-arch nopackages
67
68do_patch[noexec] = "1"
69do_compile[noexec] = "1"
70do_install[noexec] = "1"
71deltask do_populate_sysroot
72
73INHIBIT_DEFAULT_DEPS = "1"
74
75DEPENDS = "u-boot-mkimage-native dtc-native"
76
77FITIMAGE_SIGN ?= "0"
78FITIMAGE_SIGN[doc] = "Enable FIT image signing"
79FITIMAGE_SIGN_KEYDIR ?= ""
80FITIMAGE_SIGN_KEYDIR[doc] = "Key directory or pkcs#11 URI to use for signing configuration"
81FITIMAGE_MKIMAGE_EXTRA_ARGS[doc] = "Extra arguemnts to pass to uboot-mkimage call"
82FITIMAGE_HASH_ALGO ?= "sha256"
83FITIMAGE_HASH_ALGO[doc] = "Hash algorithm to use"
84FITIMAGE_ENCRYPT_ALGO ?= "rsa2048"
85FITIMAGE_ENCRYPT_ALGO[doc] = "Signature algorithm to use"
86FITIMAGE_CONFIG_PREFIX ?= "conf-"
87FITIMAGE_CONFIG_PREFIX[doc] = "Prefix to use for FIT configuration node name"
88
89FITIMAGE_LOADADDRESS ??= ""
90FITIMAGE_ENTRYPOINT ??= ""
91FITIMAGE_DTB_LOADADDRESS ??= ""
92FITIMAGE_DTB_OVERLAY_LOADADDRESS ??= ""
93FITIMAGE_RD_LOADADDRESS ??= ""
94FITIMAGE_RD_ENTRYPOINT ??= ""
95
96PACKAGE_ARCH = "${MACHINE_ARCH}"
97
98# Create dependency list from images
99python __anonymous() {
100 for image in (d.getVar('FITIMAGE_IMAGES') or "").split():
101 imageflags = d.getVarFlags('FITIMAGE_IMAGE_%s' % image, expand=['type', 'depends']) or {}
102 imgtype = imageflags.get('type')
103 if not imgtype:
104 bb.debug(1, "No [type] given for image '%s', defaulting to 'kernel'" % image)
105 imgtype = 'kernel'
106 recipe = d.getVar('FITIMAGE_IMAGE_%s' % image)
107
108 if not recipe:
109 bb.error("No recipe set for image '%s'. Specify via 'FITIMAGE_IMAGE_%s = \"<recipe-name>\"'" % (recipe, image))
110 return
111
112 d.appendVarFlag('do_unpack', 'vardeps', ' FITIMAGE_IMAGE_%s' % image)
113 depends = imageflags.get('depends')
114 if depends:
115 d.appendVarFlag('do_unpack', 'depends', ' ' + depends)
116 continue
117
118 if imgtype == 'ramdisk':
119 d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_image_complete')
120 elif 'fdt' in imgtype:
121 d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_populate_sysroot')
122 d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_deploy')
123 else:
124 d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_deploy')
125
126 if 'fdt' in imgtype and d.getVar('PREFERRED_PROVIDER_virtual/dtb'):
127 d.setVar('EXTERNAL_KERNEL_DEVICETREE', '${RECIPE_SYSROOT}/boot/devicetree')
128}
129
130S = "${WORKDIR}/sources"
131UNPACKDIR = "${S}"
132B = "${WORKDIR}/build"
133
134#
135# Emit the fitImage ITS header
136#
137def fitimage_emit_fit_header(d, fd):
138 fd.write('/dts-v1/;\n\n/ {\n')
139 fd.write(d.expand('\tdescription = "fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";\n'))
140 fd.write('\t#address-cells = <1>;\n')
141
142#
143# Emit the fitImage ITS footer
144#
145def fitimage_emit_fit_footer(d, fd):
146 fd.write('};\n')
147
148#
149# Emit the fitImage section
150#
151def fitimage_emit_section_start(d, fd, section):
152 fd.write(f'\t{section} {{\n')
153
154#
155# Emit the fitImage section end
156#
157def fitimage_emit_section_end(d, fd):
158 fd.write('\t};\n')
159
160def fitimage_emit_section_kernel(d, fd, imgpath, imgsource, imgcomp):
161 kernelcount = 1
162 kernel_csum = d.getVar("FITIMAGE_HASH_ALGO")
163 arch = d.getVar("ARCH")
164 loadaddr = d.getVar("FITIMAGE_LOADADDRESS")
165 entryaddr = d.getVar("FITIMAGE_ENTRYPOINT")
166
167 bb.note(f"Adding kernel-{kernelcount} section to ITS file")
168
169 fd.write(f'\t\tkernel-{kernelcount} {{\n')
170 fd.write('\t\t\tdescription = "Linux kernel";\n')
171 fd.write(f'\t\t\tdata = /incbin/("{imgpath}/{imgsource}");\n')
172 fd.write('\t\t\ttype = "kernel";\n')
173 fd.write(f'\t\t\tarch = "{arch}";\n')
174 fd.write('\t\t\tos = "linux";\n')
175 fd.write(f'\t\t\tcompression = "{imgcomp}";\n')
176 if (loadaddr):
177 fd.write(f'\t\t\tload = <{loadaddr}>;\n')
178 if (entryaddr):
179 fd.write(f'\t\t\tentry = <{entryaddr}>;\n')
180 fd.write('\t\t\thash-1 {\n')
181 fd.write(f'\t\t\t\talgo = "{kernel_csum}";\n')
182 fd.write('\t\t\t};\n')
183 fd.write('\t\t};\n')
184
185#
186# Emit the fitImage ITS DTB section
187#
188def _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, desc):
189 dtb_csum = d.getVar("FITIMAGE_HASH_ALGO")
190 arch = d.getVar("ARCH")
191
192 bb.note(f"Adding fdt-{dtb_file} section to ITS file")
193
194 fd.write(f'\t\tfdt-{dtb_file} {{\n')
195 fd.write(f'\t\t\tdescription = "{desc}";\n')
196 fd.write(f'\t\t\tdata = /incbin/("{dtb_path}/{dtb_file}");\n')
197 fd.write('\t\t\ttype = "flat_dt";\n')
198 fd.write(f'\t\t\tarch = "{arch}";\n')
199 fd.write('\t\t\tcompression = "none";\n')
200 if loadaddr:
201 fd.write(f'\t\t\tload = <{loadaddr}>;\n')
202 fd.write('\t\t\thash-1 {\n')
203 fd.write(f'\t\t\t\talgo = "{dtb_csum}";\n')
204 fd.write('\t\t\t};\n')
205 fd.write('\t\t};\n')
206
207
208def fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path):
209 loadaddr = d.getVar("FITIMAGE_DTB_LOADADDRESS")
210
211 _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, "Flattened Device Tree blob")
212
213#
214# Emit the fitImage ITS DTB overlay section
215#
216def fitimage_emit_section_dtb_overlay(d, fd, dtb_file, dtb_path):
217 loadaddr = d.getVar("FITIMAGE_DTB_OVERLAY_LOADADDRESS")
218
219 _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, "Flattened Device Tree Overlay blob")
220
221
222#
223# Emit the fitImage ITS ramdisk section
224#
225def fitimage_emit_section_ramdisk(d, fd, img_file, img_path):
226 ramdisk_count = "1"
227 ramdisk_csum = d.getVar("FITIMAGE_HASH_ALGO")
228 arch = d.getVar("ARCH")
229 loadaddr = d.getVar("FITIMAGE_RD_LOADADDRESS")
230 entryaddr = d.getVar("FITIMAGE_RD_ENTRYPOINT")
231
232 bb.note(f"Adding ramdisk-{ramdisk_count} section to ITS file")
233
234 fd.write(f'\t\tramdisk-{ramdisk_count} {{\n')
235 fd.write(f'\t\t\tdescription = "{img_file}";\n')
236 fd.write(f'\t\t\tdata = /incbin/("{img_path}/{img_file}");\n')
237 fd.write('\t\t\ttype = "ramdisk";\n')
238 fd.write(f'\t\t\tarch = "{arch}";\n')
239 fd.write('\t\t\tos = "linux";\n')
240 fd.write('\t\t\tcompression = "none";\n')
241 if (loadaddr):
242 fd.write(f'\t\t\tload = <{loadaddr}>;\n')
243 if (entryaddr):
244 fd.write(f'\t\t\tentry = <{entryaddr}>;\n')
245 fd.write('\t\t\thash-1 {\n')
246 fd.write(f'\t\t\t\talgo = "{ramdisk_csum}";\n')
247 fd.write('\t\t\t};\n')
248 fd.write('\t\t};\n')
249
250def fitimage_emit_section_bootscript(d, fd, imgpath, imgsource):
251 hash_algo = d.getVar("FITIMAGE_HASH_ALGO")
252 arch = d.getVar("ARCH")
253
254 bb.note(f"Adding bootscr-{imgsource} section to ITS file")
255
256 fd.write(f'\t\tbootscr-{imgsource} {{\n')
257 fd.write('\t\t\tdescription = "U-boot script";\n')
258 fd.write(f'\t\t\tdata = /incbin/("{imgpath}/{imgsource}");\n')
259 fd.write('\t\t\ttype = "script";\n')
260 fd.write(f'\t\t\tarch = "{arch}";\n')
261 fd.write('\t\t\tos = "linux";\n')
262 fd.write('\t\t\tcompression = "none";\n')
263 fd.write('\t\t\thash-1 {\n')
264 fd.write(f'\t\t\t\talgo = "{hash_algo}";\n')
265 fd.write('\t\t\t};\n')
266 fd.write('\t\t};\n')
267
268def fitimage_emit_subsection_signature(d, fd, sign_images_list):
269 hash_algo = d.getVar("FITIMAGE_HASH_ALGO")
270 encrypt_algo = d.getVar("FITIMAGE_ENCRYPT_ALGO") or ""
271 conf_sign_keyname = d.getVar("FITIMAGE_SIGN_KEYNAME")
272 signer_name = d.getVar("FITIMAGE_SIGNER")
273 signer_version = d.getVar("FITIMAGE_SIGNER_VERSION")
274 sign_images = ", ".join(f'"{s}"' for s in sign_images_list)
275
276 fd.write('\t\t\tsignature-1 {\n')
277 fd.write(f'\t\t\t\talgo = "{hash_algo},{encrypt_algo}";\n')
278 if conf_sign_keyname:
279 fd.write(f'\t\t\t\tkey-name-hint = {conf_sign_keyname}";\n')
280 fd.write(f'\t\t\t\tsign-images = {sign_images};\n')
281 fd.write(f'\t\t\t\tsigner-name = "{signer_name}";\n')
282 fd.write(f'\t\t\t\tsigner-version = "{signer_version}";\n')
283 fd.write('\t\t\t};\n')
284
285#
286# Emit the fitImage ITS configuration section
287#
288def fitimage_emit_section_config(d, fd, dtb, kernelcount, ramdiskcount, setupcount, bootscriptid, compatible, dtbcount):
289 sign = d.getVar("FITIMAGE_SIGN")
290 conf_default = None
291 conf_prefix = d.getVar('FITIMAGE_CONFIG_PREFIX', True) or ""
292
293 bb.note(f"Adding {dtb} section to ITS file")
294
295 conf_desc="Linux kernel"
296 if dtb:
297 conf_desc += ", FDT blob"
298 if ramdiskcount:
299 conf_desc += ", ramdisk"
300 if setupcount:
301 conf_desc += ", setup"
302 if bootscriptid:
303 conf_desc += ", u-boot script"
304 if dtbcount == 1:
305 conf_default = d.getVar('FITIMAGE_DEFAULT_CONFIG', True) or dtb
306
307 if conf_default:
308 fd.write(f'\t\tdefault = "{conf_default}";\n')
309 fd.write(f'\t\t{conf_prefix}{dtb} {{\n')
310 fd.write(f'\t\t\tdescription = "{dtbcount} {conf_desc}";\n')
311 if kernelcount:
312 fd.write('\t\t\tkernel = "kernel-1";\n')
313 fd.write(f'\t\t\tfdt = "fdt-{dtb}";\n')
314 if ramdiskcount:
315 fd.write(f'\t\t\tramdisk = "ramdisk-{ramdiskcount}";\n')
316 if bootscriptid:
317 fd.write(f'\t\t\tbootscr = "bootscr-{bootscriptid}";\n')
318 if compatible:
319 fd.write(f'\t\t\tcompatible = "{compatible}";\n')
320
321 if sign == "1":
322 sign_images = ["kernel"]
323 if dtb:
324 sign_images.append("fdt")
325 if ramdiskcount:
326 sign_images.append("ramdisk")
327 if setupcount:
328 sign_images.append("setup")
329 if bootscriptid:
330 sign_images.append("bootscr")
331 fitimage_emit_subsection_signature(d, fd, sign_images)
332
333 fd.write('\t\t' + '};\n')
334
335#
336# Emits a device tree overlay config section
337#
338def fitimage_emit_section_config_fdto(d, fd, dtb, compatible):
339 sign = d.getVar("FITIMAGE_SIGN")
340 bb.note("Adding overlay config section to ITS file")
341
342 fd.write(f'\t\t{dtb} {{\n')
343 fd.write(f'\t\t\tdescription = "Device Tree Overlay";\n')
344 fd.write(f'\t\t\tfdt = "fdt-{dtb}";')
345 if compatible:
346 fd.write(f'\t\t\tcompatible = "{compatible}";')
347
348 if sign == "1":
349 sign_images = ["fdt"]
350 fitimage_emit_subsection_signature(d, fd, sign_images)
351
352 fd.write('\t\t' + '};\n')
353
354python write_manifest() {
355 machine = d.getVar('MACHINE')
356 kernelcount=1
357 DTBS = ""
358 DTBOS = ""
359 ramdiskcount = ""
360 setupcount = ""
361 bootscriptid = ""
362 compatible = ""
363
364 def get_dtbs(d, dtb_suffix):
365 sysroot = d.getVar('RECIPE_SYSROOT')
366 deploydir = d.getVar('DEPLOY_DIR_IMAGE')
367
368 dtbs = (d.getVar('KERNEL_DEVICETREE') or '').split()
369 dtbs = [os.path.basename(x) for x in dtbs if x.endswith(dtb_suffix)]
370 ext_dtbs = os.listdir(d.getVar('EXTERNAL_KERNEL_DEVICETREE')) if d.getVar('EXTERNAL_KERNEL_DEVICETREE') else []
371 ext_dtbs = [x for x in ext_dtbs if x.endswith(dtb_suffix)]
372
373 result = []
374 # Prefer BSP dts if BSP and kernel provide the same dts
375 for d in sorted(set(dtbs + ext_dtbs)):
376 dtbpath = f'{sysroot}/boot/devicetree/{d}' if d in ext_dtbs else f'{deploydir}/{d}'
377 result.append(dtbpath)
378
379 return " ".join(result)
380
381 with open('%s/manifest.its' % d.getVar('B'), 'w') as fd:
382 images = d.getVar('FITIMAGE_IMAGES')
383 if not images:
384 bb.warn("No images specified in FITIMAGE_IMAGES. Generated FIT image will be empty")
385
386 fitimage_emit_fit_header(d, fd)
387 fitimage_emit_section_start(d, fd, 'images')
388
389 for image in (images or "").split():
390 imageflags = d.getVarFlags('FITIMAGE_IMAGE_%s' % image, expand=['file', 'fstype', 'type', 'comp']) or {}
391 imgtype = imageflags.get('type', '')
392 if imgtype == 'kernel':
393 default = "%s-%s%s" % (d.getVar('KERNEL_IMAGETYPE'), machine, d.getVar('KERNEL_IMAGE_BIN_EXT'))
394 imgsource = imageflags.get('file', default)
395 imgcomp = imageflags.get('comp', 'none')
396 imgpath = d.getVar("DEPLOY_DIR_IMAGE")
397 fitimage_emit_section_kernel(d, fd, imgpath, imgsource, imgcomp)
398 elif imgtype == 'fdt':
399 default = get_dtbs(d, "dtb")
400 dtbfiles = imageflags.get('file', default)
401 if not dtbfiles:
402 bb.fatal(f"No dtb file found for image '{image}'. Set KERNEL_DEVICETREE, [file] varflag, or reference devicetree.bbclass-based recipe.")
403 for dtb in dtbfiles.split():
404 dtb_path, dtb_file = os.path.split(dtb)
405 DTBS += f" {dtb}"
406 fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path)
407 elif imgtype == 'fdto':
408 default = get_dtbs(d, "dtbo")
409 dtbofiles = imageflags.get('file', default)
410 if not dtbofiles:
411 bb.fatal(f"No dtbo file found for image '{image}'. Set KERNEL_DEVICETREE, [file] varflag, or reference devicetree.bbclass-based recipe.")
412 for dtb in dtbofiles.split():
413 dtb_path, dtb_file = os.path.split(dtb)
414 DTBOS = DTBOS + " " + dtb
415 fitimage_emit_section_dtb_overlay(d, fd, dtb_file, dtb_path)
416 elif imgtype == 'fdtapply':
417 import subprocess
418 dtbofiles = imageflags.get('file', None)
419 if not dtbofiles:
420 bb.fatal(f"No dtbo file found for image '{image}'. Set via [file] varflag.")
421 dtboutname = imageflags.get('name', None)
422 if not dtboutname:
423 bb.fatal(f"No dtb output name found for image '{image}'. Set via [name] varflag.")
424 dtbresult = "%s/%s" % (d.getVar('B'), dtboutname)
425 dtbcommand = ""
426 for dtb in dtbofiles.split():
427 dtb_path, dtb_file = os.path.split(dtb)
428 if not dtb_path:
429 dtb_path = d.getVar("DEPLOY_DIR_IMAGE")
430 if not dtbcommand:
431 if not dtb_file.endswith('.dtb'):
432 bb.fatal(f"fdtapply failed: Expected (non-overlay) .dtb file as first element, but got {dtb_file}")
433 dtbcommand = f"fdtoverlay -i {dtb_path}/{dtb_file} -o {dtbresult}"
434 else:
435 if not dtb_file.endswith('.dtbo'):
436 bb.fatal(f"fdtapply failed: Expected .dtbo file, but got {dtb_file}")
437 dtbcommand += f" {dtb_path}/{dtb_file}"
438 result = subprocess.run(dtbcommand, stderr=subprocess.PIPE, shell=True, text=True)
439 if result.returncode != 0:
440 bb.fatal(f"Running {dtbcommand} failed: {result.stderr}")
441 dtb_path, dtb_file = os.path.split(dtbresult)
442 DTBS += f" {dtbresult}"
443 fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path)
444 elif imgtype == 'ramdisk':
445 ramdiskcount = "1"
446 default_imgfstype = d.getVar('INITRAMFS_FSTYPES' or "").split()[0]
447 img_fstype = imageflags.get('fstype', default_imgfstype)
448 img_file = "%s%s.%s" % (d.getVar('FITIMAGE_IMAGE_%s' % image), d.getVar('IMAGE_MACHINE_SUFFIX'), img_fstype)
449 img_path = d.getVar("DEPLOY_DIR_IMAGE")
450 fitimage_emit_section_ramdisk(d, fd, img_file, img_path)
451 elif imgtype == 'bootscript':
452 if bootscriptid:
453 bb.fatal("Only a single boot script is supported (already set to: %s)" % bootscriptid)
454 imgsource = imageflags.get('file', None)
455 imgpath = d.getVar("DEPLOY_DIR_IMAGE")
456 bootscriptid = imgsource
457 fitimage_emit_section_bootscript(d, fd, imgpath, imgsource)
458 fitimage_emit_section_end(d, fd)
459 #
460 # Step 5: Prepare a configurations section
461 #
462 fitimage_emit_section_start(d, fd, 'configurations')
463 dtbcount = 1
464 for dtb in (DTBS or "").split():
465 import subprocess
466 try:
467 cmd = "fdtget -t s {} / compatible".format(dtb)
468 compatible = subprocess.check_output(cmd, shell=True, text=True).split()[0]
469 except subprocess.CalledProcessError:
470 bb.fatal("Failed to find root-node compatible string in (%s)" % dtb)
471
472 dtb_path, dtb_file = os.path.split(dtb)
473 fitimage_emit_section_config(d, fd, dtb_file, kernelcount, ramdiskcount, setupcount, bootscriptid, compatible, dtbcount)
474 dtbcount += 1
475 for dtb in (DTBOS or "").split():
476 import subprocess
477 try:
478 cmd = "fdtget -t s {} / compatible".format(dtb)
479 compatible = subprocess.check_output(cmd, shell=True, text=True).split()[0]
480 except subprocess.CalledProcessError:
481 bb.note("Failed to find root-node compatible string in (%s)" % dtb)
482 compatible = None
483
484 dtb_path, dtb_file = os.path.split(dtb)
485 fitimage_emit_section_config_fdto(d, fd, dtb_file, compatible)
486
487 fitimage_emit_section_end(d, fd)
488 fitimage_emit_fit_footer(d, fd)
489}
490
491do_configure[postfuncs] += "write_manifest"
492
493do_fitimage () {
494 if [ "${FITIMAGE_SIGN}" = "1" ]; then
495 uboot-mkimage ${FITIMAGE_MKIMAGE_EXTRA_ARGS} \
496 -k ${FITIMAGE_SIGN_KEYDIR} -r \
497 -f "${B}/manifest.its" \
498 "${B}/fitImage"
499 else
500 uboot-mkimage ${FITIMAGE_MKIMAGE_EXTRA_ARGS} \
501 -f "${B}/manifest.its" \
502 "${B}/fitImage"
503 fi
504}
505addtask fitimage after do_configure
506
507ITS_NAME ?= "${PN}-${KERNEL_ARTIFACT_NAME}"
508ITS_LINK_NAME ?= "${PN}-${KERNEL_ARTIFACT_LINK_NAME}"
509FITIMAGE_IMAGE_NAME ?= "fitImage-${PN}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}"
510FITIMAGE_IMAGE_LINK_NAME ?= "fitImage-${PN}-${KERNEL_FIT_LINK_NAME}"
511
512SSTATE_SKIP_CREATION:task-deploy = '1'
513
514do_deploy() {
515 bbnote 'Copying fit-image.its source file...'
516 install -m 0644 ${B}/manifest.its ${DEPLOYDIR}/${ITS_NAME}.its
517
518 bbnote 'Copying all created fdt from type fdtapply'
519 for DTB_FILE in `find ${B} -maxdepth 1 -name *.dtb`; do
520 install -m 0644 ${DTB_FILE} ${DEPLOYDIR}/
521 done
522
523 bbnote 'Copying fitImage file...'
524 install -m 0644 ${B}/fitImage ${DEPLOYDIR}/${FITIMAGE_IMAGE_NAME}
525
526 cd ${DEPLOYDIR}
527 ln -sf ${ITS_NAME}.its ${ITS_LINK_NAME}.its
528 ln -sf ${FITIMAGE_IMAGE_NAME} ${FITIMAGE_IMAGE_LINK_NAME}
529}
530addtask deploy after do_fitimage before do_build