From: Daniel Kestrel <kestrel1...@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 <kestrel1...@t-online.de> --- CMakeLists.txt | 1 + src/avm-wasp-checksum.c | 171 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 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..8c112f3 --- /dev/null +++ b/src/avm-wasp-checksum.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Andreas Boehler <d...@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]; + size_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); + if (ferror(in_fp)) { + fprintf(stderr, "Error reading input file: %s\n", infile); + fclose(in_fp); + fclose(out_fp); + return EXIT_FAILURE; + } + for (int i = 0; i < read; i++) + crc = crc ^ buf[i]; + fwrite(buf, sizeof(uint32_t), read, out_fp); + if (ferror(out_fp)) { + fprintf(stderr, "Error writing output file: %s\n", outfile); + fclose(in_fp); + fclose(out_fp); + return EXIT_FAILURE; + } + break; + case MODEL_X490: + read = fread(buf, 1, sizeof(uint32_t) * CHUNK_SIZE, in_fp); + if (ferror(in_fp)) { + fprintf(stderr, "Error reading input file: %s\n", infile); + fclose(in_fp); + fclose(out_fp); + return EXIT_FAILURE; + } + crc32(buf, read, &crc); + fwrite(buf, 1, read, out_fp); + if (ferror(out_fp)) { + fprintf(stderr, "Error writing output file: %s\n", outfile); + fclose(in_fp); + fclose(out_fp); + return EXIT_FAILURE; + } + break; + } + } + if (model == MODEL_X490) + crc = __bswap_32(crc); + fwrite(&crc, sizeof(uint32_t), 1, out_fp); + if (ferror(out_fp)) { + fprintf(stderr, "Error writing checksum to output file: %s\n", outfile); + fclose(in_fp); + fclose(out_fp); + return EXIT_FAILURE; + } + fclose(in_fp); + fclose(out_fp); + printf("Done.\n"); + return EXIT_SUCCESS; +} -- 2.17.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel