its-maker.sh creates an .its file, given a series of arguments, which is then used to create a FIT image with mkimage.
Required to support the tew827dru, but intended to support the creation of nearly any .its file. Documentation thread on the OpenWRT forum: https://forum.openwrt.org/viewtopic.php?pid=337783 Signed-off-by: Jesse Molina <jm...@jmomo.net> --- scripts/its-maker.sh | 827 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 827 insertions(+) create mode 100755 scripts/its-maker.sh diff --git a/scripts/its-maker.sh b/scripts/its-maker.sh new file mode 100755 index 0000000..2c036a1 --- /dev/null +++ b/scripts/its-maker.sh @@ -0,0 +1,827 @@ +#!/bin/bash +# +# Create a u-boot FIT ITS (Image Tree Source) file given a convoluted series of arguments. +# +# Combination use of leading tabs and spaces is intentional for here-doc (<<-) and should be preserved. +# +# TODO/FIXMEs: +# Enforcement of mandatory/optional formatting rules. +# Clean up trap on interrupt. +# Sanitizing and sanity checking input. +# "#address-cells : Number of 32bit cells required to represent entry and +# load addresses supplied within sub-image nodes. May be omitted when no +# entry or load addresses are used." +# We should auto-calculate the address-cells and include as/if needed. +# "At least one sub-image is required." +# + +VERSION=1.2 +MYNAME=$(basename $0) +declare -a ar_IMG_IDS +declare -a ar_IMG_NAME +declare -a ar_IMG_DESCR +declare -a ar_IMG_FILE +declare -a ar_IMG_TYPE +declare -a ar_IMG_ARCH +declare -a ar_IMG_OS +declare -a ar_IMG_COMPRESSION +declare -a ar_IMG_LOAD_ADDR +declare -a ar_IMG_ENTRY_ADDR +declare -a ar_IMG_HASHES +declare -a ar_CFG_IDS +declare -a ar_CFG_NAME +declare -a ar_CFG_DESCR +declare -a ar_CFG_KERNEL +declare -a ar_CFG_RAMDISK +declare -a ar_CFG_FDT + +# case +([0-9]) regex requires shopt -s extglob. +shopt -s extglob + +echoerr() { + # Print errors to stderr. + echo "$@" 1>&2; + if [[ -n "$SEEN_ERROR" ]] ; then declare -r SEEN_ERROR=1 ; fi # If we saw any errors, set SEEN_ERROR=1, for later use. +} + +echodebug() { + # Print debug messages to stderr if debugging enabled. + if [[ "$SCRIPT_DEBUG" == 1 ]] ; then + echo "DEBUG: $@" 1>&2; + fi +} + +f_printusage() { + # Print usage info. + cat <<-EOF + Usage: + + help|--help|-h|-H Show help info. + --debug Debug the $MYNAME script. + + --out|-O Output file, otherwise output goes to stdout. + --fit-type|-T The FIT format type. Defaults to "flat_dt". + --fit-description|-D The FIT Description line. + --device|-i Device for which we are building this ITS. + + Image Commands: (all image commands must be followed by an integer ID.) + + --img-name|-n The name of the image. + --img-descr|-d The description of the image. + --img-file|-f The image data file. + --img-type|-t The type/format of the image. + --img-arch|-a The arch of the image. + --img-os|-o The OS of the image. + --img-compression|-c The compression of the image. + --img-load-addr|-l The load address for the image. + --img-entry-addr|-e The entry address for the image. + --img-hashes|-s The image hash(es), comma-seperated. + + Configuration Commands: (all configuration commands must be followed by an integer ID, except the default.) + + --cfg-default|-C The ID of the default configuration. + --cfg-name|-m The name of the configuration. + --cfg-descr|-p The description of the configuration. + --cfg-kernel|-k The kernel image ID to use for the configuration. + --cfg-ramdisk|-r The ramdisk image ID to use for the configuration. + --cfg-fdt|-x The FDT image ID to use for the configuration. + + Example: + + $MYNAME --device Widget5K --fit-type flat_dt --fit-description "Widget 5000 Extreme Edition Plus" --img-name 0 "upgrade-script" --img-descr 0 "Script to upgrade the firmware." --img-file 0 ~/tmp/myfile.scr --img-type 0 script --img-compression 0 none --img-name 1 "OS" --img-descr 1 "Widget 5000 Xe+ Operating System" --img-file 1 ~/tmp/myfile.bin --img-type 1 firmware --img-compression 1 none --img-arch 1 ARM --img-hashes 1 crc32,sha1 + + EOF +} + +f_help () { + # Print some helpful information. + cat <<- EOF + + $MYNAME constructs a u-boot FIT DTS file for use with mkimage. + + $MYNAME version: $VERSION + EOF + f_printusage + return 0 +} + +f_register_img_id () { + # Register the IMG_ID in our ar_IMG_IDS array if needed. + if ! [[ "${ar_IMG_IDS[$1]}" ]] ; then + ar_IMG_IDS[$IMG_ID]=$IMG_ID + echodebug "IMG_ID $IMG_ID added to ar_IMG_IDS" + fi +} + +f_register_cfg_id () { + # Register the CFG_ID in our ar_CFG_IDS array if needed. + # if ! [[ "${ar_CFG_IDS[$1]}" ]] ; then + if ! [[ "${ar_CFG_IDS[$1]}" ]] ; then + ar_CFG_IDS[$CFG_ID]=$CFG_ID + echodebug "CFG_ID $CFG_ID added to ar_CFG_IDS" + fi +} + +f_assemble_dts_header () { + cat <<-EOF >> $DTS_BODY + /dts-v1/; + / { + description = "${HEADER_DESCR}"; + #address-cells = <1>; + EOF +} + +f_assemble_img_header () { + cat <<-EOF >> $DTS_BODY + images { + EOF +} + +f_assemble_img_body_header () { + cat <<-EOF >> $DTS_BODY + ${ar_IMG_NAME[$IMG_ID]}@${IMG_ID} { + data = /incbin/("${ar_IMG_FILE[$IMG_ID]}"); + description = "${ar_IMG_DESCR[$IMG_ID]}"; + type = "${ar_IMG_TYPE[$IMG_ID]}"; + compression = "${ar_IMG_COMPRESSION[$IMG_ID]}"; + EOF +} + +f_assemble_img_body_arch () { + cat <<-EOF >> $DTS_BODY + arch = "${ar_IMG_ARCH[$IMG_ID]}"; + EOF +} + +f_assemble_img_body_os () { + cat <<-EOF >> $DTS_BODY + os = "${ar_IMG_OS[$IMG_ID]}"; + EOF +} + +f_assemble_img_body_load-entry () { + cat <<-EOF >> $DTS_BODY + load = <${ar_IMG_LOAD_ADDR[$IMG_ID]}>; + entry = <${ar_IMG_ENTRY_ADDR[$IMG_ID]}>; + EOF +} + +f_assemble_img_body_hash () { + cat <<-EOF >> $DTS_BODY + hash@${HASH_NUM} { + algo = "${HASH_NAME}"; + }; + EOF +} + +f_assemble_img_body_footer () { + cat <<-EOF >> $DTS_BODY + }; + EOF +} + +f_assemble_img_footer () { + cat <<-EOF >> $DTS_BODY + }; + EOF +} + +f_assemble_cfg_header () { + cat <<-EOF >> $DTS_BODY + configurations { + EOF +} + +f_assemble_cfg_header_default () { + cat <<-EOF >> $DTS_BODY + default = "${ar_CFG_NAME[$CFG_DEFAULT]}@${CFG_DEFAULT}"; + EOF +} + +f_assemble_cfg_body_header () { + cat <<-EOF >> $DTS_BODY + ${ar_CFG_NAME[$CFG_ID]}@${CFG_ID} { + description = "${ar_CFG_DESCR[$CFG_ID]}"; + kernel = "${ar_CFG_KERNEL[$CFG_ID]}"; + EOF +} + +f_assemble_cfg_body_ramdisk () { + cat <<-EOF >> $DTS_BODY + ramdisk = "${ar_CFG_RAMDISK[$CFG_ID]}"; + EOF +} + +f_assemble_cfg_body_FDT () { + cat <<-EOF >> $DTS_BODY + fdt = "${ar_CFG_FDT[$CFG_ID]}"; + EOF +} + +f_assemble_cfg_body_footer () { + cat <<-EOF >> $DTS_BODY + }; + EOF +} + +f_assemble_cfg_footer () { + cat <<-EOF >> $DTS_BODY + }; + EOF +} + +f_assemble_dts_footer () { + cat <<-EOF >> $DTS_BODY + }; + EOF +} + +f_validate_in_args3 () { + # Validate $3 input argument. + if [[ -z "$ARG3" ]] ; then + echoerr -e "\nERROR: $ARG1 $IMG_ID argument missing.\n" + exit 1 + fi + if ( echo "$ARG3" | egrep "^--" &> /dev/null ) ; then + # Look out for accidental missing values. However, this does incorrectly prohibit unusual valid data. + echoerr -e "\nERROR: Suspected missing value for $ARG1 $IMG_ID.\n" + exit 1 + fi +} + +# -- + +# No input? Print usage and exit 1. +[[ "$#" -eq 0 ]] && { f_printusage ; exit 1 ; } + +while [[ "$#" -gt 0 ]] ; do case "$1" in + --debug) + SCRIPT_DEBUG=1 + # set -o functrace + # set -x + shift 1 + ;; + help|--help|-h|-H) + f_help + exit $? + ;; + --out|-O) + OUT_FILE=$2 + echodebug "Outfile set to $2" + shift 2 + ;; + --device|-i) + DEVICE=$2 + echodebug "Device set to $2" + shift 2 + ;; + --fit-type|-T) + if [[ -z "$FIT_TYPE" ]] ; then + FIT_TYPE=$2 + echodebug "FIT type set to $2" + shift 2 + else + echoerr -e "\nERROR: --fit-fype was set more than once.\n" + exit 1 + fi + ;; + --fit-description|-D) + if [[ -z "$HEADER_DESCR" ]] ; then + HEADER_DESCR=$2 + echodebug "FIT description set to \"$2\"" + shift 2 + else + echoerr -e "\nERROR: --fit-description was set more than once.\n" + exit 1 + fi + ;; + --img-name|-n) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_NAME[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_NAME[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-name $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-name ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-descr|-d) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_DESCR[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_DESCR[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-descr $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-descr ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-file|-f) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_FILE[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_FILE[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-file $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-file ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-type|-t) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_TYPE[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_TYPE[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-type $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-type ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-arch|-a) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_ARCH[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_ARCH[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-arch $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-arch ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-os|-o) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_OS[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_OS[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-os $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-os ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-compression|-c) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_COMPRESSION[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_COMPRESSION[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-compression $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-compression ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-load-addr|-l) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_LOAD_ADDR[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_LOAD_ADDR[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-load-addr $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-load-addr ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-entry-addr|-e) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_ENTRY_ADDR[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_ENTRY_ADDR[$IMG_ID]=$3 + echodebug "$1 $IMG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --img-entry-addr $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-entry-addr ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --img-hashes|-s) + case "$2" in + +([0-9])) + IMG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_IMG_HASHES[$IMG_ID]}" ]] ; then + f_register_img_id $IMG_ID + ar_IMG_HASHES[$IMG_ID]=$3 + echodebug "$1 ${IMG_ID} set to \"$3\"" + else + echoerr -e "\nERROR: --img-hashes $IMG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset IMG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --img-hashes ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --cfg-default|-C) + if [[ -z "$CFG_DEFAULT" ]] ; then + CFG_DEFAULT=$2 + echodebug "FIT configuration default set to \"$2\"" + shift 2 + else + echoerr -e "\nERROR: --cfg-default was set more than once.\n" + exit 1 + fi + ;; + --cfg-name|-m) + case "$2" in + +([0-9])) + CFG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_CFG_NAME[$CFG_ID]}" ]] ; then + f_register_cfg_id $CFG_ID + ar_CFG_NAME[$CFG_ID]=$3 + echodebug "$1 $CFG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --cfg-name $CFG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset CFG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --cfg-name ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --cfg-descr|-p) + case "$2" in + +([0-9])) + CFG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_CFG_DESCR[$CFG_ID]}" ]] ; then + f_register_cfg_id $CFG_ID + ar_CFG_DESCR[$CFG_ID]=$3 + echodebug "$1 $CFG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --cfg-descr $CFG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset CFG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --cfg-descr ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --cfg-kernel|-k) + case "$2" in + +([0-9])) + CFG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_CFG_KERNEL[$CFG_ID]}" ]] ; then + f_register_cfg_id $CFG_ID + ar_CFG_KERNEL[$CFG_ID]=$3 + echodebug "$1 $CFG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --cfg-kernel $CFG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset CFG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --cfg-kernel ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --cfg-ramdisk|-r) + case "$2" in + +([0-9])) + CFG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_CFG_RAMDISK[$CFG_ID]}" ]] ; then + f_register_cfg_id $CFG_ID + ar_CFG_RAMDISK[$CFG_ID]=$3 + echodebug "$1 $CFG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --cfg-ramdisk $CFG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset CFG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --cfg-ramdisk ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + --cfg-fdt|-x) + case "$2" in + +([0-9])) + CFG_ID=$2 ARG1=$1 ARG2=$2 ARG3=$3 + f_validate_in_args3 + if [[ -z "${ar_CFG_FDT[$CFG_ID]}" ]] ; then + f_register_cfg_id $CFG_ID + ar_CFG_FDT[$CFG_ID]=$3 + echodebug "$1 $CFG_ID set to \"$3\"" + else + echoerr -e "\nERROR: --cfg-fdt $CFG_ID was set more than once.\n" + exit 1 + fi + shift 3 ; unset CFG_ID ARG1 ARG2 ARG3 + ;; + *) + echoerr -e "\nERROR: Invalid --cfg-fdt ID. Must be an integer.\n" + exit 1 + ;; + esac + ;; + *) + echoerr -e "\nERROR: Invalid argument \"$1\".\n" + f_printusage + exit 1 + ;; +esac ; done + +# Build the ITS. +# +# NOTE: The ITS format and it's rules are complicated and we don't guarantee the production of a valid file. +# We will do some basic validity checking, but producing an invalid ITS is a valid scenario. +# It is mkimage's job to determine if the content of a ITS is valid or not. + +DTS_BODY=$(mktemp) + +# Assemble the header. +# + +# If we didn't get a FIT/header description, make one up by default. +if [[ -z "$HEADER_DESCR" ]] ; then + if [[ -z "$DEVICE" ]] ; then + HEADER_DESCR="$MYNAME FIT image" + else # use $DEVICE if we have it. + HEADER_DESCR="$MYNAME FIT image for ${DEVICE}" + fi +fi + +f_assemble_dts_header + +# At least one image entry is required by the ITS format. +if [[ -z "${ar_IMG_IDS[@]}" ]] ; then + echoerr -e "\nERROR: At least one valid image is required.\n" + exit 1 +fi + +f_assemble_img_header + +# If an image name wasn't supplied, we will make one up. +# We could do this later, but let's be consistent with the way the Configurations are named. +for IMGBLOCK in ${ar_IMG_IDS[@]} ; do + IMG_ID=$IMGBLOCK + if [[ -z "${ar_IMG_NAME[$IMG_ID]}" ]] ; then + ar_IMG_NAME[$IMG_ID]=img${IMG_ID} + echodebug "IMG_ID $IMG_ID setting name to \"${ar_IMG_NAME[$IMG_ID]}\"." + fi +done ; unset IMGBLOCK IMG_ID + +# Assemble an Image block for each. + +for IMGBLOCK in ${ar_IMG_IDS[@]} ; do + IMG_ID=$IMGBLOCK + echodebug "Processing IMG_ID $IMG_ID" + # The following fields are required for all images: description, type, data, compression. + for EACH in "${ar_IMG_DESCR[$IMG_ID]}" "${ar_IMG_TYPE[$IMG_ID]}" "${ar_IMG_FILE[$IMG_ID]}" "${ar_IMG_COMPRESSION[$IMG_ID]}" ; do + if [[ -z "$EACH" ]] ; then + MISSING_IMG_REQUIRED=1 + fi + done ; unset EACH + [[ "$MISSING_IMG_REQUIRED" == 1 ]] && { + echoerr -e "\nERROR: Missing one or more required attributes for IMG_ID $IMG_ID.\n" + exit 1 ; } + f_assemble_img_body_header + case "${ar_IMG_TYPE[$IMG_ID]}" in # ARCH is conditionally mandatory for certain image types. + standalone|kernel|firmware|ramdisk|fdt) + if [[ -z "${ar_IMG_ARCH[$IMG_ID]}" ]] ; then + echoerr -e "\nERROR: --img-arch required for this image type.\n" + exit 1 + fi + ;; + esac + if [[ -n "${ar_IMG_ARCH[$IMG_ID]}" ]] ; then # Add architecture. + f_assemble_img_body_arch + fi + case "${ar_IMG_TYPE[$IMG_ID]}" in # OS is conditionally mandatory for kernels. + kernel) + if [[ -z "${ar_IMG_OS[$IMG_ID]}" ]] ; then + echoerr -e "\nERROR: --img-os required for this image type.\n" + exit 1 + fi + ;; + esac + if [[ -n "${ar_IMG_OS[$IMG_ID]}" ]] ; then # Add OS. + f_assemble_img_body_os + fi + case "${ar_IMG_TYPE[$IMG_ID]}" in # LOAD/ENTRY is conditionally mandatory for standalone kernels. + standalone|kernel) + if [[ -z "${ar_IMG_LOAD_ADDR[$IMG_ID]}" ]] || [[ -z "${ar_IMG_ENTRY_ADDR[$IMG_ID]}" ]]; then + echoerr -e "\nERROR: --img-load-addr and --img-entry-addr are required for this image type.\n" + exit 1 + fi + ;; + esac + if [[ -n "${ar_IMG_LOAD_ADDR[$IMG_ID]}" ]] && [[ -n "${ar_IMG_ENTRY_ADDR[$IMG_ID]}" ]]; then # Load and entry required together. + f_assemble_img_body_load-entry + elif [[ -n "${ar_IMG_LOAD_ADDR[$IMG_ID]}" ]] && [[ -z "${ar_IMG_ENTRY_ADDR[$IMG_ID]}" ]]; then # One without the other is an error. + echoerr -e "\nERROR: An image entry address is required if a load address is specified for IMG_ID $IMG_ID.\n" + exit 1 + elif [[ -z "${ar_IMG_LOAD_ADDR[$IMG_ID]}" ]] && [[ -n "${ar_IMG_ENTRY_ADDR[$IMG_ID]}" ]]; then # One without the other is an error. + echoerr -e "\nERROR: An image load address is required if an entry address is specified for IMG_ID $IMG_ID.\n" + exit 1 + fi + if [[ -n "${ar_IMG_HASHES[$IMG_ID]}" ]] ; then # Hashes are optional. + echodebug "IMG_ID $IMG_ID has hashes" + HASH_NUM=0 + while IFS=',' ; do + for EACH in ${ar_IMG_HASHES[$IMG_ID]} ; do + echodebug "Processing IMG_ID $IMG_ID HASH_ID $EACH" + HASH_NAME=$EACH + f_assemble_img_body_hash + HASH_NUM=$(( HASH_NUM + 1 )) + done ; unset EACH + break + done ; unset HASH_NUM HASH_NAME + fi + f_assemble_img_body_footer +done ; unset IMGBLOCK IMG_ID + +f_assemble_img_footer + +# Configurations are optional. +if [[ "${#ar_CFG_IDS[@]}" -gt 0 ]] ; then + f_assemble_cfg_header + + # If a configuration name wasn't supplied, we will make one up. + # Because the default configuration might not have a name yet, we do this before f_assemble_cfg_header_default. + for CFGBLOCK in ${ar_CFG_IDS[@]} ; do + CFG_ID=$CFGBLOCK + if [[ -z "${ar_CFG_NAME[$CFG_ID]}" ]] ; then + ar_CFG_NAME[$CFG_ID]=config${CFG_ID} + echodebug "CFG_ID $CFG_ID setting name to \"${ar_CFG_NAME[$CFG_ID]}\"." + fi + done ; unset CFGBLOCK CFG_ID + + # If we defined a default configuration, then use it. + if [[ -n "$CFG_DEFAULT" ]] ; then + if [[ ! "${ar_CFG_IDS[$CFG_DEFAULT]}" ]] ; then # If we have a default, the associated cfg ID must exist. + echoerr -e "\nERROR: A default configuration is defined, but CFG_ID \"$CFG_DEFAULT\" does not exist.\n" + exit 1 + fi + f_assemble_cfg_header_default + fi + + # Assemble a configuration block for each. + for CFGBLOCK in ${ar_CFG_IDS[@]} ; do + CFG_ID=$CFGBLOCK + echodebug "Processing CFG_ID $CFG_ID" + # The following fields are required for all configurations: description, kernel. + for EACH in "${ar_CFG_DESCR[$CFG_ID]}" "${ar_CFG_KERNEL[$CFG_ID]}" ; do + if [[ -z "$EACH" ]] ; then + MISSING_CFG_REQUIRED=1 + fi + done ; unset EACH + [[ "$MISSING_CFG_REQUIRED" == 1 ]] && { + echoerr -e "\nERROR: Missing one or more required attributes for CFG_ID $CFG_ID.\n" + exit 1 ; } + f_assemble_cfg_body_header + if [[ -n "${ar_CFG_KERNEL[$CFG_ID]}" ]] ; then # A defined kernel must match up to an image of type "kernel". + if ! [[ "${ar_IMG_TYPE[${ar_CFG_KERNEL[$CFG_ID]}]}" == kernel ]] ; then + echoerr -e "\nERROR: Configuration kernel ID \"${CFG_ID}\" image does not exist, or is not of \"kernel\" type.\n" + exit 1 + fi + fi + if [[ -n "${ar_CFG_RAMDISK[$CFG_ID]}" ]] ; then # Add ramdisk. + if ! [[ "${ar_IMG_TYPE[${ar_CFG_RAMDISK[$CFG_ID]}]}" == ramdisk ]] ; then + echoerr -e "\nERROR: Configuration ramdisk ID \"${CFG_ID}\" image does not exist, or is not of \"ramdisk\" type.\n" + exit 1 + fi + f_assemble_cfg_body_ramdisk + fi + if [[ -n "${ar_CFG_FDT[$CFG_ID]}" ]] ; then # Add FDT. + if ! [[ "${ar_IMG_TYPE[${ar_CFG_FDT[$CFG_ID]}]}" == fdt ]] ; then + echoerr -e "\nERROR: Configuration FDT ID \"${CFG_ID}\" image does not exist, or is not of \"fdt\" type.\n" + exit 1 + fi + f_assemble_cfg_body_FDT + fi + f_assemble_cfg_body_footer + done ; unset CFGBLOCK CFG_ID + + f_assemble_cfg_footer +fi + +# Assemble DTS the footer. +f_assemble_dts_footer + +# If we don't have an output file, print to stdout. +if [[ -z "$OUT_FILE" ]] ; then + echodebug "Printing DTS to stdout" + cat "$DTS_BODY" && rm -f "$DTS_BODY" +else + # Make sure we are not going to clobber a file. + if [[ -f "$OUT_FILE" ]] ; then + echoerr -e "\nERROR: Output file \"OUT_FILE\" already exists!\n" + exit 1 + fi + echodebug "Writing output file." + cat "$DTS_BODY" > $OUT_FILE ; X_WRITE_OUT=$? + if [[ "$X_WRITE_OUT" == 0 ]] ; then + echo -e "\nDTS file written to: $OUT_FILE\n" + rm -f "$DTS_BODY" + else + echoerr -e "\nERROR: Writing output file failed.\n" + exit 1 + fi +fi -- 2.1.4 _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev