From b20be52a4ee5867cd0a21dc9891605e189c48219 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Fri, 26 Jan 2024 14:16:31 +0100 Subject: fitimage: add support to build arbitrary FIT images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FIT image support in OE is quite limited: 1) No support to build an arbitrary number of FIT images since the FIT image generation is tightly coupled to the kernel image. 2) A lot of U_BOOT-specific variables which may not be necessary for other bootloaders. 3) No usage of the meta-oe signing.bbclass for signed FIT images. This alternative class is added to solve the above-mentioned problems: 1) The class can be inherited by an arbitrary number of .bb recipes to generate FIT images 2) No U_BOOT-specific variables are used 3) .bb recipes can prepend the do_fitimage() to provide the key using the signing.bbclass e.g.: do_fitimage:prepend() { signing_prepare signing_use_role "${FITIMAGE_SIGNING_KEY_ROLE}" } Then enable and configure signing as follows: FITIMAGE_SIGN = "1" FITIMAGE_MKIMAGE_EXTRA_ARGS = "--engine pkcs11" FITIMAGE_SIGN_KEYDIR = "${PKCS11_URI} This class is inspired by the meta-phytec fitimage.bbclass [1]. [1] https://git.phytec.de/meta-phytec/tree/classes/fitimage.bbclass Signed-off-by: Marco Felsch Signed-off-by: Enrico Jörns Signed-off-by: Khem Raj --- meta-oe/classes/fitimage.bbclass | 530 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 530 insertions(+) create mode 100644 meta-oe/classes/fitimage.bbclass diff --git a/meta-oe/classes/fitimage.bbclass b/meta-oe/classes/fitimage.bbclass new file mode 100644 index 0000000000..78e30eca33 --- /dev/null +++ b/meta-oe/classes/fitimage.bbclass @@ -0,0 +1,530 @@ +# SPDX-License-Identifier: MIT +# +# Copyright PHYTEC Messtechnik GmbH +# Copyright (C) 2024 Pengutronix, +# +# Class for creating (signed) FIT images +# Description: +# +# You have to define the 'images' to put in the FIT image in your recipe file +# following this example: +# +# FITIMAGE_IMAGES ?= "kernel fdt fdto setup ramdisk bootscript" +# +# FITIMAGE_IMAGE_kernel ?= "virtual/kernel" +# FITIMAGE_IMAGE_kernel[type] ?= "kernel" +# +# FITIMAGE_IMAGE_fdt ?= "virtual/dtb" # or "virtual/kernel" +# FITIMAGE_IMAGE_fdt[type] ?= "fdt" +# #FITIMAGE_IMAGE_fdt[file] ?= "hw-name.dtb" +# +# FITIMAGE_IMAGE_fdto ?= "virtual/kernel" +# FITIMAGE_IMAGE_fdto[type] ?= "fdto" +# FITIMAGE_IMAGE_fdto[file] ?= +# +# Add a devicetree created on-thy-fly of a base dtb and serveral dtbo's +# FITIMAGE_IMAGE_fdtapply ?= "virtual/kernel" +# FITIMAGE_IMAGE_fdtapply[type] ?= "fdtapply" +# FITIMAGE_IMAGE_fdtapply[file] ?= "base.dtb overlay-1.dtbo overlay-2.dtbo" +# FITIMAGE_IMAGE_fdtapply[name] ?= "" +# +# FITIMAGE_IMAGE_ramdisk ?= "core-image-minimal" +# FITIMAGE_IMAGE_ramdisk[type] ?= "ramdisk" +# FITIMAGE_IMAGE_ramdisk[fstype] ?= "cpio.gz" +# +# FITIMAGE_IMAGE_bootscript ?= "bootscript" +# FITIMAGE_IMAGE_bootscript[type] ?= "bootscript" +# FITIMAGE_IMAGE_bootscript[file] ?= "boot.scr" +# +# Valid options for the [type] varflag are: "kernel", "fdt", "fdto", "fdtapply", "ramdisk", "bootscript". +# +# To enable signing, set +# +# FITIMAGE_SIGN = "1" +# +# and configure FITIMAGE_SIGN_KEYDIR (and FITIMAGE_SIGN_KEYNAME) according to +# your needs. +# +# For signing via PKCS#11 URIs provided by the meta-oe signing.bbclass, add: +# +# inherit signing +# +# FITIMAGE_SIGNING_KEY_ROLE = "fit" +# +# do_fitimage:prepend() { +# signing_prepare +# signing_use_role "${FITIMAGE_SIGNING_KEY_ROLE}" +# } +# +# FITIMAGE_SIGN = "1" +# FITIMAGE_MKIMAGE_EXTRA_ARGS = "--engine pkcs11" +# FITIMAGE_SIGN_KEYDIR = "${PKCS11_URI}" + + +LICENSE ?= "MIT" + +inherit deploy kernel-artifact-names image-artifact-names kernel-arch nopackages + +do_patch[noexec] = "1" +do_compile[noexec] = "1" +do_install[noexec] = "1" +deltask do_populate_sysroot + +INHIBIT_DEFAULT_DEPS = "1" + +DEPENDS = "u-boot-mkimage-native dtc-native" + +FITIMAGE_SIGN ?= "0" +FITIMAGE_SIGN[doc] = "Enable FIT image signing" +FITIMAGE_SIGN_KEYDIR ?= "" +FITIMAGE_SIGN_KEYDIR[doc] = "Key directory or pkcs#11 URI to use for signing configuration" +FITIMAGE_MKIMAGE_EXTRA_ARGS[doc] = "Extra arguemnts to pass to uboot-mkimage call" +FITIMAGE_HASH_ALGO ?= "sha256" +FITIMAGE_HASH_ALGO[doc] = "Hash algorithm to use" +FITIMAGE_ENCRYPT_ALGO ?= "rsa2048" +FITIMAGE_ENCRYPT_ALGO[doc] = "Signature algorithm to use" +FITIMAGE_CONFIG_PREFIX ?= "conf-" +FITIMAGE_CONFIG_PREFIX[doc] = "Prefix to use for FIT configuration node name" + +FITIMAGE_LOADADDRESS ??= "" +FITIMAGE_ENTRYPOINT ??= "" +FITIMAGE_DTB_LOADADDRESS ??= "" +FITIMAGE_DTB_OVERLAY_LOADADDRESS ??= "" +FITIMAGE_RD_LOADADDRESS ??= "" +FITIMAGE_RD_ENTRYPOINT ??= "" + +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# Create dependency list from images +python __anonymous() { + for image in (d.getVar('FITIMAGE_IMAGES') or "").split(): + imageflags = d.getVarFlags('FITIMAGE_IMAGE_%s' % image, expand=['type', 'depends']) or {} + imgtype = imageflags.get('type') + if not imgtype: + bb.debug(1, "No [type] given for image '%s', defaulting to 'kernel'" % image) + imgtype = 'kernel' + recipe = d.getVar('FITIMAGE_IMAGE_%s' % image) + + if not recipe: + bb.error("No recipe set for image '%s'. Specify via 'FITIMAGE_IMAGE_%s = \"\"'" % (recipe, image)) + return + + d.appendVarFlag('do_unpack', 'vardeps', ' FITIMAGE_IMAGE_%s' % image) + depends = imageflags.get('depends') + if depends: + d.appendVarFlag('do_unpack', 'depends', ' ' + depends) + continue + + if imgtype == 'ramdisk': + d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_image_complete') + elif 'fdt' in imgtype: + d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_populate_sysroot') + d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_deploy') + else: + d.appendVarFlag('do_unpack', 'depends', ' ' + recipe + ':do_deploy') + + if 'fdt' in imgtype and d.getVar('PREFERRED_PROVIDER_virtual/dtb'): + d.setVar('EXTERNAL_KERNEL_DEVICETREE', '${RECIPE_SYSROOT}/boot/devicetree') +} + +S = "${WORKDIR}/sources" +UNPACKDIR = "${S}" +B = "${WORKDIR}/build" + +# +# Emit the fitImage ITS header +# +def fitimage_emit_fit_header(d, fd): + fd.write('/dts-v1/;\n\n/ {\n') + fd.write(d.expand('\tdescription = "fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";\n')) + fd.write('\t#address-cells = <1>;\n') + +# +# Emit the fitImage ITS footer +# +def fitimage_emit_fit_footer(d, fd): + fd.write('};\n') + +# +# Emit the fitImage section +# +def fitimage_emit_section_start(d, fd, section): + fd.write(f'\t{section} {{\n') + +# +# Emit the fitImage section end +# +def fitimage_emit_section_end(d, fd): + fd.write('\t};\n') + +def fitimage_emit_section_kernel(d, fd, imgpath, imgsource, imgcomp): + kernelcount = 1 + kernel_csum = d.getVar("FITIMAGE_HASH_ALGO") + arch = d.getVar("ARCH") + loadaddr = d.getVar("FITIMAGE_LOADADDRESS") + entryaddr = d.getVar("FITIMAGE_ENTRYPOINT") + + bb.note(f"Adding kernel-{kernelcount} section to ITS file") + + fd.write(f'\t\tkernel-{kernelcount} {{\n') + fd.write('\t\t\tdescription = "Linux kernel";\n') + fd.write(f'\t\t\tdata = /incbin/("{imgpath}/{imgsource}");\n') + fd.write('\t\t\ttype = "kernel";\n') + fd.write(f'\t\t\tarch = "{arch}";\n') + fd.write('\t\t\tos = "linux";\n') + fd.write(f'\t\t\tcompression = "{imgcomp}";\n') + if (loadaddr): + fd.write(f'\t\t\tload = <{loadaddr}>;\n') + if (entryaddr): + fd.write(f'\t\t\tentry = <{entryaddr}>;\n') + fd.write('\t\t\thash-1 {\n') + fd.write(f'\t\t\t\talgo = "{kernel_csum}";\n') + fd.write('\t\t\t};\n') + fd.write('\t\t};\n') + +# +# Emit the fitImage ITS DTB section +# +def _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, desc): + dtb_csum = d.getVar("FITIMAGE_HASH_ALGO") + arch = d.getVar("ARCH") + + bb.note(f"Adding fdt-{dtb_file} section to ITS file") + + fd.write(f'\t\tfdt-{dtb_file} {{\n') + fd.write(f'\t\t\tdescription = "{desc}";\n') + fd.write(f'\t\t\tdata = /incbin/("{dtb_path}/{dtb_file}");\n') + fd.write('\t\t\ttype = "flat_dt";\n') + fd.write(f'\t\t\tarch = "{arch}";\n') + fd.write('\t\t\tcompression = "none";\n') + if loadaddr: + fd.write(f'\t\t\tload = <{loadaddr}>;\n') + fd.write('\t\t\thash-1 {\n') + fd.write(f'\t\t\t\talgo = "{dtb_csum}";\n') + fd.write('\t\t\t};\n') + fd.write('\t\t};\n') + + +def fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path): + loadaddr = d.getVar("FITIMAGE_DTB_LOADADDRESS") + + _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, "Flattened Device Tree blob") + +# +# Emit the fitImage ITS DTB overlay section +# +def fitimage_emit_section_dtb_overlay(d, fd, dtb_file, dtb_path): + loadaddr = d.getVar("FITIMAGE_DTB_OVERLAY_LOADADDRESS") + + _fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path, loadaddr, "Flattened Device Tree Overlay blob") + + +# +# Emit the fitImage ITS ramdisk section +# +def fitimage_emit_section_ramdisk(d, fd, img_file, img_path): + ramdisk_count = "1" + ramdisk_csum = d.getVar("FITIMAGE_HASH_ALGO") + arch = d.getVar("ARCH") + loadaddr = d.getVar("FITIMAGE_RD_LOADADDRESS") + entryaddr = d.getVar("FITIMAGE_RD_ENTRYPOINT") + + bb.note(f"Adding ramdisk-{ramdisk_count} section to ITS file") + + fd.write(f'\t\tramdisk-{ramdisk_count} {{\n') + fd.write(f'\t\t\tdescription = "{img_file}";\n') + fd.write(f'\t\t\tdata = /incbin/("{img_path}/{img_file}");\n') + fd.write('\t\t\ttype = "ramdisk";\n') + fd.write(f'\t\t\tarch = "{arch}";\n') + fd.write('\t\t\tos = "linux";\n') + fd.write('\t\t\tcompression = "none";\n') + if (loadaddr): + fd.write(f'\t\t\tload = <{loadaddr}>;\n') + if (entryaddr): + fd.write(f'\t\t\tentry = <{entryaddr}>;\n') + fd.write('\t\t\thash-1 {\n') + fd.write(f'\t\t\t\talgo = "{ramdisk_csum}";\n') + fd.write('\t\t\t};\n') + fd.write('\t\t};\n') + +def fitimage_emit_section_bootscript(d, fd, imgpath, imgsource): + hash_algo = d.getVar("FITIMAGE_HASH_ALGO") + arch = d.getVar("ARCH") + + bb.note(f"Adding bootscr-{imgsource} section to ITS file") + + fd.write(f'\t\tbootscr-{imgsource} {{\n') + fd.write('\t\t\tdescription = "U-boot script";\n') + fd.write(f'\t\t\tdata = /incbin/("{imgpath}/{imgsource}");\n') + fd.write('\t\t\ttype = "script";\n') + fd.write(f'\t\t\tarch = "{arch}";\n') + fd.write('\t\t\tos = "linux";\n') + fd.write('\t\t\tcompression = "none";\n') + fd.write('\t\t\thash-1 {\n') + fd.write(f'\t\t\t\talgo = "{hash_algo}";\n') + fd.write('\t\t\t};\n') + fd.write('\t\t};\n') + +def fitimage_emit_subsection_signature(d, fd, sign_images_list): + hash_algo = d.getVar("FITIMAGE_HASH_ALGO") + encrypt_algo = d.getVar("FITIMAGE_ENCRYPT_ALGO") or "" + conf_sign_keyname = d.getVar("FITIMAGE_SIGN_KEYNAME") + signer_name = d.getVar("FITIMAGE_SIGNER") + signer_version = d.getVar("FITIMAGE_SIGNER_VERSION") + sign_images = ", ".join(f'"{s}"' for s in sign_images_list) + + fd.write('\t\t\tsignature-1 {\n') + fd.write(f'\t\t\t\talgo = "{hash_algo},{encrypt_algo}";\n') + if conf_sign_keyname: + fd.write(f'\t\t\t\tkey-name-hint = {conf_sign_keyname}";\n') + fd.write(f'\t\t\t\tsign-images = {sign_images};\n') + fd.write(f'\t\t\t\tsigner-name = "{signer_name}";\n') + fd.write(f'\t\t\t\tsigner-version = "{signer_version}";\n') + fd.write('\t\t\t};\n') + +# +# Emit the fitImage ITS configuration section +# +def fitimage_emit_section_config(d, fd, dtb, kernelcount, ramdiskcount, setupcount, bootscriptid, compatible, dtbcount): + sign = d.getVar("FITIMAGE_SIGN") + conf_default = None + conf_prefix = d.getVar('FITIMAGE_CONFIG_PREFIX', True) or "" + + bb.note(f"Adding {dtb} section to ITS file") + + conf_desc="Linux kernel" + if dtb: + conf_desc += ", FDT blob" + if ramdiskcount: + conf_desc += ", ramdisk" + if setupcount: + conf_desc += ", setup" + if bootscriptid: + conf_desc += ", u-boot script" + if dtbcount == 1: + conf_default = d.getVar('FITIMAGE_DEFAULT_CONFIG', True) or dtb + + if conf_default: + fd.write(f'\t\tdefault = "{conf_default}";\n') + fd.write(f'\t\t{conf_prefix}{dtb} {{\n') + fd.write(f'\t\t\tdescription = "{dtbcount} {conf_desc}";\n') + if kernelcount: + fd.write('\t\t\tkernel = "kernel-1";\n') + fd.write(f'\t\t\tfdt = "fdt-{dtb}";\n') + if ramdiskcount: + fd.write(f'\t\t\tramdisk = "ramdisk-{ramdiskcount}";\n') + if bootscriptid: + fd.write(f'\t\t\tbootscr = "bootscr-{bootscriptid}";\n') + if compatible: + fd.write(f'\t\t\tcompatible = "{compatible}";\n') + + if sign == "1": + sign_images = ["kernel"] + if dtb: + sign_images.append("fdt") + if ramdiskcount: + sign_images.append("ramdisk") + if setupcount: + sign_images.append("setup") + if bootscriptid: + sign_images.append("bootscr") + fitimage_emit_subsection_signature(d, fd, sign_images) + + fd.write('\t\t' + '};\n') + +# +# Emits a device tree overlay config section +# +def fitimage_emit_section_config_fdto(d, fd, dtb, compatible): + sign = d.getVar("FITIMAGE_SIGN") + bb.note("Adding overlay config section to ITS file") + + fd.write(f'\t\t{dtb} {{\n') + fd.write(f'\t\t\tdescription = "Device Tree Overlay";\n') + fd.write(f'\t\t\tfdt = "fdt-{dtb}";') + if compatible: + fd.write(f'\t\t\tcompatible = "{compatible}";') + + if sign == "1": + sign_images = ["fdt"] + fitimage_emit_subsection_signature(d, fd, sign_images) + + fd.write('\t\t' + '};\n') + +python write_manifest() { + machine = d.getVar('MACHINE') + kernelcount=1 + DTBS = "" + DTBOS = "" + ramdiskcount = "" + setupcount = "" + bootscriptid = "" + compatible = "" + + def get_dtbs(d, dtb_suffix): + sysroot = d.getVar('RECIPE_SYSROOT') + deploydir = d.getVar('DEPLOY_DIR_IMAGE') + + dtbs = (d.getVar('KERNEL_DEVICETREE') or '').split() + dtbs = [os.path.basename(x) for x in dtbs if x.endswith(dtb_suffix)] + ext_dtbs = os.listdir(d.getVar('EXTERNAL_KERNEL_DEVICETREE')) if d.getVar('EXTERNAL_KERNEL_DEVICETREE') else [] + ext_dtbs = [x for x in ext_dtbs if x.endswith(dtb_suffix)] + + result = [] + # Prefer BSP dts if BSP and kernel provide the same dts + for d in sorted(set(dtbs + ext_dtbs)): + dtbpath = f'{sysroot}/boot/devicetree/{d}' if d in ext_dtbs else f'{deploydir}/{d}' + result.append(dtbpath) + + return " ".join(result) + + with open('%s/manifest.its' % d.getVar('B'), 'w') as fd: + images = d.getVar('FITIMAGE_IMAGES') + if not images: + bb.warn("No images specified in FITIMAGE_IMAGES. Generated FIT image will be empty") + + fitimage_emit_fit_header(d, fd) + fitimage_emit_section_start(d, fd, 'images') + + for image in (images or "").split(): + imageflags = d.getVarFlags('FITIMAGE_IMAGE_%s' % image, expand=['file', 'fstype', 'type', 'comp']) or {} + imgtype = imageflags.get('type', '') + if imgtype == 'kernel': + default = "%s-%s%s" % (d.getVar('KERNEL_IMAGETYPE'), machine, d.getVar('KERNEL_IMAGE_BIN_EXT')) + imgsource = imageflags.get('file', default) + imgcomp = imageflags.get('comp', 'none') + imgpath = d.getVar("DEPLOY_DIR_IMAGE") + fitimage_emit_section_kernel(d, fd, imgpath, imgsource, imgcomp) + elif imgtype == 'fdt': + default = get_dtbs(d, "dtb") + dtbfiles = imageflags.get('file', default) + if not dtbfiles: + bb.fatal(f"No dtb file found for image '{image}'. Set KERNEL_DEVICETREE, [file] varflag, or reference devicetree.bbclass-based recipe.") + for dtb in dtbfiles.split(): + dtb_path, dtb_file = os.path.split(dtb) + DTBS += f" {dtb}" + fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path) + elif imgtype == 'fdto': + default = get_dtbs(d, "dtbo") + dtbofiles = imageflags.get('file', default) + if not dtbofiles: + bb.fatal(f"No dtbo file found for image '{image}'. Set KERNEL_DEVICETREE, [file] varflag, or reference devicetree.bbclass-based recipe.") + for dtb in dtbofiles.split(): + dtb_path, dtb_file = os.path.split(dtb) + DTBOS = DTBOS + " " + dtb + fitimage_emit_section_dtb_overlay(d, fd, dtb_file, dtb_path) + elif imgtype == 'fdtapply': + import subprocess + dtbofiles = imageflags.get('file', None) + if not dtbofiles: + bb.fatal(f"No dtbo file found for image '{image}'. Set via [file] varflag.") + dtboutname = imageflags.get('name', None) + if not dtboutname: + bb.fatal(f"No dtb output name found for image '{image}'. Set via [name] varflag.") + dtbresult = "%s/%s" % (d.getVar('B'), dtboutname) + dtbcommand = "" + for dtb in dtbofiles.split(): + dtb_path, dtb_file = os.path.split(dtb) + if not dtb_path: + dtb_path = d.getVar("DEPLOY_DIR_IMAGE") + if not dtbcommand: + if not dtb_file.endswith('.dtb'): + bb.fatal(f"fdtapply failed: Expected (non-overlay) .dtb file as first element, but got {dtb_file}") + dtbcommand = f"fdtoverlay -i {dtb_path}/{dtb_file} -o {dtbresult}" + else: + if not dtb_file.endswith('.dtbo'): + bb.fatal(f"fdtapply failed: Expected .dtbo file, but got {dtb_file}") + dtbcommand += f" {dtb_path}/{dtb_file}" + result = subprocess.run(dtbcommand, stderr=subprocess.PIPE, shell=True, text=True) + if result.returncode != 0: + bb.fatal(f"Running {dtbcommand} failed: {result.stderr}") + dtb_path, dtb_file = os.path.split(dtbresult) + DTBS += f" {dtbresult}" + fitimage_emit_section_dtb(d, fd, dtb_file, dtb_path) + elif imgtype == 'ramdisk': + ramdiskcount = "1" + default_imgfstype = d.getVar('INITRAMFS_FSTYPES' or "").split()[0] + img_fstype = imageflags.get('fstype', default_imgfstype) + img_file = "%s%s.%s" % (d.getVar('FITIMAGE_IMAGE_%s' % image), d.getVar('IMAGE_MACHINE_SUFFIX'), img_fstype) + img_path = d.getVar("DEPLOY_DIR_IMAGE") + fitimage_emit_section_ramdisk(d, fd, img_file, img_path) + elif imgtype == 'bootscript': + if bootscriptid: + bb.fatal("Only a single boot script is supported (already set to: %s)" % bootscriptid) + imgsource = imageflags.get('file', None) + imgpath = d.getVar("DEPLOY_DIR_IMAGE") + bootscriptid = imgsource + fitimage_emit_section_bootscript(d, fd, imgpath, imgsource) + fitimage_emit_section_end(d, fd) + # + # Step 5: Prepare a configurations section + # + fitimage_emit_section_start(d, fd, 'configurations') + dtbcount = 1 + for dtb in (DTBS or "").split(): + import subprocess + try: + cmd = "fdtget -t s {} / compatible".format(dtb) + compatible = subprocess.check_output(cmd, shell=True, text=True).split()[0] + except subprocess.CalledProcessError: + bb.fatal("Failed to find root-node compatible string in (%s)" % dtb) + + dtb_path, dtb_file = os.path.split(dtb) + fitimage_emit_section_config(d, fd, dtb_file, kernelcount, ramdiskcount, setupcount, bootscriptid, compatible, dtbcount) + dtbcount += 1 + for dtb in (DTBOS or "").split(): + import subprocess + try: + cmd = "fdtget -t s {} / compatible".format(dtb) + compatible = subprocess.check_output(cmd, shell=True, text=True).split()[0] + except subprocess.CalledProcessError: + bb.note("Failed to find root-node compatible string in (%s)" % dtb) + compatible = None + + dtb_path, dtb_file = os.path.split(dtb) + fitimage_emit_section_config_fdto(d, fd, dtb_file, compatible) + + fitimage_emit_section_end(d, fd) + fitimage_emit_fit_footer(d, fd) +} + +do_configure[postfuncs] += "write_manifest" + +do_fitimage () { + if [ "${FITIMAGE_SIGN}" = "1" ]; then + uboot-mkimage ${FITIMAGE_MKIMAGE_EXTRA_ARGS} \ + -k ${FITIMAGE_SIGN_KEYDIR} -r \ + -f "${B}/manifest.its" \ + "${B}/fitImage" + else + uboot-mkimage ${FITIMAGE_MKIMAGE_EXTRA_ARGS} \ + -f "${B}/manifest.its" \ + "${B}/fitImage" + fi +} +addtask fitimage after do_configure + +ITS_NAME ?= "${PN}-${KERNEL_ARTIFACT_NAME}" +ITS_LINK_NAME ?= "${PN}-${KERNEL_ARTIFACT_LINK_NAME}" +FITIMAGE_IMAGE_NAME ?= "fitImage-${PN}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}" +FITIMAGE_IMAGE_LINK_NAME ?= "fitImage-${PN}-${KERNEL_FIT_LINK_NAME}" + +SSTATE_SKIP_CREATION:task-deploy = '1' + +do_deploy() { + bbnote 'Copying fit-image.its source file...' + install -m 0644 ${B}/manifest.its ${DEPLOYDIR}/${ITS_NAME}.its + + bbnote 'Copying all created fdt from type fdtapply' + for DTB_FILE in `find ${B} -maxdepth 1 -name *.dtb`; do + install -m 0644 ${DTB_FILE} ${DEPLOYDIR}/ + done + + bbnote 'Copying fitImage file...' + install -m 0644 ${B}/fitImage ${DEPLOYDIR}/${FITIMAGE_IMAGE_NAME} + + cd ${DEPLOYDIR} + ln -sf ${ITS_NAME}.its ${ITS_LINK_NAME}.its + ln -sf ${FITIMAGE_IMAGE_NAME} ${FITIMAGE_IMAGE_LINK_NAME} +} +addtask deploy after do_fitimage before do_build -- cgit v1.2.3-54-g00ecf