[PATCH] firmware-utils: support checksum for AVM fritzbox wasp SOCs
kestrel1974 at t-online.de
kestrel1974 at t-online.de
Thu Jan 13 02:20:03 PST 2022
From: Daniel Kestrel <kestrel1974 at t-online.de>
This patch adds creating the checksum to be able to create an
image and boot the secondary ath79 based wireless assist (WASP)
SoC with a second instance of OpenWrt for some AVM Fritzbox
devices (3390, 3490, 5490, 7490).
The utility is called avm-wasp-checksum and was originally
created by Andreas Boehler.
Signed-off-by: Daniel Kestrel <kestrel1974 at t-online.de>
---
CMakeLists.txt | 1 +
src/avm-wasp-checksum.c | 141 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 142 insertions(+)
create mode 100644 src/avm-wasp-checksum.c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f406520..5f886ba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,6 +29,7 @@ ENDMACRO(FW_UTIL)
FW_UTIL(add_header "" "" "")
FW_UTIL(addpattern "" "" "")
FW_UTIL(asustrx "" "" "")
+FW_UTIL(avm-wasp-checksum "" --std=gnu99 "")
FW_UTIL(bcm4908asus "" "" "")
FW_UTIL(bcm4908kernel "" "" "")
FW_UTIL(buffalo-enc src/buffalo-lib.c "" "")
diff --git a/src/avm-wasp-checksum.c b/src/avm-wasp-checksum.c
new file mode 100644
index 0000000..cbf6a19
--- /dev/null
+++ b/src/avm-wasp-checksum.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Andreas Boehler <dev at aboehler.at>
+ *
+ * This tool was based on:
+ * firmware-crc.pl by Atheros Communications
+ *
+ * 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h> /* for getopt() */
+#include <byteswap.h>
+
+char *infile;
+char *outfile;
+char *progname;
+enum {
+ MODEL_3390,
+ MODEL_X490
+} model;
+
+#define CHUNK_SIZE 256
+
+uint32_t crc32_for_byte(uint32_t r)
+{
+ for (int j = 0; j < 8; ++j)
+ r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1;
+ return r ^ (uint32_t)0xFF000000L;
+}
+
+void crc32(const void *data, size_t n_bytes, uint32_t *crc)
+{
+ static uint32_t table[0x100];
+
+ if (!*table)
+ for (size_t i = 0; i < 0x100; ++i)
+ table[i] = crc32_for_byte(i);
+ for (size_t i = 0; i < n_bytes; ++i)
+ *crc = table[(uint8_t)*crc ^ ((uint8_t *)data)[i]] ^ *crc >> 8;
+}
+
+static void usage(int status)
+{
+ fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname);
+ fprintf(stderr,
+ "\n"
+ "Options:\n"
+ " -i input file name\n"
+ " -o output file name\n"
+ " -m model (3390, x490 for 3490/5490/7490)\n"
+ " -h show this screen\n"
+ );
+
+ exit(status);
+}
+
+int main(int argc, char *argv[])
+{
+ uint32_t crc = 0;
+ FILE *in_fp;
+ FILE *out_fp;
+ uint32_t buf[CHUNK_SIZE];
+ ssize_t read;
+
+ progname = argv[0];
+
+ while (1) {
+ int c;
+
+ c = getopt(argc, argv, "i:o:m:h");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'i':
+ infile = optarg;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case 'm':
+ if (strcmp(optarg, "3390") == 0)
+ model = MODEL_3390;
+ else if (strcmp(optarg, "x490") == 0)
+ model = MODEL_X490;
+ else
+ usage(EXIT_FAILURE);
+ break;
+ case 'h':
+ usage(EXIT_SUCCESS);
+ default:
+ usage(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ if (!infile || !outfile)
+ usage(EXIT_FAILURE);
+
+ in_fp = fopen(infile, "r");
+ if (!in_fp) {
+ fprintf(stderr, "Error opening input file: %s\n", infile);
+ return EXIT_FAILURE;
+ }
+ out_fp = fopen(outfile, "w");
+ if (!out_fp) {
+ fprintf(stderr, "Error opening output file: %s\n", outfile);
+ fclose(in_fp);
+ return EXIT_FAILURE;
+ }
+
+ while (!feof(in_fp)) {
+ switch (model) {
+ case MODEL_3390:
+ read = fread(buf, sizeof(uint32_t), CHUNK_SIZE, in_fp);
+ for (int i = 0; i < read; i++)
+ crc = crc ^ buf[i];
+ fwrite(buf, sizeof(uint32_t), read, out_fp);
+ break;
+ case MODEL_X490:
+ read = fread(buf, 1, sizeof(uint32_t) * CHUNK_SIZE, in_fp);
+ crc32(buf, read, &crc);
+ fwrite(buf, 1, read, out_fp);
+ break;
+ }
+ }
+ if (model == MODEL_X490)
+ crc = __bswap_32(crc);
+ fwrite(&crc, sizeof(uint32_t), 1, out_fp);
+ fclose(in_fp);
+ fclose(out_fp);
+ printf("Done.\n");
+ return EXIT_SUCCESS;
+}
--
2.17.1
More information about the openwrt-devel
mailing list