<div dir="ltr"><div>From: Joseph East <<a href="mailto:eastyjr@gmail.com" target="_blank">eastyjr@gmail.com</a>></div><div><br></div><div>Patchset based on previous work by Cody Schafer and Luc Forcier to allow TRX images with Belkin IDs to be compiled as part of the BRCM47XX platform for Linux 3.18.</div><p>The patchset has been tested with a Belkin F7D4401 (PlayMax N600), other devices part of the previous patch are untested but have been included, however the Belkin QA TRX signature has been removed.</p><p>The otrx tool has been modified to accept a -m argument which allows comparison against a user defined TRX signature, this works in tandem with the changes in platform.sh to verify the different Belkin TRXs for supported models.</p><p>Signed-off-by: Joseph East <<a href="mailto:eastyjr@gmail.com" target="_blank">eastyjr@gmail.com</a>><br>---<br> package/system/mtd/src/trx.c                       | 28 ++++++++++++--<br> package/utils/otrx/src/otrx.c                      | 31 +++++++++++++++-<br> .../brcm47xx/base-files/lib/upgrade/platform.sh    | 39 ++++++++++++++++++++<br> target/linux/brcm47xx/image/Makefile               | 19 ++++++++++<br> .../brcm47xx/image/lzma-loader/src/decompress.c    | 25 ++++++++++++-<br> ...nclude-Belkin-F7D4XXX-F7D3XXX-TRX-for-mtd.patch | 43 ++++++++++++++++++++++<br> 6 files changed, 177 insertions(+), 8 deletions(-)<br> create mode 100644 target/linux/brcm47xx/patches-3.18/032-11-MIPS-BCM47XX-Include-Belkin-F7D4XXX-F7D3XXX-TRX-for-mtd.patch</p><p>diff --git a/package/system/mtd/src/trx.c b/package/system/mtd/src/trx.c<br>index 245ee76..8e4980c 100644<br>--- a/package/system/mtd/src/trx.c<br>+++ b/package/system/mtd/src/trx.c<br>@@ -35,7 +35,12 @@<br> #include "mtd.h"<br> #include "crc32.h"<br> <br>-#define TRX_MAGIC       0x30524448      /* "HDR0" */<br>+#define TRX_MAGIC               0x30524448      /* "HDR0" */<br>+#define BELKIN_F7D3301_MAGIC    0x20100322<br>+#define BELKIN_F7D3302_MAGIC    0x20090928<br>+#define BELKIN_F7D4302_MAGIC    0x20101006<br>+#define BELKIN_F7D4401_MAGIC    0x00018517<br>+<br> struct trx_header {<br>  uint32_t magic;  /* "HDR0" */<br>  uint32_t len;  /* Length of file including header */<br>@@ -55,6 +60,21 @@ struct trx_header {<br> ssize_t pread(int fd, void *buf, size_t count, off_t offset);<br> ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);<br> <br>+static bool is_trx_magic(uint32_t magic)<br>+{<br>+    magic = STORE32_LE(magic);<br>+    switch (magic) {<br>+    case TRX_MAGIC:<br>+    case BELKIN_F7D3301_MAGIC:<br>+    case BELKIN_F7D3302_MAGIC:<br>+    case BELKIN_F7D4302_MAGIC:<br>+    case BELKIN_F7D4401_MAGIC:<br>+        return true;<br>+    default:<br>+        return false;<br>+    }<br>+}<br>+<br> int<br> trx_fixup(int fd, const char *name)<br> {<br>@@ -83,7 +103,7 @@ trx_fixup(int fd, const char *name)<br>  }<br> <br>  trx = ptr;<br>- if (trx->magic != TRX_MAGIC) {<br>+ if (!is_trx_magic(trx->magic)) {<br>   fprintf(stderr, "TRX header not found\n");<br>   goto err;<br>  }<br>@@ -118,7 +138,7 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)<br>   return 0;<br>  }<br> <br>- if (trx->magic != TRX_MAGIC || trx->len < sizeof(struct trx_header)) {<br>+ if (!is_trx_magic(trx->magic) || trx->len < sizeof(struct trx_header)) {<br>   if (quiet < 2) {<br>    fprintf(stderr, "Bad trx header\n");<br>    fprintf(stderr, "This is not the correct file format; refusing to flash.\n"<br>@@ -184,7 +204,7 @@ mtd_fixtrx(const char *mtd, size_t offset)<br>  }<br> <br>  trx = (struct trx_header *) (buf + offset);<br>- if (trx->magic != STORE32_LE(0x30524448)) {<br>+ if (!is_trx_magic(trx->magic)) {<br>   fprintf(stderr, "No trx magic found\n");<br>   exit(1);<br>  }<br>diff --git a/package/utils/otrx/src/otrx.c b/package/utils/otrx/src/otrx.c<br>index 101a310..36ebe62 100644<br>--- a/package/utils/otrx/src/otrx.c<br>+++ b/package/utils/otrx/src/otrx.c<br>@@ -47,6 +47,8 @@ struct trx_header {<br> <br> char *trx_path;<br> size_t trx_offset = 0;<br>+uint8_t use_trx_override = 0;<br>+uint32_t trx_override = 0;<br> char *partition[TRX_MAX_PARTS] = {};<br> <br> static inline size_t otrx_min(size_t x, size_t y) {<br>@@ -143,11 +145,35 @@ uint32_t otrx_crc32(uint8_t *buf, size_t len) {<br> static void otrx_check_parse_options(int argc, char **argv) {<br>  int c;<br> <br>- while ((c = getopt(argc, argv, "o:")) != -1) {<br>+ while ((c = getopt(argc, argv, "m:o:")) != -1) {<br>   switch (c) {<br>   case 'o':<br>    trx_offset = atoi(optarg);<br>    break;<br>+  case 'm':<br>+   trx_override = strtol(optarg, NULL, 16);<br>+   use_trx_override = 1;<br>+   break;<br>+  }<br>+ }<br>+}<br>+<br>+static int is_trx_magic(uint32_t magic) {<br>+        magic = cpu_to_le32(magic);<br>+ if(use_trx_override) {<br>+         if(magic == trx_override) {<br>+                 return 1;<br>+         }<br>+         else {<br>+                 return 0;<br>+         }<br>+ }<br>+ else {<br>+  if(magic == TRX_MAGIC) {<br>+   return 1;<br>+  }<br>+  else {<br>+   return 0;<br>   }<br>  }<br> }<br>@@ -186,7 +212,7 @@ static int otrx_check(int argc, char **argv) {<br>   goto err_close;<br>  }<br> <br>- if (le32_to_cpu(hdr.magic) != TRX_MAGIC) {<br>+ if (!is_trx_magic(le32_to_cpu(hdr.magic))) {<br>   fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic));<br>   err =  -EINVAL;<br>   goto err_close;<br>@@ -548,6 +574,7 @@ static void usage() {<br>  printf("Checking TRX file:\n");<br>  printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n");<br>  printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");<br>+ printf("\t-m signature\t\t\tCompare against input TRX signature\n");<br>  printf("\n");<br>  printf("Creating new TRX file:\n");<br>  printf("\totrx create <file> [options] [partitions]\n");<br>diff --git a/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh b/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh<br>index cbadefb..9f12715 100644<br>--- a/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh<br>+++ b/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh<br>@@ -51,6 +51,10 @@ platform_expected_image() {<br>   "Linksys WRT310N V2") echo "cybertan 310N"; return;;<br>   "Linksys WRT610N V1") echo "cybertan 610N"; return;;<br>   "Linksys WRT610N V2") echo "cybertan 610N"; return;;<br>+  "Belkin F7D3301") echo "22031020"; return;;<br>+  "Belkin F7D3302") echo "28090920"; return;;<br>+  "Belkin F7D4302") echo "06101020"; return;;<br>+  "Belkin F7D4401")       echo "17850100"; return;;<br>  esac<br> }<br> <br>@@ -67,6 +71,22 @@ brcm47xx_identify() {<br>    echo "chk"<br>    return<br>    ;;<br>+  "17850100")<br>+   echo "beltrx"<br>+                        return<br>+                        ;;<br>+                "06101020")<br>+   echo "beltrx"<br>+                        return<br>+                        ;;<br>+                "28090920")<br>+   echo "beltrx"<br>+                        return<br>+                        ;;<br>+                "22031020")<br>+                        echo "beltrx"<br>+                        return<br>+                        ;;<br>  esac<br> <br>  magic=$(get_magic_long_at "$1" 14)<br>@@ -124,6 +144,25 @@ platform_check_image() {<br>     error=1<br>    fi<br>   ;;<br>+  "beltrx")<br>+   local dev_board_id=$(platform_expected_image)<br>+   local machine=$(platform_machine)<br>+   local magic=$(get_magic_long "$1")<br>+   echo "Found TRX image with Belkin Magic TRX"<br>+   echo "Anticipating a $machine, checking..."<br>+   [ -n "$dev_board_id" -a "$magic" != "$dev_board_id" ] &&<br>+   {<br>+    echo "Firmware does not match machine $machine, aborting"<br>+    echo "Though it still may be an otherwise valid TRX"<br>+    error=1<br>+   }<br>+<br>+   local be_magic=${magic:6:2}${magic:4:2}${magic:2:2}${magic:0:2}<br>+   if ! otrx check "$1" -m "$be_magic"; then<br>+    echo "Not a valid TRX image"<br>+    error=1<br>+   fi<br>+  ;;<br>   *)<br>    echo "Invalid image type. Please use only .trx files"<br>    error=1<br>diff --git a/target/linux/brcm47xx/image/Makefile b/target/linux/brcm47xx/image/Makefile<br>index 6768820..45ed330 100644<br>--- a/target/linux/brcm47xx/image/Makefile<br>+++ b/target/linux/brcm47xx/image/Makefile<br>@@ -34,6 +34,17 @@ endif<br>  $(call prepare_generic_squashfs,$(KDIR)/fs_mark)<br> endef<br> <br>+# Function for multiple Belkin Trx<br>+# 1: trx input<br>+# 2: bin output<br>+# 3: 4 magic bytes<br>+define Image/Build/Belkin_<br>+ echo -ne $(3) > $(2).head<br>+ dd if=$(1) of=/dev/stdout bs=4 skip=1 > $(2).tail<br>+ cat $(2).head $(2).tail > $(2)<br>+ rm -f $(2).head $(2).tail<br>+endef<br>+<br> define Image/Build/wgt634u<br>  dd if=$(KDIR)/loader.elf of=$(BIN_DIR)/$(IMG_PREFIX)-wgt634u-$(2).bin bs=131072 conv=sync<br>  cat $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx >> $(BIN_DIR)/$(IMG_PREFIX)-wgt634u-$(2).bin<br>@@ -71,6 +82,10 @@ define Image/Build/Edi<br>  $(STAGING_DIR_HOST)/bin/trx2edips $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(3).bin<br> endef<br> <br>+define Image/Build/Belkin<br>+ $(call Image/Build/Belkin_,$(BIN_DIR)/$(IMG_PREFIX)-$(1).trx,$(BIN_DIR)/openwrt-$(2)-$(patsubst jffs2-%,jffs2,$(1)).bin,$(3))<br>+endef<br>+<br> define Image/Build/Huawei<br>  dd if=/dev/zero of=$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(3)-gz.bin bs=92 count=1<br>  echo -ne 'HDR0\x08\x00\x00\x00' >> $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(3)-gz.bin<br>@@ -362,6 +377,10 @@ define Image/Build<br>   -f $(KDIR)/vmlinux.gz \<br>   $(call trxalign/$(1),$(1))<br>  $(call Image/Build/$(SUBTARGET)/$(1),$(1))<br>+ $(call Image/Build/Belkin,$(1),f7d3301,'\x22\x03\x10\x20')<br>+ $(call Image/Build/Belkin,$(1),f7d3302,'\x28\x09\x09\x20')<br>+ $(call Image/Build/Belkin,$(1),f7d4302,'\x06\x10\x10\x20')<br>+ $(call Image/Build/Belkin,$(1),f7d4401,'\x17\x85\x01\x00')<br> # $(call Image/Build/Chk,$(1),wgr614_v9,U12H094T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))<br> # $(call Image/Build/Chk,$(1),wndr3400_vcna,U12H155T01_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))<br> # $(call Image/Build/Chk,$(1),wnr3500U,U12H136T00_NETGEAR,2,$(patsubst jffs2-%,jffs2,$(1)))<br>diff --git a/target/linux/brcm47xx/image/lzma-loader/src/decompress.c b/target/linux/brcm47xx/image/lzma-loader/src/decompress.c<br>index 05681b1..076bff0 100644<br>--- a/target/linux/brcm47xx/image/lzma-loader/src/decompress.c<br>+++ b/target/linux/brcm47xx/image/lzma-loader/src/decompress.c<br>@@ -89,6 +89,10 @@ struct trx_header {<br> <br> #define EDIMAX_PS_HEADER_MAGIC 0x36315350 /*  "PS16"  */<br> #define EDIMAX_PS_HEADER_LEN 0xc /* 12 bytes long for edimax header */<br>+#define BELKIN_F7D3301_MAGIC 0x20100322 /* Belkin TRX */<br>+#define BELKIN_F7D3302_MAGIC 0x20090928<br>+#define BELKIN_F7D4302_MAGIC 0x20101006<br>+#define BELKIN_F7D4401_MAGIC 0x00018517<br> <br> /* beyound the image end, size not known in advance */<br> extern unsigned char workspace[];<br>@@ -121,6 +125,24 @@ static __inline__ unsigned char get_byte(void)<br>  return read_byte(0, &buffer, &fake), *buffer;<br> }<br> <br>+static int has_trx_magic(unsigned char *data)<br>+{<br>+    UInt32 magic = ((struct trx_header *)data)->magic;<br>+<br>+    switch (magic) {<br>+    case TRX_MAGIC:<br>+    case EDIMAX_PS_HEADER_MAGIC:<br>+    case BELKIN_F7D3301_MAGIC:<br>+    case BELKIN_F7D3302_MAGIC:<br>+    case BELKIN_F7D4302_MAGIC:<br>+    case BELKIN_F7D4401_MAGIC:<br>+        return 1;<br>+    default:<br>+        return 0;<br>+    }<br>+}<br>+<br>+<br> /* should be the first function */<br> void entry(unsigned long icache_size, unsigned long icache_lsize, <br>  unsigned long dcache_size, unsigned long dcache_lsize,<br>@@ -138,8 +160,7 @@ void entry(unsigned long icache_size, unsigned long icache_lsize,<br> <br>  /* look for trx header, 32-bit data access */<br>  for (data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH));<br>-  ((struct trx_header *)data)->magic != TRX_MAGIC &&<br>-  ((struct trx_header *)data)->magic != EDIMAX_PS_HEADER_MAGIC;<br>+   !has_trx_magic(data);<br>    data += 65536);<br> <br>  if (((struct trx_header *)data)->magic == EDIMAX_PS_HEADER_MAGIC)<br>diff --git a/target/linux/brcm47xx/patches-3.18/032-11-MIPS-BCM47XX-Include-Belkin-F7D4XXX-F7D3XXX-TRX-for-mtd.patch b/target/linux/brcm47xx/patches-3.18/032-11-MIPS-BCM47XX-Include-Belkin-F7D4XXX-F7D3XXX-TRX-for-mtd.patch<br>new file mode 100644<br>index 0000000..8e2c1df<br>--- /dev/null<br>+++ b/target/linux/brcm47xx/patches-3.18/032-11-MIPS-BCM47XX-Include-Belkin-F7D4XXX-F7D3XXX-TRX-for-mtd.patch<br>@@ -0,0 +1,43 @@<br>+--- a/drivers/mtd/bcm47xxpart.c<br>++++ b/drivers/mtd/bcm47xxpart.c<br>+@@ -45,6 +45,10 @@<br>+ #define TRX_MAGIC   0x30524448<br>+ #define SHSQ_MAGIC   0x71736873 /* shsq (weird ZTE H218N endianness) */<br>+ #define UBI_EC_MAGIC   0x23494255 /* UBI# */<br>++#define BELKIN_F7D3301_MAGIC  0x20100322 /* Belkin TRX */<br>++#define BELKIN_F7D3302_MAGIC  0x20090928<br>++#define BELKIN_F7D4302_MAGIC  0x20101006<br>++#define BELKIN_F7D4401_MAGIC  0x00018517<br>+ <br>+ struct trx_header {<br>+  uint32_t magic;<br>+@@ -55,6 +59,20 @@ struct trx_header {<br>+  uint32_t offset[3];<br>+ } __packed;<br>+ <br>++static bool is_trx_magic(uint32_t magic)<br>++{<br>++ switch (magic) {<br>++ case TRX_MAGIC:<br>++ case BELKIN_F7D3301_MAGIC:<br>++ case BELKIN_F7D3302_MAGIC:<br>++ case BELKIN_F7D4302_MAGIC:<br>++ case BELKIN_F7D4401_MAGIC:<br>++  return true;<br>++ default:<br>++  return false;<br>++ }<br>++}<br>++<br>+ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name,<br>+      u64 offset, uint32_t mask_flags)<br>+ {<br>+@@ -189,7 +207,7 @@ static int bcm47xxpart_parse(struct mtd_<br>+   }<br>+ <br>+   /* TRX */<br>+-  if (buf[0x000 / 4] == TRX_MAGIC) {<br>++  if (is_trx_magic(buf[0x000 / 4])) {<br>+    if (BCM47XXPART_MAX_PARTS - curr_part < 4) {<br>+     pr_warn("Not enough partitions left to register trx, scanning stopped!\n");<br>+     break;<span><font color="#888888"><br>-- <br>2.1.4</font></span></p></div>