ramips: add missing information to dlink headers
authorAlan Luck <luckyhome2008@gmail.com>
Tue, 20 Apr 2021 09:44:01 +0000 (19:44 +1000)
committerDavid Bauer <mail@david-bauer.net>
Fri, 24 Sep 2021 10:32:28 +0000 (12:32 +0200)
Add additional header information required for newer
bootloaders found on DIR-2660-A1 & A2.

Also remove the MTD splitter compatible from the second firmware
partition, as OpenWrt only supports handling of the first one.

Signed-off-by: Alan Luck <luckyhome2008@gmail.com>
[rephrase commit message, remove removal of read-only flags]
Signed-off-by: David Bauer <mail@david-bauer.net>
target/linux/ramips/dts/mt7621_dlink_dir-xx60-a1.dtsi
target/linux/ramips/image/Makefile
target/linux/ramips/image/mt7621.mk
tools/firmware-utils/Makefile
tools/firmware-utils/src/uimage_sgehdr.c [new file with mode: 0644]

index a1550cfb40190c69596791008e6ffa7e29a248cf..9dcc050af2a97e9f8033952b3882978b8aad57b8 100644 (file)
 
                partition@4980000 {
                        label = "firmware2";
-                       compatible = "openwrt,uimage", "denx,uimage";
-                       openwrt,padding = <96>;
                        reg = <0x4980000 0x2800000>;
                };
 
index 3671caef9dc6effe62d50ccd04ed5155b180350f..d523a62e0bc718d5922214db05a8aabb59ef4b30 100644 (file)
@@ -144,6 +144,12 @@ define Build/uimage-padhdr
        mv $@.new $@
 endef
 
+define Build/uimage-sgehdr
+       uimage_sgehdr -i $@ -o $@.new -m $(DEVICE_MODEL) \
+               -h $(DEVICE_VARIANT) -s V1.00000
+       mv $@.new $@
+endef
+
 define Build/umedia-header
        fix-u-media-header -T 0x46 -B $(1) -i $@ -o $@.new && mv $@.new $@
 endef
index c115d04bd67b62d7708e0c5f5a952fd36955ed1b..6e7391baef22493e9593d553d91650dbec62a387 100644 (file)
@@ -286,12 +286,11 @@ define Device/dlink_dir-8xx-a1
   IMAGE_SIZE := 16000k
   DEVICE_VENDOR := D-Link
   DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware
-  KERNEL_INITRAMFS := $$(KERNEL) | uimage-padhdr 96
+  KERNEL := $$(KERNEL) | uimage-sgehdr
   IMAGES += factory.bin
-  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | uimage-padhdr 96 |\
-       pad-rootfs | check-size | append-metadata
-  IMAGE/factory.bin := append-kernel | append-rootfs | uimage-padhdr 96 |\
-       check-size
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | \
+       check-size | append-metadata
+  IMAGE/factory.bin := append-kernel | append-rootfs | check-size
 endef
 
 define Device/dlink_dir-8xx-r1
@@ -314,7 +313,7 @@ define Device/dlink_dir-xx60-a1
   DEVICE_VENDOR := D-Link
   DEVICE_PACKAGES := kmod-mt7615e kmod-mt7615-firmware kmod-usb3 \
        kmod-usb-ledtrig-usbport
-  KERNEL := $$(KERNEL) | uimage-padhdr 96
+  KERNEL := $$(KERNEL) | uimage-sgehdr
   IMAGES += factory.bin
   IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
   IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | \
index 995fc79ece7ea410f62ee4b2ac736a5cc435b346..d5b08168166a7517699c949b2bf661d75fae7051 100644 (file)
@@ -95,6 +95,7 @@ define Host/Compile
        $(call cc,trx2edips,-Wall)
        $(call cc,trx2usr,-Wall)
        $(call cc,uimage_padhdr,-Wall -lz)
+       $(call cc,uimage_sgehdr,-Wall -lz)
        $(call cc,wrt400n cyg_crc32,-Wall)
        $(call cc,xorimage,-Wall)
        $(call cc,zyimage,-Wall)
diff --git a/tools/firmware-utils/src/uimage_sgehdr.c b/tools/firmware-utils/src/uimage_sgehdr.c
new file mode 100644 (file)
index 0000000..28143a8
--- /dev/null
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * uimage_sgehdr.c : add 96 bytes of extra header information after the normal tail of uimage header
+ * this is an edited version of uimage_padhdr.c
+ *
+ * Copyright (C) 2019 NOGUCHI Hiroshi <drvlabo@gmail.com>
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <zlib.h>
+
+
+/* from u-boot/include/image.h */
+#define IH_NMLEN               32      /* Image Name Length            */
+#define SGE_PRODUCTLEN         64      /* sge_Product Length           */
+#define SGE_VERSIONLEN         16      /* sge Version Length           */
+#define OrignalHL              64      /* Original Header Length       */
+
+/*
+ * SGE format image header,
+ * all data in network byte order (aka natural aka bigendian).
+ */
+struct image_header {
+       uint32_t        ih_magic;       /* Image Header Magic Number    */
+       uint32_t        ih_hcrc;        /* Image Header CRC Checksum    */
+       uint32_t        ih_time;        /* Image Creation Timestamp     */
+       uint32_t        ih_size;        /* Image Data Size              */
+       uint32_t        ih_load;        /* Data  Load  Address          */
+       uint32_t        ih_ep;          /* Entry Point Address          */
+       uint32_t        ih_dcrc;        /* Image Data CRC Checksum      */
+       uint8_t         ih_os;          /* Operating System             */
+       uint8_t         ih_arch;        /* CPU architecture             */
+       uint8_t         ih_type;        /* Image Type                   */
+       uint8_t         ih_comp;        /* Compression Type             */
+       uint8_t         ih_name[IH_NMLEN];      /* Image Name           */
+       uint8_t         sgeih_p[SGE_PRODUCTLEN];        /* sge_Product          */
+       uint8_t         sgeih_sv[SGE_VERSIONLEN];       /* sge Software Version         */
+       uint8_t         sgeih_hv[SGE_VERSIONLEN];       /* sge Hardware Version         */
+};
+
+
+/* default padding size */
+#define        IH_PAD_BYTES            (96)
+
+
+static void usage(char *prog)
+{
+       fprintf(stderr,
+               "%s -i <input_uimage_file> -o <output_file> -m <model> -h <hardware version> -s <software version>\n",
+               prog);
+}
+
+int main(int argc, char *argv[])
+{
+       struct stat statbuf;
+       u_int8_t *filebuf;
+       int ifd;
+       int ofd;
+       ssize_t rsz;
+       u_int32_t crc_recalc;
+       struct image_header *imgh;
+       int opt;
+       char *infname = NULL;
+       char *outfname = NULL;
+       char *model = NULL;
+       char *hversion = NULL;
+       char *sversion = NULL;
+       int padsz = IH_PAD_BYTES;
+       int ltmp;
+
+       while ((opt = getopt(argc, argv, "i:o:m:h:s:")) != -1) {
+               switch (opt) {
+               case 'i':
+                       infname = optarg;
+                       break;
+               case 'o':
+                       outfname = optarg;
+                       break;
+               case 'm':
+                       model = optarg;
+                       break;
+               case 'h':
+                       hversion = optarg;
+                       break;
+               case 's':
+                       sversion = optarg;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (!infname || !outfname) {
+               usage(argv[0]);
+               exit(1);
+       }
+
+       ifd = open(infname, O_RDONLY);
+       if (ifd < 0) {
+               fprintf(stderr,
+                       "could not open input file. (errno = %d)\n", errno);
+               exit(1);
+       }
+
+       ofd = open(outfname, O_WRONLY | O_CREAT, 0644);
+       if (ofd < 0) {
+               fprintf(stderr,
+                       "could not open output file. (errno = %d)\n", errno);
+               exit(1);
+       }
+
+       if (fstat(ifd, &statbuf) < 0) {
+               fprintf(stderr,
+                       "could not fstat input file. (errno = %d)\n", errno);
+               exit(1);
+       }
+
+       filebuf = malloc(statbuf.st_size + padsz);
+       if (!filebuf) {
+               fprintf(stderr, "buffer allocation failed\n");
+               exit(1);
+       }
+
+       rsz = read(ifd, filebuf, OrignalHL);
+       if (rsz != OrignalHL) {
+               fprintf(stderr,
+                       "could not read input file (errno = %d).\n", errno);
+               exit(1);
+       }
+
+       memset(&(filebuf[OrignalHL]), 0, padsz);
+
+       rsz = read(ifd, &(filebuf[sizeof(*imgh)]),
+                               statbuf.st_size - OrignalHL);
+       if (rsz != (int32_t)(statbuf.st_size - OrignalHL)) {
+               fprintf(stderr,
+                       "could not read input file (errno = %d).\n", errno);
+               exit(1);
+       }
+
+       imgh = (struct image_header *)filebuf;
+
+       imgh->ih_hcrc = 0;
+
+       strncpy(imgh->sgeih_p, model, sizeof(imgh->sgeih_p));
+       strncpy(imgh->sgeih_sv, sversion, sizeof(imgh->sgeih_sv));
+       strncpy(imgh->sgeih_hv, hversion, sizeof(imgh->sgeih_hv));
+
+       crc_recalc = crc32(0, filebuf, sizeof(*imgh));
+       imgh->ih_hcrc = htonl(crc_recalc);
+
+       rsz = write(ofd, filebuf, statbuf.st_size + padsz);
+       if (rsz != (int32_t)statbuf.st_size + padsz) {
+               fprintf(stderr,
+                       "could not write output file (errnor = %d).\n", errno);
+               exit(1);
+       }
+
+       return 0;
+}