[openwrt/openwrt] firmware-utils: image generator for D-Link DAP-1330

LEDE Commits lede-commits at lists.infradead.org
Thu Apr 5 06:29:06 PDT 2018


neoraider pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/0d8a0a6a17ea203527a5c61241ea19d763aed567

commit 0d8a0a6a17ea203527a5c61241ea19d763aed567
Author: Nicolò Veronese <nicveronese at gmail.com>
AuthorDate: Fri Jun 16 12:06:07 2017 +0000

    firmware-utils: image generator for D-Link DAP-1330
    
    Signed-off-by: Nicolò Veronese <nicveronese at gmail.com>
---
 tools/firmware-utils/Makefile        |   1 +
 tools/firmware-utils/src/mkdapimg2.c | 204 +++++++++++++++++++++++++++++++++++
 2 files changed, 205 insertions(+)

diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile
index ba4df64..7c0180a 100644
--- a/tools/firmware-utils/Makefile
+++ b/tools/firmware-utils/Makefile
@@ -63,6 +63,7 @@ define Host/Compile
 	$(call cc,mkbrncmdline)
 	$(call cc,mkbrnimg)
 	$(call cc,mkdapimg)
+	$(call cc,mkdapimg2)
 	$(call cc, mkcameofw, -Wall)
 	$(call cc,seama md5)
 	$(call cc,oseama md5, -Wall)
diff --git a/tools/firmware-utils/src/mkdapimg2.c b/tools/firmware-utils/src/mkdapimg2.c
new file mode 100644
index 0000000..aef003c
--- /dev/null
+++ b/tools/firmware-utils/src/mkdapimg2.c
@@ -0,0 +1,204 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2 as published by the Free Software Foundation.
+ *
+ * (C) Nicolò Veronese <nicveronese at gmail.com>
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <string.h>
+#include <errno.h>
+
+#include <netinet/in.h>	// htonl
+
+// Usage: mkdapimg2 -s signature [-v version] [-r region]
+//                  [-k uImage block size] -i <input> -o <output>
+//
+// NOTE: The kernel block size is used to know the offset of the rootfs
+// in the image file.
+//
+// The system writes in the uImage partition until the end of uImage
+// is reached, after that, the system jumps to the offset specified with the -k
+// parameter and begin writing at the beginning of the rootfs MTD partition.
+//
+// If the -k parameter is the size of the original uImage partition, the system
+// continue writing in the rootfs partition starting from the last block
+// that has been wrote. (This is useful if the new kernel size is
+// different from the original one)
+//
+// Example:
+// ------------------------------------------
+// Creating 7 MTD partitions on "ath-nor0":
+// 0x000000000000-0x000000010000 : "u-boot"
+// 0x000000010000-0x000000020000 : "ART"
+// 0x000000020000-0x000000030000 : "MP"
+// 0x000000030000-0x000000040000 : "config"
+// 0x000000040000-0x000000120000 : "uImage"
+// 0x000000120000-0x000000800000 : "rootfs"
+// 0x000000040000-0x000000800000 : "firmware"
+// ------------------------------------------
+//
+// 0x000000120000-0x000000040000 = 0xE0000 -> 917504
+//
+// e.g.: mkdapimg2 -s HONEYBEE-FIRMWARE-DAP-1330 -v 1.00.21 -r Default
+//                 -k 917504 -i sysupgarde.bin -o factory.bin
+//
+//
+// The img_hdr_struct was taken from the D-Link SDK:
+// DAP-1330_OSS-firmware_1.00b21/DAP-1330_OSS-firmware_1.00b21/uboot/uboot.patch
+
+#define MAX_SIGN_LEN	32
+#define MAX_FW_VER_LEN	16
+#define MAX_REG_LEN	8
+
+struct img_hdr_struct {
+	uint32_t hdr_len;
+	uint32_t checksum;
+	uint32_t total_size;
+	uint32_t kernel_size;
+	char signature[MAX_SIGN_LEN];
+	char fw_ver[MAX_FW_VER_LEN];
+	char fw_reg[MAX_REG_LEN];
+} imghdr ;
+
+char *progname;
+
+void
+perrexit(int code, char *msg)
+{
+	fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(errno));
+	exit(code);
+}
+
+void
+usage()
+{
+	fprintf(stderr, "usage: %s -s signature [-v version] [-r region] [-k uImage part size] -i <input> -o <output>\n", progname);
+	exit(1);
+}
+
+int
+main(int ac, char *av[])
+{
+	char signature[MAX_SIGN_LEN];
+	char version[MAX_FW_VER_LEN];
+	char region[MAX_REG_LEN];
+	int kernel = 0;
+
+	FILE *ifile, *ofile;
+	int c;
+
+	uint32_t cksum;
+	uint32_t bcnt;
+
+	progname = basename(av[0]);
+
+	memset(signature, 0, sizeof(signature));
+	memset(version, 0, sizeof(version));
+	memset(region, 0, sizeof(region));
+
+	while ( 1 ) {
+		char *ptr;
+		int c;
+
+		c = getopt(ac, av, "s:v:r:k:i:o:");
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 's':
+			if (strlen(optarg) > MAX_SIGN_LEN + 1) {
+				fprintf(stderr, "%s: signature exceeds %d chars\n",
+					progname, MAX_SIGN_LEN);
+				exit(1);
+			}
+			strcpy(signature, optarg);
+			break;
+		case 'v':
+			if (strlen(optarg) > MAX_FW_VER_LEN + 1) {
+				fprintf(stderr, "%s: version exceeds %d chars\n",
+					progname, MAX_FW_VER_LEN);
+				exit(1);
+			}
+			strcpy(version, optarg);
+			break;
+		case 'r':
+			if (strlen(optarg) > MAX_REG_LEN + 1) {
+				fprintf(stderr, "%s: region exceeds %d chars\n",
+					progname, MAX_REG_LEN);
+				exit(1);
+			}
+			strcpy(region, optarg);
+			break;
+		case 'k':
+			kernel = strtoul(optarg, &ptr, 0);
+			if(ptr[0] == 'k'){
+				kernel *= 1000;
+			}
+			break;
+		case 'i':
+			if ((ifile = fopen(optarg, "r")) == NULL)
+				perrexit(1, optarg);
+			break;
+		case 'o':
+			if ((ofile = fopen(optarg, "w")) == NULL)
+				perrexit(1, optarg);
+			break;
+		default:
+			usage();
+		}
+	}
+
+	if (signature[0] == 0 || ifile == NULL || ofile == NULL) {
+		usage();
+		exit(1);
+	}
+
+	for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++)
+		cksum += c & 0xff;
+
+	if (fseek(ifile, 0, SEEK_SET) < 0)
+		perrexit(2, "fseek on input");
+
+	// Fill in the header
+	memset(&imghdr, 0, sizeof(imghdr));
+	imghdr.hdr_len = sizeof(imghdr);
+	imghdr.checksum = htonl(cksum);
+	imghdr.total_size = htonl(bcnt);
+	imghdr.kernel_size = htonl(kernel);
+
+	strncpy(imghdr.signature, signature, MAX_SIGN_LEN);
+	strncpy(imghdr.fw_ver, version, MAX_FW_VER_LEN);
+	strncpy(imghdr.fw_reg, region, MAX_REG_LEN);
+
+	if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0)
+		perrexit(2, "fwrite header on output");
+
+	while ((c = fgetc(ifile)) != EOF) {
+		if (fputc(c, ofile) == EOF)
+			perrexit(2, "fputc on output");
+	}
+
+	if (ferror(ifile))
+		perrexit(2, "fgetc on input");
+
+	fclose(ofile);
+	fclose(ifile);
+
+	fprintf(stderr, "imgHdr.hdr_len = %lu\n", sizeof(imghdr));
+	fprintf(stderr, "imgHdr.checksum = 0x%08x\n", cksum);
+	fprintf(stderr, "imgHdr.total_size = 0x%08x\n", bcnt);
+	fprintf(stderr, "imgHdr.kernel_size = 0x%08x\n", kernel);
+	fprintf(stderr, "imgHdr.header = %s\n", signature);
+	fprintf(stderr, "imgHdr.fw_ver = %s\n", version);
+	fprintf(stderr, "imgHdr.fw_reg = %s\n", region);
+
+	return 0;
+}



More information about the lede-commits mailing list