blob: 7e30a5d47eaac97d34fce984eaeb5a60ef5e6c81 [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=""
424
Patrick Williams2390b1b2022-11-03 13:47:49 -0500425 dtb_image_sect=$(symlink_points_below $dtb_image "${EXTERNAL_KERNEL_DEVICETREE}")
426 if [ -z "$dtb_image_sect" ]; then
427 dtb_image_sect=$dtb_image
428 fi
429
Patrick Williams2a254922023-08-11 09:48:11 -0500430 dtb_path="${EXTERNAL_KERNEL_DEVICETREE}/${dtb_image_sect}"
431 compatible_line="compatible = \"$(fdtget "$dtb_path" / compatible | sed 's/ /", "/g')\";"
432
Patrick Williams2390b1b2022-11-03 13:47:49 -0500433 dtb_image=$(echo $dtb_image | tr '/' '_')
434 dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
435
Patrick Williams92b42cb2022-09-03 06:53:57 -0500436 # conf node name is selected based on dtb ID if it is present,
437 # otherwise its selected based on kernel ID
438 if [ -n "$dtb_image" ]; then
439 conf_node=$conf_node$dtb_image
440 else
441 conf_node=$conf_node$kernel_id
442 fi
443
444 if [ -n "$kernel_id" ]; then
445 conf_desc="Linux kernel"
446 sep=", "
447 kernel_line="kernel = \"kernel-$kernel_id\";"
448 fi
449
450 if [ -n "$dtb_image" ]; then
451 conf_desc="$conf_desc${sep}FDT blob"
452 sep=", "
Patrick Williams2390b1b2022-11-03 13:47:49 -0500453 fdt_line="fdt = \"fdt-$dtb_image_sect\";"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500454 fi
455
456 if [ -n "$ramdisk_id" ]; then
457 conf_desc="$conf_desc${sep}ramdisk"
458 sep=", "
459 ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
460 fi
461
462 if [ -n "$bootscr_id" ]; then
463 conf_desc="$conf_desc${sep}u-boot script"
464 sep=", "
465 bootscr_line="bootscr = \"bootscr-$bootscr_id\";"
466 fi
467
468 if [ -n "$config_id" ]; then
469 conf_desc="$conf_desc${sep}setup"
470 setup_line="setup = \"setup-$config_id\";"
471 fi
472
473 if [ "$default_flag" = "1" ]; then
474 # default node is selected based on dtb ID if it is present,
475 # otherwise its selected based on kernel ID
476 if [ -n "$dtb_image" ]; then
Andrew Geissler517393d2023-01-13 08:55:19 -0600477 # Select default node as user specified dtb when
478 # multiple dtb exists.
479 if [ -n "$default_dtb_image" ]; then
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500480 default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
Andrew Geissler517393d2023-01-13 08:55:19 -0600481 else
482 default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
483 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500484 else
485 default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
486 fi
487 fi
488
489 cat << EOF >> $its_file
490 $default_line
491 $conf_node {
492 description = "$default_flag $conf_desc";
Patrick Williams2a254922023-08-11 09:48:11 -0500493 $compatible_line
Patrick Williams92b42cb2022-09-03 06:53:57 -0500494 $kernel_line
495 $fdt_line
496 $ramdisk_line
497 $bootscr_line
498 $setup_line
499 hash-1 {
500 algo = "$conf_csum";
501 };
502EOF
503
504 if [ -n "$conf_sign_keyname" ] ; then
505
506 sign_line="sign-images = "
507 sep=""
508
509 if [ -n "$kernel_id" ]; then
510 sign_line="$sign_line${sep}\"kernel\""
511 sep=", "
512 fi
513
514 if [ -n "$dtb_image" ]; then
515 sign_line="$sign_line${sep}\"fdt\""
516 sep=", "
517 fi
518
519 if [ -n "$ramdisk_id" ]; then
520 sign_line="$sign_line${sep}\"ramdisk\""
521 sep=", "
522 fi
523
524 if [ -n "$bootscr_id" ]; then
525 sign_line="$sign_line${sep}\"bootscr\""
526 sep=", "
527 fi
528
529 if [ -n "$config_id" ]; then
530 sign_line="$sign_line${sep}\"setup\""
531 fi
532
533 sign_line="$sign_line;"
534
535 cat << EOF >> $its_file
536 signature-1 {
537 algo = "$conf_csum,$conf_sign_algo";
538 key-name-hint = "$conf_sign_keyname";
539 padding = "$conf_padding_algo";
540 $sign_line
541 };
542EOF
543 fi
544
545 cat << EOF >> $its_file
546 };
547EOF
548}
549
550#
551# Assemble fitImage
552#
553# $1 ... .its filename
554# $2 ... fitImage name
555# $3 ... include ramdisk
556fitimage_assemble() {
557 kernelcount=1
558 dtbcount=""
559 DTBS=""
560 ramdiskcount=$3
561 setupcount=""
562 bootscr_id=""
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500563 default_dtb_image=""
564 rm -f $1 arch/${ARCH}/boot/$2
Patrick Williams92b42cb2022-09-03 06:53:57 -0500565
566 if [ -n "${UBOOT_SIGN_IMG_KEYNAME}" -a "${UBOOT_SIGN_KEYNAME}" = "${UBOOT_SIGN_IMG_KEYNAME}" ]; then
567 bbfatal "Keys used to sign images and configuration nodes must be different."
568 fi
569
570 fitimage_emit_fit_header $1
571
572 #
573 # Step 1: Prepare a kernel image section.
574 #
575 fitimage_emit_section_maint $1 imagestart
576
577 uboot_prep_kimage
578 fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
579
580 #
581 # Step 2: Prepare a DTB image section
582 #
583
584 if [ -n "${KERNEL_DEVICETREE}" ]; then
585 dtbcount=1
586 for DTB in ${KERNEL_DEVICETREE}; do
587 if echo $DTB | grep -q '/dts/'; then
588 bbwarn "$DTB contains the full path to the the dts file, but only the dtb name should be used."
589 DTB=`basename $DTB | sed 's,\.dts$,.dtb,g'`
590 fi
591
592 # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
593 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
594 continue
595 fi
596
Patrick Williams2390b1b2022-11-03 13:47:49 -0500597 DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500598 if [ ! -e "$DTB_PATH" ]; then
Patrick Williams2390b1b2022-11-03 13:47:49 -0500599 DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500600 fi
601
Andrew Geissler220dafd2023-10-04 10:18:08 -0500602 # Strip off the path component from the filename
603 if "${@'false' if oe.types.boolean(d.getVar('KERNEL_DTBVENDORED')) else 'true'}"; then
604 DTB=`basename $DTB`
605 fi
606
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500607 # Set the default dtb image if it exists in the devicetree.
608 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
609 default_dtb_image=$(echo "$DTB" | tr '/' '_')
610 fi
611
612 DTB=$(echo "$DTB" | tr '/' '_')
613
Patrick Williams92b42cb2022-09-03 06:53:57 -0500614 # Skip DTB if we've picked it up previously
615 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
616
617 DTBS="$DTBS $DTB"
Patrick Williams2390b1b2022-11-03 13:47:49 -0500618 DTB=$(echo $DTB | tr '/' '_')
Patrick Williams92b42cb2022-09-03 06:53:57 -0500619 fitimage_emit_section_dtb $1 $DTB $DTB_PATH
620 done
621 fi
622
623 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
624 dtbcount=1
Andrew Geissler517393d2023-01-13 08:55:19 -0600625 for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtb' -printf '%P\n' | sort) \
626 $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtbo' -printf '%P\n' | sort); do
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500627 # Set the default dtb image if it exists in the devicetree.
628 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
629 default_dtb_image=$(echo "$DTB" | tr '/' '_')
630 fi
631
632 DTB=$(echo "$DTB" | tr '/' '_')
633
Andrew Geissler517393d2023-01-13 08:55:19 -0600634 # Skip DTB/DTBO if we've picked it up previously
Patrick Williams92b42cb2022-09-03 06:53:57 -0500635 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
636
637 DTBS="$DTBS $DTB"
Patrick Williams2390b1b2022-11-03 13:47:49 -0500638
639 # Also skip if a symlink. We'll later have each config section point at it
640 [ $(symlink_points_below $DTB "${EXTERNAL_KERNEL_DEVICETREE}") ] && continue
641
642 DTB=$(echo $DTB | tr '/' '_')
Patrick Williams92b42cb2022-09-03 06:53:57 -0500643 fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
644 done
645 fi
646
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500647 if [ -n "${FIT_CONF_DEFAULT_DTB}" ] && [ -z $default_dtb_image ]; then
648 bbwarn "${FIT_CONF_DEFAULT_DTB} is not available in the list of device trees."
649 fi
650
Patrick Williams92b42cb2022-09-03 06:53:57 -0500651 #
652 # Step 3: Prepare a u-boot script section
653 #
654
655 if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
656 if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
657 cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
658 bootscr_id="${UBOOT_ENV_BINARY}"
659 fitimage_emit_section_boot_script $1 "$bootscr_id" ${UBOOT_ENV_BINARY}
660 else
661 bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
662 fi
663 fi
664
665 #
666 # Step 4: Prepare a setup section. (For x86)
667 #
Patrick Williams2390b1b2022-11-03 13:47:49 -0500668 if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
Patrick Williams92b42cb2022-09-03 06:53:57 -0500669 setupcount=1
Patrick Williams2390b1b2022-11-03 13:47:49 -0500670 fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
Patrick Williams92b42cb2022-09-03 06:53:57 -0500671 fi
672
673 #
674 # Step 5: Prepare a ramdisk section.
675 #
676 if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
677 # Find and use the first initramfs image archive type we find
678 found=
679 for img in ${FIT_SUPPORTED_INITRAMFS_FSTYPES}; do
680 initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img"
681 if [ -e "$initramfs_path" ]; then
682 bbnote "Found initramfs image: $initramfs_path"
683 found=true
684 fitimage_emit_section_ramdisk $1 "$ramdiskcount" "$initramfs_path"
685 break
686 else
687 bbnote "Did not find initramfs image: $initramfs_path"
688 fi
689 done
690
691 if [ -z "$found" ]; then
692 bbfatal "Could not find a valid initramfs type for ${INITRAMFS_IMAGE_NAME}, the supported types are: ${FIT_SUPPORTED_INITRAMFS_FSTYPES}"
693 fi
694 fi
695
696 fitimage_emit_section_maint $1 sectend
697
698 # Force the first Kernel and DTB in the default config
699 kernelcount=1
700 if [ -n "$dtbcount" ]; then
701 dtbcount=1
702 fi
703
704 #
705 # Step 6: Prepare a configurations section
706 #
707 fitimage_emit_section_maint $1 confstart
708
709 # kernel-fitimage.bbclass currently only supports a single kernel (no less or
710 # more) to be added to the FIT image along with 0 or more device trees and
711 # 0 or 1 ramdisk.
712 # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
713 # When the initramfs bundle is used ramdisk is disabled.
714 # If a device tree is to be part of the FIT image, then select
715 # the default configuration to be used is based on the dtbcount. If there is
716 # no dtb present than select the default configuation to be based on
717 # the kernelcount.
718 if [ -n "$DTBS" ]; then
719 i=1
720 for DTB in ${DTBS}; do
721 dtb_ext=${DTB##*.}
722 if [ "$dtb_ext" = "dtbo" ]; then
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500723 fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500724 else
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500725 fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500726 fi
727 i=`expr $i + 1`
728 done
729 else
730 defaultconfigcount=1
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500731 fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id" "$setupcount" $defaultconfigcount "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500732 fi
733
734 fitimage_emit_section_maint $1 sectend
735
736 fitimage_emit_section_maint $1 fitend
737
738 #
739 # Step 7: Assemble the image
740 #
741 ${UBOOT_MKIMAGE} \
742 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
743 -f $1 \
Patrick Williams2390b1b2022-11-03 13:47:49 -0500744 ${KERNEL_OUTPUT_DIR}/$2
Patrick Williams92b42cb2022-09-03 06:53:57 -0500745
746 #
Patrick Williams2390b1b2022-11-03 13:47:49 -0500747 # Step 8: Sign the image
Patrick Williams92b42cb2022-09-03 06:53:57 -0500748 #
749 if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
Patrick Williams92b42cb2022-09-03 06:53:57 -0500750 ${UBOOT_MKIMAGE_SIGN} \
751 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
752 -F -k "${UBOOT_SIGN_KEYDIR}" \
Patrick Williams2390b1b2022-11-03 13:47:49 -0500753 -r ${KERNEL_OUTPUT_DIR}/$2 \
Patrick Williams92b42cb2022-09-03 06:53:57 -0500754 ${UBOOT_MKIMAGE_SIGN_ARGS}
755 fi
756}
757
758do_assemble_fitimage() {
759 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
760 cd ${B}
Patrick Williams2390b1b2022-11-03 13:47:49 -0500761 fitimage_assemble fit-image.its fitImage-none ""
762 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
763 ln -sf fitImage-none ${B}/${KERNEL_OUTPUT_DIR}/fitImage
764 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500765 fi
766}
767
768addtask assemble_fitimage before do_install after do_compile
769
Patrick Williams2390b1b2022-11-03 13:47:49 -0500770SYSROOT_DIRS:append = " /sysroot-only"
771do_install:append() {
772 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
773 [ "${UBOOT_SIGN_ENABLE}" = "1" ]; then
774 install -D ${B}/${KERNEL_OUTPUT_DIR}/fitImage-none ${D}/sysroot-only/fitImage
775 fi
776}
777
Patrick Williams92b42cb2022-09-03 06:53:57 -0500778do_assemble_fitimage_initramfs() {
779 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
780 test -n "${INITRAMFS_IMAGE}" ; then
781 cd ${B}
782 if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
Patrick Williams2390b1b2022-11-03 13:47:49 -0500783 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-bundle ""
784 ln -sf fitImage-bundle ${B}/${KERNEL_OUTPUT_DIR}/fitImage
Patrick Williams92b42cb2022-09-03 06:53:57 -0500785 else
786 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
787 fi
788 fi
789}
790
791addtask assemble_fitimage_initramfs before do_deploy after do_bundle_initramfs
792
793do_kernel_generate_rsa_keys() {
794 if [ "${UBOOT_SIGN_ENABLE}" = "0" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
795 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."
796 fi
797
798 if [ "${UBOOT_SIGN_ENABLE}" = "1" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
799
800 # Generate keys to sign configuration nodes, only if they don't already exist
801 if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key ] || \
802 [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt ]; then
803
804 # make directory if it does not already exist
805 mkdir -p "${UBOOT_SIGN_KEYDIR}"
806
807 bbnote "Generating RSA private key for signing fitImage"
808 openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
809 "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
810 "${FIT_SIGN_NUMBITS}"
811
812 bbnote "Generating certificate for signing fitImage"
813 openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
814 -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
815 -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt
816 fi
817
818 # Generate keys to sign image nodes, only if they don't already exist
819 if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key ] || \
820 [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt ]; then
821
822 # make directory if it does not already exist
823 mkdir -p "${UBOOT_SIGN_KEYDIR}"
824
825 bbnote "Generating RSA private key for signing fitImage"
826 openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
827 "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
828 "${FIT_SIGN_NUMBITS}"
829
830 bbnote "Generating certificate for signing fitImage"
831 openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
832 -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
833 -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt
834 fi
835 fi
836}
837
838addtask kernel_generate_rsa_keys before do_assemble_fitimage after do_compile
839
840kernel_do_deploy[vardepsexclude] = "DATETIME"
841kernel_do_deploy:append() {
842 # Update deploy directory
843 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
844
845 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
846 bbnote "Copying fit-image.its source file..."
847 install -m 0644 ${B}/fit-image.its "$deployDir/fitImage-its-${KERNEL_FIT_NAME}.its"
848 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
849 ln -snf fitImage-its-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${KERNEL_FIT_LINK_NAME}"
850 fi
851
852 bbnote "Copying linux.bin file..."
853 install -m 0644 ${B}/linux.bin $deployDir/fitImage-linux.bin-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}
854 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
855 ln -snf fitImage-linux.bin-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT} "$deployDir/fitImage-linux.bin-${KERNEL_FIT_LINK_NAME}"
856 fi
857 fi
858
859 if [ -n "${INITRAMFS_IMAGE}" ]; then
860 bbnote "Copying fit-image-${INITRAMFS_IMAGE}.its source file..."
861 install -m 0644 ${B}/fit-image-${INITRAMFS_IMAGE}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its"
862 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
863 ln -snf fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
864 fi
865
866 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
867 bbnote "Copying fitImage-${INITRAMFS_IMAGE} file..."
Patrick Williams2390b1b2022-11-03 13:47:49 -0500868 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 -0500869 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
870 ln -snf fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
871 fi
872 fi
873 fi
874 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500875}