| # SPDX-License-Identifier: MIT |
| # |
| # Copyright PHYTEC Messtechnik GmbH |
| # Copyright (C) 2024 Pengutronix, <yocto@pengutronix.de> |
| # |
| # 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] ?= <list of all dtbo files from KERNEL_DEVICETREE> |
| # |
| # 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] ?= "<name for new generated fdt>" |
| # |
| # 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-name>\"'" % (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') 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') or f'{conf_prefix}{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 |