new file mode 100644
@@ -0,0 +1,730 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+inherit kernel-uboot kernel-artifact-names uboot-config
+
+python __anonymous () {
+ #check if there are any dtb providers
+ providerdtb = d.getVar("PREFERRED_PROVIDER_virtual/dtb")
+ if providerdtb:
+ d.setVar('EXTERNAL_KERNEL_DEVICETREE', "${RECIPE_SYSROOT}/boot/devicetree")
+}
+
+# Description string
+FIT_DESC ?= "Kernel fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}"
+
+# Kernel fitImage Hash Algo
+FIT_HASH_ALG ?= "sha256"
+
+# Kernel fitImage Signature Algo
+FIT_SIGN_ALG ?= "rsa2048"
+
+# Kernel / U-Boot fitImage Padding Algo
+FIT_PAD_ALG ?= "pkcs-1.5"
+
+# Generate keys for signing Kernel fitImage
+FIT_GENERATE_KEYS ?= "0"
+
+# Size of private keys in number of bits
+FIT_SIGN_NUMBITS ?= "2048"
+
+# args to openssl genrsa (Default is just the public exponent)
+FIT_KEY_GENRSA_ARGS ?= "-F4"
+
+# args to openssl req (Default is -batch for non interactive mode and
+# -new for new certificate)
+FIT_KEY_REQ_ARGS ?= "-batch -new"
+
+# Standard format for public key certificate
+FIT_KEY_SIGN_PKCS ?= "-x509"
+
+# Sign individual images as well
+FIT_SIGN_INDIVIDUAL ?= "0"
+
+FIT_CONF_PREFIX ?= "conf-"
+FIT_CONF_PREFIX[doc] = "Prefix to use for FIT configuration node name"
+
+FIT_SUPPORTED_INITRAMFS_FSTYPES ?= "cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.zst cpio.gz ext2.gz cpio"
+
+# Allow user to select the default DTB for FIT image when multiple dtb's exists.
+FIT_CONF_DEFAULT_DTB ?= ""
+
+# length of address in number of <u32> cells
+# ex: 1 32bits address, 2 64bits address
+FIT_ADDRESS_CELLS ?= "1"
+
+# Keys used to sign individually image nodes.
+# The keys to sign image nodes must be different from those used to sign
+# configuration nodes, otherwise the "required" property, from
+# UBOOT_DTB_BINARY, will be set to "conf", because "conf" prevails on "image".
+# Then the images signature checking will not be mandatory and no error will be
+# raised in case of failure.
+# UBOOT_SIGN_IMG_KEYNAME = "dev2" # keys name in keydir (eg. "dev2.crt", "dev2.key")
+
+#
+# Emit the fitImage ITS header
+#
+# $1 ... .its filename
+fitimage_emit_fit_header() {
+ cat << EOF >> $1
+/dts-v1/;
+
+/ {
+ description = "${FIT_DESC}";
+ #address-cells = <${FIT_ADDRESS_CELLS}>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... .its filename
+# $2 ... Section bit type: imagestart - image section start
+# confstart - configuration section start
+# sectend - section end
+# fitend - fitimage end
+#
+fitimage_emit_section_maint() {
+ case $2 in
+ imagestart)
+ cat << EOF >> $1
+
+ images {
+EOF
+ ;;
+ confstart)
+ cat << EOF >> $1
+
+ configurations {
+EOF
+ ;;
+ sectend)
+ cat << EOF >> $1
+ };
+EOF
+ ;;
+ fitend)
+ cat << EOF >> $1
+};
+EOF
+ ;;
+ esac
+}
+
+#
+# Emit the fitImage ITS kernel section
+#
+# $1 ... .its filename
+# $2 ... Image counter
+# $3 ... Path to kernel image
+# $4 ... Compression type
+fitimage_emit_section_kernel() {
+
+ kernel_csum="${FIT_HASH_ALG}"
+ kernel_sign_algo="${FIT_SIGN_ALG}"
+ kernel_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+
+ ENTRYPOINT="${UBOOT_ENTRYPOINT}"
+ if [ -n "${UBOOT_ENTRYSYMBOL}" ]; then
+ ENTRYPOINT=`${HOST_PREFIX}nm vmlinux | \
+ awk '$3=="${UBOOT_ENTRYSYMBOL}" {print "0x"$1;exit}'`
+ fi
+
+ cat << EOF >> $1
+ kernel-$2 {
+ description = "Linux kernel";
+ data = /incbin/("$3");
+ type = "${UBOOT_MKIMAGE_KERNEL_TYPE}";
+ arch = "${UBOOT_ARCH}";
+ os = "linux";
+ compression = "$4";
+ load = <${UBOOT_LOADADDRESS}>;
+ entry = <$ENTRYPOINT>;
+ hash-1 {
+ algo = "$kernel_csum";
+ };
+ };
+EOF
+
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$kernel_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$kernel_csum,$kernel_sign_algo";
+ key-name-hint = "$kernel_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+#
+# Emit the fitImage ITS DTB section
+#
+# $1 ... .its filename
+# $2 ... Image counter
+# $3 ... Path to DTB image
+fitimage_emit_section_dtb() {
+
+ dtb_csum="${FIT_HASH_ALG}"
+ dtb_sign_algo="${FIT_SIGN_ALG}"
+ dtb_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+
+ dtb_loadline=""
+ dtb_ext=${DTB##*.}
+ if [ "${dtb_ext}" = "dtbo" ]; then
+ if [ -n "${UBOOT_DTBO_LOADADDRESS}" ]; then
+ dtb_loadline="load = <${UBOOT_DTBO_LOADADDRESS}>;"
+ fi
+ elif [ -n "${UBOOT_DTB_LOADADDRESS}" ]; then
+ dtb_loadline="load = <${UBOOT_DTB_LOADADDRESS}>;"
+ fi
+ cat << EOF >> $1
+ fdt-$2 {
+ description = "Flattened Device Tree blob";
+ data = /incbin/("$3");
+ type = "flat_dt";
+ arch = "${UBOOT_ARCH}";
+ compression = "none";
+ $dtb_loadline
+ hash-1 {
+ algo = "$dtb_csum";
+ };
+ };
+EOF
+
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$dtb_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$dtb_csum,$dtb_sign_algo";
+ key-name-hint = "$dtb_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+#
+# Emit the fitImage ITS u-boot script section
+#
+# $1 ... .its filename
+# $2 ... Image counter
+# $3 ... Path to boot script image
+fitimage_emit_section_boot_script() {
+
+ bootscr_csum="${FIT_HASH_ALG}"
+ bootscr_sign_algo="${FIT_SIGN_ALG}"
+ bootscr_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+
+ cat << EOF >> $1
+ bootscr-$2 {
+ description = "U-boot script";
+ data = /incbin/("$3");
+ type = "script";
+ arch = "${UBOOT_ARCH}";
+ compression = "none";
+ hash-1 {
+ algo = "$bootscr_csum";
+ };
+ };
+EOF
+
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$bootscr_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$bootscr_csum,$bootscr_sign_algo";
+ key-name-hint = "$bootscr_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+#
+# Emit the fitImage ITS setup section
+#
+# $1 ... .its filename
+# $2 ... Image counter
+# $3 ... Path to setup image
+fitimage_emit_section_setup() {
+
+ setup_csum="${FIT_HASH_ALG}"
+
+ cat << EOF >> $1
+ setup-$2 {
+ description = "Linux setup.bin";
+ data = /incbin/("$3");
+ type = "x86_setup";
+ arch = "${UBOOT_ARCH}";
+ os = "linux";
+ compression = "none";
+ load = <0x00090000>;
+ entry = <0x00090000>;
+ hash-1 {
+ algo = "$setup_csum";
+ };
+ };
+EOF
+}
+
+#
+# Emit the fitImage ITS ramdisk section
+#
+# $1 ... .its filename
+# $2 ... Image counter
+# $3 ... Path to ramdisk image
+fitimage_emit_section_ramdisk() {
+
+ ramdisk_csum="${FIT_HASH_ALG}"
+ ramdisk_sign_algo="${FIT_SIGN_ALG}"
+ ramdisk_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
+ ramdisk_loadline=""
+ ramdisk_entryline=""
+
+ if [ -n "${UBOOT_RD_LOADADDRESS}" ]; then
+ ramdisk_loadline="load = <${UBOOT_RD_LOADADDRESS}>;"
+ fi
+ if [ -n "${UBOOT_RD_ENTRYPOINT}" ]; then
+ ramdisk_entryline="entry = <${UBOOT_RD_ENTRYPOINT}>;"
+ fi
+
+ cat << EOF >> $1
+ ramdisk-$2 {
+ description = "${INITRAMFS_IMAGE}";
+ data = /incbin/("$3");
+ type = "ramdisk";
+ arch = "${UBOOT_ARCH}";
+ os = "linux";
+ compression = "none";
+ $ramdisk_loadline
+ $ramdisk_entryline
+ hash-1 {
+ algo = "$ramdisk_csum";
+ };
+ };
+EOF
+
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$ramdisk_sign_keyname" ] ; then
+ sed -i '$ d' $1
+ cat << EOF >> $1
+ signature-1 {
+ algo = "$ramdisk_csum,$ramdisk_sign_algo";
+ key-name-hint = "$ramdisk_sign_keyname";
+ };
+ };
+EOF
+ fi
+}
+
+#
+# echoes symlink destination if it points below directory
+#
+# $1 ... file that's a potential symlink
+# $2 ... expected parent directory
+symlink_points_below() {
+ file="$2/$1"
+ dir=$2
+
+ if ! [ -L "$file" ]; then
+ return
+ fi
+
+ realpath="$(realpath --relative-to=$dir $file)"
+ if [ -z "${realpath%%../*}" ]; then
+ return
+ fi
+
+ echo "$realpath"
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... .its filename
+# $2 ... Linux kernel ID
+# $3 ... DTB image name
+# $4 ... ramdisk ID
+# $5 ... u-boot script ID
+# $6 ... config ID
+# $7 ... default flag
+# $8 ... default DTB image name
+fitimage_emit_section_config() {
+
+ conf_csum="${FIT_HASH_ALG}"
+ conf_sign_algo="${FIT_SIGN_ALG}"
+ conf_padding_algo="${FIT_PAD_ALG}"
+ if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then
+ conf_sign_keyname="${UBOOT_SIGN_KEYNAME}"
+ fi
+
+ its_file="$1"
+ kernel_id="$2"
+ dtb_image="$3"
+ ramdisk_id="$4"
+ bootscr_id="$5"
+ config_id="$6"
+ default_flag="$7"
+ default_dtb_image="$8"
+
+ # Test if we have any DTBs at all
+ sep=""
+ conf_desc=""
+ conf_node="${FIT_CONF_PREFIX}"
+ kernel_line=""
+ fdt_line=""
+ ramdisk_line=""
+ bootscr_line=""
+ setup_line=""
+ default_line=""
+ compatible_line=""
+
+ dtb_image_sect=$(symlink_points_below $dtb_image "${EXTERNAL_KERNEL_DEVICETREE}")
+ if [ -z "$dtb_image_sect" ]; then
+ dtb_image_sect=$dtb_image
+ fi
+
+ dtb_path="${EXTERNAL_KERNEL_DEVICETREE}/${dtb_image_sect}"
+ if [ -f "$dtb_path" ] || [ -L "$dtb_path" ]; then
+ compat=$(fdtget -t s "$dtb_path" / compatible | sed 's/ /", "/g')
+ if [ -n "$compat" ]; then
+ compatible_line="compatible = \"$compat\";"
+ fi
+ fi
+
+ dtb_image=$(echo $dtb_image | tr '/' '_')
+ dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
+
+ # conf node name is selected based on dtb ID if it is present,
+ # otherwise its selected based on kernel ID
+ if [ -n "$dtb_image" ]; then
+ conf_node=$conf_node$dtb_image
+ else
+ conf_node=$conf_node$kernel_id
+ fi
+
+ if [ -n "$kernel_id" ]; then
+ conf_desc="Linux kernel"
+ sep=", "
+ kernel_line="kernel = \"kernel-$kernel_id\";"
+ fi
+
+ if [ -n "$dtb_image" ]; then
+ conf_desc="$conf_desc${sep}FDT blob"
+ sep=", "
+ fdt_line="fdt = \"fdt-$dtb_image_sect\";"
+ fi
+
+ if [ -n "$ramdisk_id" ]; then
+ conf_desc="$conf_desc${sep}ramdisk"
+ sep=", "
+ ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
+ fi
+
+ if [ -n "$bootscr_id" ]; then
+ conf_desc="$conf_desc${sep}u-boot script"
+ sep=", "
+ bootscr_line="bootscr = \"bootscr-$bootscr_id\";"
+ fi
+
+ if [ -n "$config_id" ]; then
+ conf_desc="$conf_desc${sep}setup"
+ setup_line="setup = \"setup-$config_id\";"
+ fi
+
+ if [ "$default_flag" = "1" ]; then
+ # default node is selected based on dtb ID if it is present,
+ # otherwise its selected based on kernel ID
+ if [ -n "$dtb_image" ]; then
+ # Select default node as user specified dtb when
+ # multiple dtb exists.
+ if [ -n "$default_dtb_image" ]; then
+ default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
+ else
+ default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
+ fi
+ else
+ default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
+ fi
+ fi
+
+ cat << EOF >> $its_file
+ $default_line
+ $conf_node {
+ description = "$default_flag $conf_desc";
+ $compatible_line
+ $kernel_line
+ $fdt_line
+ $ramdisk_line
+ $bootscr_line
+ $setup_line
+ hash-1 {
+ algo = "$conf_csum";
+ };
+EOF
+
+ if [ -n "$conf_sign_keyname" ] ; then
+
+ sign_line="sign-images = "
+ sep=""
+
+ if [ -n "$kernel_id" ]; then
+ sign_line="$sign_line${sep}\"kernel\""
+ sep=", "
+ fi
+
+ if [ -n "$dtb_image" ]; then
+ sign_line="$sign_line${sep}\"fdt\""
+ sep=", "
+ fi
+
+ if [ -n "$ramdisk_id" ]; then
+ sign_line="$sign_line${sep}\"ramdisk\""
+ sep=", "
+ fi
+
+ if [ -n "$bootscr_id" ]; then
+ sign_line="$sign_line${sep}\"bootscr\""
+ sep=", "
+ fi
+
+ if [ -n "$config_id" ]; then
+ sign_line="$sign_line${sep}\"setup\""
+ fi
+
+ sign_line="$sign_line;"
+
+ cat << EOF >> $its_file
+ signature-1 {
+ algo = "$conf_csum,$conf_sign_algo";
+ key-name-hint = "$conf_sign_keyname";
+ padding = "$conf_padding_algo";
+ $sign_line
+ };
+EOF
+ fi
+
+ cat << EOF >> $its_file
+ };
+EOF
+}
+
+#
+# Assemble fitImage .its source
+#
+# $1 ... .its filename
+# $2 ... include ramdisk
+fitimage_assemble_its() {
+ kernelcount=1
+ dtbcount=""
+ DTBS=""
+ ramdiskcount=$2
+ setupcount=""
+ bootscr_id=""
+ default_dtb_image=""
+
+ rm -f $1
+
+ if [ -n "${UBOOT_SIGN_IMG_KEYNAME}" -a "${UBOOT_SIGN_KEYNAME}" = "${UBOOT_SIGN_IMG_KEYNAME}" ]; then
+ bbfatal "Keys used to sign images and configuration nodes must be different."
+ fi
+
+ fitimage_emit_fit_header $1
+
+ #
+ # Step 1: Prepare a kernel image section.
+ #
+ fitimage_emit_section_maint $1 imagestart
+
+ uboot_prep_kimage
+ fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
+
+ #
+ # Step 2: Prepare a DTB image section
+ #
+
+ if [ -n "${KERNEL_DEVICETREE}" ]; then
+ dtbcount=1
+ for DTB in ${KERNEL_DEVICETREE}; do
+ if echo $DTB | grep -q '/dts/'; then
+ bbwarn "$DTB contains the full path to the the dts file, but only the dtb name should be used."
+ DTB=`basename $DTB | sed 's,\.dts$,.dtb,g'`
+ fi
+
+ # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
+ if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
+ continue
+ fi
+
+ DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
+ if [ ! -e "$DTB_PATH" ]; then
+ DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
+ fi
+
+ # Strip off the path component from the filename
+ if "${@'false' if oe.types.boolean(d.getVar('KERNEL_DTBVENDORED')) else 'true'}"; then
+ DTB=`basename $DTB`
+ fi
+
+ # Set the default dtb image if it exists in the devicetree.
+ if [ "${FIT_CONF_DEFAULT_DTB}" = "$DTB" ];then
+ default_dtb_image=$(echo "$DTB" | tr '/' '_')
+ fi
+
+ DTB=$(echo "$DTB" | tr '/' '_')
+
+ # Skip DTB if we've picked it up previously
+ echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
+
+ DTBS="$DTBS $DTB"
+ DTB=$(echo $DTB | tr '/' '_')
+ fitimage_emit_section_dtb $1 $DTB $DTB_PATH
+ done
+ fi
+
+ if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
+ dtbcount=1
+ for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtb' -printf '%P\n' | sort) \
+ $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtbo' -printf '%P\n' | sort); do
+ # Set the default dtb image if it exists in the devicetree.
+ if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
+ default_dtb_image=$(echo "$DTB" | tr '/' '_')
+ fi
+
+ DTB=$(echo "$DTB" | tr '/' '_')
+
+ # Skip DTB/DTBO if we've picked it up previously
+ echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
+
+ DTBS="$DTBS $DTB"
+
+ # Also skip if a symlink. We'll later have each config section point at it
+ [ $(symlink_points_below $DTB "${EXTERNAL_KERNEL_DEVICETREE}") ] && continue
+
+ DTB=$(echo $DTB | tr '/' '_')
+ fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
+ done
+ fi
+
+ if [ -n "${FIT_CONF_DEFAULT_DTB}" ] && [ -z $default_dtb_image ]; then
+ bbwarn "${FIT_CONF_DEFAULT_DTB} is not available in the list of device trees."
+ fi
+
+ #
+ # Step 3: Prepare a u-boot script section
+ #
+
+ if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
+ if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
+ cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
+ bootscr_id="${UBOOT_ENV_BINARY}"
+ fitimage_emit_section_boot_script $1 "$bootscr_id" ${UBOOT_ENV_BINARY}
+ else
+ bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
+ fi
+ fi
+
+ #
+ # Step 4: Prepare a setup section. (For x86)
+ #
+ if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
+ setupcount=1
+ fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
+ fi
+
+ #
+ # Step 5: Prepare a ramdisk section.
+ #
+ if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
+ # Find and use the first initramfs image archive type we find
+ found=
+ for img in ${FIT_SUPPORTED_INITRAMFS_FSTYPES}; do
+ initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img"
+ if [ -e "$initramfs_path" ]; then
+ bbnote "Found initramfs image: $initramfs_path"
+ found=true
+ fitimage_emit_section_ramdisk $1 "$ramdiskcount" "$initramfs_path"
+ break
+ else
+ bbnote "Did not find initramfs image: $initramfs_path"
+ fi
+ done
+
+ if [ -z "$found" ]; then
+ bbfatal "Could not find a valid initramfs type for ${INITRAMFS_IMAGE_NAME}, the supported types are: ${FIT_SUPPORTED_INITRAMFS_FSTYPES}"
+ fi
+ fi
+
+ fitimage_emit_section_maint $1 sectend
+
+ # Force the first Kernel and DTB in the default config
+ kernelcount=1
+ if [ -n "$dtbcount" ]; then
+ dtbcount=1
+ fi
+
+ #
+ # Step 6: Prepare a configurations section
+ #
+ fitimage_emit_section_maint $1 confstart
+
+ # kernel-fitimage.bbclass currently only supports a single kernel (no less or
+ # more) to be added to the FIT image along with 0 or more device trees and
+ # 0 or 1 ramdisk.
+ # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
+ # When the initramfs bundle is used ramdisk is disabled.
+ # If a device tree is to be part of the FIT image, then select
+ # the default configuration to be used is based on the dtbcount. If there is
+ # no dtb present than select the default configuation to be based on
+ # the kernelcount.
+ if [ -n "$DTBS" ]; then
+ i=1
+ for DTB in ${DTBS}; do
+ dtb_ext=${DTB##*.}
+ if [ "$dtb_ext" = "dtbo" ]; then
+ fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
+ else
+ fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
+ fi
+ i=`expr $i + 1`
+ done
+ else
+ defaultconfigcount=1
+ fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id" "$setupcount" $defaultconfigcount "$default_dtb_image"
+ fi
+
+ fitimage_emit_section_maint $1 sectend
+
+ fitimage_emit_section_maint $1 fitend
+}
+
+#
+# Assemble fitImage .itb blob
+#
+# $1 ... .its filename
+# $2 ... .itb filename
+fitimage_assemble_itb() {
+ #
+ # Step 1: Assemble the image
+ #
+ rm -f arch/${ARCH}/boot/$1
+ ${UBOOT_MKIMAGE} \
+ ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
+ -f $1 \
+ ${KERNEL_OUTPUT_DIR}/$2
+
+ #
+ # Step 2: Sign the image
+ #
+ if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
+ ${UBOOT_MKIMAGE_SIGN} \
+ ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
+ -F -k "${UBOOT_SIGN_KEYDIR}" \
+ -r ${KERNEL_OUTPUT_DIR}/$2 \
+ ${UBOOT_MKIMAGE_SIGN_ARGS}
+ fi
+}
@@ -4,7 +4,7 @@
# SPDX-License-Identifier: MIT
#
-inherit kernel-uboot kernel-artifact-names uboot-config
+inherit kernel-uboot kernel-artifact-names uboot-config kernel-fitimage-its
def get_fit_replacement_type(d):
kerneltypes = d.getVar('KERNEL_IMAGETYPES') or ""
@@ -49,716 +49,6 @@ python __anonymous () {
if providerdtb:
d.appendVarFlag('do_assemble_fitimage', 'depends', ' virtual/dtb:do_populate_sysroot')
d.appendVarFlag('do_assemble_fitimage_initramfs', 'depends', ' virtual/dtb:do_populate_sysroot')
- d.setVar('EXTERNAL_KERNEL_DEVICETREE', "${RECIPE_SYSROOT}/boot/devicetree")
-}
-
-
-# Description string
-FIT_DESC ?= "Kernel fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}"
-
-# Kernel fitImage Hash Algo
-FIT_HASH_ALG ?= "sha256"
-
-# Kernel fitImage Signature Algo
-FIT_SIGN_ALG ?= "rsa2048"
-
-# Kernel / U-Boot fitImage Padding Algo
-FIT_PAD_ALG ?= "pkcs-1.5"
-
-# Generate keys for signing Kernel fitImage
-FIT_GENERATE_KEYS ?= "0"
-
-# Size of private keys in number of bits
-FIT_SIGN_NUMBITS ?= "2048"
-
-# args to openssl genrsa (Default is just the public exponent)
-FIT_KEY_GENRSA_ARGS ?= "-F4"
-
-# args to openssl req (Default is -batch for non interactive mode and
-# -new for new certificate)
-FIT_KEY_REQ_ARGS ?= "-batch -new"
-
-# Standard format for public key certificate
-FIT_KEY_SIGN_PKCS ?= "-x509"
-
-# Sign individual images as well
-FIT_SIGN_INDIVIDUAL ?= "0"
-
-FIT_CONF_PREFIX ?= "conf-"
-FIT_CONF_PREFIX[doc] = "Prefix to use for FIT configuration node name"
-
-FIT_SUPPORTED_INITRAMFS_FSTYPES ?= "cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.zst cpio.gz ext2.gz cpio"
-
-# Allow user to select the default DTB for FIT image when multiple dtb's exists.
-FIT_CONF_DEFAULT_DTB ?= ""
-
-# length of address in number of <u32> cells
-# ex: 1 32bits address, 2 64bits address
-FIT_ADDRESS_CELLS ?= "1"
-
-# Keys used to sign individually image nodes.
-# The keys to sign image nodes must be different from those used to sign
-# configuration nodes, otherwise the "required" property, from
-# UBOOT_DTB_BINARY, will be set to "conf", because "conf" prevails on "image".
-# Then the images signature checking will not be mandatory and no error will be
-# raised in case of failure.
-# UBOOT_SIGN_IMG_KEYNAME = "dev2" # keys name in keydir (eg. "dev2.crt", "dev2.key")
-
-#
-# Emit the fitImage ITS header
-#
-# $1 ... .its filename
-fitimage_emit_fit_header() {
- cat << EOF >> $1
-/dts-v1/;
-
-/ {
- description = "${FIT_DESC}";
- #address-cells = <${FIT_ADDRESS_CELLS}>;
-EOF
-}
-
-#
-# Emit the fitImage section bits
-#
-# $1 ... .its filename
-# $2 ... Section bit type: imagestart - image section start
-# confstart - configuration section start
-# sectend - section end
-# fitend - fitimage end
-#
-fitimage_emit_section_maint() {
- case $2 in
- imagestart)
- cat << EOF >> $1
-
- images {
-EOF
- ;;
- confstart)
- cat << EOF >> $1
-
- configurations {
-EOF
- ;;
- sectend)
- cat << EOF >> $1
- };
-EOF
- ;;
- fitend)
- cat << EOF >> $1
-};
-EOF
- ;;
- esac
-}
-
-#
-# Emit the fitImage ITS kernel section
-#
-# $1 ... .its filename
-# $2 ... Image counter
-# $3 ... Path to kernel image
-# $4 ... Compression type
-fitimage_emit_section_kernel() {
-
- kernel_csum="${FIT_HASH_ALG}"
- kernel_sign_algo="${FIT_SIGN_ALG}"
- kernel_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
-
- ENTRYPOINT="${UBOOT_ENTRYPOINT}"
- if [ -n "${UBOOT_ENTRYSYMBOL}" ]; then
- ENTRYPOINT=`${HOST_PREFIX}nm vmlinux | \
- awk '$3=="${UBOOT_ENTRYSYMBOL}" {print "0x"$1;exit}'`
- fi
-
- cat << EOF >> $1
- kernel-$2 {
- description = "Linux kernel";
- data = /incbin/("$3");
- type = "${UBOOT_MKIMAGE_KERNEL_TYPE}";
- arch = "${UBOOT_ARCH}";
- os = "linux";
- compression = "$4";
- load = <${UBOOT_LOADADDRESS}>;
- entry = <$ENTRYPOINT>;
- hash-1 {
- algo = "$kernel_csum";
- };
- };
-EOF
-
- if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$kernel_sign_keyname" ] ; then
- sed -i '$ d' $1
- cat << EOF >> $1
- signature-1 {
- algo = "$kernel_csum,$kernel_sign_algo";
- key-name-hint = "$kernel_sign_keyname";
- };
- };
-EOF
- fi
-}
-
-#
-# Emit the fitImage ITS DTB section
-#
-# $1 ... .its filename
-# $2 ... Image counter
-# $3 ... Path to DTB image
-fitimage_emit_section_dtb() {
-
- dtb_csum="${FIT_HASH_ALG}"
- dtb_sign_algo="${FIT_SIGN_ALG}"
- dtb_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
-
- dtb_loadline=""
- dtb_ext=${DTB##*.}
- if [ "${dtb_ext}" = "dtbo" ]; then
- if [ -n "${UBOOT_DTBO_LOADADDRESS}" ]; then
- dtb_loadline="load = <${UBOOT_DTBO_LOADADDRESS}>;"
- fi
- elif [ -n "${UBOOT_DTB_LOADADDRESS}" ]; then
- dtb_loadline="load = <${UBOOT_DTB_LOADADDRESS}>;"
- fi
- cat << EOF >> $1
- fdt-$2 {
- description = "Flattened Device Tree blob";
- data = /incbin/("$3");
- type = "flat_dt";
- arch = "${UBOOT_ARCH}";
- compression = "none";
- $dtb_loadline
- hash-1 {
- algo = "$dtb_csum";
- };
- };
-EOF
-
- if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$dtb_sign_keyname" ] ; then
- sed -i '$ d' $1
- cat << EOF >> $1
- signature-1 {
- algo = "$dtb_csum,$dtb_sign_algo";
- key-name-hint = "$dtb_sign_keyname";
- };
- };
-EOF
- fi
-}
-
-#
-# Emit the fitImage ITS u-boot script section
-#
-# $1 ... .its filename
-# $2 ... Image counter
-# $3 ... Path to boot script image
-fitimage_emit_section_boot_script() {
-
- bootscr_csum="${FIT_HASH_ALG}"
- bootscr_sign_algo="${FIT_SIGN_ALG}"
- bootscr_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
-
- cat << EOF >> $1
- bootscr-$2 {
- description = "U-boot script";
- data = /incbin/("$3");
- type = "script";
- arch = "${UBOOT_ARCH}";
- compression = "none";
- hash-1 {
- algo = "$bootscr_csum";
- };
- };
-EOF
-
- if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$bootscr_sign_keyname" ] ; then
- sed -i '$ d' $1
- cat << EOF >> $1
- signature-1 {
- algo = "$bootscr_csum,$bootscr_sign_algo";
- key-name-hint = "$bootscr_sign_keyname";
- };
- };
-EOF
- fi
-}
-
-#
-# Emit the fitImage ITS setup section
-#
-# $1 ... .its filename
-# $2 ... Image counter
-# $3 ... Path to setup image
-fitimage_emit_section_setup() {
-
- setup_csum="${FIT_HASH_ALG}"
-
- cat << EOF >> $1
- setup-$2 {
- description = "Linux setup.bin";
- data = /incbin/("$3");
- type = "x86_setup";
- arch = "${UBOOT_ARCH}";
- os = "linux";
- compression = "none";
- load = <0x00090000>;
- entry = <0x00090000>;
- hash-1 {
- algo = "$setup_csum";
- };
- };
-EOF
-}
-
-#
-# Emit the fitImage ITS ramdisk section
-#
-# $1 ... .its filename
-# $2 ... Image counter
-# $3 ... Path to ramdisk image
-fitimage_emit_section_ramdisk() {
-
- ramdisk_csum="${FIT_HASH_ALG}"
- ramdisk_sign_algo="${FIT_SIGN_ALG}"
- ramdisk_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
- ramdisk_loadline=""
- ramdisk_entryline=""
-
- if [ -n "${UBOOT_RD_LOADADDRESS}" ]; then
- ramdisk_loadline="load = <${UBOOT_RD_LOADADDRESS}>;"
- fi
- if [ -n "${UBOOT_RD_ENTRYPOINT}" ]; then
- ramdisk_entryline="entry = <${UBOOT_RD_ENTRYPOINT}>;"
- fi
-
- cat << EOF >> $1
- ramdisk-$2 {
- description = "${INITRAMFS_IMAGE}";
- data = /incbin/("$3");
- type = "ramdisk";
- arch = "${UBOOT_ARCH}";
- os = "linux";
- compression = "none";
- $ramdisk_loadline
- $ramdisk_entryline
- hash-1 {
- algo = "$ramdisk_csum";
- };
- };
-EOF
-
- if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$ramdisk_sign_keyname" ] ; then
- sed -i '$ d' $1
- cat << EOF >> $1
- signature-1 {
- algo = "$ramdisk_csum,$ramdisk_sign_algo";
- key-name-hint = "$ramdisk_sign_keyname";
- };
- };
-EOF
- fi
-}
-
-#
-# echoes symlink destination if it points below directory
-#
-# $1 ... file that's a potential symlink
-# $2 ... expected parent directory
-symlink_points_below() {
- file="$2/$1"
- dir=$2
-
- if ! [ -L "$file" ]; then
- return
- fi
-
- realpath="$(realpath --relative-to=$dir $file)"
- if [ -z "${realpath%%../*}" ]; then
- return
- fi
-
- echo "$realpath"
-}
-
-#
-# Emit the fitImage ITS configuration section
-#
-# $1 ... .its filename
-# $2 ... Linux kernel ID
-# $3 ... DTB image name
-# $4 ... ramdisk ID
-# $5 ... u-boot script ID
-# $6 ... config ID
-# $7 ... default flag
-# $8 ... default DTB image name
-fitimage_emit_section_config() {
-
- conf_csum="${FIT_HASH_ALG}"
- conf_sign_algo="${FIT_SIGN_ALG}"
- conf_padding_algo="${FIT_PAD_ALG}"
- if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then
- conf_sign_keyname="${UBOOT_SIGN_KEYNAME}"
- fi
-
- its_file="$1"
- kernel_id="$2"
- dtb_image="$3"
- ramdisk_id="$4"
- bootscr_id="$5"
- config_id="$6"
- default_flag="$7"
- default_dtb_image="$8"
-
- # Test if we have any DTBs at all
- sep=""
- conf_desc=""
- conf_node="${FIT_CONF_PREFIX}"
- kernel_line=""
- fdt_line=""
- ramdisk_line=""
- bootscr_line=""
- setup_line=""
- default_line=""
- compatible_line=""
-
- dtb_image_sect=$(symlink_points_below $dtb_image "${EXTERNAL_KERNEL_DEVICETREE}")
- if [ -z "$dtb_image_sect" ]; then
- dtb_image_sect=$dtb_image
- fi
-
- dtb_path="${EXTERNAL_KERNEL_DEVICETREE}/${dtb_image_sect}"
- if [ -f "$dtb_path" ] || [ -L "$dtb_path" ]; then
- compat=$(fdtget -t s "$dtb_path" / compatible | sed 's/ /", "/g')
- if [ -n "$compat" ]; then
- compatible_line="compatible = \"$compat\";"
- fi
- fi
-
- dtb_image=$(echo $dtb_image | tr '/' '_')
- dtb_image_sect=$(echo "${dtb_image_sect}" | tr '/' '_')
-
- # conf node name is selected based on dtb ID if it is present,
- # otherwise its selected based on kernel ID
- if [ -n "$dtb_image" ]; then
- conf_node=$conf_node$dtb_image
- else
- conf_node=$conf_node$kernel_id
- fi
-
- if [ -n "$kernel_id" ]; then
- conf_desc="Linux kernel"
- sep=", "
- kernel_line="kernel = \"kernel-$kernel_id\";"
- fi
-
- if [ -n "$dtb_image" ]; then
- conf_desc="$conf_desc${sep}FDT blob"
- sep=", "
- fdt_line="fdt = \"fdt-$dtb_image_sect\";"
- fi
-
- if [ -n "$ramdisk_id" ]; then
- conf_desc="$conf_desc${sep}ramdisk"
- sep=", "
- ramdisk_line="ramdisk = \"ramdisk-$ramdisk_id\";"
- fi
-
- if [ -n "$bootscr_id" ]; then
- conf_desc="$conf_desc${sep}u-boot script"
- sep=", "
- bootscr_line="bootscr = \"bootscr-$bootscr_id\";"
- fi
-
- if [ -n "$config_id" ]; then
- conf_desc="$conf_desc${sep}setup"
- setup_line="setup = \"setup-$config_id\";"
- fi
-
- if [ "$default_flag" = "1" ]; then
- # default node is selected based on dtb ID if it is present,
- # otherwise its selected based on kernel ID
- if [ -n "$dtb_image" ]; then
- # Select default node as user specified dtb when
- # multiple dtb exists.
- if [ -n "$default_dtb_image" ]; then
- default_line="default = \"${FIT_CONF_PREFIX}$default_dtb_image\";"
- else
- default_line="default = \"${FIT_CONF_PREFIX}$dtb_image\";"
- fi
- else
- default_line="default = \"${FIT_CONF_PREFIX}$kernel_id\";"
- fi
- fi
-
- cat << EOF >> $its_file
- $default_line
- $conf_node {
- description = "$default_flag $conf_desc";
- $compatible_line
- $kernel_line
- $fdt_line
- $ramdisk_line
- $bootscr_line
- $setup_line
- hash-1 {
- algo = "$conf_csum";
- };
-EOF
-
- if [ -n "$conf_sign_keyname" ] ; then
-
- sign_line="sign-images = "
- sep=""
-
- if [ -n "$kernel_id" ]; then
- sign_line="$sign_line${sep}\"kernel\""
- sep=", "
- fi
-
- if [ -n "$dtb_image" ]; then
- sign_line="$sign_line${sep}\"fdt\""
- sep=", "
- fi
-
- if [ -n "$ramdisk_id" ]; then
- sign_line="$sign_line${sep}\"ramdisk\""
- sep=", "
- fi
-
- if [ -n "$bootscr_id" ]; then
- sign_line="$sign_line${sep}\"bootscr\""
- sep=", "
- fi
-
- if [ -n "$config_id" ]; then
- sign_line="$sign_line${sep}\"setup\""
- fi
-
- sign_line="$sign_line;"
-
- cat << EOF >> $its_file
- signature-1 {
- algo = "$conf_csum,$conf_sign_algo";
- key-name-hint = "$conf_sign_keyname";
- padding = "$conf_padding_algo";
- $sign_line
- };
-EOF
- fi
-
- cat << EOF >> $its_file
- };
-EOF
-}
-
-#
-# Assemble fitImage
-#
-# $1 ... .its filename
-# $2 ... fitImage name
-# $3 ... include ramdisk
-fitimage_assemble() {
- kernelcount=1
- dtbcount=""
- DTBS=""
- ramdiskcount=$3
- setupcount=""
- bootscr_id=""
- default_dtb_image=""
- rm -f $1 arch/${ARCH}/boot/$2
-
- if [ -n "${UBOOT_SIGN_IMG_KEYNAME}" -a "${UBOOT_SIGN_KEYNAME}" = "${UBOOT_SIGN_IMG_KEYNAME}" ]; then
- bbfatal "Keys used to sign images and configuration nodes must be different."
- fi
-
- fitimage_emit_fit_header $1
-
- #
- # Step 1: Prepare a kernel image section.
- #
- fitimage_emit_section_maint $1 imagestart
-
- uboot_prep_kimage
- fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
-
- #
- # Step 2: Prepare a DTB image section
- #
-
- if [ -n "${KERNEL_DEVICETREE}" ]; then
- dtbcount=1
- for DTB in ${KERNEL_DEVICETREE}; do
- if echo $DTB | grep -q '/dts/'; then
- bbwarn "$DTB contains the full path to the the dts file, but only the dtb name should be used."
- DTB=`basename $DTB | sed 's,\.dts$,.dtb,g'`
- fi
-
- # Skip ${DTB} if it's also provided in ${EXTERNAL_KERNEL_DEVICETREE}
- if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ] && [ -s ${EXTERNAL_KERNEL_DEVICETREE}/${DTB} ]; then
- continue
- fi
-
- DTB_PATH="${KERNEL_OUTPUT_DIR}/dts/$DTB"
- if [ ! -e "$DTB_PATH" ]; then
- DTB_PATH="${KERNEL_OUTPUT_DIR}/$DTB"
- fi
-
- # Strip off the path component from the filename
- if "${@'false' if oe.types.boolean(d.getVar('KERNEL_DTBVENDORED')) else 'true'}"; then
- DTB=`basename $DTB`
- fi
-
- # Set the default dtb image if it exists in the devicetree.
- if [ "${FIT_CONF_DEFAULT_DTB}" = "$DTB" ];then
- default_dtb_image=$(echo "$DTB" | tr '/' '_')
- fi
-
- DTB=$(echo "$DTB" | tr '/' '_')
-
- # Skip DTB if we've picked it up previously
- echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
-
- DTBS="$DTBS $DTB"
- DTB=$(echo $DTB | tr '/' '_')
- fitimage_emit_section_dtb $1 $DTB $DTB_PATH
- done
- fi
-
- if [ -n "${EXTERNAL_KERNEL_DEVICETREE}" ]; then
- dtbcount=1
- for DTB in $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtb' -printf '%P\n' | sort) \
- $(find "${EXTERNAL_KERNEL_DEVICETREE}" -name '*.dtbo' -printf '%P\n' | sort); do
- # Set the default dtb image if it exists in the devicetree.
- if [ ${FIT_CONF_DEFAULT_DTB} = $DTB ];then
- default_dtb_image=$(echo "$DTB" | tr '/' '_')
- fi
-
- DTB=$(echo "$DTB" | tr '/' '_')
-
- # Skip DTB/DTBO if we've picked it up previously
- echo "$DTBS" | tr ' ' '\n' | grep -xq "$DTB" && continue
-
- DTBS="$DTBS $DTB"
-
- # Also skip if a symlink. We'll later have each config section point at it
- [ $(symlink_points_below $DTB "${EXTERNAL_KERNEL_DEVICETREE}") ] && continue
-
- DTB=$(echo $DTB | tr '/' '_')
- fitimage_emit_section_dtb $1 $DTB "${EXTERNAL_KERNEL_DEVICETREE}/$DTB"
- done
- fi
-
- if [ -n "${FIT_CONF_DEFAULT_DTB}" ] && [ -z $default_dtb_image ]; then
- bbwarn "${FIT_CONF_DEFAULT_DTB} is not available in the list of device trees."
- fi
-
- #
- # Step 3: Prepare a u-boot script section
- #
-
- if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
- if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
- cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
- bootscr_id="${UBOOT_ENV_BINARY}"
- fitimage_emit_section_boot_script $1 "$bootscr_id" ${UBOOT_ENV_BINARY}
- else
- bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
- fi
- fi
-
- #
- # Step 4: Prepare a setup section. (For x86)
- #
- if [ -e ${KERNEL_OUTPUT_DIR}/setup.bin ]; then
- setupcount=1
- fitimage_emit_section_setup $1 $setupcount ${KERNEL_OUTPUT_DIR}/setup.bin
- fi
-
- #
- # Step 5: Prepare a ramdisk section.
- #
- if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
- # Find and use the first initramfs image archive type we find
- found=
- for img in ${FIT_SUPPORTED_INITRAMFS_FSTYPES}; do
- initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.$img"
- if [ -e "$initramfs_path" ]; then
- bbnote "Found initramfs image: $initramfs_path"
- found=true
- fitimage_emit_section_ramdisk $1 "$ramdiskcount" "$initramfs_path"
- break
- else
- bbnote "Did not find initramfs image: $initramfs_path"
- fi
- done
-
- if [ -z "$found" ]; then
- bbfatal "Could not find a valid initramfs type for ${INITRAMFS_IMAGE_NAME}, the supported types are: ${FIT_SUPPORTED_INITRAMFS_FSTYPES}"
- fi
- fi
-
- fitimage_emit_section_maint $1 sectend
-
- # Force the first Kernel and DTB in the default config
- kernelcount=1
- if [ -n "$dtbcount" ]; then
- dtbcount=1
- fi
-
- #
- # Step 6: Prepare a configurations section
- #
- fitimage_emit_section_maint $1 confstart
-
- # kernel-fitimage.bbclass currently only supports a single kernel (no less or
- # more) to be added to the FIT image along with 0 or more device trees and
- # 0 or 1 ramdisk.
- # It is also possible to include an initramfs bundle (kernel and rootfs in one binary)
- # When the initramfs bundle is used ramdisk is disabled.
- # If a device tree is to be part of the FIT image, then select
- # the default configuration to be used is based on the dtbcount. If there is
- # no dtb present than select the default configuation to be based on
- # the kernelcount.
- if [ -n "$DTBS" ]; then
- i=1
- for DTB in ${DTBS}; do
- dtb_ext=${DTB##*.}
- if [ "$dtb_ext" = "dtbo" ]; then
- fitimage_emit_section_config $1 "" "$DTB" "" "$bootscr_id" "" "`expr $i = $dtbcount`" "$default_dtb_image"
- else
- fitimage_emit_section_config $1 $kernelcount "$DTB" "$ramdiskcount" "$bootscr_id" "$setupcount" "`expr $i = $dtbcount`" "$default_dtb_image"
- fi
- i=`expr $i + 1`
- done
- else
- defaultconfigcount=1
- fitimage_emit_section_config $1 $kernelcount "" "$ramdiskcount" "$bootscr_id" "$setupcount" $defaultconfigcount "$default_dtb_image"
- fi
-
- fitimage_emit_section_maint $1 sectend
-
- fitimage_emit_section_maint $1 fitend
-
- #
- # Step 7: Assemble the image
- #
- ${UBOOT_MKIMAGE} \
- ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
- -f $1 \
- ${KERNEL_OUTPUT_DIR}/$2
-
- #
- # Step 8: Sign the image
- #
- if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
- ${UBOOT_MKIMAGE_SIGN} \
- ${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
- -F -k "${UBOOT_SIGN_KEYDIR}" \
- -r ${KERNEL_OUTPUT_DIR}/$2 \
- ${UBOOT_MKIMAGE_SIGN_ARGS}
- fi
}
do_assemble_fitimage() {
@@ -25,7 +25,7 @@
# For more details on signature process, please refer to U-Boot documentation.
# We need some variables from u-boot-config
-inherit uboot-config
+inherit uboot-config kernel-fitimage-its
# Enable use of a U-Boot fitImage
UBOOT_FITIMAGE_ENABLE ?= "0"
@@ -94,10 +94,10 @@ UBOOT_FIT_UBOOT_ENTRYPOINT ?= "${UBOOT_ENTRYPOINT}"
python() {
# We need u-boot-tools-native if we're creating a U-Boot fitImage
sign = d.getVar('UBOOT_SIGN_ENABLE') == '1'
+ if sign:
+ d.setVar('KERNEL_OUTPUT_DIR', d.getVar('B'))
if d.getVar('UBOOT_FITIMAGE_ENABLE') == '1' or sign:
d.appendVar('DEPENDS', " u-boot-tools-native dtc-native")
- if sign:
- d.appendVar('DEPENDS', " " + d.getVar('KERNEL_PN'))
}
concat_dtb() {
@@ -352,7 +352,14 @@ uboot_assemble_fitimage_helper() {
do_uboot_assemble_fitimage() {
if [ "${UBOOT_SIGN_ENABLE}" = "1" ] ; then
- cp "${STAGING_DIR_HOST}/sysroot-only/fitImage" "${B}/fitImage-linux"
+ # Sign dummy kernel in order to add the keys to our dtb, the
+ # actual kernel fitImage is signed in kernel-fitimage.bbclass
+ # using the same key material.
+ mkdir -p arch/${ARCH}/boot/
+ touch arch/${ARCH}/boot/vmlinuz.bin
+ fitimage_assemble_its fit-image.its ""
+ sed -i "/incbin/ s@/incbin/.*@/incbin/(\"${B}/u-boot.dtb\");@" fit-image.its
+ fitimage_assemble_itb fit-image.its fitImage-linux
fi
if [ -n "${UBOOT_CONFIG}" ]; then
In case both UBOOT_SIGN_ENABLE and UBOOT_ENV are enabled and kernel-fitimage.bbclass is in use to generate signed kernel fitImage, there is a circular dependency between uboot-sign and kernel-fitimage bbclasses . The loop looks like this: kernel-fitimage.bbclass: - do_populate_sysroot depends on do_assemble_fitimage - do_assemble_fitimage depends on virtual/bootloader:do_populate_sysroot - virtual/bootloader:do_populate_sysroot depends on virtual/bootloader:do_install => The virtual/bootloader:do_install installs and the virtual/bootloader:do_populate_sysroot places into sysroot an U-Boot environment script embedded into kernel fitImage during do_assemble_fitimage run . uboot-sign.bbclass: - DEPENDS on KERNEL_PN, which is really virtual/kernel. More accurately - do_deploy depends on do_uboot_assemble_fitimage - do_install depends on do_uboot_assemble_fitimage - do_uboot_assemble_fitimage depends on virtual/kernel:do_populate_sysroot => do_install depends on virtual/kernel:do_populate_sysroot => virtual/bootloader:do_install depends on virtual/kernel:do_populate_sysroot virtual/kernel:do_populate_sysroot depends on virtual/bootloader:do_install Attempt to resolve the loop. Pull fitimage_assemble() into separate new bbclass kernel-fitimage-its.bbclass and split fitimage_assemble() into two functions, fitimage_assemble_its() to generate the fit-image.its and fitimage_assemble_itb() to run mkimage on fit-image.its and produce the final fitImage-none fitImage. Inherit kernel-fitimage-its.bbclass in uboot-sign.bbclass and use these two new functions to generate a dummy signed fitImage which, instead of containing any meaningful blobs as payloads contains a dummy u-boot.dtb as payload for every single blob included in the fitImage. The placement of signature {} nodes in this dummy signed fitImage exactly matches the final signed kernel fitImage, which is very important. The follow up mkimage invocation which inserts public key material into u-boot.dtb /signature {} node does not care about the content of the dummy signed fitImage blobs, that mkimage invocation only cares about the placement of signature {} nodes in that dummy signed fitImage. That mkimage invocation uses the placement of these signature {} nodes to construct u-boot.dtb /signature/<key> 'required' property content, which is used by U-Boot when authenticating blobs in the fitImage using the public <key> that was currently inserted into the u-boot.dtb by mkimage . Fixes: 5e12dc911d0c ("u-boot: Rework signing to remove interdependencies") Signed-off-by: Marek Vasut <marex@denx.de> --- Cc: Adrian Freihofer <adrian.freihofer@siemens.com> Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> Cc: Richard Purdie <richard.purdie@linuxfoundation.org> Cc: Sean Anderson <sean.anderson@seco.com> --- V2: Take a different approach, split the kernel-fitimage.bbclass and use it to generate dummy fitImage on demand --- .../kernel-fitimage-its.bbclass | 730 ++++++++++++++++++ meta/classes-recipe/kernel-fitimage.bbclass | 712 +---------------- meta/classes-recipe/uboot-sign.bbclass | 15 +- 3 files changed, 742 insertions(+), 715 deletions(-) create mode 100644 meta/classes-recipe/kernel-fitimage-its.bbclass