1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7inherit kernel-uboot kernel-artifact-names uboot-config
8
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")
53}
54
55
56# Description string
57FIT_DESC ?= "Kernel fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}"
58
59# 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
84# 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
92# Allow user to select the default DTB for FIT image when multiple dtb's exists.
93FIT_CONF_DEFAULT_DTB ?= ""
94
95# length of address in number of <u32> cells
96# ex: 1 32bits address, 2 64bits address
97FIT_ADDRESS_CELLS ?= "1"
98
99# 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}";
117        #address-cells = <${FIT_ADDRESS_CELLS}>;
118EOF
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#
365# 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#
386# 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
395# $8 ... default DTB image name
396fitimage_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"
412	default_dtb_image="$8"
413
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	compatible_line=""
425
426	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
431	dtb_path="${EXTERNAL_KERNEL_DEVICETREE}/${dtb_image_sect}"
432	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
438
439	dtb_image=$(echo $dtb_image | tr '/' '_')
440	dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
441
442	# 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=", "
459		fdt_line="fdt = \"fdt-$dtb_image_sect\";"
460	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
483		        # Select default node as user specified dtb when
484		        # multiple dtb exists.
485		        if [ -n "$default_dtb_image" ]; then
486			        default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
487		        else
488			        default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
489		        fi
490		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";
499                        $compatible_line
500                        $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=""
569	default_dtb_image=""
570	rm -f $1 arch/${ARCH}/boot/$2
571
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
603			DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
604			if [ ! -e "$DTB_PATH" ]; then
605				DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
606			fi
607
608		        # 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
613			# 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
620			# Skip DTB if we've picked it up previously
621			echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
622
623			DTBS="$DTBS $DTB"
624			DTB=$(echo $DTB | tr '/' '_')
625			fitimage_emit_section_dtb $1 $DTB $DTB_PATH
626		done
627	fi
628
629	if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
630		dtbcount=1
631		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
633			# 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
640			# Skip DTB/DTBO if we've picked it up previously
641			echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
642
643			DTBS="$DTBS $DTB"
644
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 '/' '_')
649			fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
650		done
651	fi
652
653	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
657	#
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	#
674	if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
675		setupcount=1
676		fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
677	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
729				fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
730			else
731				fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
732			fi
733			i=`expr $i + 1`
734		done
735	else
736		defaultconfigcount=1
737		fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id"  "$setupcount" $defaultconfigcount "$default_dtb_image"
738	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 \
750		${KERNEL_OUTPUT_DIR}/$2
751
752	#
753	# Step 8: Sign the image
754	#
755	if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
756		${UBOOT_MKIMAGE_SIGN} \
757			${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
758			-F -k "${UBOOT_SIGN_KEYDIR}" \
759			-r ${KERNEL_OUTPUT_DIR}/$2 \
760			${UBOOT_MKIMAGE_SIGN_ARGS}
761	fi
762}
763
764do_assemble_fitimage() {
765	if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
766		cd ${B}
767		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
771	fi
772}
773
774addtask assemble_fitimage before do_install after do_compile
775
776SYSROOT_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
784do_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
789			fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-bundle ""
790			ln -sf fitImage-bundle ${B}/${KERNEL_OUTPUT_DIR}/fitImage
791		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..."
874				install -m 0644 ${B}/${KERNEL_OUTPUT_DIR}/fitImage-${INITRAMFS_IMAGE} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}"
875				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
881}
882