| |
| inherit kernel-arch kernel-artifact-names uboot-config deploy |
| require conf/image-fitimage.conf |
| |
| S = "${UNPACKDIR}" |
| |
| PACKAGE_ARCH = "${MACHINE_ARCH}" |
| |
| # This bbclass requires KERNEL_CLASSES += "kernel-fit-extra-artifacts" |
| EXCLUDE_FROM_WORLD = "1" |
| |
| DEPENDS += "\ |
| u-boot-tools-native dtc-native \ |
| ${@'kernel-signing-keys-native' if d.getVar('FIT_GENERATE_KEYS') == '1' else ''} \ |
| " |
| |
| python () { |
| image = d.getVar('INITRAMFS_IMAGE') |
| if image and d.getVar('INITRAMFS_IMAGE_BUNDLE') != '1': |
| if d.getVar('INITRAMFS_MULTICONFIG'): |
| mc = d.getVar('BB_CURRENT_MC') |
| d.appendVarFlag('do_compile', 'mcdepends', ' mc:' + mc + ':${INITRAMFS_MULTICONFIG}:${INITRAMFS_IMAGE}:do_image_complete') |
| else: |
| d.appendVarFlag('do_compile', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete') |
| |
| #check if there are any dtb providers |
| providerdtb = d.getVar("PREFERRED_PROVIDER_virtual/dtb") |
| if providerdtb: |
| d.appendVarFlag('do_compile', 'depends', ' virtual/dtb:do_populate_sysroot') |
| d.setVar('EXTERNAL_KERNEL_DEVICETREE', "${RECIPE_SYSROOT}/boot/devicetree") |
| |
| # Parse loadables config |
| loadables = d.getVar('FIT_LOADABLES') |
| if loadables: |
| # Check that the loadables configuration variables are not set directly |
| # directly, then assign them a synthetic value for testability purposes |
| for v in ['FIT_LOADABLE_ARCH', 'FIT_LOADABLE_COMPRESSION', |
| 'FIT_LOADABLE_DESCRIPTION', 'FIT_LOADABLE_ENTRYPOINT', |
| 'FIT_LOADABLE_FILENAME', 'FIT_LOADABLE_LOADADDRESS', |
| 'FIT_LOADABLE_OS', 'FIT_LOADABLE_TYPE']: |
| if d.getVar(v): |
| raise bb.parse.SkipRecipe("You cannot use %s as a variable, you can only set flags." % v) |
| |
| synt_value = " ? ".join([ d.getVarFlag(v, loadable) or "" for loadable in loadables.split() ]) |
| d.setVar(v, synt_value) |
| } |
| |
| do_configure[noexec] = "1" |
| |
| INITRAMFS_DEPLOY_DIR_IMAGE ?= "${DEPLOY_DIR_IMAGE}" |
| UBOOT_MKIMAGE_KERNEL_TYPE ?= "kernel" |
| KERNEL_IMAGEDEST ?= "/boot" |
| |
| FIT_KERNEL_SIGN_ENABLE ?= "${UBOOT_SIGN_ENABLE}" |
| FIT_KERNEL_SIGN_KEYNAME ?= "${UBOOT_SIGN_KEYNAME}" |
| FIT_KERNEL_SIGN_KEYDIR ?= "${UBOOT_SIGN_KEYDIR}" |
| |
| def apply_dtbvendored(d,dtb): |
| if d.getVar('KERNEL_DTBVENDORED') != "1": |
| mapped_name = os.path.basename(dtb) |
| else: |
| mapped_name = dtb.replace('/', '_') |
| return mapped_name |
| |
| python do_compile() { |
| import shutil |
| import oe.fitimage |
| |
| itsfile = "fit-image.its" |
| fitname = "fitImage" |
| kernel_deploydir = d.getVar('DEPLOY_DIR_IMAGE') |
| kernel_deploysubdir = d.getVar('KERNEL_DEPLOYSUBDIR') |
| if kernel_deploysubdir: |
| kernel_deploydir = os.path.join(kernel_deploydir, kernel_deploysubdir) |
| |
| # Collect all the its nodes before the its file is generated and mkimage gets executed |
| root_node = oe.fitimage.ItsNodeRootKernel( |
| d.getVar("FIT_DESC"), d.getVar("FIT_ADDRESS_CELLS"), |
| d.getVar('HOST_PREFIX'), d.getVar('UBOOT_ARCH'), d.getVar("FIT_CONF_PREFIX"), |
| oe.types.boolean(d.getVar('FIT_KERNEL_SIGN_ENABLE')), d.getVar("FIT_KERNEL_SIGN_KEYDIR"), |
| d.getVar("UBOOT_MKIMAGE"), d.getVar("UBOOT_MKIMAGE_DTCOPTS"), |
| d.getVar('FIT_MKIMAGE_EXTRA_OPTS'), |
| d.getVar("UBOOT_MKIMAGE_SIGN"), d.getVar("UBOOT_MKIMAGE_SIGN_ARGS"), |
| d.getVar('FIT_HASH_ALG'), d.getVar('FIT_SIGN_ALG'), d.getVar('FIT_PAD_ALG'), |
| d.getVar('FIT_KERNEL_SIGN_KEYNAME'), |
| oe.types.boolean(d.getVar('FIT_SIGN_INDIVIDUAL')), d.getVar('UBOOT_SIGN_IMG_KEYNAME') |
| ) |
| |
| # Prepare a kernel image section. |
| shutil.copyfile(os.path.join(kernel_deploydir, "linux.bin"), "linux.bin") |
| with open(os.path.join(kernel_deploydir, "linux_comp")) as linux_comp_f: |
| linux_comp = linux_comp_f.read() |
| root_node.fitimage_emit_section_kernel("kernel-1", "linux.bin", linux_comp, |
| d.getVar('UBOOT_LOADADDRESS'), d.getVar('UBOOT_ENTRYPOINT'), |
| d.getVar('UBOOT_MKIMAGE_KERNEL_TYPE'), d.getVar("UBOOT_ENTRYSYMBOL")) |
| |
| # Prepare a DTB image section |
| kernel_devicetree = d.getVar('KERNEL_DEVICETREE') |
| external_kernel_devicetree = d.getVar("EXTERNAL_KERNEL_DEVICETREE") |
| if kernel_devicetree: |
| for dtb in kernel_devicetree.split(): |
| # In deploy_dir the DTBs are without sub-directories also with KERNEL_DTBVENDORED = "1" |
| dtb_name = os.path.basename(dtb) |
| # With vendored DTs, use the DT name as listed in KERNEL_DEVICETREE |
| # and replace any path separators with underscores, this behaves the |
| # same way as KERNEL_DTBVENDORED = "1" did in OE 5.0 and older. |
| conf_name = apply_dtbvendored(d, dtb) |
| |
| # Skip DTB if it's also provided in EXTERNAL_KERNEL_DEVICETREE directory |
| if external_kernel_devicetree: |
| ext_dtb_path = os.path.join(external_kernel_devicetree, dtb_name) |
| if os.path.exists(ext_dtb_path) and os.path.getsize(ext_dtb_path) > 0: |
| continue |
| |
| # Copy the dtb or dtbo file into the FIT image assembly directory |
| shutil.copyfile(os.path.join(kernel_deploydir, dtb_name), dtb_name) |
| root_node.fitimage_emit_section_dtb(conf_name, dtb_name, |
| d.getVar("UBOOT_DTB_LOADADDRESS"), d.getVar("UBOOT_DTBO_LOADADDRESS")) |
| |
| if external_kernel_devicetree: |
| # iterate over all .dtb and .dtbo files in the external kernel devicetree directory |
| # and copy them to the FIT image assembly directory |
| for dtb_name in sorted(os.listdir(external_kernel_devicetree)): |
| if dtb_name.endswith('.dtb') or dtb_name.endswith('.dtbo'): |
| dtb_path = os.path.join(external_kernel_devicetree, dtb_name) |
| |
| # For symlinks, add a configuration node that refers to the DTB image node to which the symlink points |
| symlink_target = oe.fitimage.symlink_points_below(dtb_name, external_kernel_devicetree) |
| if symlink_target: |
| root_node.fitimage_emit_section_dtb_alias(dtb_name, symlink_target, True) |
| # For real DTB files add an image node and a configuration node |
| else: |
| shutil.copyfile(dtb_path, dtb_name) |
| root_node.fitimage_emit_section_dtb(dtb_name, dtb_name, |
| d.getVar("UBOOT_DTB_LOADADDRESS"), d.getVar("UBOOT_DTBO_LOADADDRESS"), True) |
| |
| # Prepare a u-boot script section |
| fit_uboot_env = d.getVar("FIT_UBOOT_ENV") |
| if fit_uboot_env: |
| root_node.fitimage_emit_section_boot_script("bootscr-"+fit_uboot_env , fit_uboot_env) |
| |
| # Prepare a setup section (For x86) |
| setup_bin_path = os.path.join(kernel_deploydir, "setup.bin") |
| if os.path.exists(setup_bin_path): |
| shutil.copyfile(setup_bin_path, "setup.bin") |
| root_node.fitimage_emit_section_setup("setup-1", "setup.bin") |
| |
| # Prepare a ramdisk section. |
| initramfs_image = d.getVar('INITRAMFS_IMAGE') |
| if initramfs_image and d.getVar("INITRAMFS_IMAGE_BUNDLE") != '1': |
| # Find and use the first initramfs image archive type we find |
| found = False |
| for img in d.getVar("FIT_SUPPORTED_INITRAMFS_FSTYPES").split(): |
| initramfs_path = os.path.join(d.getVar("INITRAMFS_DEPLOY_DIR_IMAGE"), "%s.%s" % (d.getVar('INITRAMFS_IMAGE_NAME'), img)) |
| if os.path.exists(initramfs_path): |
| bb.note("Found initramfs image: " + initramfs_path) |
| found = True |
| root_node.fitimage_emit_section_ramdisk("ramdisk-1", initramfs_path, |
| initramfs_image, |
| d.getVar("UBOOT_RD_LOADADDRESS"), |
| d.getVar("UBOOT_RD_ENTRYPOINT")) |
| break |
| else: |
| bb.note("Did not find initramfs image: " + initramfs_path) |
| |
| if not found: |
| bb.fatal("Could not find a valid initramfs type for %s, the supported types are: %s" % (d.getVar('INITRAMFS_IMAGE_NAME'), d.getVar('FIT_SUPPORTED_INITRAMFS_FSTYPES'))) |
| |
| # |
| # Prepare loadables sections |
| # |
| for loadable in d.getVar('FIT_LOADABLES').split(): |
| loadable_file = d.getVarFlag('FIT_LOADABLE_FILENAME', loadable) |
| if not loadable_file: |
| bb.fatal("File for loadable %s not specified through FIT_LOADABLE_FILENAME[%s]" % (loadable, loadable)) |
| |
| loadable_loadaddress = d.getVarFlag('FIT_LOADABLE_LOADADDRESS', loadable) |
| if not loadable_loadaddress: |
| bb.fatal("Load address for loadable %s not specified through FIT_LOADABLE_LOADADDRESS[%s]" % (loadable, loadable)) |
| |
| # Optional parameters |
| loadable_arch = d.getVarFlag('FIT_LOADABLE_ARCH', loadable) |
| loadable_compression = d.getVarFlag('FIT_LOADABLE_COMPRESSION', loadable) |
| loadable_description = d.getVarFlag('FIT_LOADABLE_DESCRIPTION', loadable) or ("%s loadable" % loadable) |
| loadable_entrypoint = d.getVarFlag('FIT_LOADABLE_ENTRYPOINT', loadable) |
| loadable_os = d.getVarFlag('FIT_LOADABLE_OS', loadable) |
| loadable_type = d.getVarFlag('FIT_LOADABLE_TYPE', loadable) |
| |
| # Check if loadable artifact exists |
| loadable_path = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), loadable_file) |
| if not os.path.exists(loadable_path): |
| bb.fatal("File for loadable %s not found at %s" % (loadable, loadable_path)) |
| |
| root_node.fitimage_emit_section_loadable(loadable, |
| loadable_path, loadable_type, |
| loadable_description, |
| loadable_compression, |
| loadable_arch, loadable_os, |
| loadable_loadaddress, |
| loadable_entrypoint) |
| |
| # Figure out if we have a default dtb and if we need to honor the |
| # KERNEL_DTBVENDORED variable to tweak the name to match what will be |
| # in the fitImage. |
| default_dtb = d.getVar("FIT_CONF_DEFAULT_DTB") |
| if default_dtb: |
| default_dtb = apply_dtbvendored(d, default_dtb) |
| |
| # Generate the configuration section |
| root_node.fitimage_emit_section_config(default_dtb, d.getVar("FIT_CONF_MAPPINGS")) |
| |
| # Write the its file |
| root_node.write_its_file(itsfile) |
| |
| # Assemble the FIT image |
| root_node.run_mkimage_assemble(itsfile, fitname) |
| |
| # Sign the FIT image if required |
| root_node.run_mkimage_sign(fitname) |
| } |
| do_compile[depends] += "virtual/kernel:do_deploy" |
| |
| do_install() { |
| install -d "${D}/${KERNEL_IMAGEDEST}" |
| install -m 0644 "${B}/fitImage" "${D}/${KERNEL_IMAGEDEST}/fitImage" |
| } |
| |
| FILES:${PN} = "${KERNEL_IMAGEDEST}" |
| |
| |
| do_deploy() { |
| deploy_dir="${DEPLOYDIR}" |
| if [ -n "${KERNEL_DEPLOYSUBDIR}" ]; then |
| deploy_dir="${DEPLOYDIR}/${KERNEL_DEPLOYSUBDIR}" |
| fi |
| install -d "$deploy_dir" |
| install -m 0644 "${B}/fitImage" "$deploy_dir/fitImage" |
| install -m 0644 "${B}/fit-image.its" "$deploy_dir/fit-image.its" |
| |
| if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then |
| ln -snf fit-image.its "$deploy_dir/fitImage-its-${KERNEL_FIT_NAME}.its" |
| if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then |
| ln -snf fit-image.its "$deploy_dir/fitImage-its-${KERNEL_FIT_LINK_NAME}" |
| fi |
| fi |
| |
| if [ -n "${INITRAMFS_IMAGE}" ]; then |
| ln -snf fit-image.its "$deploy_dir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its" |
| if [ -n "${KERNEL_FIT_LINK_NAME}" ]; then |
| ln -snf fit-image.its "$deploy_dir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}" |
| fi |
| |
| if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then |
| ln -snf fitImage "$deploy_dir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}${KERNEL_FIT_BIN_EXT}" |
| if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then |
| ln -snf fitImage "$deploy_dir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}" |
| fi |
| fi |
| fi |
| } |
| addtask deploy after do_compile before do_build |