ramips: add missing information to dlink headers
authorAlan Luck <luckyhome2008@gmail.com>
Tue, 20 Apr 2021 09:44:01 +0000 (19:44 +1000)
committerRafał Miłecki <rafal@milecki.pl>
Tue, 5 Oct 2021 13:42:49 +0000 (15:42 +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>
CMakeLists.txt
src/uimage_sgehdr.c [new file with mode: 0644]

index 148cdc7eb2928605f26d1eb7c8805b2d9fab638c..544ee7df23de21dda27627e3b608ac8008d80bee 100644 (file)
@@ -97,6 +97,7 @@ FW_UTIL(trx "" "" "")
 FW_UTIL(trx2edips "" "" "")
 FW_UTIL(trx2usr "" "" "")
 FW_UTIL(uimage_padhdr "" "" ${ZLIB_LIBRARIES})
+FW_UTIL(uimage_sgehdr "" "" ${ZLIB_LIBRARIES})
 FW_UTIL(wrt400n src/cyg_crc32.c "" "")
 FW_UTIL(xorimage "" "" "")
 FW_UTIL(zyimage "" "" "")
diff --git a/src/uimage_sgehdr.c b/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;
+}