From: Ahmed Naseef Date: Tue, 30 Dec 2025 04:57:29 +0000 (+0400) Subject: econet: image: add little endian TRX support for EN7528 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ba87609b81fac6199129d80335a5f8798af3f17;p=thirdparty%2Fopenwrt.git econet: image: add little endian TRX support for EN7528 The EN7528 SoC uses a little endian MIPS architecture, unlike the big endian EN751221 family. The tclinux TRX firmware format stores multi-byte fields in the CPU's native byte order, requiring different header layouts for each architecture: - Big endian (EN751221): magic "2RDH", fields in big endian order - Little endian (EN7528): magic "HDR2", fields in little endian order Update tclinux-trx.sh to support both endianness variants: - Add --endian parameter to select byte order (default: be) - Add --model parameter for optional platform identifier field - Convert to named parameters for clarity and extensibility - Use hex32() helper for endian-aware 32-bit field output Move TRX_ENDIAN configuration to subtarget files, allowing each subtarget to specify its native byte order: - en751221.mk: TRX_ENDIAN := be - en7528.mk: TRX_ENDIAN := le Signed-off-by: Ahmed Naseef Link: https://github.com/openwrt/openwrt/pull/21326 Signed-off-by: Hauke Mehrtens --- diff --git a/target/linux/econet/image/Makefile b/target/linux/econet/image/Makefile index 120ad234d31..2d96d137479 100644 --- a/target/linux/econet/image/Makefile +++ b/target/linux/econet/image/Makefile @@ -7,7 +7,9 @@ endef # tclinux-trx is the default format used in the SDK define Build/tclinux-trx - ./tclinux-trx.sh $@ $(IMAGE_ROOTFS) $(VERSION_DIST)-$(REVISION) > $@.new + ./tclinux-trx.sh --kernel $@ --rootfs $(IMAGE_ROOTFS) \ + --version $(VERSION_DIST)-$(REVISION) --endian $(TRX_ENDIAN) \ + $(if $(TRX_MODEL),--model $(TRX_MODEL)) > $@.new mv $@.new $@ endef diff --git a/target/linux/econet/image/en751221.mk b/target/linux/econet/image/en751221.mk index 16154b3fc09..126288bfecb 100644 --- a/target/linux/econet/image/en751221.mk +++ b/target/linux/econet/image/en751221.mk @@ -1,3 +1,5 @@ +TRX_ENDIAN := be + define Device/en751221_generic DEVICE_VENDOR := EN751221 Family DEVICE_MODEL := Initramfs Image diff --git a/target/linux/econet/image/en7528.mk b/target/linux/econet/image/en7528.mk index 1bd8cb58d87..680d03b654e 100644 --- a/target/linux/econet/image/en7528.mk +++ b/target/linux/econet/image/en7528.mk @@ -1,3 +1,5 @@ +TRX_ENDIAN := le + define Device/en7528_generic DEVICE_VENDOR := EN7528 DEVICE_MODEL := Generic diff --git a/target/linux/econet/image/tclinux-trx.sh b/target/linux/econet/image/tclinux-trx.sh index 90a88d05437..3750e9112da 100755 --- a/target/linux/econet/image/tclinux-trx.sh +++ b/target/linux/econet/image/tclinux-trx.sh @@ -14,14 +14,76 @@ die() { exit 1 } -[ $# -eq 3 ] || die "SYNTAX: $0 " -kernel=$1 -rootfs=$2 -version=$3 +usage() { + cat >&2 < --rootfs --version [options] + +Options: + --kernel Path to kernel lzma file (required) + --rootfs Path to rootfs squashfs file (required) + --version Version string, max 31 chars (required) + --endian Endianness: 'be' for big endian, 'le' for little endian (default: be) + --model Model/platform name, max 31 chars (default: empty) +EOF + exit 1 +} + +# Defaults +kernel="" +rootfs="" +version="" +endian="be" +model="" + +# Parse named arguments +while [ $# -gt 0 ]; do + case "$1" in + --kernel) + kernel="$2" + shift 2 + ;; + --rootfs) + rootfs="$2" + shift 2 + ;; + --version) + version="$2" + shift 2 + ;; + --endian) + endian="$2" + shift 2 + ;; + --model) + model="$2" + shift 2 + ;; + -h|--help) + usage + ;; + *) + die "Unknown option: $1" + ;; + esac +done + +# Validate required arguments +[ -n "$kernel" ] || die "Missing required argument: --kernel" +[ -n "$rootfs" ] || die "Missing required argument: --rootfs" +[ -n "$version" ] || die "Missing required argument: --version" + +# Validate endianness +case "$endian" in + be|BE) endian="be" ;; + le|LE) endian="le" ;; + *) die "Invalid endianness: $endian (must be 'be' or 'le')" ;; +esac + which zytrx >/dev/null || die "zytrx not found in PATH $PATH" [ -f "$kernel" ] || die "Kernel file not found: $kernel" [ -f "$rootfs" ] || die "Rootfs file not found: $rootfs" [ "$(echo "$version" | wc -c)" -lt 32 ] || die "Version string too long: $version" +[ -z "$model" ] || [ "$(printf '%s' "$model" | wc -c)" -lt 32 ] || die "Model string too long: $model" kernel_len=$(stat -c '%s' "$kernel") header_plus_kernel_len=$(($HDRLEN + $kernel_len)) @@ -33,6 +95,7 @@ else padding_len=0 fi +echo "endian: $endian" >&2 echo "padding_len: $padding_len" >&2 padded_rootfs_len=$(($padding_len + $rootfs_len)) @@ -55,6 +118,18 @@ from_hex() { perl -pe 's/\s+//g; s/(..)/chr(hex($1))/ge' } +# Output a 32-bit value in hex with correct endianness +# Usage: hex32 +hex32() { + val=$(printf '%08x' "$1") + if [ "$endian" = "le" ]; then + # Swap bytes for little endian: AABBCCDD -> DDCCBBAA + echo "$val" | sed 's/\(..\)\(..\)\(..\)\(..\)/\4\3\2\1/' + else + echo "$val" + fi +} + trx_crc32() { tmpfile=$(mktemp) outtmpfile=$(mktemp) @@ -69,19 +144,24 @@ trx_crc32() { -v x \ -i "$tmpfile" \ -o "$outtmpfile" >/dev/null - dd if="$outtmpfile" bs=4 count=1 skip=3 | to_hex + crc_hex=$(dd if="$outtmpfile" bs=4 count=1 skip=3 2>/dev/null | to_hex) rm "$tmpfile" "$outtmpfile" >/dev/null + hex32 "0x$crc_hex" } tclinux_trx_hdr() { - # TRX header magic - printf '2RDH' | to_hex + # TRX header magic: "2RDH" for big endian, "HDR2" for little endian + if [ "$endian" = "le" ]; then + printf 'HDR2' | to_hex + else + printf '2RDH' | to_hex + fi # Length of the header - printf '%08x\n' "$HDRLEN" + hex32 "$HDRLEN" # Length of header + content - printf '%08x\n' "$total_len" + hex32 "$total_len" # crc32 of the content trx_crc32 @@ -94,19 +174,24 @@ tclinux_trx_hdr() { head -c 32 /dev/zero | to_hex # kernel length - printf '%08x\n' "$kernel_len" + hex32 "$kernel_len" # rootfs length - printf '%08x\n' "$padded_rootfs_len" + hex32 "$padded_rootfs_len" # romfile length (0) - printf '00000000\n' + hex32 0 - # "model" (32 bytes of zeros) - head -c 32 /dev/zero | to_hex + # model (32 bytes, zero-padded) + if [ -n "$model" ]; then + printf '%s' "$model" | to_hex + head -c "$((32 - $(printf '%s' "$model" | wc -c)))" /dev/zero | to_hex + else + head -c 32 /dev/zero | to_hex + fi # Load address (CONFIG_ZBOOT_LOAD_ADDRESS) - printf '80020000\n' + hex32 0x80020000 # "reserved" 128 bytes of zeros head -c 128 /dev/zero | to_hex