On 08/09/2016 07:04, J Mo wrote: > its-maker.sh creates an .its file, given a series of arguments, which is then > used to create a FIT image. > > Required to support the tew827dru, but intended to support the creation of > any valid .its file. > > Signed-off-by: jmomo <jm...@jmomo.net>
this seems overly complicated. is there no existing tool to create its images ? > --- > scripts/its-maker.sh | 598 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 598 insertions(+) > create mode 100644 scripts/its-maker.sh > > This is a new script to make ITS files, which are then used to produce a FIT > image. > > The existing mkits.sh script was device-specific and otherwise can not > produce the FIT I need. > > It does not support configurations, yet, but I'll add that if desired. > > After I wrote my script, I became aware that Jason Wu was working on fixing > up mkits.sh, but there hasn't been any progress and I'm not sure he's still > interested in working on it. I will make him aware of my work: > https://patchwork.ozlabs.org/patch/599455/ > > diff --git a/scripts/its-maker.sh b/scripts/its-maker.sh > new file mode 100644 > index 0000000..7f4ba26 > --- /dev/null > +++ b/scripts/its-maker.sh > @@ -0,0 +1,598 @@ > +#!/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: > +# Support for Configurations not done. > +# Clean up trap on interupt, etc. > +# Mandatory/optional fields could be better. > +# Consider harmonizing with mkimage arguments? > +# > +# References: > +# > https://casper.berkeley.edu/svn/trunk/roach/sw/uboot/doc/uImage.FIT/source_file_format.txt > +# > https://lxr.missinglinkelectronics.com/uboot/doc/uImage.FIT/beaglebone_vboot.txt > +# http://lists.denx.de/pipermail/u-boot/2008-March/030898.html > +# https://wiki.linaro.org/WorkingGroups/Security/Verified-U-boot > + > +VERSION=1.0 > +MYNAME=$(basename $0) > +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 > + > +# 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: > + > + --out|-O Output file, otherwise output > goes to stdout. > + --device|-i Device for which we are building > this ITS. > + --fit-type|-T The FIT format type. Defaults to > "flat_dt". > + --fit-description|-D The FIT Description line. > + > + 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. > + > + --debug Debug the $MYNAME script. > + help|--help|-h|-H Show help info. > + > + 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") > + echodebug "IMG_ID $IMG_ID added to ar_IMG_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 > + default = "config@1"; > + configurations { > + EOF > +} > + > +f_assemble_cfg_body () { > + # FIXME: Not done. > + cat <<-EOF >> $DTS_BODY > + config@1 { > + description = "OpenWrt"; > + kernel = "kernel@1"; > + fdt = "fdt@1"; > + }; > + 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 > + ;; > + *) > + echoerr -e "\nERROR: Invalid argument \"$1\".\n" > + f_printusage > + exit 1 > + ;; > +esac ; done > + > +# Build the ITS. > +# NOTE: The ITS format is complicated. It's our job to build the ITS. It's > mkimage's job to determine if the content is valid. > +# We do some basic validity checking, but producing an invalid ITS is a > valid scenerio. > + > +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="LEDE FIT image" > + else # use $DEVICE if we have it. > + HEADER_DESCR="LEDE 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 > + > +# 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 > + # FIXME: Error on one but not the other. > + 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 > + > +# Assemble a Configuration block for each. > +# FIXME: not done. > +for EACH in ${ar_CFG_IDS[@]} ; do > + CFG_ID=$EACH > + f_assemble_cfg_header > + f_assemble_cfg_body > + f_assemble_cfg_footer > +done ; unset EACH CFG_ID > + > +# Assemble 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 > + > _______________________________________________ Lede-dev mailing list Lede-dev@lists.infradead.org http://lists.infradead.org/mailman/listinfo/lede-dev