summaryrefslogtreecommitdiffstats
path: root/meta-oe/classes/fitimage.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/classes/fitimage.bbclass')
-rw-r--r--meta-oe/classes/fitimage.bbclass540
1 files changed, 540 insertions, 0 deletions
diff --git a/meta-oe/classes/fitimage.bbclass b/meta-oe/classes/fitimage.bbclass
new file mode 100644
index 0000000000..03fa2fcd57
--- /dev/null
+++ b/meta-oe/classes/fitimage.bbclass
@@ -0,0 +1,540 @@
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.fatal(f"No recipe set for image '{image}'. Specify via 'FITIMAGE_IMAGE_{image} = \"<recipe-name>\"'")
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 = "${UNPACKDIR}"
131B = "${WORKDIR}/build"
132
133#
134# Emit the fitImage ITS header
135#
136def fitimage_emit_fit_header(d, fd):
137 fd.write('/dts-v1/;\n\n/ {\n')
138 fd.write(d.expand('\tdescription = "fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";\n'))
139 fd.write('\t#address-cells = <1>;\n')
140
141#
142# Emit the fitImage ITS footer
143#
144def fitimage_emit_fit_footer(d, fd):
145 fd.write('};\n')
146
147#
148# Emit the fitImage section
149#
150def fitimage_emit_section_start(d, fd, section):
151 fd.write(f'\t{section} {{\n')
152
153#
154# Emit the fitImage section end
155#
156def fitimage_emit_section_end(d, fd):
157 fd.write('\t};\n')
158
159def fitimage_emit_section_kernel(d, fd, imgpath, imgsource, imgcomp):
160 kernelcount = 1
161 kernel_csum = d.getVar("FITIMAGE_HASH_ALGO")
162 arch = d.getVar("ARCH")
163 loadaddr = d.getVar("FITIMAGE_LOADADDRESS")
164 entryaddr = d.getVar("FITIMAGE_ENTRYPOINT")
165
166 bb.note(f"Adding kernel-{kernelcount} section to ITS file")
167
168 fd.write(f'\t\tkernel-{kernelcount} {{\n')
169 fd.write('\t\t\tdescription = "Linux kernel";\n')
170 fd.write(f'\t\t\tdata = /incbin/("{imgpath}/{imgsource}");\n')
171 fd.write('\t\t\ttype = "kernel";\n')
172 fd.write(f'\t\t\tarch = "{arch}";\n')
173 fd.write('\t\t\tos = "linux";\n')
174 fd.write(f'\t\t\tcompression = "{imgcomp}";\n')
175 if (loadaddr):
176 fd.write(f'\t\t\tload = <{loadaddr}>;\n')
177 if (entryaddr):
178 fd.write(f'\t\t\tentry = <{entryaddr}>;\n')
179 fd.write('\t\t\thash-1 {\n')
180 fd.write(f'\t\t\t\talgo = "{kernel_csum}";\n')
181 fd.write('\t\t\t};\n')
182 fd.write('\t\t};\n')
183
184#
185# Emit the fitImage ITS DTB section
186#
187def _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, desc):
188 dtb_csum = d.getVar("FITIMAGE_HASH_ALGO")
189 arch = d.getVar("ARCH")
190
191 bb.note(f"Adding fdt-{dtb_file} section to ITS file")
192
193 fd.write(f'\t\tfdt-{dtb_file} {{\n')
194 fd.write(f'\t\t\tdescription = "{desc}";\n')
195 fd.write(f'\t\t\tdata = /incbin/("{dtb_path}/{dtb_file}");\n')
196 fd.write('\t\t\ttype = "flat_dt";\n')
197 fd.write(f'\t\t\tarch = "{arch}";\n')
198 fd.write('\t\t\tcompression = "none";\n')
199 if loadaddr:
200 fd.write(f'\t\t\tload = <{loadaddr}>;\n')
201 fd.write('\t\t\thash-1 {\n')
202 fd.write(f'\t\t\t\talgo = "{dtb_csum}";\n')
203 fd.write('\t\t\t};\n')
204 fd.write('\t\t};\n')
205
206
207def fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path):
208 loadaddr = d.getVar("FITIMAGE_DTB_LOADADDRESS")
209
210 _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, "Flattened Device Tree blob")
211
212#
213# Emit the fitImage ITS DTB overlay section
214#
215def fitimage_emit_section_dtb_overlay(d, fd, dtb_file, dtb_path):
216 loadaddr = d.getVar("FITIMAGE_DTB_OVERLAY_LOADADDRESS")
217
218 _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, "Flattened Device Tree Overlay blob")
219
220
221#
222# Emit the fitImage ITS ramdisk section
223#
224def fitimage_emit_section_ramdisk(d, fd, img_file, img_path):
225 ramdisk_count = "1"
226 ramdisk_csum = d.getVar("FITIMAGE_HASH_ALGO")
227 arch = d.getVar("ARCH")
228 loadaddr = d.getVar("FITIMAGE_RD_LOADADDRESS")
229 entryaddr = d.getVar("FITIMAGE_RD_ENTRYPOINT")
230
231 bb.note(f"Adding ramdisk-{ramdisk_count} section to ITS file")
232
233 fd.write(f'\t\tramdisk-{ramdisk_count} {{\n')
234 fd.write(f'\t\t\tdescription = "{img_file}";\n')
235 fd.write(f'\t\t\tdata = /incbin/("{img_path}/{img_file}");\n')
236 fd.write('\t\t\ttype = "ramdisk";\n')
237 fd.write(f'\t\t\tarch = "{arch}";\n')
238 fd.write('\t\t\tos = "linux";\n')
239 fd.write('\t\t\tcompression = "none";\n')
240 if (loadaddr):
241 fd.write(f'\t\t\tload = <{loadaddr}>;\n')
242 if (entryaddr):
243 fd.write(f'\t\t\tentry = <{entryaddr}>;\n')
244 fd.write('\t\t\thash-1 {\n')
245 fd.write(f'\t\t\t\talgo = "{ramdisk_csum}";\n')
246 fd.write('\t\t\t};\n')
247 fd.write('\t\t};\n')
248
249def fitimage_emit_section_bootscript(d, fd, imgpath, imgsource):
250 hash_algo = d.getVar("FITIMAGE_HASH_ALGO")
251 arch = d.getVar("ARCH")
252
253 bb.note(f"Adding bootscr-{imgsource} section to ITS file")
254
255 fd.write(f'\t\tbootscr-{imgsource} {{\n')
256 fd.write('\t\t\tdescription = "U-boot script";\n')
257 fd.write(f'\t\t\tdata = /incbin/("{imgpath}/{imgsource}");\n')
258 fd.write('\t\t\ttype = "script";\n')
259 fd.write(f'\t\t\tarch = "{arch}";\n')
260 fd.write('\t\t\tos = "linux";\n')
261 fd.write('\t\t\tcompression = "none";\n')
262 fd.write('\t\t\thash-1 {\n')
263 fd.write(f'\t\t\t\talgo = "{hash_algo}";\n')
264 fd.write('\t\t\t};\n')
265 fd.write('\t\t};\n')
266
267def fitimage_emit_subsection_signature(d, fd, sign_images_list):
268 hash_algo = d.getVar("FITIMAGE_HASH_ALGO")
269 encrypt_algo = d.getVar("FITIMAGE_ENCRYPT_ALGO") or ""
270 conf_sign_keyname = d.getVar("FITIMAGE_SIGN_KEYNAME")
271 signer_name = d.getVar("FITIMAGE_SIGNER")
272 signer_version = d.getVar("FITIMAGE_SIGNER_VERSION")
273 sign_images = ", ".join(f'"{s}"' for s in sign_images_list)
274
275 fd.write('\t\t\tsignature-1 {\n')
276 fd.write(f'\t\t\t\talgo = "{hash_algo},{encrypt_algo}";\n')
277 if conf_sign_keyname:
278 fd.write(f'\t\t\t\tkey-name-hint = "{conf_sign_keyname}";\n')
279 fd.write(f'\t\t\t\tsign-images = {sign_images};\n')
280 fd.write(f'\t\t\t\tsigner-name = "{signer_name}";\n')
281 fd.write(f'\t\t\t\tsigner-version = "{signer_version}";\n')
282 fd.write('\t\t\t};\n')
283
284#
285# Emit the fitImage ITS configuration section
286#
287def fitimage_emit_section_config(d, fd, dtb, kernelcount, ramdiskcount, setupcount, bootscriptid, compatible, dtbcount):
288 sign = d.getVar("FITIMAGE_SIGN")
289 conf_default = None
290 conf_prefix = d.getVar('FITIMAGE_CONFIG_PREFIX') or ""
291
292 bb.note(f"Adding {conf_prefix}{dtb} section to ITS file")
293
294 conf_desc="Linux kernel"
295 if dtb:
296 conf_desc += ", FDT blob"
297 if ramdiskcount:
298 conf_desc += ", ramdisk"
299 if setupcount:
300 conf_desc += ", setup"
301 if bootscriptid:
302 conf_desc += ", u-boot script"
303 if dtbcount == 1:
304 conf_default = d.getVar('FITIMAGE_DEFAULT_CONFIG') or f'{conf_prefix}{dtb}'
305
306 if conf_default:
307 fd.write(f'\t\tdefault = "{conf_default}";\n')
308 fd.write(f'\t\t{conf_prefix}{dtb} {{\n')
309 fd.write(f'\t\t\tdescription = "{dtbcount} {conf_desc}";\n')
310 if kernelcount:
311 fd.write('\t\t\tkernel = "kernel-1";\n')
312 fd.write(f'\t\t\tfdt = "fdt-{dtb}";\n')
313 if ramdiskcount:
314 fd.write(f'\t\t\tramdisk = "ramdisk-{ramdiskcount}";\n')
315 if bootscriptid:
316 fd.write(f'\t\t\tbootscr = "bootscr-{bootscriptid}";\n')
317 if compatible:
318 fd.write(f'\t\t\tcompatible = "{compatible}";\n')
319
320 if sign == "1":
321 sign_images = ["kernel"]
322 if dtb:
323 sign_images.append("fdt")
324 if ramdiskcount:
325 sign_images.append("ramdisk")
326 if setupcount:
327 sign_images.append("setup")
328 if bootscriptid:
329 sign_images.append("bootscr")
330 fitimage_emit_subsection_signature(d, fd, sign_images)
331
332 fd.write('\t\t' + '};\n')
333
334#
335# Emits a device tree overlay config section
336#
337def fitimage_emit_section_config_fdto(d, fd, dtb, compatible):
338 sign = d.getVar("FITIMAGE_SIGN")
339 bb.note("Adding overlay config section to ITS file")
340
341 fd.write(f'\t\t{dtb} {{\n')
342 fd.write(f'\t\t\tdescription = "Device Tree Overlay";\n')
343 fd.write(f'\t\t\tfdt = "fdt-{dtb}";\n')
344 if compatible:
345 fd.write(f'\t\t\tcompatible = "{compatible}";\n')
346
347 if sign == "1":
348 sign_images = ["fdt"]
349 fitimage_emit_subsection_signature(d, fd, sign_images)
350
351 fd.write('\t\t' + '};\n')
352
353python write_manifest() {
354 machine = d.getVar('MACHINE')
355 kernelcount=1
356 DTBS = ""
357 DTBOS = ""
358 ramdiskcount = ""
359 setupcount = ""
360 bootscriptid = ""
361 compatible = ""
362
363 def get_dtbs(d, dtb_suffix):
364 sysroot = d.getVar('RECIPE_SYSROOT')
365 deploydir = d.getVar('DEPLOY_DIR_IMAGE')
366
367 dtbs = (d.getVar('KERNEL_DEVICETREE') or '').split()
368 dtbs = [os.path.basename(x) for x in dtbs if x.endswith(dtb_suffix)]
369 ext_dtbs = os.listdir(d.getVar('EXTERNAL_KERNEL_DEVICETREE')) if d.getVar('EXTERNAL_KERNEL_DEVICETREE') else []
370 ext_dtbs = [x for x in ext_dtbs if x.endswith(dtb_suffix)]
371
372 result = []
373 # Prefer BSP dts if BSP and kernel provide the same dts
374 for d in sorted(set(dtbs + ext_dtbs)):
375 dtbpath = f'{sysroot}/boot/devicetree/{d}' if d in ext_dtbs else f'{deploydir}/{d}'
376 result.append(dtbpath)
377
378 return " ".join(result)
379
380 with open('%s/manifest.its' % d.getVar('B'), 'w') as fd:
381 images = d.getVar('FITIMAGE_IMAGES')
382 if not images:
383 bb.warn("No images specified in FITIMAGE_IMAGES. Generated FIT image will be empty")
384
385 fitimage_emit_fit_header(d, fd)
386 fitimage_emit_section_start(d, fd, 'images')
387
388 for image in (images or "").split():
389 imageflags = d.getVarFlags('FITIMAGE_IMAGE_%s' % image, expand=['file', 'fstype', 'type', 'comp']) or {}
390 imgtype = imageflags.get('type', 'kernel')
391 if imgtype == 'kernel':
392 if d.getVar('KERNEL_IMAGETYPE') not in ('zImage', 'Image') and not imageflags.get('comp'):
393 bb.warn(f"KERNEL_IMAGETYPE is '{d.getVar('KERNEL_IMAGETYPE')}' but FITIMAGE_IMAGE_kernel[comp] is not set.")
394 default = "%s-%s%s" % (d.getVar('KERNEL_IMAGETYPE'), machine, d.getVar('KERNEL_IMAGE_BIN_EXT'))
395 imgsource = imageflags.get('file', default)
396 imgcomp = imageflags.get('comp', 'none')
397 imgpath = d.getVar("DEPLOY_DIR_IMAGE")
398 fitimage_emit_section_kernel(d, fd, imgpath, imgsource, imgcomp)
399 elif imgtype == 'fdt':
400 default = get_dtbs(d, "dtb")
401 dtbfiles = imageflags.get('file', default)
402 if not dtbfiles:
403 bb.fatal(f"No dtb file found for image '{image}'. Set KERNEL_DEVICETREE, [file] varflag, or reference devicetree.bbclass-based recipe.")
404 for dtb in dtbfiles.split():
405 dtb_path, dtb_file = os.path.split(dtb)
406 DTBS += f" {dtb}"
407 fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path)
408 elif imgtype == 'fdto':
409 default = get_dtbs(d, "dtbo")
410 dtbofiles = imageflags.get('file', default)
411 if not dtbofiles:
412 bb.fatal(f"No dtbo file found for image '{image}'. Set KERNEL_DEVICETREE, [file] varflag, or reference devicetree.bbclass-based recipe.")
413 for dtb in dtbofiles.split():
414 dtb_path, dtb_file = os.path.split(dtb)
415 DTBOS = DTBOS + " " + dtb
416 fitimage_emit_section_dtb_overlay(d, fd, dtb_file, dtb_path)
417 elif imgtype == 'fdtapply':
418 import subprocess
419 dtbofiles = imageflags.get('file', None)
420 if not dtbofiles:
421 bb.fatal(f"No dtbo file found for image '{image}'. Set via [file] varflag.")
422 dtboutname = imageflags.get('name', None)
423 if not dtboutname:
424 bb.fatal(f"No dtb output name found for image '{image}'. Set via [name] varflag.")
425 dtbresult = "%s/%s" % (d.getVar('B'), dtboutname)
426 dtbcommand = ""
427 for dtb in dtbofiles.split():
428 dtb_path, dtb_file = os.path.split(dtb)
429 if not dtb_path:
430 dtb_path = d.getVar("DEPLOY_DIR_IMAGE")
431 if not dtbcommand:
432 if not dtb_file.endswith('.dtb'):
433 bb.fatal(f"fdtapply failed: Expected (non-overlay) .dtb file as first element, but got {dtb_file}")
434 dtbcommand = f"fdtoverlay -i {dtb_path}/{dtb_file} -o {dtbresult}"
435 else:
436 if not dtb_file.endswith('.dtbo'):
437 bb.fatal(f"fdtapply failed: Expected .dtbo file, but got {dtb_file}")
438 dtbcommand += f" {dtb_path}/{dtb_file}"
439 result = subprocess.run(dtbcommand, stderr=subprocess.PIPE, shell=True, text=True)
440 if result.returncode != 0:
441 bb.fatal(f"Running {dtbcommand} failed: {result.stderr}")
442 dtb_path, dtb_file = os.path.split(dtbresult)
443 DTBS += f" {dtbresult}"
444 fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path)
445 elif imgtype == 'ramdisk':
446 ramdiskcount = "1"
447 default_imgfstype = d.getVar('INITRAMFS_FSTYPES' or "").split()[0]
448 img_fstype = imageflags.get('fstype', default_imgfstype)
449 img_file = "%s%s.%s" % (d.getVar('FITIMAGE_IMAGE_%s' % image), d.getVar('IMAGE_MACHINE_SUFFIX'), img_fstype)
450 img_path = d.getVar("DEPLOY_DIR_IMAGE")
451 fitimage_emit_section_ramdisk(d, fd, img_file, img_path)
452 elif imgtype == 'bootscript':
453 if bootscriptid:
454 bb.fatal("Only a single boot script is supported (already set to: %s)" % bootscriptid)
455 imgsource = imageflags.get('file', None)
456 imgpath = d.getVar("DEPLOY_DIR_IMAGE")
457 bootscriptid = imgsource
458 fitimage_emit_section_bootscript(d, fd, imgpath, imgsource)
459 else:
460 bb.fatal(f"Unsupported image type: '{imgtype}'")
461 fitimage_emit_section_end(d, fd)
462 #
463 # Step 5: Prepare a configurations section
464 #
465 fitimage_emit_section_start(d, fd, 'configurations')
466 confcount = 0
467 dtbcount = 1
468 for dtb in (DTBS or "").split():
469 import subprocess
470 try:
471 cmd = "fdtget -t s {} / compatible".format(dtb)
472 compatible = subprocess.check_output(cmd, shell=True, text=True).split()[0]
473 except subprocess.CalledProcessError:
474 bb.fatal("Failed to find root-node compatible string in (%s)" % dtb)
475
476 dtb_path, dtb_file = os.path.split(dtb)
477 fitimage_emit_section_config(d, fd, dtb_file, kernelcount, ramdiskcount, setupcount, bootscriptid, compatible, dtbcount)
478 dtbcount += 1
479 confcount += 1
480 for dtb in (DTBOS or "").split():
481 import subprocess
482 try:
483 cmd = "fdtget -t s {} / compatible".format(dtb)
484 compatible = subprocess.check_output(cmd, shell=True, text=True).split()[0]
485 except subprocess.CalledProcessError:
486 bb.note("Failed to find root-node compatible string in (%s)" % dtb)
487 compatible = None
488
489 dtb_path, dtb_file = os.path.split(dtb)
490 fitimage_emit_section_config_fdto(d, fd, dtb_file, compatible)
491 confcount += 1
492
493 fitimage_emit_section_end(d, fd)
494
495 if confcount == 0:
496 bb.fatal("Empty 'configurations' node generated! At least one 'fdt' or 'fdto' type is required.")
497
498 fitimage_emit_fit_footer(d, fd)
499}
500
501do_configure[postfuncs] += "write_manifest"
502
503do_fitimage () {
504 if [ "${FITIMAGE_SIGN}" = "1" ]; then
505 uboot-mkimage ${FITIMAGE_MKIMAGE_EXTRA_ARGS} \
506 -k "${FITIMAGE_SIGN_KEYDIR}" -r \
507 -f "${B}/manifest.its" \
508 "${B}/fitImage"
509 else
510 uboot-mkimage ${FITIMAGE_MKIMAGE_EXTRA_ARGS} \
511 -f "${B}/manifest.its" \
512 "${B}/fitImage"
513 fi
514}
515addtask fitimage after do_configure
516
517ITS_NAME ?= "${PN}-${KERNEL_ARTIFACT_NAME}"
518ITS_LINK_NAME ?= "${PN}-${KERNEL_ARTIFACT_LINK_NAME}"
519FITIMAGE_IMAGE_NAME ?= "fitImage-${PN}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}"
520FITIMAGE_IMAGE_LINK_NAME ?= "fitImage-${PN}-${KERNEL_FIT_LINK_NAME}"
521
522SSTATE_SKIP_CREATION:task-deploy = '1'
523
524do_deploy() {
525 bbnote 'Copying fit-image.its source file...'
526 install -m 0644 ${B}/manifest.its ${DEPLOYDIR}/${ITS_NAME}.its
527
528 bbnote 'Copying all created fdt from type fdtapply'
529 for DTB_FILE in `find ${B} -maxdepth 1 -name *.dtb`; do
530 install -m 0644 ${DTB_FILE} ${DEPLOYDIR}/
531 done
532
533 bbnote 'Copying fitImage file...'
534 install -m 0644 ${B}/fitImage ${DEPLOYDIR}/${FITIMAGE_IMAGE_NAME}
535
536 cd ${DEPLOYDIR}
537 ln -sf ${ITS_NAME}.its ${ITS_LINK_NAME}.its
538 ln -sf ${FITIMAGE_IMAGE_NAME} ${FITIMAGE_IMAGE_LINK_NAME}
539}
540addtask deploy after do_fitimage before do_build