blob: 4b74ddc20155353683dfbbdd60a7087b59f940fe [file] [log] [blame]
Patrick Williams92b42cb2022-09-03 06:53:57 -05001#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
Patrick Williams2390b1b2022-11-03 13:47:49 -05007inherit kernel-uboot kernel-artifact-names uboot-config
Patrick Williams92b42cb2022-09-03 06:53:57 -05008
9def get_fit_replacement_type(d):
10 kerneltypes = d.getVar('KERNEL_IMAGETYPES') or ""
11 replacementtype = ""
12 if 'fitImage' in kerneltypes.split():
13 uarch = d.getVar("UBOOT_ARCH")
14 if uarch == "arm64":
15 replacementtype = "Image"
16 elif uarch == "riscv":
17 replacementtype = "Image"
18 elif uarch == "mips":
19 replacementtype = "vmlinuz.bin"
20 elif uarch == "x86":
21 replacementtype = "bzImage"
22 elif uarch == "microblaze":
23 replacementtype = "linux.bin"
24 else:
25 replacementtype = "zImage"
26 return replacementtype
27
28KERNEL_IMAGETYPE_REPLACEMENT ?= "${@get_fit_replacement_type(d)}"
29DEPENDS:append = " ${@'u-boot-tools-native dtc-native' if 'fitImage' in (d.getVar('KERNEL_IMAGETYPES') or '').split() else ''}"
30
31python __anonymous () {
32 # Override KERNEL_IMAGETYPE_FOR_MAKE variable, which is internal
33 # to kernel.bbclass . We have to override it, since we pack zImage
34 # (at least for now) into the fitImage .
35 typeformake = d.getVar("KERNEL_IMAGETYPE_FOR_MAKE") or ""
36 if 'fitImage' in typeformake.split():
37 d.setVar('KERNEL_IMAGETYPE_FOR_MAKE', typeformake.replace('fitImage', d.getVar('KERNEL_IMAGETYPE_REPLACEMENT')))
38
39 image = d.getVar('INITRAMFS_IMAGE')
40 if image:
41 d.appendVarFlag('do_assemble_fitimage_initramfs', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
42
43 ubootenv = d.getVar('UBOOT_ENV')
44 if ubootenv:
45 d.appendVarFlag('do_assemble_fitimage', 'depends', ' virtual/bootloader:do_populate_sysroot')
46
47 #check if there are any dtb providers
48 providerdtb = d.getVar("PREFERRED_PROVIDER_virtual/dtb")
49 if providerdtb:
50 d.appendVarFlag('do_assemble_fitimage', 'depends', ' virtual/dtb:do_populate_sysroot')
51 d.appendVarFlag('do_assemble_fitimage_initramfs', 'depends', ' virtual/dtb:do_populate_sysroot')
52 d.setVar('EXTERNAL_KERNEL_DEVICETREE', "${RECIPE_SYSROOT}/boot/devicetree")
Patrick Williams92b42cb2022-09-03 06:53:57 -050053}
54
55
56# Description string
57FIT_DESC ?= "Kernel fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}"
58
Patrick Williams2390b1b2022-11-03 13:47:49 -050059# Kernel fitImage Hash Algo
60FIT_HASH_ALG ?= "sha256"
61
62# Kernel fitImage Signature Algo
63FIT_SIGN_ALG ?= "rsa2048"
64
65# Kernel / U-Boot fitImage Padding Algo
66FIT_PAD_ALG ?= "pkcs-1.5"
67
68# Generate keys for signing Kernel fitImage
69FIT_GENERATE_KEYS ?= "0"
70
71# Size of private keys in number of bits
72FIT_SIGN_NUMBITS ?= "2048"
73
74# args to openssl genrsa (Default is just the public exponent)
75FIT_KEY_GENRSA_ARGS ?= "-F4"
76
77# args to openssl req (Default is -batch for non interactive mode and
78# -new for new certificate)
79FIT_KEY_REQ_ARGS ?= "-batch -new"
80
81# Standard format for public key certificate
82FIT_KEY_SIGN_PKCS ?= "-x509"
83
Patrick Williams92b42cb2022-09-03 06:53:57 -050084# Sign individual images as well
85FIT_SIGN_INDIVIDUAL ?= "0"
86
87FIT_CONF_PREFIX ?= "conf-"
88FIT_CONF_PREFIX[doc] = "Prefix to use for FIT configuration node name"
89
90FIT_SUPPORTED_INITRAMFS_FSTYPES ?= "cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.zst cpio.gz ext2.gz cpio"
91
Andrew Geissler517393d2023-01-13 08:55:19 -060092# Allow user to select the default DTB for FIT image when multiple dtb's exists.
93FIT_CONF_DEFAULT_DTB ?= ""
94
Andrew Geissler028142b2023-05-05 11:29:21 -050095# length of address in number of <u32> cells
96# ex: 1 32bits address, 2 64bits address
97FIT_ADDRESS_CELLS ?= "1"
98
Patrick Williams92b42cb2022-09-03 06:53:57 -050099# Keys used to sign individually image nodes.
100# The keys to sign image nodes must be different from those used to sign
101# configuration nodes, otherwise the "required" property, from
102# UBOOT_DTB_BINARY, will be set to "conf", because "conf" prevails on "image".
103# Then the images signature checking will not be mandatory and no error will be
104# raised in case of failure.
105# UBOOT_SIGN_IMG_KEYNAME = "dev2" # keys name in keydir (eg. "dev2.crt", "dev2.key")
106
107#
108# Emit the fitImage ITS header
109#
110# $1 ... .its filename
111fitimage_emit_fit_header() {
112 cat << EOF >> $1
113/dts-v1/;
114
115/ {
116 description = "${FIT_DESC}";
Andrew Geissler028142b2023-05-05 11:29:21 -0500117 #address-cells = <${FIT_ADDRESS_CELLS}>;
Patrick Williams92b42cb2022-09-03 06:53:57 -0500118EOF
119}
120
121#
122# Emit the fitImage section bits
123#
124# $1 ... .its filename
125# $2 ... Section bit type: imagestart - image section start
126# confstart - configuration section start
127# sectend - section end
128# fitend - fitimage end
129#
130fitimage_emit_section_maint() {
131 case $2 in
132 imagestart)
133 cat << EOF >> $1
134
135 images {
136EOF
137 ;;
138 confstart)
139 cat << EOF >> $1
140
141 configurations {
142EOF
143 ;;
144 sectend)
145 cat << EOF >> $1
146 };
147EOF
148 ;;
149 fitend)
150 cat << EOF >> $1
151};
152EOF
153 ;;
154 esac
155}
156
157#
158# Emit the fitImage ITS kernel section
159#
160# $1 ... .its filename
161# $2 ... Image counter
162# $3 ... Path to kernel image
163# $4 ... Compression type
164fitimage_emit_section_kernel() {
165
166 kernel_csum="${FIT_HASH_ALG}"
167 kernel_sign_algo="${FIT_SIGN_ALG}"
168 kernel_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
169
170 ENTRYPOINT="${UBOOT_ENTRYPOINT}"
171 if [ -n "${UBOOT_ENTRYSYMBOL}" ]; then
172 ENTRYPOINT=`${HOST_PREFIX}nm vmlinux | \
173 awk '$3=="${UBOOT_ENTRYSYMBOL}" {print "0x"$1;exit}'`
174 fi
175
176 cat << EOF >> $1
177 kernel-$2 {
178 description = "Linux kernel";
179 data = /incbin/("$3");
180 type = "${UBOOT_MKIMAGE_KERNEL_TYPE}";
181 arch = "${UBOOT_ARCH}";
182 os = "linux";
183 compression = "$4";
184 load = <${UBOOT_LOADADDRESS}>;
185 entry = <$ENTRYPOINT>;
186 hash-1 {
187 algo = "$kernel_csum";
188 };
189 };
190EOF
191
192 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$kernel_sign_keyname" ] ; then
193 sed -i '$ d' $1
194 cat << EOF >> $1
195 signature-1 {
196 algo = "$kernel_csum,$kernel_sign_algo";
197 key-name-hint = "$kernel_sign_keyname";
198 };
199 };
200EOF
201 fi
202}
203
204#
205# Emit the fitImage ITS DTB section
206#
207# $1 ... .its filename
208# $2 ... Image counter
209# $3 ... Path to DTB image
210fitimage_emit_section_dtb() {
211
212 dtb_csum="${FIT_HASH_ALG}"
213 dtb_sign_algo="${FIT_SIGN_ALG}"
214 dtb_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
215
216 dtb_loadline=""
217 dtb_ext=${DTB##*.}
218 if [ "${dtb_ext}" = "dtbo" ]; then
219 if [ -n "${UBOOT_DTBO_LOADADDRESS}" ]; then
220 dtb_loadline="load = <${UBOOT_DTBO_LOADADDRESS}>;"
221 fi
222 elif [ -n "${UBOOT_DTB_LOADADDRESS}" ]; then
223 dtb_loadline="load = <${UBOOT_DTB_LOADADDRESS}>;"
224 fi
225 cat << EOF >> $1
226 fdt-$2 {
227 description = "Flattened Device Tree blob";
228 data = /incbin/("$3");
229 type = "flat_dt";
230 arch = "${UBOOT_ARCH}";
231 compression = "none";
232 $dtb_loadline
233 hash-1 {
234 algo = "$dtb_csum";
235 };
236 };
237EOF
238
239 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$dtb_sign_keyname" ] ; then
240 sed -i '$ d' $1
241 cat << EOF >> $1
242 signature-1 {
243 algo = "$dtb_csum,$dtb_sign_algo";
244 key-name-hint = "$dtb_sign_keyname";
245 };
246 };
247EOF
248 fi
249}
250
251#
252# Emit the fitImage ITS u-boot script section
253#
254# $1 ... .its filename
255# $2 ... Image counter
256# $3 ... Path to boot script image
257fitimage_emit_section_boot_script() {
258
259 bootscr_csum="${FIT_HASH_ALG}"
260 bootscr_sign_algo="${FIT_SIGN_ALG}"
261 bootscr_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
262
263 cat << EOF >> $1
264 bootscr-$2 {
265 description = "U-boot script";
266 data = /incbin/("$3");
267 type = "script";
268 arch = "${UBOOT_ARCH}";
269 compression = "none";
270 hash-1 {
271 algo = "$bootscr_csum";
272 };
273 };
274EOF
275
276 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$bootscr_sign_keyname" ] ; then
277 sed -i '$ d' $1
278 cat << EOF >> $1
279 signature-1 {
280 algo = "$bootscr_csum,$bootscr_sign_algo";
281 key-name-hint = "$bootscr_sign_keyname";
282 };
283 };
284EOF
285 fi
286}
287
288#
289# Emit the fitImage ITS setup section
290#
291# $1 ... .its filename
292# $2 ... Image counter
293# $3 ... Path to setup image
294fitimage_emit_section_setup() {
295
296 setup_csum="${FIT_HASH_ALG}"
297
298 cat << EOF >> $1
299 setup-$2 {
300 description = "Linux setup.bin";
301 data = /incbin/("$3");
302 type = "x86_setup";
303 arch = "${UBOOT_ARCH}";
304 os = "linux";
305 compression = "none";
306 load = <0x00090000>;
307 entry = <0x00090000>;
308 hash-1 {
309 algo = "$setup_csum";
310 };
311 };
312EOF
313}
314
315#
316# Emit the fitImage ITS ramdisk section
317#
318# $1 ... .its filename
319# $2 ... Image counter
320# $3 ... Path to ramdisk image
321fitimage_emit_section_ramdisk() {
322
323 ramdisk_csum="${FIT_HASH_ALG}"
324 ramdisk_sign_algo="${FIT_SIGN_ALG}"
325 ramdisk_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
326 ramdisk_loadline=""
327 ramdisk_entryline=""
328
329 if [ -n "${UBOOT_RD_LOADADDRESS}" ]; then
330 ramdisk_loadline="load = <${UBOOT_RD_LOADADDRESS}>;"
331 fi
332 if [ -n "${UBOOT_RD_ENTRYPOINT}" ]; then
333 ramdisk_entryline="entry = <${UBOOT_RD_ENTRYPOINT}>;"
334 fi
335
336 cat << EOF >> $1
337 ramdisk-$2 {
338 description = "${INITRAMFS_IMAGE}";
339 data = /incbin/("$3");
340 type = "ramdisk";
341 arch = "${UBOOT_ARCH}";
342 os = "linux";
343 compression = "none";
344 $ramdisk_loadline
345 $ramdisk_entryline
346 hash-1 {
347 algo = "$ramdisk_csum";
348 };
349 };
350EOF
351
352 if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$ramdisk_sign_keyname" ] ; then
353 sed -i '$ d' $1
354 cat << EOF >> $1
355 signature-1 {
356 algo = "$ramdisk_csum,$ramdisk_sign_algo";
357 key-name-hint = "$ramdisk_sign_keyname";
358 };
359 };
360EOF
361 fi
362}
363
364#
Patrick Williams2390b1b2022-11-03 13:47:49 -0500365# echoes symlink destination if it points below directory
366#
367# $1 ... file that's a potential symlink
368# $2 ... expected parent directory
369symlink_points_below() {
370 file="$2/$1"
371 dir=$2
372
373 if ! [ -L "$file" ]; then
374 return
375 fi
376
377 realpath="$(realpath --relative-to=$dir $file)"
378 if [ -z "${realpath%%../*}" ]; then
379 return
380 fi
381
382 echo "$realpath"
383}
384
385#
Patrick Williams92b42cb2022-09-03 06:53:57 -0500386# Emit the fitImage ITS configuration section
387#
388# $1 ... .its filename
389# $2 ... Linux kernel ID
390# $3 ... DTB image name
391# $4 ... ramdisk ID
392# $5 ... u-boot script ID
393# $6 ... config ID
394# $7 ... default flag
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500395# $8 ... default DTB image name
Patrick Williams92b42cb2022-09-03 06:53:57 -0500396fitimage_emit_section_config() {
397
398 conf_csum="${FIT_HASH_ALG}"
399 conf_sign_algo="${FIT_SIGN_ALG}"
400 conf_padding_algo="${FIT_PAD_ALG}"
401 if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then
402 conf_sign_keyname="${UBOOT_SIGN_KEYNAME}"
403 fi
404
405 its_file="$1"
406 kernel_id="$2"
407 dtb_image="$3"
408 ramdisk_id="$4"
409 bootscr_id="$5"
410 config_id="$6"
411 default_flag="$7"
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500412 default_dtb_image="$8"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500413
414 # Test if we have any DTBs at all
415 sep=""
416 conf_desc=""
417 conf_node="${FIT_CONF_PREFIX}"
418 kernel_line=""
419 fdt_line=""
420 ramdisk_line=""
421 bootscr_line=""
422 setup_line=""
423 default_line=""
Patrick Williams03514f12024-04-05 07:04:11 -0500424 compatible_line=""
Patrick Williams92b42cb2022-09-03 06:53:57 -0500425
Patrick Williams2390b1b2022-11-03 13:47:49 -0500426 dtb_image_sect=$(symlink_points_below $dtb_image "${EXTERNAL_KERNEL_DEVICETREE}")
427 if [ -z "$dtb_image_sect" ]; then
428 dtb_image_sect=$dtb_image
429 fi
430
Patrick Williams2a254922023-08-11 09:48:11 -0500431 dtb_path="${EXTERNAL_KERNEL_DEVICETREE}/${dtb_image_sect}"
Patrick Williams03514f12024-04-05 07:04:11 -0500432 if [ -e "$dtb_path" ]; then
433 compat=$(fdtget -t s "$dtb_path" / compatible | sed 's/ /", "/g')
434 if [ -n "$compat" ]; then
435 compatible_line="compatible = \"$compat\";"
436 fi
437 fi
Patrick Williams2a254922023-08-11 09:48:11 -0500438
Patrick Williams2390b1b2022-11-03 13:47:49 -0500439 dtb_image=$(echo $dtb_image | tr '/' '_')
440 dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
441
Patrick Williams92b42cb2022-09-03 06:53:57 -0500442 # conf node name is selected based on dtb ID if it is present,
443 # otherwise its selected based on kernel ID
444 if [ -n "$dtb_image" ]; then
445 conf_node=$conf_node$dtb_image
446 else
447 conf_node=$conf_node$kernel_id
448 fi
449
450 if [ -n "$kernel_id" ]; then
451 conf_desc="Linux kernel"
452 sep=", "
453 kernel_line="kernel = \"kernel-$kernel_id\";"
454 fi
455
456 if [ -n "$dtb_image" ]; then
457 conf_desc="$conf_desc${sep}FDT blob"
458 sep=", "
Patrick Williams2390b1b2022-11-03 13:47:49 -0500459 fdt_line="fdt = \"fdt-$dtb_image_sect\";"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500460 fi
461
462 if [ -n "$ramdisk_id" ]; then
463 conf_desc="$conf_desc${sep}ramdisk"
464 sep=", "
465 ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
466 fi
467
468 if [ -n "$bootscr_id" ]; then
469 conf_desc="$conf_desc${sep}u-boot script"
470 sep=", "
471 bootscr_line="bootscr = \"bootscr-$bootscr_id\";"
472 fi
473
474 if [ -n "$config_id" ]; then
475 conf_desc="$conf_desc${sep}setup"
476 setup_line="setup = \"setup-$config_id\";"
477 fi
478
479 if [ "$default_flag" = "1" ]; then
480 # default node is selected based on dtb ID if it is present,
481 # otherwise its selected based on kernel ID
482 if [ -n "$dtb_image" ]; then
Andrew Geissler517393d2023-01-13 08:55:19 -0600483 # Select default node as user specified dtb when
484 # multiple dtb exists.
485 if [ -n "$default_dtb_image" ]; then
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500486 default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
Andrew Geissler517393d2023-01-13 08:55:19 -0600487 else
488 default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
489 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500490 else
491 default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
492 fi
493 fi
494
495 cat << EOF >> $its_file
496 $default_line
497 $conf_node {
498 description = "$default_flag $conf_desc";
Patrick Williams2a254922023-08-11 09:48:11 -0500499 $compatible_line
Patrick Williams92b42cb2022-09-03 06:53:57 -0500500 $kernel_line
501 $fdt_line
502 $ramdisk_line
503 $bootscr_line
504 $setup_line
505 hash-1 {
506 algo = "$conf_csum";
507 };
508EOF
509
510 if [ -n "$conf_sign_keyname" ] ; then
511
512 sign_line="sign-images = "
513 sep=""
514
515 if [ -n "$kernel_id" ]; then
516 sign_line="$sign_line${sep}\"kernel\""
517 sep=", "
518 fi
519
520 if [ -n "$dtb_image" ]; then
521 sign_line="$sign_line${sep}\"fdt\""
522 sep=", "
523 fi
524
525 if [ -n "$ramdisk_id" ]; then
526 sign_line="$sign_line${sep}\"ramdisk\""
527 sep=", "
528 fi
529
530 if [ -n "$bootscr_id" ]; then
531 sign_line="$sign_line${sep}\"bootscr\""
532 sep=", "
533 fi
534
535 if [ -n "$config_id" ]; then
536 sign_line="$sign_line${sep}\"setup\""
537 fi
538
539 sign_line="$sign_line;"
540
541 cat << EOF >> $its_file
542 signature-1 {
543 algo = "$conf_csum,$conf_sign_algo";
544 key-name-hint = "$conf_sign_keyname";
545 padding = "$conf_padding_algo";
546 $sign_line
547 };
548EOF
549 fi
550
551 cat << EOF >> $its_file
552 };
553EOF
554}
555
556#
557# Assemble fitImage
558#
559# $1 ... .its filename
560# $2 ... fitImage name
561# $3 ... include ramdisk
562fitimage_assemble() {
563 kernelcount=1
564 dtbcount=""
565 DTBS=""
566 ramdiskcount=$3
567 setupcount=""
568 bootscr_id=""
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500569 default_dtb_image=""
570 rm -f $1 arch/${ARCH}/boot/$2
Patrick Williams92b42cb2022-09-03 06:53:57 -0500571
572 if [ -n "${UBOOT_SIGN_IMG_KEYNAME}" -a "${UBOOT_SIGN_KEYNAME}" = "${UBOOT_SIGN_IMG_KEYNAME}" ]; then
573 bbfatal "Keys used to sign images and configuration nodes must be different."
574 fi
575
576 fitimage_emit_fit_header $1
577
578 #
579 # Step 1: Prepare a kernel image section.
580 #
581 fitimage_emit_section_maint $1 imagestart
582
583 uboot_prep_kimage
584 fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
585
586 #
587 # Step 2: Prepare a DTB image section
588 #
589
590 if [ -n "${KERNEL_DEVICETREE}" ]; then
591 dtbcount=1
592 for DTB in ${KERNEL_DEVICETREE}; do
593 if echo $DTB | grep -q '/dts/'; then
594 bbwarn "$DTB contains the full path to the the dts file, but only the dtb name should be used."
595 DTB=`basename $DTB | sed 's,\.dts$,.dtb,g'`
596 fi
597
598 # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
599 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
600 continue
601 fi
602
Patrick Williams2390b1b2022-11-03 13:47:49 -0500603 DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500604 if [ ! -e "$DTB_PATH" ]; then
Patrick Williams2390b1b2022-11-03 13:47:49 -0500605 DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500606 fi
607
Andrew Geissler220dafd2023-10-04 10:18:08 -0500608 # Strip off the path component from the filename
609 if "${@'false' if oe.types.boolean(d.getVar('KERNEL_DTBVENDORED')) else 'true'}"; then
610 DTB=`basename $DTB`
611 fi
612
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500613 # Set the default dtb image if it exists in the devicetree.
614 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
615 default_dtb_image=$(echo "$DTB" | tr '/' '_')
616 fi
617
618 DTB=$(echo "$DTB" | tr '/' '_')
619
Patrick Williams92b42cb2022-09-03 06:53:57 -0500620 # Skip DTB if we've picked it up previously
621 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
622
623 DTBS="$DTBS $DTB"
Patrick Williams2390b1b2022-11-03 13:47:49 -0500624 DTB=$(echo $DTB | tr '/' '_')
Patrick Williams92b42cb2022-09-03 06:53:57 -0500625 fitimage_emit_section_dtb $1 $DTB $DTB_PATH
626 done
627 fi
628
629 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
630 dtbcount=1
Andrew Geissler517393d2023-01-13 08:55:19 -0600631 for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtb' -printf '%P\n' | sort) \
632 $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtbo' -printf '%P\n' | sort); do
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500633 # Set the default dtb image if it exists in the devicetree.
634 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
635 default_dtb_image=$(echo "$DTB" | tr '/' '_')
636 fi
637
638 DTB=$(echo "$DTB" | tr '/' '_')
639
Andrew Geissler517393d2023-01-13 08:55:19 -0600640 # Skip DTB/DTBO if we've picked it up previously
Patrick Williams92b42cb2022-09-03 06:53:57 -0500641 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
642
643 DTBS="$DTBS $DTB"
Patrick Williams2390b1b2022-11-03 13:47:49 -0500644
645 # Also skip if a symlink. We'll later have each config section point at it
646 [ $(symlink_points_below $DTB "${EXTERNAL_KERNEL_DEVICETREE}") ] && continue
647
648 DTB=$(echo $DTB | tr '/' '_')
Patrick Williams92b42cb2022-09-03 06:53:57 -0500649 fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
650 done
651 fi
652
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500653 if [ -n "${FIT_CONF_DEFAULT_DTB}" ] && [ -z $default_dtb_image ]; then
654 bbwarn "${FIT_CONF_DEFAULT_DTB} is not available in the list of device trees."
655 fi
656
Patrick Williams92b42cb2022-09-03 06:53:57 -0500657 #
658 # Step 3: Prepare a u-boot script section
659 #
660
661 if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
662 if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
663 cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
664 bootscr_id="${UBOOT_ENV_BINARY}"
665 fitimage_emit_section_boot_script $1 "$bootscr_id" ${UBOOT_ENV_BINARY}
666 else
667 bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
668 fi
669 fi
670
671 #
672 # Step 4: Prepare a setup section. (For x86)
673 #
Patrick Williams2390b1b2022-11-03 13:47:49 -0500674 if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
Patrick Williams92b42cb2022-09-03 06:53:57 -0500675 setupcount=1
Patrick Williams2390b1b2022-11-03 13:47:49 -0500676 fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
Patrick Williams92b42cb2022-09-03 06:53:57 -0500677 fi
678
679 #
680 # Step 5: Prepare a ramdisk section.
681 #
682 if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
683 # Find and use the first initramfs image archive type we find
684 found=
685 for img in ${FIT_SUPPORTED_INITRAMFS_FSTYPES}; do
686 initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img"
687 if [ -e "$initramfs_path" ]; then
688 bbnote "Found initramfs image: $initramfs_path"
689 found=true
690 fitimage_emit_section_ramdisk $1 "$ramdiskcount" "$initramfs_path"
691 break
692 else
693 bbnote "Did not find initramfs image: $initramfs_path"
694 fi
695 done
696
697 if [ -z "$found" ]; then
698 bbfatal "Could not find a valid initramfs type for ${INITRAMFS_IMAGE_NAME}, the supported types are: ${FIT_SUPPORTED_INITRAMFS_FSTYPES}"
699 fi
700 fi
701
702 fitimage_emit_section_maint $1 sectend
703
704 # Force the first Kernel and DTB in the default config
705 kernelcount=1
706 if [ -n "$dtbcount" ]; then
707 dtbcount=1
708 fi
709
710 #
711 # Step 6: Prepare a configurations section
712 #
713 fitimage_emit_section_maint $1 confstart
714
715 # kernel-fitimage.bbclass currently only supports a single kernel (no less or
716 # more) to be added to the FIT image along with 0 or more device trees and
717 # 0 or 1 ramdisk.
718 # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
719 # When the initramfs bundle is used ramdisk is disabled.
720 # If a device tree is to be part of the FIT image, then select
721 # the default configuration to be used is based on the dtbcount. If there is
722 # no dtb present than select the default configuation to be based on
723 # the kernelcount.
724 if [ -n "$DTBS" ]; then
725 i=1
726 for DTB in ${DTBS}; do
727 dtb_ext=${DTB##*.}
728 if [ "$dtb_ext" = "dtbo" ]; then
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500729 fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500730 else
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500731 fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500732 fi
733 i=`expr $i + 1`
734 done
735 else
736 defaultconfigcount=1
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500737 fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id" "$setupcount" $defaultconfigcount "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500738 fi
739
740 fitimage_emit_section_maint $1 sectend
741
742 fitimage_emit_section_maint $1 fitend
743
744 #
745 # Step 7: Assemble the image
746 #
747 ${UBOOT_MKIMAGE} \
748 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
749 -f $1 \
Patrick Williams2390b1b2022-11-03 13:47:49 -0500750 ${KERNEL_OUTPUT_DIR}/$2
Patrick Williams92b42cb2022-09-03 06:53:57 -0500751
752 #
Patrick Williams2390b1b2022-11-03 13:47:49 -0500753 # Step 8: Sign the image
Patrick Williams92b42cb2022-09-03 06:53:57 -0500754 #
755 if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
Patrick Williams92b42cb2022-09-03 06:53:57 -0500756 ${UBOOT_MKIMAGE_SIGN} \
757 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
758 -F -k "${UBOOT_SIGN_KEYDIR}" \
Patrick Williams2390b1b2022-11-03 13:47:49 -0500759 -r ${KERNEL_OUTPUT_DIR}/$2 \
Patrick Williams92b42cb2022-09-03 06:53:57 -0500760 ${UBOOT_MKIMAGE_SIGN_ARGS}
761 fi
762}
763
764do_assemble_fitimage() {
765 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
766 cd ${B}
Patrick Williams2390b1b2022-11-03 13:47:49 -0500767 fitimage_assemble fit-image.its fitImage-none ""
768 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
769 ln -sf fitImage-none ${B}/${KERNEL_OUTPUT_DIR}/fitImage
770 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500771 fi
772}
773
774addtask assemble_fitimage before do_install after do_compile
775
Patrick Williams2390b1b2022-11-03 13:47:49 -0500776SYSROOT_DIRS:append = " /sysroot-only"
777do_install:append() {
778 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
779 [ "${UBOOT_SIGN_ENABLE}" = "1" ]; then
780 install -D ${B}/${KERNEL_OUTPUT_DIR}/fitImage-none ${D}/sysroot-only/fitImage
781 fi
782}
783
Patrick Williams92b42cb2022-09-03 06:53:57 -0500784do_assemble_fitimage_initramfs() {
785 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
786 test -n "${INITRAMFS_IMAGE}" ; then
787 cd ${B}
788 if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
Patrick Williams2390b1b2022-11-03 13:47:49 -0500789 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-bundle ""
790 ln -sf fitImage-bundle ${B}/${KERNEL_OUTPUT_DIR}/fitImage
Patrick Williams92b42cb2022-09-03 06:53:57 -0500791 else
792 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
793 fi
794 fi
795}
796
797addtask assemble_fitimage_initramfs before do_deploy after do_bundle_initramfs
798
799do_kernel_generate_rsa_keys() {
800 if [ "${UBOOT_SIGN_ENABLE}" = "0" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
801 bbwarn "FIT_GENERATE_KEYS is set to 1 even though UBOOT_SIGN_ENABLE is set to 0. The keys will not be generated as they won't be used."
802 fi
803
804 if [ "${UBOOT_SIGN_ENABLE}" = "1" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
805
806 # Generate keys to sign configuration nodes, only if they don't already exist
807 if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key ] || \
808 [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt ]; then
809
810 # make directory if it does not already exist
811 mkdir -p "${UBOOT_SIGN_KEYDIR}"
812
813 bbnote "Generating RSA private key for signing fitImage"
814 openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
815 "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
816 "${FIT_SIGN_NUMBITS}"
817
818 bbnote "Generating certificate for signing fitImage"
819 openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
820 -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
821 -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt
822 fi
823
824 # Generate keys to sign image nodes, only if they don't already exist
825 if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key ] || \
826 [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt ]; then
827
828 # make directory if it does not already exist
829 mkdir -p "${UBOOT_SIGN_KEYDIR}"
830
831 bbnote "Generating RSA private key for signing fitImage"
832 openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
833 "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
834 "${FIT_SIGN_NUMBITS}"
835
836 bbnote "Generating certificate for signing fitImage"
837 openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
838 -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
839 -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt
840 fi
841 fi
842}
843
844addtask kernel_generate_rsa_keys before do_assemble_fitimage after do_compile
845
846kernel_do_deploy[vardepsexclude] = "DATETIME"
847kernel_do_deploy:append() {
848 # Update deploy directory
849 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
850
851 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
852 bbnote "Copying fit-image.its source file..."
853 install -m 0644 ${B}/fit-image.its "$deployDir/fitImage-its-${KERNEL_FIT_NAME}.its"
854 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
855 ln -snf fitImage-its-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${KERNEL_FIT_LINK_NAME}"
856 fi
857
858 bbnote "Copying linux.bin file..."
859 install -m 0644 ${B}/linux.bin $deployDir/fitImage-linux.bin-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}
860 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
861 ln -snf fitImage-linux.bin-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT} "$deployDir/fitImage-linux.bin-${KERNEL_FIT_LINK_NAME}"
862 fi
863 fi
864
865 if [ -n "${INITRAMFS_IMAGE}" ]; then
866 bbnote "Copying fit-image-${INITRAMFS_IMAGE}.its source file..."
867 install -m 0644 ${B}/fit-image-${INITRAMFS_IMAGE}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its"
868 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
869 ln -snf fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
870 fi
871
872 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
873 bbnote "Copying fitImage-${INITRAMFS_IMAGE} file..."
Patrick Williams2390b1b2022-11-03 13:47:49 -0500874 install -m 0644 ${B}/${KERNEL_OUTPUT_DIR}/fitImage-${INITRAMFS_IMAGE} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500875 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
876 ln -snf fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
877 fi
878 fi
879 fi
880 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500881}