]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
econet: image: add little endian TRX support for EN7528
authorAhmed Naseef <naseefkm@gmail.com>
Tue, 30 Dec 2025 04:57:29 +0000 (08:57 +0400)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 15 Feb 2026 00:12:52 +0000 (01:12 +0100)
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 <naseefkm@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21326
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/econet/image/Makefile
target/linux/econet/image/en751221.mk
target/linux/econet/image/en7528.mk
target/linux/econet/image/tclinux-trx.sh

index 120ad234d31bf2703c7c47ac4f3d0fcc1a9e1c36..2d96d1374794be6c3bd05cb99894cae76aa8d306 100644 (file)
@@ -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
 
index 16154b3fc09ddbcfb576270d5fbe01e30e176fa1..126288bfecb2110834713ef01e1596260920a141 100644 (file)
@@ -1,3 +1,5 @@
+TRX_ENDIAN := be
+
 define Device/en751221_generic
   DEVICE_VENDOR := EN751221 Family
   DEVICE_MODEL := Initramfs Image
index 1bd8cb58d87df0183f92b4af5223dd5e939fe2de..680d03b654ebe0d81492454266ab9f3ebcd5d1be 100644 (file)
@@ -1,3 +1,5 @@
+TRX_ENDIAN := le
+
 define Device/en7528_generic
   DEVICE_VENDOR := EN7528
   DEVICE_MODEL := Generic
index 90a88d054378cb1ba1a7f020e7abead6c29bfa06..3750e9112da4387faef86a39bceee522d61ce368 100755 (executable)
@@ -14,14 +14,76 @@ die() {
     exit 1
 }
 
-[ $# -eq 3 ] || die "SYNTAX: $0 <kernel lzma> <rootfs squashfs> <version string>"
-kernel=$1
-rootfs=$2
-version=$3
+usage() {
+    cat >&2 <<EOF
+SYNTAX: $0 --kernel <file> --rootfs <file> --version <string> [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 <value>
+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