blob: f1c46a453c8c1df5d29fcd27ff4824d011b50f2d [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
430 dtb_image=$(echo $dtb_image | tr '/' '_')
431 dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
432
Patrick Williams92b42cb2022-09-03 06:53:57 -0500433 # conf node name is selected based on dtb ID if it is present,
434 # otherwise its selected based on kernel ID
435 if [ -n "$dtb_image" ]; then
436 conf_node=$conf_node$dtb_image
437 else
438 conf_node=$conf_node$kernel_id
439 fi
440
441 if [ -n "$kernel_id" ]; then
442 conf_desc="Linux kernel"
443 sep=", "
444 kernel_line="kernel = \"kernel-$kernel_id\";"
445 fi
446
447 if [ -n "$dtb_image" ]; then
448 conf_desc="$conf_desc${sep}FDT blob"
449 sep=", "
Patrick Williams2390b1b2022-11-03 13:47:49 -0500450 fdt_line="fdt = \"fdt-$dtb_image_sect\";"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500451 fi
452
453 if [ -n "$ramdisk_id" ]; then
454 conf_desc="$conf_desc${sep}ramdisk"
455 sep=", "
456 ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
457 fi
458
459 if [ -n "$bootscr_id" ]; then
460 conf_desc="$conf_desc${sep}u-boot script"
461 sep=", "
462 bootscr_line="bootscr = \"bootscr-$bootscr_id\";"
463 fi
464
465 if [ -n "$config_id" ]; then
466 conf_desc="$conf_desc${sep}setup"
467 setup_line="setup = \"setup-$config_id\";"
468 fi
469
470 if [ "$default_flag" = "1" ]; then
471 # default node is selected based on dtb ID if it is present,
472 # otherwise its selected based on kernel ID
473 if [ -n "$dtb_image" ]; then
Andrew Geissler517393d2023-01-13 08:55:19 -0600474 # Select default node as user specified dtb when
475 # multiple dtb exists.
476 if [ -n "$default_dtb_image" ]; then
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500477 default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
Andrew Geissler517393d2023-01-13 08:55:19 -0600478 else
479 default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
480 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500481 else
482 default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
483 fi
484 fi
485
486 cat << EOF >> $its_file
487 $default_line
488 $conf_node {
489 description = "$default_flag $conf_desc";
490 $kernel_line
491 $fdt_line
492 $ramdisk_line
493 $bootscr_line
494 $setup_line
495 hash-1 {
496 algo = "$conf_csum";
497 };
498EOF
499
500 if [ -n "$conf_sign_keyname" ] ; then
501
502 sign_line="sign-images = "
503 sep=""
504
505 if [ -n "$kernel_id" ]; then
506 sign_line="$sign_line${sep}\"kernel\""
507 sep=", "
508 fi
509
510 if [ -n "$dtb_image" ]; then
511 sign_line="$sign_line${sep}\"fdt\""
512 sep=", "
513 fi
514
515 if [ -n "$ramdisk_id" ]; then
516 sign_line="$sign_line${sep}\"ramdisk\""
517 sep=", "
518 fi
519
520 if [ -n "$bootscr_id" ]; then
521 sign_line="$sign_line${sep}\"bootscr\""
522 sep=", "
523 fi
524
525 if [ -n "$config_id" ]; then
526 sign_line="$sign_line${sep}\"setup\""
527 fi
528
529 sign_line="$sign_line;"
530
531 cat << EOF >> $its_file
532 signature-1 {
533 algo = "$conf_csum,$conf_sign_algo";
534 key-name-hint = "$conf_sign_keyname";
535 padding = "$conf_padding_algo";
536 $sign_line
537 };
538EOF
539 fi
540
541 cat << EOF >> $its_file
542 };
543EOF
544}
545
546#
547# Assemble fitImage
548#
549# $1 ... .its filename
550# $2 ... fitImage name
551# $3 ... include ramdisk
552fitimage_assemble() {
553 kernelcount=1
554 dtbcount=""
555 DTBS=""
556 ramdiskcount=$3
557 setupcount=""
558 bootscr_id=""
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500559 default_dtb_image=""
560 rm -f $1 arch/${ARCH}/boot/$2
Patrick Williams92b42cb2022-09-03 06:53:57 -0500561
562 if [ -n "${UBOOT_SIGN_IMG_KEYNAME}" -a "${UBOOT_SIGN_KEYNAME}" = "${UBOOT_SIGN_IMG_KEYNAME}" ]; then
563 bbfatal "Keys used to sign images and configuration nodes must be different."
564 fi
565
566 fitimage_emit_fit_header $1
567
568 #
569 # Step 1: Prepare a kernel image section.
570 #
571 fitimage_emit_section_maint $1 imagestart
572
573 uboot_prep_kimage
574 fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
575
576 #
577 # Step 2: Prepare a DTB image section
578 #
579
580 if [ -n "${KERNEL_DEVICETREE}" ]; then
581 dtbcount=1
582 for DTB in ${KERNEL_DEVICETREE}; do
583 if echo $DTB | grep -q '/dts/'; then
584 bbwarn "$DTB contains the full path to the the dts file, but only the dtb name should be used."
585 DTB=`basename $DTB | sed 's,\.dts$,.dtb,g'`
586 fi
587
588 # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
589 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
590 continue
591 fi
592
Patrick Williams2390b1b2022-11-03 13:47:49 -0500593 DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500594 if [ ! -e "$DTB_PATH" ]; then
Patrick Williams2390b1b2022-11-03 13:47:49 -0500595 DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500596 fi
597
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500598 # Set the default dtb image if it exists in the devicetree.
599 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
600 default_dtb_image=$(echo "$DTB" | tr '/' '_')
601 fi
602
603 DTB=$(echo "$DTB" | tr '/' '_')
604
Patrick Williams92b42cb2022-09-03 06:53:57 -0500605 # Skip DTB if we've picked it up previously
606 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
607
608 DTBS="$DTBS $DTB"
Patrick Williams2390b1b2022-11-03 13:47:49 -0500609 DTB=$(echo $DTB | tr '/' '_')
Patrick Williams92b42cb2022-09-03 06:53:57 -0500610 fitimage_emit_section_dtb $1 $DTB $DTB_PATH
611 done
612 fi
613
614 if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
615 dtbcount=1
Andrew Geissler517393d2023-01-13 08:55:19 -0600616 for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtb' -printf '%P\n' | sort) \
617 $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtbo' -printf '%P\n' | sort); do
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500618 # Set the default dtb image if it exists in the devicetree.
619 if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
620 default_dtb_image=$(echo "$DTB" | tr '/' '_')
621 fi
622
623 DTB=$(echo "$DTB" | tr '/' '_')
624
Andrew Geissler517393d2023-01-13 08:55:19 -0600625 # Skip DTB/DTBO if we've picked it up previously
Patrick Williams92b42cb2022-09-03 06:53:57 -0500626 echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
627
628 DTBS="$DTBS $DTB"
Patrick Williams2390b1b2022-11-03 13:47:49 -0500629
630 # Also skip if a symlink. We'll later have each config section point at it
631 [ $(symlink_points_below $DTB "${EXTERNAL_KERNEL_DEVICETREE}") ] && continue
632
633 DTB=$(echo $DTB | tr '/' '_')
Patrick Williams92b42cb2022-09-03 06:53:57 -0500634 fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
635 done
636 fi
637
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500638 if [ -n "${FIT_CONF_DEFAULT_DTB}" ] && [ -z $default_dtb_image ]; then
639 bbwarn "${FIT_CONF_DEFAULT_DTB} is not available in the list of device trees."
640 fi
641
Patrick Williams92b42cb2022-09-03 06:53:57 -0500642 #
643 # Step 3: Prepare a u-boot script section
644 #
645
646 if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
647 if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
648 cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
649 bootscr_id="${UBOOT_ENV_BINARY}"
650 fitimage_emit_section_boot_script $1 "$bootscr_id" ${UBOOT_ENV_BINARY}
651 else
652 bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
653 fi
654 fi
655
656 #
657 # Step 4: Prepare a setup section. (For x86)
658 #
Patrick Williams2390b1b2022-11-03 13:47:49 -0500659 if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
Patrick Williams92b42cb2022-09-03 06:53:57 -0500660 setupcount=1
Patrick Williams2390b1b2022-11-03 13:47:49 -0500661 fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
Patrick Williams92b42cb2022-09-03 06:53:57 -0500662 fi
663
664 #
665 # Step 5: Prepare a ramdisk section.
666 #
667 if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
668 # Find and use the first initramfs image archive type we find
669 found=
670 for img in ${FIT_SUPPORTED_INITRAMFS_FSTYPES}; do
671 initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img"
672 if [ -e "$initramfs_path" ]; then
673 bbnote "Found initramfs image: $initramfs_path"
674 found=true
675 fitimage_emit_section_ramdisk $1 "$ramdiskcount" "$initramfs_path"
676 break
677 else
678 bbnote "Did not find initramfs image: $initramfs_path"
679 fi
680 done
681
682 if [ -z "$found" ]; then
683 bbfatal "Could not find a valid initramfs type for ${INITRAMFS_IMAGE_NAME}, the supported types are: ${FIT_SUPPORTED_INITRAMFS_FSTYPES}"
684 fi
685 fi
686
687 fitimage_emit_section_maint $1 sectend
688
689 # Force the first Kernel and DTB in the default config
690 kernelcount=1
691 if [ -n "$dtbcount" ]; then
692 dtbcount=1
693 fi
694
695 #
696 # Step 6: Prepare a configurations section
697 #
698 fitimage_emit_section_maint $1 confstart
699
700 # kernel-fitimage.bbclass currently only supports a single kernel (no less or
701 # more) to be added to the FIT image along with 0 or more device trees and
702 # 0 or 1 ramdisk.
703 # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
704 # When the initramfs bundle is used ramdisk is disabled.
705 # If a device tree is to be part of the FIT image, then select
706 # the default configuration to be used is based on the dtbcount. If there is
707 # no dtb present than select the default configuation to be based on
708 # the kernelcount.
709 if [ -n "$DTBS" ]; then
710 i=1
711 for DTB in ${DTBS}; do
712 dtb_ext=${DTB##*.}
713 if [ "$dtb_ext" = "dtbo" ]; then
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500714 fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500715 else
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500716 fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500717 fi
718 i=`expr $i + 1`
719 done
720 else
721 defaultconfigcount=1
Patrick Williams8e7b46e2023-05-01 14:19:06 -0500722 fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id" "$setupcount" $defaultconfigcount "$default_dtb_image"
Patrick Williams92b42cb2022-09-03 06:53:57 -0500723 fi
724
725 fitimage_emit_section_maint $1 sectend
726
727 fitimage_emit_section_maint $1 fitend
728
729 #
730 # Step 7: Assemble the image
731 #
732 ${UBOOT_MKIMAGE} \
733 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
734 -f $1 \
Patrick Williams2390b1b2022-11-03 13:47:49 -0500735 ${KERNEL_OUTPUT_DIR}/$2
Patrick Williams92b42cb2022-09-03 06:53:57 -0500736
737 #
Patrick Williams2390b1b2022-11-03 13:47:49 -0500738 # Step 8: Sign the image
Patrick Williams92b42cb2022-09-03 06:53:57 -0500739 #
740 if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
Patrick Williams92b42cb2022-09-03 06:53:57 -0500741 ${UBOOT_MKIMAGE_SIGN} \
742 ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
743 -F -k "${UBOOT_SIGN_KEYDIR}" \
Patrick Williams2390b1b2022-11-03 13:47:49 -0500744 -r ${KERNEL_OUTPUT_DIR}/$2 \
Patrick Williams92b42cb2022-09-03 06:53:57 -0500745 ${UBOOT_MKIMAGE_SIGN_ARGS}
746 fi
747}
748
749do_assemble_fitimage() {
750 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
751 cd ${B}
Patrick Williams2390b1b2022-11-03 13:47:49 -0500752 fitimage_assemble fit-image.its fitImage-none ""
753 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
754 ln -sf fitImage-none ${B}/${KERNEL_OUTPUT_DIR}/fitImage
755 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500756 fi
757}
758
759addtask assemble_fitimage before do_install after do_compile
760
Patrick Williams2390b1b2022-11-03 13:47:49 -0500761SYSROOT_DIRS:append = " /sysroot-only"
762do_install:append() {
763 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
764 [ "${UBOOT_SIGN_ENABLE}" = "1" ]; then
765 install -D ${B}/${KERNEL_OUTPUT_DIR}/fitImage-none ${D}/sysroot-only/fitImage
766 fi
767}
768
Patrick Williams92b42cb2022-09-03 06:53:57 -0500769do_assemble_fitimage_initramfs() {
770 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
771 test -n "${INITRAMFS_IMAGE}" ; then
772 cd ${B}
773 if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
Patrick Williams2390b1b2022-11-03 13:47:49 -0500774 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-bundle ""
775 ln -sf fitImage-bundle ${B}/${KERNEL_OUTPUT_DIR}/fitImage
Patrick Williams92b42cb2022-09-03 06:53:57 -0500776 else
777 fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
778 fi
779 fi
780}
781
782addtask assemble_fitimage_initramfs before do_deploy after do_bundle_initramfs
783
784do_kernel_generate_rsa_keys() {
785 if [ "${UBOOT_SIGN_ENABLE}" = "0" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
786 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."
787 fi
788
789 if [ "${UBOOT_SIGN_ENABLE}" = "1" ] && [ "${FIT_GENERATE_KEYS}" = "1" ]; then
790
791 # Generate keys to sign configuration nodes, only if they don't already exist
792 if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key ] || \
793 [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt ]; then
794
795 # make directory if it does not already exist
796 mkdir -p "${UBOOT_SIGN_KEYDIR}"
797
798 bbnote "Generating RSA private key for signing fitImage"
799 openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
800 "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
801 "${FIT_SIGN_NUMBITS}"
802
803 bbnote "Generating certificate for signing fitImage"
804 openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
805 -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".key \
806 -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_KEYNAME}".crt
807 fi
808
809 # Generate keys to sign image nodes, only if they don't already exist
810 if [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key ] || \
811 [ ! -f "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt ]; then
812
813 # make directory if it does not already exist
814 mkdir -p "${UBOOT_SIGN_KEYDIR}"
815
816 bbnote "Generating RSA private key for signing fitImage"
817 openssl genrsa ${FIT_KEY_GENRSA_ARGS} -out \
818 "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
819 "${FIT_SIGN_NUMBITS}"
820
821 bbnote "Generating certificate for signing fitImage"
822 openssl req ${FIT_KEY_REQ_ARGS} "${FIT_KEY_SIGN_PKCS}" \
823 -key "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".key \
824 -out "${UBOOT_SIGN_KEYDIR}/${UBOOT_SIGN_IMG_KEYNAME}".crt
825 fi
826 fi
827}
828
829addtask kernel_generate_rsa_keys before do_assemble_fitimage after do_compile
830
831kernel_do_deploy[vardepsexclude] = "DATETIME"
832kernel_do_deploy:append() {
833 # Update deploy directory
834 if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
835
836 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
837 bbnote "Copying fit-image.its source file..."
838 install -m 0644 ${B}/fit-image.its "$deployDir/fitImage-its-${KERNEL_FIT_NAME}.its"
839 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
840 ln -snf fitImage-its-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${KERNEL_FIT_LINK_NAME}"
841 fi
842
843 bbnote "Copying linux.bin file..."
844 install -m 0644 ${B}/linux.bin $deployDir/fitImage-linux.bin-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}
845 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
846 ln -snf fitImage-linux.bin-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT} "$deployDir/fitImage-linux.bin-${KERNEL_FIT_LINK_NAME}"
847 fi
848 fi
849
850 if [ -n "${INITRAMFS_IMAGE}" ]; then
851 bbnote "Copying fit-image-${INITRAMFS_IMAGE}.its source file..."
852 install -m 0644 ${B}/fit-image-${INITRAMFS_IMAGE}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its"
853 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
854 ln -snf fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
855 fi
856
857 if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
858 bbnote "Copying fitImage-${INITRAMFS_IMAGE} file..."
Patrick Williams2390b1b2022-11-03 13:47:49 -0500859 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 -0500860 if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
861 ln -snf fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
862 fi
863 fi
864 fi
865 fi
Patrick Williams92b42cb2022-09-03 06:53:57 -0500866}