mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2025-12-14 14:25:53 +01:00
fitimage: add support to build arbitrary FIT images
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
<fit-image-name>.bb recipes to generate FIT images
2) No U_BOOT-specific variables are used
3) <fit-image-name>.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 <m.felsch@pengutronix.de>
Signed-off-by: Enrico Jörns <ejo@pengutronix.de>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
This commit is contained in:
parent
a090cd3e0e
commit
b20be52a4e
530
meta-oe/classes/fitimage.bbclass
Normal file
530
meta-oe/classes/fitimage.bbclass
Normal file
|
|
@ -0,0 +1,530 @@
|
|||
# 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', 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
|
||||
Loading…
Reference in New Issue
Block a user