diff options
author | Petr Štetiar <ynezz@true.cz> | 2021-07-05 11:54:26 +0200 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2021-10-05 16:20:10 +0200 |
commit | 8cc9a74a3f6bf363645efda6db417f8dadd3d844 (patch) | |
tree | 68f1648a077df8e49328f087eccaf94c2e47d1e8 | |
parent | f82c93b93c0a021921ac7a30ba6e7a090c7ddd1c (diff) | |
download | upstream-8cc9a74a3f6bf363645efda6db417f8dadd3d844.tar.gz upstream-8cc9a74a3f6bf363645efda6db417f8dadd3d844.tar.bz2 upstream-8cc9a74a3f6bf363645efda6db417f8dadd3d844.zip |
firmware-utils: update to version 2021-10-05
Includes following changes:
db65821f006c cmake: fix missing install target
3a0cfc856991 Add initial GitLab CI support
8f47adea6f87 Add missing includes for byte swap operations
fbafae9f8037 Convert to CMake based project
Additionaly moves source code into separate Git project repository and
converts the package build to utilize CMake.
Signed-off-by: Petr Štetiar <ynezz@true.cz>
[rmilecki: rebase, update to the latest repo git & rm -r src]
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
104 files changed, 9 insertions, 37775 deletions
diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index d5b0816816..79b44cc870 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -6,105 +6,16 @@ # include $(TOPDIR)/rules.mk -PKG_NAME := firmware-utils -PKG_RELEASE := 11 +PKG_NAME:=firmware-utils +PKG_RELEASE:=12 -include $(INCLUDE_DIR)/host-build.mk -include $(INCLUDE_DIR)/kernel.mk - -define cc - $(HOSTCC) \ - $(HOST_CFLAGS) \ - -Wno-unused-parameter \ - -include endian.h $(HOST_LDFLAGS) \ - -o $(HOST_BUILD_DIR)/bin/$(firstword $(1)) \ - $(foreach src,$(1),src/$(src).c) \ - $(2) -endef +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=$(PROJECT_GIT)/project/firmware-utils.git +PKG_SOURCE_DATE:=2021-10-05 +PKG_SOURCE_VERSION:=2f70fedc92bd08f9e182fcc388688f36310a597d +PKG_MIRROR_HASH:=c2e63b1f1ef1ef2f8f2d1adb5d030112881500fdadaf82c113b6dabe00cdd06b -define Host/Compile - mkdir -p $(HOST_BUILD_DIR)/bin - $(call cc,add_header,-Wall) - $(call cc,addpattern,-Wall) - $(call cc,asustrx,-Wall) - $(call cc,bcm4908asus,-Wall) - $(call cc,bcm4908kernel,-Wall) - $(call cc,buffalo-enc buffalo-lib,-Wall) - $(call cc,buffalo-tag buffalo-lib,-Wall) - $(call cc,buffalo-tftp buffalo-lib,-Wall) - $(call cc,dgfirmware,-Wall) - $(call cc,dgn3500sum,-Wall) - $(call cc,dns313-header,-Wall) - $(call cc,edimax_fw_header,-Wall) - $(call cc,encode_crc,-Wall) - $(call cc,fix-u-media-header cyg_crc32,-Wall) - $(call cc,hcsmakeimage bcmalgo,-Wall) - $(call cc,imagetag imagetag_cmdline cyg_crc32,-Wall) - $(call cc,jcgimage,-lz -Wall) - $(call cc,lxlfw,-Wall) - $(call cc,lzma2eva,-lz -Wall) - $(call cc,makeamitbin,-Wall) - $(call cc,mkbrncmdline,-Wall) - $(call cc,mkbrnimg,-Wall) - $(call cc,mkbuffaloimg,-Wall) - $(call cc,mkcameofw,-Wall) - $(call cc,mkcasfw,-Wall) - $(call cc,mkchkimg,-Wall) - $(call cc,mkcsysimg,-Wall) - $(call cc,mkdapimg,-Wall) - $(call cc,mkdapimg2,-Wall) - $(call cc,mkdhpimg buffalo-lib,-Wall) - $(call cc,mkdlinkfw mkdlinkfw-lib,-lz -Wall --std=c99) - $(call cc,mkdniimg,-Wall) - $(call cc,mkedimaximg,-Wall) - $(call cc,mkfwimage,-lz -Wall -Werror -Wextra -D_FILE_OFFSET_BITS=64) - $(call cc,mkfwimage2,-lz -Wall) - $(call cc,mkheader_gemtek,-lz -Wall) - $(call cc,mkhilinkfw,-lcrypto -Wall) - $(call cc,mkmerakifw sha1,-Wall) - $(call cc,mkmerakifw-old,-Wall) - $(call cc,mkmylofw,-Wall) - $(call cc,mkplanexfw sha1,-Wall) - $(call cc,mkporayfw,-Wall) - $(call cc,mkrasimage,--std=gnu99 -Wall) - $(call cc,mkrtn56uimg,-lz -Wall) - $(call cc,mksenaofw md5,-Wall --std=gnu99) - $(call cc,mksercommfw,-Wall) - $(call cc,mktitanimg,-Wall) - $(call cc,mktplinkfw mktplinkfw-lib md5,-Wall -fgnu89-inline) - $(call cc,mktplinkfw2 mktplinkfw-lib md5,-Wall -fgnu89-inline) - $(call cc,mkwrggimg md5,-Wall) - $(call cc,mkwrgimg md5,-Wall) - $(call cc,mkzcfw cyg_crc32,-Wall) - $(call cc,mkzynfw,-Wall) - $(call cc,mkzyxelzldfw md5,-Wall) - $(call cc,motorola-bin,-Wall) - $(call cc,nand_ecc,-Wall) - $(call cc,nec-enc,-Wall --std=gnu99) - $(call cc,osbridge-crc,-Wall) - $(call cc,oseama md5,-Wall) - $(call cc,otrx,-Wall) - $(call cc,pc1crypt) - $(call cc,ptgen cyg_crc32,-Wall) - $(call cc,seama md5,-Wall) - $(call cc,sign_dlink_ru md5,-Wall) - $(call cc,spw303v,-Wall) - $(call cc,srec2bin) - $(call cc,tplink-safeloader md5,-Wall --std=gnu99) - $(call cc,trx,-Wall) - $(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) - $(call cc,zytrx,-Wall) - $(call cc,zyxbcm,-Wall) -endef - -define Host/Install - $(INSTALL_BIN) $(HOST_BUILD_DIR)/bin/* $(STAGING_DIR_HOST)/bin/ -endef +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/cmake.mk $(eval $(call HostBuild)) diff --git a/tools/firmware-utils/src/add_header.c b/tools/firmware-utils/src/add_header.c deleted file mode 100644 index a5ad5f4119..0000000000 --- a/tools/firmware-utils/src/add_header.c +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * add_header.c - partially based on OpenWrt's motorola-bin.c - * - * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> - * Gabor Juhos <juhosg@openwrt.org> - */ - -/* - * The add_header utility used by various vendors preprends the buf - * image with a header containing a CRC32 value which is generated for the - * model id + reserved space for CRC32 + buf, then replaces the reserved - * area with the actual CRC32. This replacement tool mimics this behavior. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <netinet/in.h> -#include <inttypes.h> - -#define BPB 8 /* bits/byte */ - -static uint32_t crc32[1<<BPB]; - -static void init_crc32() -{ - const uint32_t poly = ntohl(0x2083b8ed); - int n; - - for (n = 0; n < 1<<BPB; n++) { - uint32_t crc = n; - int bit; - - for (bit = 0; bit < BPB; bit++) - crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); - crc32[n] = crc; - } -} - -static uint32_t crc32buf(unsigned char *buf, size_t len) -{ - uint32_t crc = 0xFFFFFFFF; - - for (; len; len--, buf++) - crc = crc32[(uint8_t)crc ^ *buf] ^ (crc >> BPB); - return ~crc; -} - -struct header { - char model[16]; - uint32_t crc; -}; - -static void usage(const char *) __attribute__ (( __noreturn__ )); - -static void usage(const char *mess) -{ - fprintf(stderr, "Error: %s\n", mess); - fprintf(stderr, "Usage: add_header model_id input_file output_file\n"); - fprintf(stderr, "\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - off_t len; // of original buf - off_t buflen; // of the output file - int fd; - void *input_file; // pointer to the input file (mmmapped) - struct header header; - unsigned char *buf; // pointer to prefix + copy of original buf - - // verify parameters - - if (argc != 4) - usage("wrong number of arguments"); - - // mmap input_file - if ((fd = open(argv[2], O_RDONLY)) < 0 - || (len = lseek(fd, 0, SEEK_END)) < 0 - || (input_file = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1) - || close(fd) < 0) - { - fprintf(stderr, "Error loading file %s: %s\n", argv[2], strerror(errno)); - exit(1); - } - - buflen = len + sizeof(header); - - init_crc32(); - - // copy model name into header - strncpy(header.model, argv[1], sizeof(header.model)); - header.crc = 0; - - // create a firmware image in memory and copy the input_file to it - buf = malloc(buflen); - memcpy(buf, &header, sizeof(header)); - memcpy(&buf[sizeof(header)], input_file, len); - - // CRC of temporary header + buf - header.crc = htonl(crc32buf(buf, buflen)); - - memcpy(buf, &header, sizeof(header)); - - // write the buf - if ((fd = open(argv[3], O_CREAT|O_WRONLY|O_TRUNC,0644)) < 0 - || write(fd, buf, buflen) != buflen - || close(fd) < 0) - { - fprintf(stderr, "Error storing file %s: %s\n", argv[3], strerror(errno)); - exit(2); - } - - free(buf); - - munmap(input_file,len); - - return 0; -} diff --git a/tools/firmware-utils/src/addpattern.c b/tools/firmware-utils/src/addpattern.c deleted file mode 100644 index 74286fd563..0000000000 --- a/tools/firmware-utils/src/addpattern.c +++ /dev/null @@ -1,345 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org> - */ - -/* July 29, 2004 - * - * This is a hacked replacement for the 'addpattern' utility used to - * create wrt54g .bin firmware files. It isn't pretty, but it does - * the job for me. - * - * Extensions: - * -v allows setting the version string on the command line. - * -{0|1} sets the (currently ignored) hw_ver flag in the header - * to 0 or 1 respectively. - */ - -/* January 12, 2005 - * - * Modified by rodent at rodent dot za dot net - * Support added for the new WRT54G v2.2 and WRT54GS v1.1 "flags" - * Without the flags set to 0x7, the above units will refuse to flash. - * - * Extensions: - * -{0|1|2} sets {0|1} sets hw_ver flag to 0/1. {2} sets hw_ver to 1 - * and adds the new hardware "flags" for the v2.2/v1.1 units -*/ - -/* January 1, 2007 - * - * Modified by juan.i.gonzalez at subdown dot net - * Support added for the AG241v2 and similar - * - * Extensions: - * -r #.# adds revision hardware flags. AG241v2 and similar. - * - * AG241V2 firmware sets the hw_ver to 0x44. - * - * Example: -r 2.0 - * - * Convert 2.0 to 20 to be an integer, and add 0x30 to skip special ASCII - * #define HW_Version ((HW_REV * 10) + 0x30) -> from cyutils.h -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <unistd.h> -#include <sys/stat.h> - -/**********************************************************************/ - -#define CODE_ID "U2ND" /* from code_pattern.h */ -#define CODE_PATTERN "W54S" /* from code_pattern.h */ -#define PBOT_PATTERN "PBOT" - -#define CYBERTAN_VERSION "v3.37.2" /* from cyutils.h */ - -/* WRT54G v2.2 and WRT54GS v1.1 "flags" (from 3.37.32 firmware cyutils.h) */ -#define SUPPORT_4712_CHIP 0x0001 -#define SUPPORT_INTEL_FLASH 0x0002 -#define SUPPORT_5325E_SWITCH 0x0004 -/* (from 3.00.24 firmware cyutils.h) */ -#define SUPPORT_4704_CHIP 0x0008 -#define SUPPORT_5352E_CHIP 0x0010 -/* (from WD My Net Wi-Fi Range Extender's cyutils.s) */ -#define SUPPORT_4703_CHIP 0x0020 - -struct code_header { /* from cyutils.h */ - char magic[8]; - char fwdate[3]; - char fwvern[3]; - char id[4]; /* U2ND */ - char hw_ver; /* 0: for 4702, 1: for 4712 -- new in 2.04.3 */ - - unsigned char sn; // Serial Number - unsigned char flags[2]; /* SUPPORT_ flags new for 3.37.2 (WRT54G v2.2 and WRT54GS v1.1) */ - unsigned char stable[2]; // The image is stable (for dual image) - unsigned char try1[2]; // Try to boot image first time (for dual image) - unsigned char try2[2]; // Try to boot image second time (for dual image) - unsigned char try3[2]; // Try to boot image third time (for dual_image) - unsigned char res3[2]; -} ; - -struct board_info { - char *id; - char *pattern; - char hw_ver; - char sn; - char flags[2]; -}; - -struct board_info boards[] = { - { - .id = "E2100L", - .pattern = "NL1X", - .hw_ver = 0x00, - .sn = 0x0f, - .flags = {0x3f, 0x00}, - }, - { - .id = "WRT160NL", - .pattern = "NL16", - .hw_ver = 0x00, - .sn = 0x0f, - .flags = {0x3f, 0x00}, - }, - { - .id = "mynet-rext", - .pattern = "WDHNSTFH", - .hw_ver = 0x00, - .sn = 0x00, - .flags = {0x3f, 0x00}, - }, { - /* Terminating entry */ - .id = NULL, - } -}; - -/**********************************************************************/ - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: addpattern [-i trxfile] [-o binfile] [-B board_id] [-p pattern] [-s serial] [-g] [-b] [-v v#.#.#] [-r #.#] [-{0|1|2|4|5}] -h\n"); - exit(EXIT_FAILURE); -} - -static time_t source_date_epoch = -1; -static void set_source_date_epoch() { - char *env = getenv("SOURCE_DATE_EPOCH"); - char *endptr = env; - errno = 0; - if (env && *env) { - source_date_epoch = strtoull(env, &endptr, 10); - if (errno || (endptr && *endptr != '\0')) { - fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); - exit(1); - } - } -} - -struct board_info *find_board(char *id) -{ - struct board_info *board; - - for (board = boards; board->id != NULL; board++) - if (strcasecmp(id, board->id) == 0) - return board; - - return NULL; -} - -int main(int argc, char **argv) -{ - char buf[1024]; /* keep this at 1k or adjust garbage calc below */ - struct code_header *hdr; - FILE *in = stdin; - FILE *out = stdout; - char *ifn = NULL; - char *ofn = NULL; - char *pattern = CODE_PATTERN; - char *pbotpat = PBOT_PATTERN; - char *version = CYBERTAN_VERSION; - char *board_id = NULL; - struct board_info *board = NULL; - int gflag = 0; - int pbotflag = 0; - int c; - int v0, v1, v2; - size_t off, n; - time_t t; - struct tm *ptm; - - fprintf(stderr, "mjn3's addpattern replacement - v0.81\n"); - - hdr = (struct code_header *) buf; - memset(hdr, 0, sizeof(struct code_header)); - - while ((c = getopt(argc, argv, "i:o:p:s:gbv:01245hr:B:")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'p': - pattern = optarg; - break; - case 's': - hdr->sn = (unsigned char) atoi (optarg); - break; - case 'g': - gflag = 1; - break; - case 'b': - pbotflag = 1; - break; - case 'v': /* extension to allow setting version */ - version = optarg; - break; - case '0': - hdr->hw_ver = 0; - break; - case '1': - hdr->hw_ver = 1; - break; - case '2': /* new 54G v2.2 and 54GS v1.1 flags */ - hdr->hw_ver = 1; - hdr->flags[0] |= SUPPORT_4712_CHIP; - hdr->flags[0] |= SUPPORT_INTEL_FLASH; - hdr->flags[0] |= SUPPORT_5325E_SWITCH; - break; - case '4': - /* V4 firmware sets the flags to 0x1f */ - hdr->hw_ver = 0; - hdr->flags[0] = 0x1f; - break; - case '5': - /* V5 is appended to trxV2 image */ - hdr->stable[0] = 0x73; // force image to be stable - hdr->stable[1] = 0x00; - hdr->try1[0] = 0x74; // force try1 to be set - hdr->try1[1] = 0x00; - hdr->try2[0] = hdr->try2[1] = 0xFF; - hdr->try3[0] = hdr->try3[1] = 0xFF; - break; - case 'r': - hdr->hw_ver = (char)(atof(optarg)*10)+0x30; - break; - case 'B': - board_id = optarg; - break; - - case 'h': - default: - usage(); - } - } - - if (optind != argc || optind == 1) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - if (board_id) { - board = find_board(board_id); - if (board == NULL) { - fprintf(stderr, "unknown board \"%s\"\n", board_id); - usage(); - } - pattern = board->pattern; - hdr->hw_ver = board->hw_ver; - hdr->sn = board->sn; - hdr->flags[0] = board->flags[0]; - hdr->flags[1] = board->flags[1]; - } - - if (strlen(pattern) > 8) { - fprintf(stderr, "illegal pattern \"%s\"\n", pattern); - usage(); - } - - if (ifn && !(in = fopen(ifn, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", ifn); - usage(); - } - - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - set_source_date_epoch(); - if (source_date_epoch != -1) { - t = source_date_epoch; - } else if ((time(&t) == (time_t)(-1))) { - fprintf(stderr, "time call failed\n"); - return EXIT_FAILURE; - } - - ptm = gmtime(&t); - - if (3 != sscanf(version, "v%d.%d.%d", &v0, &v1, &v2)) { - fprintf(stderr, "bad version string \"%s\"\n", version); - return EXIT_FAILURE; - } - - memcpy(hdr->magic, pattern, strlen(pattern)); - if (pbotflag) - memcpy(&hdr->magic[4], pbotpat, 4); - hdr->fwdate[0] = ptm->tm_year % 100; - hdr->fwdate[1] = ptm->tm_mon + 1; - hdr->fwdate[2] = ptm->tm_mday; - hdr->fwvern[0] = v0; - hdr->fwvern[1] = v1; - hdr->fwvern[2] = v2; - memcpy(hdr->id, CODE_ID, strlen(CODE_ID)); - - off = sizeof(struct code_header); - - fprintf(stderr, "writing firmware v%d.%d.%d on %d/%d/%d (y/m/d)\n", - v0, v1, v2, - hdr->fwdate[0], hdr->fwdate[1], hdr->fwdate[2]); - - - while ((n = fread(buf + off, 1, sizeof(buf)-off, in) + off) > 0) { - off = 0; - if (n < sizeof(buf)) { - if (ferror(in)) { - FREAD_ERROR: - fprintf(stderr, "fread error\n"); - return EXIT_FAILURE; - } - if (gflag) { - gflag = sizeof(buf) - n; - memset(buf + n, 0xff, gflag); - fprintf(stderr, "adding %d bytes of garbage\n", gflag); - n = sizeof(buf); - } - } - if (!fwrite(buf, n, 1, out)) { - FWRITE_ERROR: - fprintf(stderr, "fwrite error\n"); - return EXIT_FAILURE; - } - } - - if (ferror(in)) { - goto FREAD_ERROR; - } - - if (fflush(out)) { - goto FWRITE_ERROR; - } - - fclose(in); - fclose(out); - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/asustrx.c b/tools/firmware-utils/src/asustrx.c deleted file mode 100644 index ce721687d8..0000000000 --- a/tools/firmware-utils/src/asustrx.c +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * asustrx - * - * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com> - */ - -#include <byteswap.h> -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le32(x) bswap_32(x) -#define le32_to_cpu(x) bswap_32(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le32(x) (x) -#define le32_to_cpu(x) (x) -#else -#error "Unsupported endianness" -#endif - -#define TRX_MAGIC 0x30524448 -#define TRX_FLAGS_OFFSET 12 - -struct trx_header { - uint32_t magic; - uint32_t length; - uint32_t crc32; - uint16_t flags; - uint16_t version; - uint32_t offset[3]; -}; - -struct asustrx_tail { - uint8_t version[4]; - char productid[12]; - uint8_t unused[48]; -}; - -char *in_path = NULL; -char *out_path = NULL; -char *productid = NULL; -uint8_t version[4] = { }; - -static const uint32_t crc32_tbl[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - -static void parse_options(int argc, char **argv) { - int c; - - while ((c = getopt(argc, argv, "i:o:p:v:")) != -1) { - switch (c) { - case 'i': - in_path = optarg; - break; - case 'o': - out_path = optarg; - break; - case 'p': - productid = optarg; - break; - case 'v': - if (sscanf(optarg, "%hhu.%hhu.%hhu.%hhu", &version[0], &version[1], &version[2], &version[3]) != 4) - fprintf(stderr, "Version %s doesn't match suppored 4-digits format\n", optarg); - break; - } - } -} - -static void usage() { - printf("Usage:\n"); - printf("\t-i file\t\t\t\tinput TRX file\n"); - printf("\t-o file\t\t\t\toutput Asus TRX file\n"); - printf("\t-p productid\t\t\tproduct (device) ID\n"); - printf("\t-v version\t\t\tfirmware version formatted with 4 digits like: 1.2.3.4\n"); -} - -int main(int argc, char **argv) { - struct trx_header hdr; - struct asustrx_tail tail = { }; - FILE *out = NULL; - FILE *in = NULL; - uint8_t buf[1024]; - size_t bytes; - size_t length = 0; - uint32_t crc32 = 0xffffffff; - int i; - int err = 0; - - /* Parse & validate arguments */ - parse_options(argc, argv); - if (!in_path || !out_path || !productid) { - usage(); - err = -EINVAL; - goto err; - } - - /* Fill Asus tail */ - tail.version[0] = version[0]; - tail.version[1] = version[1]; - tail.version[2] = version[2]; - tail.version[3] = version[3]; - strncpy(tail.productid, productid, sizeof(tail.productid)); - - /* Open files */ - in = fopen(in_path, "r"); - if (!in) { - fprintf(stderr, "Couldn't open %s\n", in_path); - err = -EIO; - goto err; - } - out = fopen(out_path, "w+"); - if (!out) { - fprintf(stderr, "Couldn't open %s\n", out_path); - err = -EIO; - goto err; - } - - /* Check is there is empty place for Asus tail */ - bytes = sizeof(struct asustrx_tail); - fseek(in, -bytes, SEEK_END); - if (fread(buf, 1, bytes, in) != bytes) { - fprintf(stderr, "Couldn't read %zu B from %s\n", bytes, in_path); - err = -EIO; - goto err; - } - for (i = 0; i < bytes; i++) { - if (buf[i]) { - fprintf(stderr, "Input TRX doesn't have last 64 B empty %s\n", out_path); - err = -ENOSPC; - goto err; - } - } - - /* Copy whole TRX */ - rewind(in); - while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { - if (fwrite(buf, 1, bytes, out) != bytes) { - fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); - err = -EIO; - goto err; - } - } - - /* Overwrite last 64 B with Asus tail */ - bytes = sizeof(tail); - fseek(out, -bytes, SEEK_CUR); - if (fwrite(&tail, 1, bytes, out) != bytes) { - fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); - err = -EIO; - goto err; - } - - /* Calculate crc32 */ - fseek(out, TRX_FLAGS_OFFSET, SEEK_SET); - length = TRX_FLAGS_OFFSET; - while ((bytes = fread(buf, 1, sizeof(buf), out )) > 0) { - length += bytes; - for (i = 0; i < bytes; i++) - crc32 = crc32_tbl[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8); - } - - /* Update header */ - bytes = sizeof(hdr); - rewind(out); - if (fread(&hdr, 1, sizeof(hdr), out) != bytes) { - fprintf(stderr, "Couldn't read %zu B from %s\n", bytes, in_path); - err = -EIO; - goto err; - } - hdr.crc32 = cpu_to_le32(crc32); - rewind(out); - if (fwrite(&hdr, 1, bytes, out) != bytes) { - fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); - err = -EIO; - goto err; - } - -err: - if (out) - fclose(out); - if (in) - fclose(in); - return err; -} diff --git a/tools/firmware-utils/src/bcm4908asus.c b/tools/firmware-utils/src/bcm4908asus.c deleted file mode 100644 index 837c02c33a..0000000000 --- a/tools/firmware-utils/src/bcm4908asus.c +++ /dev/null @@ -1,444 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl> - */ - -#include <byteswap.h> -#include <errno.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le32(x) bswap_32(x) -#define le32_to_cpu(x) bswap_32(x) -#define cpu_to_le16(x) bswap_16(x) -#define le16_to_cpu(x) bswap_16(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le32(x) (x) -#define le32_to_cpu(x) (x) -#define cpu_to_le16(x) (x) -#define le16_to_cpu(x) (x) -#else -#error "Unsupported endianness" -#endif - -/* BCM4908 specific tail - appended to the firmware image */ -struct bcm4908img_tail { - uint32_t crc32; - uint32_t unk1; - uint32_t family; - uint32_t unk2; - uint32_t unk3; -}; - -/* Asus BCM4908 tail - placed at the end of BCM4908 firmware, right before BCM4908 tail */ -struct bcm4908asus_tail { - uint8_t fw_ver[4]; - uint16_t build_no; - uint16_t extend_no_u16; - char productid[12]; /* The longest seen was 9 (e.g. GT-AC5300) */ - uint8_t unused1[8]; - uint32_t extend_no_u32; - uint8_t unused2[31]; - uint8_t ver_flags; /* Version or flags (only seen values: 0x00 and 0x01) */ -}; - -/* - * Example: - * - * 0053ffb0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| - * 0053ffc0 03 00 00 04 80 01 94 52 47 54 2d 41 43 35 33 30 |.......RGT-AC530| - * 0053ffd0 30 00 00 00 00 00 00 00 00 00 00 00 94 52 00 00 |0............R..| - * 0053ffe0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| - * 0053fff0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 |................| - * 00540000 c4 20 e6 72 32 57 00 00 08 49 00 00 03 00 00 00 |. .r2W...I......| - * 00540010 02 00 00 00 |....| - */ - -char *in_path = NULL; -char *out_path = NULL; - -static inline size_t bcm4908asus_min(size_t x, size_t y) { - return x < y ? x : y; -} - -static const uint32_t crc32_tbl[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - -uint32_t bcm4908img_crc32(uint32_t crc, uint8_t *buf, size_t len) { - while (len) { - crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8); - buf++; - len--; - } - - return crc; -} - -/************************************************** - * Info - **************************************************/ - -static int bcm4908asus_info(int argc, char **argv) -{ - struct bcm4908asus_tail asus_tail; - struct bcm4908img_tail img_tail; - struct stat st; - const char *pathname; - size_t bytes, length; - uint8_t buf[1024]; - uint32_t crc32; - bool empty; - FILE *fp; - int i; - int err = 0; - - if (argc < 3) { - fprintf(stderr, "No BCM4908 Asus image pathname passed\n"); - err = -EINVAL; - goto out; - } - pathname = argv[2]; - - if (stat(pathname, &st)) { - fprintf(stderr, "Failed to stat %s\n", pathname); - err = -EIO; - goto out; - } - - fp = fopen(pathname, "r"); - if (!fp) { - fprintf(stderr, "Failed to open %s\n", pathname); - err = -EACCES; - goto out; - } - - crc32 = 0xffffffff; - length = st.st_size - sizeof(asus_tail) - sizeof(img_tail); - while (length && (bytes = fread(buf, 1, bcm4908asus_min(sizeof(buf), length), fp)) > 0) { - crc32 = bcm4908img_crc32(crc32, buf, bytes); - length -= bytes; - } - - if (length) { - fprintf(stderr, "Failed to read from %s\n", pathname); - err = -EIO; - goto err_close; - } - - if (fread(&asus_tail, 1, sizeof(asus_tail), fp) != sizeof(asus_tail)) { - fprintf(stderr, "Failed to read BCM4908 Asus image tail\n"); - err = -EIO; - goto err_close; - } - crc32 = bcm4908img_crc32(crc32, (uint8_t *)&asus_tail, sizeof(asus_tail)); - - if (fread(&img_tail, 1, sizeof(img_tail), fp) != sizeof(img_tail)) { - fprintf(stderr, "Failed to read BCM4908 Asus image tail\n"); - err = -EIO; - goto err_close; - } - - if (crc32 != le32_to_cpu(img_tail.crc32)) { - fprintf(stderr, "Invalid crc32 (calculated 0x%08x expected 0x%08x)\n", crc32, le32_to_cpu(img_tail.crc32)); - err = -EINVAL; - goto err_close; - } - - empty = true; - for (i = 0; i < sizeof(asus_tail); i++) { - if (((uint8_t *)&asus_tail)[i] != 0xff) { - empty = false; - break; - } - } - if (empty) { - fprintf(stderr, "BCM4908 image doesn't contain Asus tail\n"); - err = -EINVAL; - goto err_close; - } - - printf("Firmware version:\t%u.%u.%u.%u\n", asus_tail.fw_ver[0], asus_tail.fw_ver[1], asus_tail.fw_ver[2], asus_tail.fw_ver[3]); - printf("Build number:\t\t%u\n", le16_to_cpu(asus_tail.build_no)); - printf("Extended number:\t%u\n", asus_tail.ver_flags & 0x1 ? le32_to_cpu(asus_tail.extend_no_u32) : le16_to_cpu(asus_tail.extend_no_u16)); - printf("Product ID:\t\t%s\n", asus_tail.productid); - -err_close: - fclose(fp); -out: - return err; -} - -/************************************************** - * Create - **************************************************/ - -static void bcm4908asus_create_parse_options(int argc, char **argv, struct bcm4908asus_tail *tail) -{ - uint32_t tmp32; - uint16_t tmp16; - int c; - - while ((c = getopt(argc, argv, "i:o:p:f:b:e:")) != -1) { - switch (c) { - case 'i': - in_path = optarg; - break; - case 'o': - out_path = optarg; - break; - case 'p': - strncpy(tail->productid, optarg, sizeof(tail->productid)); - break; - case 'f': - if (sscanf(optarg, "%hhu.%hhu.%hhu.%hhu", &(tail->fw_ver[0]), &tail->fw_ver[1], &tail->fw_ver[2], &tail->fw_ver[3]) != 4) - fprintf(stderr, "Version %s doesn't match suppored 4-digits format\n", optarg); - break; - case 'b': - tmp16 = strtol(optarg, NULL, 0); - tail->build_no = cpu_to_le16(tmp16); - break; - case 'e': - tmp32 = strtol(optarg, NULL, 0); - tail->ver_flags = 0x01; - tail->extend_no_u32 = cpu_to_le32(tmp32); - tail->extend_no_u16 = cpu_to_le16((uint16_t)tmp32); - break; - } - } -} - -static int bcm4908asus_create(int argc, char **argv) -{ - struct bcm4908asus_tail asus_tail = {}; - struct bcm4908img_tail img_tail = {}; - struct stat st; - uint32_t crc32_old; - uint32_t crc32_new; - uint8_t buf[1024]; - FILE *out = NULL; - FILE *in = NULL; - size_t length; - size_t bytes; - FILE *fp; - int i; - int err = 0; - - /* Parse & validate arguments */ - bcm4908asus_create_parse_options(argc, argv, &asus_tail); - if (!in_path) { - fprintf(stderr, "No BCM4908 Asus image pathname passed\n"); - err = -EINVAL; - goto err; - } - - /* Check input file: size, access, empty space for Asus tail */ - - if (stat(in_path, &st)) { - fprintf(stderr, "Failed to stat %s\n", in_path); - err = -EIO; - goto err; - } - - in = fopen(in_path, "r+"); - if (!in) { - fprintf(stderr, "Failed to open %s\n", in_path); - err = -EIO; - goto err; - } - - length = st.st_size - sizeof(asus_tail) - sizeof(img_tail); - fseek(in, length, SEEK_SET); - if (fread(buf, 1, sizeof(asus_tail), in) != sizeof(asus_tail)) { - fprintf(stderr, "Failed to read BCM4908 image from %s\n", in_path); - err = -EIO; - goto err; - } - for (i = 0; i < sizeof(asus_tail); i++) { - if (buf[i] != 0xff) { - fprintf(stderr, "Input BCM4908 image doesn't have empty 64 B tail\n"); - err = -ENOSPC; - goto err; - } - } - rewind(in); - - /* Create new BCM4908 Asus image file if requested (otherwise input file will get modified) */ - - if (out_path && !(out = fopen(out_path, "w+"))) { - fprintf(stderr, "Failed to open %s\n", out_path); - err = -EIO; - goto err; - } - - /* Calculate CRC for data that doesn't get modified. Optionally copy input file if requested */ - - crc32_old = 0xffffffff; - length = st.st_size - sizeof(asus_tail) - sizeof(img_tail); - while (length && (bytes = fread(buf, 1, bcm4908asus_min(sizeof(buf), length), in)) > 0) { - if (out && fwrite(buf, 1, bytes, out) != bytes) { - fprintf(stderr, "Failed to write %zu B to %s\n", bytes, out_path); - err = -EIO; - goto err; - } - crc32_old = bcm4908img_crc32(crc32_old, buf, bytes); - length -= bytes; - } - - if (length) { - fprintf(stderr, "Failed to read from %s\n", in_path); - err = -EIO; - goto err; - } - - crc32_new = crc32_old; - - /* Finish calculating old checksum & verify it */ - - for (i = 0; i < sizeof(asus_tail); i++) { - uint8_t val = 0xff; - - crc32_old = bcm4908img_crc32(crc32_old, &val, 1); - } - fseek(in, sizeof(asus_tail), SEEK_CUR); - - if (fread(&img_tail, 1, sizeof(img_tail), in) != sizeof(img_tail)) { - fprintf(stderr, "Failed to read BCM4908 image tail from %s\n", in_path); - err = -EIO; - goto err; - } - - if (crc32_old != le32_to_cpu(img_tail.crc32)) { - fprintf(stderr, "Invalid data crc32: calculated 0x%08x instead of 0x%08x\n", crc32_old, le32_to_cpu(img_tail.crc32)); - err = -EPROTO; - goto err; - } - - /* Write Asus tail & updated BCM4908 tail */ - - if (out) { - fp = out; - } else { - fp = in; - fseek(in, -sizeof(asus_tail) - sizeof(img_tail), SEEK_CUR); - } - - if (fwrite(&asus_tail, 1, sizeof(asus_tail), fp) != sizeof(asus_tail)) { - fprintf(stderr, "Failed to write BCM4908 image Asus tail to %s\n", out_path); - err = -EIO; - goto err; - } - - crc32_new = bcm4908img_crc32(crc32_new, (uint8_t *)&asus_tail, sizeof(asus_tail)); - img_tail.crc32 = cpu_to_le32(crc32_new); - if (fwrite(&img_tail, 1, sizeof(img_tail), fp) != sizeof(img_tail)) { - fprintf(stderr, "Failed to write BCM4908 image tail to %s\n", out_path); - err = -EIO; - goto err; - } - -err: - if (out) - fclose(out); - if (in) - fclose(in); - return err; -} - -static void usage() { - printf("Usage:\n"); - printf("\n"); - printf("Info about BCM4908 Asus image:\n"); - printf("\tbcm4908asus info <file>\tget info about BCM4908 Asus image\n"); - printf("\n"); - printf("Create a BCM4908 Asus image:\n"); - printf("\tbcm4908asus create\tinsert Asus info into BCM4908 image\n"); - printf("\t-i file\t\t\t\tinput BCM4908 image file (required)\n"); - printf("\t-o file\t\t\t\toutput BCM4908 Asus image file\n"); - printf("\t-p productid\t\t\tproduct (device) ID\n"); - printf("\t-f firmware version\t\tfirmware version formatted with 4 digits like: 1.2.3.4\n"); - printf("\t-b build number\t\tbuild number (e.g. 380, 382, 384)\n"); - printf("\t-e extend number\t\textended number (e.g. 21140, 81622, 81695, 82037)\n"); -} - -int main(int argc, char **argv) { - if (argc > 1) { - if (!strcmp(argv[1], "info")) - return bcm4908asus_info(argc, argv); - else if (!strcmp(argv[1], "create")) - return bcm4908asus_create(argc, argv); - } - - usage(); - - return 0; -} diff --git a/tools/firmware-utils/src/bcm4908kernel.c b/tools/firmware-utils/src/bcm4908kernel.c deleted file mode 100644 index eaf04a0a48..0000000000 --- a/tools/firmware-utils/src/bcm4908kernel.c +++ /dev/null @@ -1,127 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl> - */ - -#include <byteswap.h> -#include <endian.h> -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#if !defined(__BYTE_ORDER) -#error "Unknown byte order" -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le32(x) bswap_32(x) -#define le32_to_cpu(x) bswap_32(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le32(x) (x) -#define le32_to_cpu(x) (x) -#else -#error "Unsupported endianness" -#endif - -struct bcm4908kernel_header { - uint32_t boot_load_addr; /* AKA la_address */ - uint32_t boot_addr; /* AKA la_entrypt */ - uint32_t data_len; - uint8_t magic[4]; - uint32_t uncomplen; /* Empty for LZMA, used for LZ4 */ -}; - -static void usage() { - printf("Usage:\n"); - printf("\n"); - printf("\t-i pathname\t\t\tinput kernel filepath\n"); - printf("\t-o pathname\t\t\toutput kernel filepath\n"); -} - -int main(int argc, char **argv) { - struct bcm4908kernel_header header; - uint8_t buf[1024]; - FILE *out = NULL; - FILE *in = NULL; - size_t length; - size_t bytes; - int err = 0; - char c; - - if (argc >= 2 && !strcmp(argv[1], "-h")) { - usage(); - return 0; - } - - while ((c = getopt(argc, argv, "i:o:")) != -1) { - switch (c) { - case 'i': - in = fopen(optarg, "r"); - break; - case 'o': - out = fopen(optarg, "w+"); - break; - } - } - - if (!in || !out) { - fprintf(stderr, "Failed to open input and/or output file\n"); - usage(); - return -EINVAL; - } - - if (fread(&header, 1, sizeof(header), in) != sizeof(header)) { - fprintf(stderr, "Failed to read %zu bytes from input file\n", sizeof(header)); - err = -EIO; - goto err_close; - } - - if (!memcmp(header.magic, "BRCM", 4)) { - fprintf(stderr, "Input file already contains BCM4908 kernel header\n"); - err = -EIO; - goto err_close; - } - - err = fseek(out, sizeof(header), SEEK_SET); - if (err) { - err = -errno; - fprintf(stderr, "Failed to fseek(): %d\n", err); - goto err_close; - } - - length = 0; - rewind(in); - while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { - if (fwrite(buf, 1, bytes, out) != bytes) { - fprintf(stderr, "Failed to write %zu B to the output file\n", bytes); - err = -EIO; - goto err_close; - } - length += bytes; - } - - header.boot_load_addr = cpu_to_le32(0x00080000); - header.boot_addr = cpu_to_le32(0x00080000); - header.data_len = cpu_to_le32(length); - header.magic[0] = 'B'; - header.magic[1] = 'R'; - header.magic[2] = 'C'; - header.magic[3] = 'M'; - header.uncomplen = 0; - - fseek(out, 0, SEEK_SET); - - if (fwrite(&header, 1, sizeof(header), out) != sizeof(header)) { - fprintf(stderr, "Failed to write header to the output file\n"); - err = -EIO; - goto err_close; - } - -err_close: - fclose(out); - fclose(in); - return err; -} diff --git a/tools/firmware-utils/src/bcm_tag.h b/tools/firmware-utils/src/bcm_tag.h deleted file mode 100644 index a0d560884f..0000000000 --- a/tools/firmware-utils/src/bcm_tag.h +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#ifndef __BCM63XX_TAG_H -#define __BCM63XX_TAG_H - -#define TAGVER_LEN 4 /* Length of Tag Version */ -#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ -#define SIG1_LEN 20 /* Company Signature 1 Length */ -#define SIG2_LEN 14 /* Company Signature 2 Lenght */ -#define BOARDID_LEN 16 /* Length of BoardId */ -#define ENDIANFLAG_LEN 2 /* Endian Flag Length */ -#define CHIPID_LEN 6 /* Chip Id Length */ -#define IMAGE_LEN 10 /* Length of Length Field */ -#define ADDRESS_LEN 12 /* Length of Address field */ -#define DUALFLAG_LEN 2 /* Dual Image flag Length */ -#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ -#define RSASIG_LEN 20 /* Length of RSA Signature in tag */ -#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ -#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ -#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ -#define CRC_LEN 4 /* Length of CRC in bytes */ -#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */ - -#define NUM_PIRELLI 2 -#define IMAGETAG_CRC_START 0xFFFFFFFF - -#define PIRELLI_BOARDS { \ - "AGPF-S0", \ - "DWV-S0", \ -} - -/* - * The broadcom firmware assumes the rootfs starts the image, - * therefore uses the rootfs start (flashImageAddress) - * to determine where to flash the image. Since we have the kernel first - * we have to give it the kernel address, but the crc uses the length - * associated with this address (rootLength), which is added to the kernel - * length (kernelLength) to determine the length of image to flash and thus - * needs to be rootfs + deadcode (jffs2 EOF marker) -*/ - -struct bcm_tag { - char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag - char sig_1[SIG1_LEN]; // 4-23: Company Line 1 - char sig_2[SIG2_LEN]; // 24-37: Company Line 2 - char chipid[CHIPID_LEN]; // 38-43: Chip this image is for - char boardid[BOARDID_LEN]; // 44-59: Board name - char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE - char totalLength[IMAGE_LEN]; // 62-71: Total length of image - char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE - char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE - char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) - char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing - char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel - char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel - char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present - char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present - char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) - char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT) - char flashLayoutVer[FLASHLAYOUTVER_LEN];// 192-195: Version flash layout - char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32 - char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information - char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) - char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition - char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition - char imageSequence[4]; // 228-231: Image sequence number - char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot - char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion - char reserved2[16]; // 240-255: Unused at present -}; - -#endif /* __BCM63XX_TAG_H */ diff --git a/tools/firmware-utils/src/bcmalgo.c b/tools/firmware-utils/src/bcmalgo.c deleted file mode 100644 index fd6c1c116e..0000000000 --- a/tools/firmware-utils/src/bcmalgo.c +++ /dev/null @@ -1,248 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdlib.h> -#include <sys/types.h> -#include <stdio.h> -#include <inttypes.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> -#include <sys/time.h> -#include <sys/stat.h> -#include "bcmalgo.h" - - -#define UTIL_VERSION "0.1" -#define ENDIAN_REVERSE_NEEDED - -uint32_t reverse_endian32 ( uint32_t data ) -{ -#ifdef ENDIAN_REVERSE_NEEDED - return 0 | ( data & 0x000000ff ) << 24 - | ( data & 0x0000ff00 ) << 8 - | ( data & 0x00ff0000 ) >> 8 - | ( data & 0xff000000 ) >> 24; -#else - return data; -#endif -} - -uint16_t reverse_endian16 ( uint16_t data ) -{ -#ifdef ENDIAN_REVERSE_NEEDED - return 0 | ( data & 0x00ff ) << 8 - | ( data & 0xff00 ) >> 8; -#else - return data; -#endif -} - - - -uint32_t get_buffer_crc ( char* filebuffer,size_t size ) -{ - - long crc=0xffffffffL; - long crcxor = 0xffffffffL; - long num4 = 0xffffffffL; - long num5 = size; - long num6 = 0x4c11db7L; - long num7 = 0x80000000L; - int i; - long j; - for ( i = 0; i < ( num5 ); i++ ) - { - long num2 = filebuffer[i]; - for ( j = 0x80L; j != 0L; j = j >> 1 ) - { - long num3 = crc & num7; - crc = crc << 1; - if ( ( num2 & j ) != 0L ) - { - num3 ^= num7; - } - if ( num3 != 0L ) - { - crc ^= num6; - } - } - } - crc ^= crcxor; - crc &= num4; - - uint8_t b1 = ( uint8_t ) ( ( crc & -16777216L ) >> 0x18 ); - uint8_t b2 = ( uint8_t ) ( ( crc & 0xff0000L ) >> 0x10 ); - uint8_t b3 = ( uint8_t ) ( ( crc & 0xff00L ) >> 8 ); - uint8_t b4 = ( uint8_t ) ( crc & 0xffL ); - int32_t crc_result = ( b1 | b2 << 8| b3 << 16| b4 <<24 ); - return reverse_endian32 ( crc_result ); -} - -//Thnx to Vector for the algo. -uint32_t get_file_crc ( char* filename ) -{ - struct stat buf; - stat ( filename,&buf ); - char* filebuffer = malloc ( buf.st_size+10 ); - FILE* fd = fopen ( filename,"r" ); - fread ( filebuffer, 1, buf.st_size,fd ); - fclose ( fd ); - uint32_t crc = get_buffer_crc ( filebuffer,buf.st_size ); - free ( filebuffer ); - return crc; -} - - - -uint16_t get_hcs ( ldr_header_t* hd ) -{ - uint8_t* head = ( uint8_t* ) hd; - uint8_t hcs_minor; - uint8_t hcs_major; - uint16_t n = 0xffff; - int state = 0; - int i,j; - for ( i = 0; i < 0x54; i++ ) - { - uint16_t m = head[i]; - m = m << 8; - for ( j = 0; j < 8; j++ ) - { - if ( ( ( n ^ m ) & 0x8000 ) == 0 ) - { - state = 0; - } - else - { - state = 1; - } - n = n << 1; - if ( state ) - { - n ^= 0x1021; - } - m = m << 1; - } - n &= 0xffff; - } - n ^= 0xffff; - hcs_major = ( uint8_t ) ( ( n & 0xff00 ) >> 8 ); - hcs_minor = ( uint8_t ) ( n & 0xff ); - uint16_t hcs = hcs_major <<8 | hcs_minor; - return hcs; -} - -ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ) -{ - ldr_header_t* hd = malloc ( sizeof ( ldr_header_t ) ); - hd->magic=reverse_endian16 ( magic ); - hd->control=0; //FixMe: Make use of it once compression is around - hd->rev_min = reverse_endian16 ( rev_min ); - hd->rev_maj = reverse_endian16 ( rev_maj ); - hd->build_date = reverse_endian32 ( build_date ); - hd->filelen = reverse_endian32 ( filelen ); - hd->ldaddress = reverse_endian32 ( ldaddress ); - printf ( "Creating header for %s...\n", filename ); - if ( strlen ( filename ) >63 ) - { - printf ( "[!] Filename too long - stripping it to 63 bytes.\n" ); - strncpy ( ( char* ) &hd->filename, filename, 63 ); - hd->filename[63]=0x00; - } - else - { - strcpy ( ( char* ) &hd->filename, filename ); - } - hd->crc=reverse_endian32 ( crc_data ); - hd->hcs = reverse_endian16 ( get_hcs ( hd ) ); - return hd; -} - -static char control_unc[] = "Uncompressed"; -static char control_lz[] = "LZRW1/KH"; -static char control_mlzo[] = "mini-LZO"; -static char control_nrv[] = "NRV2D99 [Bootloader?]"; -static char control_nstdlzma[] = "(non-standard) LZMA"; -static char control_unk[] = "Unknown"; -char* get_control_info ( uint16_t control ) -{ - control = reverse_endian16 ( control ); - switch ( control ) - { - case 0: - return control_unc; - break; - case 1: - return control_lz; - break; - case 2: - return control_mlzo; - break; - case 3: - return control_unc; - break; - case 4: - return control_nrv; - break; - case 5: - return control_nstdlzma; - break; - case 6: - return control_unc; - break; - case 7: - return control_unc; - break; - default: - return control_unk; - break; - } - -} - -int dump_header ( ldr_header_t* hd ) -{ - printf ( "=== Header Information ===\n" ); - printf ( "Header magic:\t0x%04X\n",reverse_endian16 ( hd->magic ) ); - printf ( "Control:\t0x%04X (%s)\n",reverse_endian16 ( hd->control ), get_control_info ( hd->control ) ); - printf ( "Major rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_maj ) ); - printf ( "Minor rev. :\t0x%04X\n",reverse_endian16 ( hd->rev_min ) ); - printf ( "File name :\t%s\n", ( char* ) &hd->filename ); - printf ( "File length:\t%d bytes\n", reverse_endian32 ( hd->filelen ) ); - printf ( "Build time:\t0x%08X //FixMe: print in human-readable form\n", reverse_endian32 ( hd->build_date ) ); //FixMe: - printf ( "HCS:\t\t0x%04X ",reverse_endian16 ( hd->hcs ) ); - uint16_t hcs = get_hcs ( hd ); - int ret=0; - if ( hcs ==reverse_endian16 ( hd->hcs ) ) - { - printf ( "(OK!)\n" ); - } - else - { - printf ( "(ERROR! expected 0x%04X)\n",hcs ); - ret=1; - } -//printf("HCS:\t0x%02X",reverse_endian32(hd->hcs)); - printf ( "Load address:\t0x%08X\n", reverse_endian32 ( hd->ldaddress ) ); //FixMe: - printf ( "HNW:\t\t0x%04X\n",reverse_endian16 ( hd->her_znaet_chto ) ); //Hell knows what - printf ( "CRC:\t\t0x%08X\n",reverse_endian32 ( hd->crc ) ); - printf ( "=== Binary Header Dump===\n" ); - int i; - uint8_t* head = ( uint8_t* ) hd; - for ( i=0;i<=sizeof ( ldr_header_t );i++ ) - { - if ( i % 8==0 ) - printf ( "\n" ); - printf ( "0x%02x ",head[i] ); - } - printf ( "\n\n== End Of Header dump ==\n" ); - return ret; -} - - -void print_copyright() -{ - printf ( "Part of bcm-utils package ver. " UTIL_VERSION " \n" ); - printf ( "Copyright (C) 2009 Andrew 'Necromant' Andrianov\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See COPYING for details\n" ); -} diff --git a/tools/firmware-utils/src/bcmalgo.h b/tools/firmware-utils/src/bcmalgo.h deleted file mode 100644 index 9aec7d1931..0000000000 --- a/tools/firmware-utils/src/bcmalgo.h +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#ifndef bcmutils_H -#define bcmutils_H - -typedef struct -{ - uint16_t magic; - uint16_t control; - uint16_t rev_maj; - uint16_t rev_min; - uint32_t build_date; - uint32_t filelen; - uint32_t ldaddress; - char filename[64]; - uint16_t hcs; - uint16_t her_znaet_chto; //v dushe ne ebu - uint32_t crc; -} ldr_header_t; - - -/** - * Reverses endianess of a 32bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time - * @param data - * @return - */ -uint32_t reverse_endian32 ( uint32_t data ); - -/** - * Reverses endianess of a 16bit int, if the ENDIAN_REVERSE_NEEDED defined at compile-time - * @param data - * @return - */ -uint16_t reverse_endian16 ( uint16_t data ); -/** - * Calculates the strange crc (used by bcm modems) of the file. Thnx fly out to Vector for the algorithm. - * @param filename - * @return - */ -uint32_t get_file_crc ( char* filename ); - -/** - * Calculates HCS of the header. - * @param hd - * @return - */ -uint16_t get_hcs ( ldr_header_t* hd ); - -/** - * Constructs the header of the image with the information given It also automagically calculates HCS and writes it there. - * @param magic - magic device bytes - * @param rev_maj - major revision - * @param rev_min - minor revision - * @param build_date - build date (seconds from EPOCH UTC) - * @param filelen - file length in bytes - * @param ldaddress - Load adress - * @param filename - filename - * @param crc_data - the crc of the data - * @return - */ -ldr_header_t* construct_header ( uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc_data ); - -/** - * Dumps header information to stdout. - * @param hd - */ -int dump_header ( ldr_header_t* hd ); - - -/** - * Returns a null terminated string describing what the control number meens - * DO NOT FREE IT!!! - * @param control - * @return - */ -char* get_control_info ( uint16_t control ); -#endif - -/** - * Calculates bcmCRC of a data buffer. - * @param filebuffer - pointer to buffer - * @param size - buffer size - * @return - */ -uint32_t get_buffer_crc ( char* filebuffer, size_t size ); diff --git a/tools/firmware-utils/src/buffalo-enc.c b/tools/firmware-utils/src/buffalo-enc.c deleted file mode 100644 index dec226823b..0000000000 --- a/tools/firmware-utils/src/buffalo-enc.c +++ /dev/null @@ -1,318 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> - -#include "buffalo-lib.h" - -#define ERR(fmt, args...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## args ); \ -} while (0) - -static char *progname; -static char *ifname; -static char *ofname; -static char *crypt_key = "Buffalo"; -static char *magic = "start"; -static int longstate; -static unsigned char seed = 'O'; - -static char *product; -static char *version; -static int do_decrypt; -static int offset; -static int size; - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -d decrypt instead of encrypt\n" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -l use longstate {en,de}cryption method\n" -" -k <key> use <key> for encryption (default: Buffalo)\n" -" -m <magic> set magic to <magic>\n" -" -p <product> set product name to <product>\n" -" -v <version> set version to <version>\n" -" -h show this screen\n" -" -O Offset of encrypted data in file (decryption)\n" -" -S Size of unencrypted data in file (encryption)\n" - ); - - exit(status); -} - -static int decrypt_file(void) -{ - struct enc_param ep; - ssize_t src_len; - unsigned char *buf = NULL; - int err; - int ret = -1; - - src_len = get_file_size(ifname); - if (src_len < 0) { - ERR("unable to get size of '%s'", ifname); - goto out; - } - - buf = malloc(src_len); - if (buf == NULL) { - ERR("no memory for the buffer"); - goto out; - } - - err = read_file_to_buf(ifname, buf, src_len); - if (err) { - ERR("unable to read from file '%s'", ifname); - goto out; - } - - memset(&ep, '\0', sizeof(ep)); - ep.key = (unsigned char *) crypt_key; - ep.longstate = longstate; - - err = decrypt_buf(&ep, buf + offset, src_len - offset); - if (err) { - ERR("unable to decrypt '%s'", ifname); - goto out; - } - - printf("Magic\t\t: '%s'\n", ep.magic); - printf("Seed\t\t: 0x%02x\n", ep.seed); - printf("Product\t\t: '%s'\n", ep.product); - printf("Version\t\t: '%s'\n", ep.version); - printf("Data len\t: %u\n", ep.datalen); - printf("Checksum\t: 0x%08x\n", ep.csum); - - err = write_buf_to_file(ofname, buf + offset, ep.datalen); - if (err) { - ERR("unable to write to file '%s'", ofname); - goto out; - } - - ret = 0; - -out: - free(buf); - return ret; -} - -static int encrypt_file(void) -{ - struct enc_param ep; - ssize_t src_len, tail_dst, tail_len, tail_src; - unsigned char *buf; - uint32_t hdrlen; - ssize_t totlen = 0; - int err; - int ret = -1; - - src_len = get_file_size(ifname); - if (src_len < 0) { - ERR("unable to get size of '%s'", ifname); - goto out; - } - - if (size) { - tail_dst = enc_compute_buf_len(product, version, size); - tail_len = src_len - size; - totlen = tail_dst + tail_len; - } else - totlen = enc_compute_buf_len(product, version, src_len); - - buf = malloc(totlen); - if (buf == NULL) { - ERR("no memory for the buffer"); - goto out; - } - - hdrlen = enc_compute_header_len(product, version); - - err = read_file_to_buf(ifname, &buf[hdrlen], src_len); - if (err) { - ERR("unable to read from file '%s'", ofname); - goto free_buf; - } - - if (size) { - tail_src = hdrlen + size; - memmove(&buf[tail_dst], &buf[tail_src], tail_len); - memset(&buf[tail_src], 0, tail_dst - tail_src); - src_len = size; - } - - memset(&ep, '\0', sizeof(ep)); - ep.key = (unsigned char *) crypt_key; - ep.seed = seed; - ep.longstate = longstate; - ep.csum = buffalo_csum(src_len, &buf[hdrlen], src_len); - ep.datalen = src_len; - strcpy((char *) ep.magic, magic); - strcpy((char *) ep.product, product); - strcpy((char *) ep.version, version); - - err = encrypt_buf(&ep, buf, &buf[hdrlen]); - if (err) { - ERR("invalid input file"); - goto free_buf; - } - - err = write_buf_to_file(ofname, buf, totlen); - if (err) { - ERR("unable to write to file '%s'", ofname); - goto free_buf; - } - - ret = 0; - -free_buf: - free(buf); -out: - return ret; -} - -static int check_params(void) -{ - int ret = -1; - - if (ifname == NULL) { - ERR("no input file specified"); - goto out; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto out; - } - - if (crypt_key == NULL) { - ERR("no key specified"); - goto out; - } else if (strlen(crypt_key) > BCRYPT_MAX_KEYLEN) { - ERR("key '%s' is too long", crypt_key); - goto out; - } - - if (strlen(magic) != (ENC_MAGIC_LEN - 1)) { - ERR("length of magic must be %d", ENC_MAGIC_LEN - 1); - goto out; - } - - if (!do_decrypt) { - if (product == NULL) { - ERR("no product specified"); - goto out; - } - - if (version == NULL) { - ERR("no version specified"); - goto out; - } - - if (strlen(product) > (ENC_PRODUCT_LEN - 1)) { - ERR("product name '%s' is too long", product); - goto out; - } - - if (strlen(version) > (ENC_VERSION_LEN - 1)) { - ERR("version '%s' is too long", version); - goto out; - } - } - - ret = 0; - -out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int err; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "adi:m:o:hlp:v:k:O:r:s:S:"); - if (c == -1) - break; - - switch (c) { - case 'd': - do_decrypt = 1; - break; - case 'i': - ifname = optarg; - break; - case 'l': - longstate = 1; - break; - case 'm': - magic = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'p': - product = optarg; - break; - case 'v': - version = optarg; - break; - case 'k': - crypt_key = optarg; - break; - case 's': - seed = strtoul(optarg, NULL, 16); - break; - case 'O': - offset = strtoul(optarg, NULL, 0); - break; - case 'S': - size = strtoul(optarg, NULL, 0); - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - err = check_params(); - if (err) - goto out; - - if (do_decrypt) - err = decrypt_file(); - else - err = encrypt_file(); - - if (err) - goto out; - - res = EXIT_SUCCESS; - -out: - return res; -} diff --git a/tools/firmware-utils/src/buffalo-lib.c b/tools/firmware-utils/src/buffalo-lib.c deleted file mode 100644 index 7f5a12de60..0000000000 --- a/tools/firmware-utils/src/buffalo-lib.c +++ /dev/null @@ -1,476 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <sys/stat.h> - -#include "buffalo-lib.h" - -static uint32_t crc32_table[256] = -{ - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, - 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, - 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, - 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, - 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, - 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, - 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, - 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, - 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, - 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, - 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, - 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, - 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, - 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, - 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, - 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, - 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, - 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, - 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, - 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, - 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, - 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, - 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, - 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, - 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, - 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, - 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, - 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, - 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, - 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, - 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, - 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, - 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, - 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, - 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, - 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, - 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, - 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, - 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, - 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, - 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, - 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, - 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - -int bcrypt_init(struct bcrypt_ctx *ctx, void *key, int keylen, - unsigned long state_len) -{ - unsigned char *state; - unsigned char *p = key; - unsigned long i, j; - unsigned long k = 0; - - state = malloc(state_len); - if (state == NULL) - return -1; - - ctx->i = 0; - ctx->j = 0; - ctx->state = state; - ctx->state_len = state_len; - - for (i = 0; i < state_len; i++) - state[i] = i; - - for(i = 0, j = 0; i < state_len; i++, j = (j + 1) % keylen) { - unsigned char t; - - t = state[i]; - k = (k + p[j] + t) % state_len; - state[i] = state[k]; - state[k] = t; - } - - return 0; -} - -int bcrypt_process(struct bcrypt_ctx *ctx, unsigned char *src, - unsigned char *dst, unsigned long len) -{ - unsigned char *state = ctx->state; - unsigned long state_len = ctx->state_len; - unsigned char i, j; - unsigned long k; - - i = ctx->i; - j = ctx->j; - - for (k = 0; k < len; k++) { - unsigned char t; - - i = (i + 1) % state_len; - j = (j + state[i]) % state_len; - t = state[j]; - state[j] = state[i]; - state[i] = t; - - dst[k] = src[k] ^ state[(state[i] + state[j]) % state_len]; - } - - ctx->i = i; - ctx->j = j; - - return len; -} - -void bcrypt_finish(struct bcrypt_ctx *ctx) -{ - if (ctx->state) - free(ctx->state); -} - -int bcrypt_buf(unsigned char seed, unsigned char *key, unsigned char *src, - unsigned char *dst, unsigned long len, int longstate) -{ - unsigned char bckey[BCRYPT_MAX_KEYLEN + 1]; - unsigned int keylen; - struct bcrypt_ctx ctx; - int ret; - - /* setup decryption key */ - keylen = strlen((char *) key); - bckey[0] = seed; - memcpy(&bckey[1], key, keylen); - - keylen++; - - ret = bcrypt_init(&ctx, bckey, keylen, - (longstate) ? len : BCRYPT_DEFAULT_STATE_LEN); - if (ret) - return ret; - - bcrypt_process(&ctx, src, dst, len); - bcrypt_finish(&ctx); - - return 0; -} - -uint32_t buffalo_csum(uint32_t csum, void *buf, unsigned long len) -{ - signed char *p = buf; - - while (len--) { - int i; - - csum ^= *p++; - for (i = 0; i < 8; i++) - csum = (csum >> 1) ^ ((csum & 1) ? 0xedb88320ul : 0); - } - - return csum; -} - -uint32_t buffalo_crc(void *buf, unsigned long len) -{ - unsigned char *p = buf; - unsigned long t = len; - uint32_t crc = 0; - - while (len--) - crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *p++) & 0xFF]; - - while (t) { - crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ t) & 0xFF]; - t >>= 8; - } - - return ~crc; -} - -unsigned long enc_compute_header_len(char *product, char *version) -{ - return ENC_MAGIC_LEN + 1 + strlen(product) + 1 + - strlen(version) + 1 + 3 * sizeof(uint32_t); -} - -unsigned long enc_compute_buf_len(char *product, char *version, - unsigned long datalen) -{ - unsigned long ret; - - ret = enc_compute_header_len(product, version); - ret += datalen + sizeof(uint32_t); - ret += (4 - ret % 4); - - return ret; -} - -static void put_be32(void *data, uint32_t val) -{ - unsigned char *p = data; - - p[0] = (val >> 24) & 0xff; - p[1] = (val >> 16) & 0xff; - p[2] = (val >> 8) & 0xff; - p[3] = val & 0xff; -} - -static uint32_t get_be32(void *data) -{ - unsigned char *p = data; - - return (((uint32_t)p[0]) << 24) | - (((uint32_t)p[1]) << 16) | - (((uint32_t)p[2]) << 8) | - ((uint32_t)p[3]); -} - -static int check_magic(void *magic) -{ - if (!memcmp("start", magic, ENC_MAGIC_LEN)) - return 0; - - if (!memcmp("asar1", magic, ENC_MAGIC_LEN)) - return 0; - - return -1; -} - -int encrypt_buf(struct enc_param *ep, unsigned char *hdr, - unsigned char *data) -{ - unsigned char *p; - uint32_t len; - int err; - int ret = -1; - unsigned char s; - - p = (unsigned char *) hdr; - - /* setup magic */ - len = strlen((char *) ep->magic) + 1; - memcpy(p, ep->magic, len); - p += len; - - /* setup seed */ - *p++ = ep->seed; - - /* put product len */ - len = strlen((char *) ep->product) + 1; - put_be32(p, len); - p += sizeof(uint32_t); - - /* copy and crypt product name */ - memcpy(p, ep->product, len); - err = bcrypt_buf(ep->seed, ep->key, p, p, len, ep->longstate); - if (err) - goto out; - s = *p; - p += len; - - /* put version length */ - len = strlen((char *) ep->version) + 1; - put_be32(p, len); - p += sizeof(uint32_t); - - /* copy and crypt version */ - memcpy(p, ep->version, len); - err = bcrypt_buf(s, ep->key, p, p, len, ep->longstate); - if (err) - goto out; - s = *p; - p += len; - - /* put data length */ - put_be32(p, ep->datalen); - - /* encrypt data */ - err = bcrypt_buf(s, ep->key, data, data, ep->datalen, ep->longstate); - if (err) - goto out; - - /* put checksum */ - put_be32(&data[ep->datalen], ep->csum); - - ret = 0; - -out: - return ret; -} - -int decrypt_buf(struct enc_param *ep, unsigned char *data, - unsigned long datalen) -{ - unsigned char *p; - uint32_t prod_len; - uint32_t ver_len; - uint32_t len; - uint32_t csum; - ssize_t remain; - int err; - int ret = -1; - -#define CHECKLEN(_l) do { \ - len = (_l); \ - if (remain < len) { \ - goto out; \ - } \ -} while (0) - -#define INCP() do { \ - p += len; \ - remain -= len; \ -} while (0) - - remain = datalen; - p = data; - - CHECKLEN(ENC_MAGIC_LEN); - err = check_magic(p); - if (err) - goto out; - memcpy(ep->magic, p, ENC_MAGIC_LEN); - INCP(); - - CHECKLEN(1); - ep->seed = *p; - INCP(); - - CHECKLEN(sizeof(uint32_t)); - prod_len = get_be32(p); - if (prod_len > ENC_PRODUCT_LEN) - goto out; - INCP(); - - CHECKLEN(prod_len); - memcpy(ep->product, p, prod_len); - INCP(); - - CHECKLEN(sizeof(uint32_t)); - ver_len = get_be32(p); - if (ver_len > ENC_VERSION_LEN) - goto out; - INCP(); - - CHECKLEN(ver_len); - memcpy(ep->version, p, ver_len); - INCP(); - - CHECKLEN(sizeof(uint32_t)); - ep->datalen = get_be32(p); - INCP(); - - /* decrypt data */ - CHECKLEN(ep->datalen); - err = bcrypt_buf(ep->version[0], ep->key, p, data, ep->datalen, - ep->longstate); - if (err) - goto out; - INCP(); - - CHECKLEN(sizeof(uint32_t)); - ep->csum = get_be32(p); - INCP(); - - csum = buffalo_csum(ep->datalen, data, ep->datalen); - if (csum != ep->csum) - goto out; - - /* decrypt product name */ - err = bcrypt_buf(ep->product[0], ep->key, ep->version, ep->version, - ver_len, ep->longstate); - if (err) - goto out; - - /* decrypt version */ - err = bcrypt_buf(ep->seed, ep->key, ep->product, ep->product, prod_len, - ep->longstate); - if (err) - goto out; - - ret = 0; -out: - return ret; - -#undef CHECKLEN -#undef INCP -} - -ssize_t get_file_size(char *name) -{ - struct stat st; - int err; - - err = stat(name, &st); - if (err) - return -1; - - return st.st_size; -} - -int read_file_to_buf(char *name, void *buf, ssize_t buflen) -{ - FILE *f; - size_t done; - int ret = -1; - - f = fopen(name, "r"); - if (f == NULL) - goto out; - - errno = 0; - done = fread(buf, buflen, 1, f); - if (done != 1) - goto close; - - ret = 0; - -close: - fclose(f); -out: - return ret; -} - -int write_buf_to_file(char *name, void *buf, ssize_t buflen) -{ - FILE *f; - size_t done; - int ret = -1; - - f = fopen(name, "w"); - if (f == NULL) - goto out; - - errno = 0; - done = fwrite(buf, buflen, 1, f); - if (done != 1) - goto close; - - ret = 0; - -close: - fflush(f); - fclose(f); - if (ret) - unlink(name); -out: - return ret; -} diff --git a/tools/firmware-utils/src/buffalo-lib.h b/tools/firmware-utils/src/buffalo-lib.h deleted file mode 100644 index 030f7cd1d6..0000000000 --- a/tools/firmware-utils/src/buffalo-lib.h +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> - */ - -#ifndef _BUFFALO_LIB_H -#define _BUFFALO_LIB_H - -#include <stdint.h> - -#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0])) -#define BIT(_x) (1UL << (_x)) - -#define TAG_BRAND_LEN 32 -#define TAG_PRODUCT_LEN 32 -#define TAG_VERSION_LEN 8 -#define TAG_REGION_LEN 2 -#define TAG_LANGUAGE_LEN 8 -#define TAG_PLATFORM_LEN 8 -#define TAG_HWVER_LEN 4 -#define TAG_HWVER_VAL_LEN 4 - -struct buffalo_tag { - unsigned char product[TAG_PRODUCT_LEN]; - unsigned char brand[TAG_BRAND_LEN]; - unsigned char ver_major[TAG_VERSION_LEN]; - unsigned char ver_minor[TAG_VERSION_LEN]; - unsigned char region_code[2]; - uint32_t region_mask; - unsigned char unknown0[2]; - unsigned char language[TAG_LANGUAGE_LEN]; - unsigned char platform[TAG_PLATFORM_LEN]; - unsigned char hwv[TAG_HWVER_LEN]; - unsigned char hwv_val[TAG_HWVER_VAL_LEN]; - uint8_t unknown1[24]; - - uint32_t len; - uint32_t crc; - uint32_t base1; - uint32_t base2; - uint32_t data_len; - uint8_t flag; - uint8_t unknown2[3]; -} __attribute ((packed)); - -struct buffalo_tag2 { - unsigned char product[TAG_PRODUCT_LEN]; - unsigned char brand[TAG_BRAND_LEN]; - unsigned char ver_major[TAG_VERSION_LEN]; - unsigned char ver_minor[TAG_VERSION_LEN]; - unsigned char region_code[2]; - uint32_t region_mask; - unsigned char unknown0[2]; - unsigned char language[TAG_LANGUAGE_LEN]; - unsigned char platform[TAG_PLATFORM_LEN]; - unsigned char hwv[TAG_HWVER_LEN]; - unsigned char hwv_val[TAG_HWVER_VAL_LEN]; - uint8_t unknown1[24]; - - uint32_t total_len; - uint32_t crc; - uint32_t len1; - uint32_t len2; - uint8_t flag; - uint8_t unknown2[3]; -} __attribute ((packed)); - -struct buffalo_tag3 { - unsigned char product[TAG_PRODUCT_LEN]; - unsigned char brand[TAG_BRAND_LEN]; - unsigned char ver_major[TAG_VERSION_LEN]; - unsigned char ver_minor[TAG_VERSION_LEN]; - unsigned char region_code[2]; - uint32_t region_mask; - unsigned char unknown0[2]; - unsigned char language[TAG_LANGUAGE_LEN]; - unsigned char platform[TAG_PLATFORM_LEN]; - unsigned char hwv[TAG_HWVER_LEN]; - unsigned char hwv_val[TAG_HWVER_VAL_LEN]; - uint8_t unknown1[24]; - - uint32_t total_len; - uint32_t crc; - uint32_t len1; - uint32_t base2; -} __attribute ((packed)); - -#define ENC_PRODUCT_LEN 32 -#define ENC_VERSION_LEN 8 -#define ENC_MAGIC_LEN 6 - -unsigned long enc_compute_header_len(char *product, char *version); -unsigned long enc_compute_buf_len(char *product, char *version, - unsigned long datalen); - -struct enc_param { - unsigned char *key; - unsigned char magic[ENC_MAGIC_LEN]; - unsigned char product[ENC_PRODUCT_LEN]; - unsigned char version[ENC_VERSION_LEN]; - unsigned char seed; - int longstate; - unsigned datalen; - uint32_t csum; -}; - -int encrypt_buf(struct enc_param *ep, unsigned char *hdr, - unsigned char *data); -int decrypt_buf(struct enc_param *ep, unsigned char *data, - unsigned long datalen); - -#define BCRYPT_DEFAULT_STATE_LEN 256 -#define BCRYPT_MAX_KEYLEN 254 - -struct bcrypt_ctx { - unsigned long i; - unsigned long j; - unsigned char *state; - unsigned long state_len; -}; - -int bcrypt_init(struct bcrypt_ctx *ctx, void *key, int keylen, - unsigned long state_len); -int bcrypt_process(struct bcrypt_ctx *ctx, unsigned char *src, - unsigned char *dst, unsigned long len); -void bcrypt_finish(struct bcrypt_ctx *ctx); -int bcrypt_buf(unsigned char seed, unsigned char *key, unsigned char *src, - unsigned char *dst, unsigned long len, int longstate); - -uint32_t buffalo_csum(uint32_t csum, void *buf, unsigned long len); -uint32_t buffalo_crc(void *buf, unsigned long len); - -ssize_t get_file_size(char *name); -int read_file_to_buf(char *name, void *buf, ssize_t buflen); -int write_buf_to_file(char *name, void *buf, ssize_t buflen); - -#endif /* _BUFFALO_LIB_H */ diff --git a/tools/firmware-utils/src/buffalo-tag.c b/tools/firmware-utils/src/buffalo-tag.c deleted file mode 100644 index a06eb4486c..0000000000 --- a/tools/firmware-utils/src/buffalo-tag.c +++ /dev/null @@ -1,410 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <netinet/in.h> - -#include "buffalo-lib.h" - -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -static char *region_table[] = { - "JP", "US", "EU", "AP", "TW", "KR" -}; - -#define MAX_INPUT_FILES 2 - -static char *progname; -static char *ifname[MAX_INPUT_FILES]; -static ssize_t fsize[MAX_INPUT_FILES]; -static int num_files; -static char *ofname; -static char *product; -static char *brand; -static char *language; -static char *hwver; -static char *platform; -static int flag; -static char *major; -static char *minor = "1.01"; -static int skipcrc; -static uint32_t base1; -static uint32_t base2; -static char *region_code; -static uint32_t region_mask; -static int num_regions; -static int dhp; - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -a <platform> set platform to <platform>\n" -" -b <brand> set brand to <brand>\n" -" -c <base1>\n" -" -d <base2>\n" -" -f <flag> set flag to <flag>\n" -" -i <file> read input from the file <file>\n" -" -I <file> read input from the file <file> for DHP series\n" -" -l <language> set language to <language>\n" -" -m <version> set minor version to <version>\n" -" -o <file> write output to the file <file>\n" -" -p <product> set product to <product>\n" -" -r <region> set image region to <region>\n" -" valid regions: JP, US, EU, AP, TW, KR, M_\n" -" -s skip CRC calculation\n" -" -v <version> set major version to <version>\n" -" -w <version> set harwdware version to <version>\n" -" -h show this screen\n" - ); - - exit(status); -} - -static int check_params(void) -{ - -#define CHECKSTR(_var, _name, _len) do { \ - if ((_var) == NULL) { \ - ERR("no %s specified", (_name)); \ - return -1; \ - } \ - if ((_len) > 0 && \ - strlen((_var)) > ((_len) - 1)) { \ - ERR("%s is too long", (_name)); \ - return -1; \ - } \ -} while (0) - - if (num_files == 0) - ERR("no input files specified"); - - CHECKSTR(ofname, "output file", 0); - CHECKSTR(brand, "brand", TAG_BRAND_LEN); - CHECKSTR(product, "product", TAG_PRODUCT_LEN); - CHECKSTR(platform, "platform", TAG_PLATFORM_LEN); - CHECKSTR(major, "major version", TAG_VERSION_LEN); - CHECKSTR(minor, "minor version", TAG_VERSION_LEN); - CHECKSTR(language, "language", TAG_LANGUAGE_LEN); - - if (hwver) - CHECKSTR(hwver, "hardware version", 2); - - if (num_regions == 0) { - ERR("no region code specified"); - return -1; - } - - return 0; - -#undef CHECKSTR -} - -static int process_region(char *reg) -{ - int i; - - if (strlen(reg) != 2) { - ERR("invalid region code '%s'", reg); - return -1; - } - - if (strcmp(reg, "M_") == 0) { - region_code = reg; - region_mask |= ~0; - num_regions = 32; - return 0; - } - - for (i = 0; i < ARRAY_SIZE(region_table); i++) - if (strcmp(reg, region_table[i]) == 0) { - region_code = reg; - region_mask |= 1 << i; - num_regions++; - return 0; - } - - ERR("unknown region code '%s'", reg); - return -1; -} - -static int process_ifname(char *name) -{ - if (num_files >= ARRAY_SIZE(ifname)) { - ERR("too many input files specified"); - return -1; - } - - ifname[num_files++] = name; - return 0; -} - -static void fixup_tag(unsigned char *buf, ssize_t buflen) -{ - struct buffalo_tag *tag = (struct buffalo_tag *) buf; - - memset(tag, '\0', sizeof(*tag)); - - memcpy(tag->brand, brand, strlen(brand)); - memcpy(tag->product, product, strlen(product)); - memcpy(tag->platform, platform, strlen(platform)); - memcpy(tag->ver_major, major, strlen(major)); - memcpy(tag->ver_minor, minor, strlen(minor)); - memcpy(tag->language, language, strlen(language)); - - if (num_regions > 1) { - tag->region_code[0] = 'M'; - tag->region_code[1] = '_'; - tag->region_mask = htonl(region_mask); - } else { - memcpy(tag->region_code, region_code, 2); - } - - tag->len = htonl(buflen); - tag->data_len = htonl(fsize[0]); - tag->base1 = htonl(base1); - tag->base2 = htonl(base2); - tag->flag = flag; - - if (hwver) { - memcpy(tag->hwv, "hwv", 3); - memcpy(tag->hwv_val, hwver, strlen(hwver)); - } - - if (!skipcrc) - tag->crc = htonl(buffalo_crc(buf, buflen)); -} - -static void fixup_tag2(unsigned char *buf, ssize_t buflen) -{ - struct buffalo_tag2 *tag = (struct buffalo_tag2 *) buf; - - memset(tag, '\0', sizeof(*tag)); - - memcpy(tag->brand, brand, strlen(brand)); - memcpy(tag->product, product, strlen(product)); - memcpy(tag->platform, platform, strlen(platform)); - memcpy(tag->ver_major, major, strlen(major)); - memcpy(tag->ver_minor, minor, strlen(minor)); - memcpy(tag->language, language, strlen(language)); - - if (num_regions > 1) { - tag->region_code[0] = 'M'; - tag->region_code[1] = '_'; - tag->region_mask = htonl(region_mask); - } else { - memcpy(tag->region_code, region_code, 2); - } - - tag->total_len = htonl(buflen); - tag->len1 = htonl(fsize[0]); - tag->len2 = htonl(fsize[1]); - tag->flag = flag; - - if (hwver) { - memcpy(tag->hwv, "hwv", 3); - memcpy(tag->hwv_val, hwver, strlen(hwver)); - } - - if (!skipcrc) - tag->crc = htonl(buffalo_crc(buf, buflen)); -} - -static void fixup_tag3(unsigned char *buf, ssize_t totlen) -{ - struct buffalo_tag3 *tag = (struct buffalo_tag3 *) buf; - - memset(tag, '\0', sizeof(*tag)); - - memcpy(tag->brand, brand, strlen(brand)); - memcpy(tag->product, product, strlen(product)); - memcpy(tag->platform, platform, strlen(platform)); - memcpy(tag->ver_major, major, strlen(major)); - memcpy(tag->ver_minor, minor, strlen(minor)); - memcpy(tag->language, language, strlen(language)); - - if (num_regions > 1) { - tag->region_code[0] = 'M'; - tag->region_code[1] = '_'; - tag->region_mask = htonl(region_mask); - } else { - memcpy(tag->region_code, region_code, 2); - } - - tag->total_len = htonl(totlen); - tag->len1 = htonl(fsize[0]); - tag->base2 = htonl(base2); - - if (hwver) { - memcpy(tag->hwv, "hwv", 3); - memcpy(tag->hwv_val, hwver, strlen(hwver)); - } -} - -static int tag_file(void) -{ - unsigned char *buf; - ssize_t offset; - ssize_t hdrlen; - ssize_t buflen; - int err; - int ret = -1; - int i; - - if (dhp) - hdrlen = sizeof(struct buffalo_tag3); - else if (num_files == 1) - hdrlen = sizeof(struct buffalo_tag); - else - hdrlen = sizeof(struct buffalo_tag2); - - buflen = hdrlen; - - for (i = 0; i < num_files; i++) { - fsize[i] = get_file_size(ifname[i]); - if (fsize[i] < 0) { - ERR("unable to get size of '%s'", ifname[i]); - goto out; - } - buflen += fsize[i]; - } - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - offset = hdrlen; - for (i = 0; i < num_files; i++) { - err = read_file_to_buf(ifname[i], buf + offset, fsize[i]); - if (err) { - ERR("unable to read from file '%s'", ifname[i]); - goto free_buf; - } - - offset += fsize[i]; - } - - if (dhp) - fixup_tag3(buf, fsize[0] + 200); - else if (num_files == 1) - fixup_tag(buf, buflen); - else - fixup_tag2(buf, buflen); - - err = write_buf_to_file(ofname, buf, buflen); - if (err) { - ERR("unable to write to file '%s'", ofname); - goto free_buf; - } - - ret = 0; - -free_buf: - free(buf); -out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int err; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "a:b:c:d:f:hi:l:m:o:p:r:sv:w:I:"); - if (c == -1) - break; - - switch (c) { - case 'a': - platform = optarg; - break; - case 'b': - brand = optarg; - break; - case 'c': - base1 = strtoul(optarg, NULL, 16); - break; - case 'd': - base2 = strtoul(optarg, NULL, 16); - break; - case 'f': - flag = strtoul(optarg, NULL, 2); - break; - case 'I': - dhp = 1; - /* FALLTHROUGH */ - case 'i': - err = process_ifname(optarg); - if (err) - goto out; - break; - case 'l': - language = optarg; - break; - case 'm': - minor = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'p': - product = optarg; - break; - case 'r': - err = process_region(optarg); - if (err) - goto out; - break; - case 's': - skipcrc = 1; - break; - case 'v': - major = optarg; - break; - case 'w': - hwver = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - err = check_params(); - if (err) - goto out; - - err = tag_file(); - if (err) - goto out; - - res = EXIT_SUCCESS; - -out: - return res; -} diff --git a/tools/firmware-utils/src/buffalo-tftp.c b/tools/firmware-utils/src/buffalo-tftp.c deleted file mode 100644 index 56af4caa93..0000000000 --- a/tools/firmware-utils/src/buffalo-tftp.c +++ /dev/null @@ -1,173 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> - -#include "buffalo-lib.h" - -#define ERR(fmt, args...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## args ); \ -} while (0) - -static char *progname; -static char *ifname; -static char *ofname; -static int do_decrypt; - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -d decrypt instead of encrypt\n" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -h show this screen\n" - ); - - exit(status); -} - -static const unsigned char *crypt_key1 = (unsigned char *) - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; -static const unsigned char *crypt_key2 = (unsigned char *) - "XYZ0123hijklmnopqABCDEFGHrstuvabcdefgwxyzIJKLMSTUVW456789NOPQR"; - -static void crypt_header(unsigned char *buf, ssize_t len, - const unsigned char *key1, const unsigned char *key2) -{ - ssize_t i; - - for (i = 0; i < len; i++) { - unsigned int j; - - for (j = 0; key1[j]; j++) - if (buf[i] == key1[j]) { - buf[i] = key2[j]; - break; - } - } -} - -static int crypt_file(void) -{ - unsigned char *buf = NULL; - ssize_t src_len; - int err; - int ret = -1; - - src_len = get_file_size(ifname); - if (src_len < 0) { - ERR("unable to get size of '%s'", ifname); - goto out; - } - - buf = malloc(src_len); - if (buf == NULL) { - ERR("no memory for the buffer"); - goto out; - } - - err = read_file_to_buf(ifname, buf, src_len); - if (err) { - ERR("unable to read from file '%s'", ifname); - goto out; - } - - if (do_decrypt) - crypt_header(buf, 512, crypt_key2, crypt_key1); - else - crypt_header(buf, 512, crypt_key1, crypt_key2); - - err = write_buf_to_file(ofname, buf, src_len); - if (err) { - ERR("unable to write to file '%s'", ofname); - goto out; - } - - ret = 0; - -out: - free(buf); - return ret; -} - -static int check_params(void) -{ - int ret = -1; - - if (ifname == NULL) { - ERR("no input file specified"); - goto out; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto out; - } - - ret = 0; - -out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int err; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "di:o:h"); - if (c == -1) - break; - - switch (c) { - case 'd': - do_decrypt = 1; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - err = check_params(); - if (err) - goto out; - - err = crypt_file(); - if (err) - goto out; - - res = EXIT_SUCCESS; - -out: - return res; -} diff --git a/tools/firmware-utils/src/csysimg.h b/tools/firmware-utils/src/csysimg.h deleted file mode 100644 index 1214c7dee4..0000000000 --- a/tools/firmware-utils/src/csysimg.h +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * Copyright (C) 2007,2009 Gabor Juhos <juhosg@openwrt.org> - * - * This program was based on the code found in various Linux - * source tarballs released by Edimax for it's devices. - * Original author: David Hsu <davidhsu@realtek.com.tw> - */ - -#define SIG_LEN 4 - -#define ADM_CODE_ADDR 0x80500000 -#define ADM_WEBP_ADDR 0x10000 -#define ADM_WEBP_SIZE 0x10000 -#define ADM_BOOT_SIZE 0x8000 -#define ADM_CONF_SIZE 0x8000 -#define ADM_BOOT_SIG "\x00\x60\x1A\x40" - - -/* - * Generic signatures - */ -#define SIG_CSYS "CSYS" -#define SIG_CONF "HS\x00\x00" -#define SIG_BOOT_RTL "\x00\x00\x40\x21" - -/* - * Web page signatures - */ -#define SIG_BR6104K "WB4K" -#define SIG_BR6104KP "WBKP" -#define SIG_BR6104Wg "WBGW" -#define SIG_BR6104IPC "WBIP" -#define SIG_BR6114WG SIG_BR6104IPC -#define SIG_BR6524K "2-K-" -#define SIG_BR6524KP "2-KP" /* FIXME: valid? */ -#define SIG_BR6524N "WNRA" -#define SIG_BR6524WG "2-WG" /* FIXME: valid? */ -#define SIG_BR6524WP "2-WP" /* FIXME: valid? */ -#define SIG_BR6541K "4--K" -#define SIG_BR6541KP "4-KP" /* FIXME: valid? */ -#define SIG_BR6541WP "4-WP" /* FIXME: valid? */ -#define SIG_C54BSR4 SIG_BR6104IPC -#define SIG_EW7207APg "EWAS" -#define SIG_PS1205UWg "4000" -#define SIG_PS3205U "5010" -#define SIG_PS3205UWg "5011" -#define SIG_RALINK "RNRA" -#define SIG_5GXI "5GXI" /* fake signature */ - -#define SIG_H2BR4 SIG_BR6524K -#define SIG_H2WR54G SIG_BR6524WG - -#define SIG_XRT401D SIG_BR6104K -#define SIG_XRT402D SIG_BR6524K - -/* - * CSYS image file header - */ -struct csys_header { - unsigned char sig[SIG_LEN]; - uint32_t addr; - uint32_t size; -}; diff --git a/tools/firmware-utils/src/cyg_crc.h b/tools/firmware-utils/src/cyg_crc.h deleted file mode 100644 index 68669715cf..0000000000 --- a/tools/firmware-utils/src/cyg_crc.h +++ /dev/null @@ -1,109 +0,0 @@ -//========================================================================== -// -// crc.h -// -// Interface for the CRC algorithms. -// -//========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 2002 Andrew Lunn -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): Andrew Lunn -// Contributors: Andrew Lunn -// Date: 2002-08-06 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#ifndef _SERVICES_CRC_CRC_H_ -#define _SERVICES_CRC_CRC_H_ - -#if 0 -#include <cyg/infra/cyg_type.h> -#else -#include <stdint.h> -typedef uint32_t cyg_uint32; -typedef uint16_t cyg_uint16; -#endif - -#ifndef __externC -# ifdef __cplusplus -# define __externC extern "C" -# else -# define __externC extern -# endif -#endif - -// Compute a CRC, using the POSIX 1003 definition - -__externC cyg_uint32 -cyg_posix_crc32(void *s, int len); - -// Gary S. Brown's 32 bit CRC - -__externC cyg_uint32 -cyg_crc32(void *s, int len); - -// Gary S. Brown's 32 bit CRC, but accumulate the result from a -// previous CRC calculation - -__externC cyg_uint32 -cyg_crc32_accumulate(cyg_uint32 crc, void *s, int len); - -// Ethernet FCS Algorithm - -__externC cyg_uint32 -cyg_ether_crc32(void *s, int len); - -// Ethernet FCS algorithm, but accumulate the result from a previous -// CRC calculation. - -__externC cyg_uint32 -cyg_ether_crc32_accumulate(cyg_uint32 crc, void *s, int len); - -// 16 bit CRC with polynomial x^16+x^12+x^5+1 - -__externC cyg_uint16 -cyg_crc16(void *s, int len); - -#endif // _SERVICES_CRC_CRC_H_ - - - diff --git a/tools/firmware-utils/src/cyg_crc16.c b/tools/firmware-utils/src/cyg_crc16.c deleted file mode 100644 index 3861ff03e8..0000000000 --- a/tools/firmware-utils/src/cyg_crc16.c +++ /dev/null @@ -1,111 +0,0 @@ -//========================================================================== -// -// crc16.c -// -// 16 bit CRC with polynomial x^16+x^12+x^5+1 -// -//========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// Copyright (C) 2002 Gary Thomas -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas,asl -// Date: 2001-01-31 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#if 0 -#include <cyg/crc/crc.h> -#else -#include "cyg_crc.h" -#endif - -// Table of CRC constants - implements x^16+x^12+x^5+1 -static const cyg_uint16 crc16_tab[] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, -}; - -cyg_uint16 -cyg_crc16(void *ptr, int len) -{ - unsigned char *buf = ptr; - int i; - cyg_uint16 cksum; - - cksum = 0; - for (i = 0; i < len; i++) { - cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xFF] ^ (cksum << 8); - } - return cksum; -} - diff --git a/tools/firmware-utils/src/cyg_crc32.c b/tools/firmware-utils/src/cyg_crc32.c deleted file mode 100644 index f13221e946..0000000000 --- a/tools/firmware-utils/src/cyg_crc32.c +++ /dev/null @@ -1,174 +0,0 @@ -//========================================================================== -// -// crc32.c -// -// Gary S. Brown's 32 bit CRC -// -//========================================================================== -//####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// Copyright (C) 2002 Gary Thomas -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with eCos; if not, write to the Free Software Foundation, Inc., -// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// As a special exception, if other files instantiate templates or use macros -// or inline functions from this file, or you compile this file and link it -// with other works to produce a work based on this file, this file does not -// by itself cause the resulting work to be covered by the GNU General Public -// License. However the source code for this file must still be made available -// in accordance with section (3) of the GNU General Public License. -// -// This exception does not invalidate any other reasons why a work based on -// this file might be covered by the GNU General Public License. -// -// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. -// at http://sources.redhat.com/ecos/ecos-license/ -// ------------------------------------------- -//####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas,asl -// Date: 2001-01-31 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#if 0 -#include <cyg/crc/crc.h> -#else -#include "cyg_crc.h" -#endif - - /* ====================================================================== */ - /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ - /* code or tables extracted from it, as desired without restriction. */ - /* */ - /* First, the polynomial itself and its table of feedback terms. The */ - /* polynomial is */ - /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ - /* */ - /* ====================================================================== */ - -static const cyg_uint32 crc32_tab[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL - }; - -/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but - accumulate the CRC into the result of a previous CRC. */ -cyg_uint32 -cyg_crc32_accumulate(cyg_uint32 crc32val, void *ptr, int len) -{ - unsigned char *s = ptr; - int i; - - for (i = 0; i < len; i++) { - crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); - } - return crc32val; -} - -/* This is the standard Gary S. Brown's 32 bit CRC algorithm */ -cyg_uint32 -cyg_crc32(void *s, int len) -{ - return (cyg_crc32_accumulate(0,s,len)); -} - -/* Return a 32-bit CRC of the contents of the buffer accumulating the - result from a previous CRC calculation. This uses the Ethernet FCS - algorithm.*/ -cyg_uint32 -cyg_ether_crc32_accumulate(cyg_uint32 crc32val, void *ptr, int len) -{ - unsigned char *s = ptr; - int i; - - if (s == 0) return 0L; - - crc32val = crc32val ^ 0xffffffff; - for (i = 0; i < len; i++) { - crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); - } - return crc32val ^ 0xffffffff; -} - -/* Return a 32-bit CRC of the contents of the buffer, using the - Ethernet FCS algorithm. */ -cyg_uint32 -cyg_ether_crc32(void *s, int len) -{ - return cyg_ether_crc32_accumulate(0,s,len); -} - - diff --git a/tools/firmware-utils/src/dgfirmware.c b/tools/firmware-utils/src/dgfirmware.c deleted file mode 100644 index c5549c82be..0000000000 --- a/tools/firmware-utils/src/dgfirmware.c +++ /dev/null @@ -1,384 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - - -#define IMG_SIZE 0x3e0000 - -#define KERNEL_START 0x020000 -#define KERNEL_SIZE 0x0b0000 - -#define ROOTFS_START 0x0d0000 -#define ROOTFS_SIZE 0x30ffb2 - -char* app_name; - - - - -void print_usage(void) -{ - fprintf(stderr, "usage: dgfirmware [<opts>] <img>\n"); - fprintf(stderr, " <img> firmware image filename\n"); - fprintf(stderr, " <opts> -h print this message\n"); - fprintf(stderr, " -f fix the checksum\n"); - fprintf(stderr, " -x <file> extract the rootfs file to <file>\n"); - fprintf(stderr, " -xk <file> extract the kernel to <file>\n"); - fprintf(stderr, " -m <file> merge in rootfs fil\e from <file>\n"); - fprintf(stderr, " -k <file> merge in kernel from <file>\n"); - fprintf(stderr, " -w <file> write back the modified firmware\n"); -} - - -unsigned char* read_img(const char *fname) -{ - FILE *fp; - int size; - unsigned char *img; - - fp = fopen(fname, "rb"); - if (fp == NULL) { - perror(app_name); - exit(-1); - } - - fseek(fp, 0, SEEK_END); - size = ftell(fp); - - if (size != IMG_SIZE) { - fprintf(stderr, "%s: image file has wrong size\n", app_name); - fclose(fp); - exit(-1); - } - - rewind(fp); - - img = malloc(IMG_SIZE); - if (img == NULL) { - perror(app_name); - fclose(fp); - exit(-1); - } - - if (fread(img, 1, IMG_SIZE, fp) != IMG_SIZE) { - fprintf(stderr, "%s: can't read image file\n", app_name); - fclose(fp); - exit(-1); - } - - fclose(fp); - return img; -} - - -void write_img(unsigned char* img, const char *fname) -{ - FILE *fp; - - fp = fopen(fname, "wb"); - if (fp == NULL) { - perror(app_name); - exit(-1); - } - - if (fwrite(img, 1, IMG_SIZE, fp) != IMG_SIZE) { - fprintf(stderr, "%s: can't write image file\n", app_name); - fclose(fp); - exit(-1); - } - - fclose(fp); -} - - -void write_rootfs(unsigned char* img, const char *fname) -{ - FILE *fp; - - fp = fopen(fname, "wb"); - if (fp == NULL) { - perror(app_name); - exit(-1); - } - - if (fwrite(img+ROOTFS_START, 1, ROOTFS_SIZE, fp) != ROOTFS_SIZE) { - fprintf(stderr, "%s: can't write image file\n", app_name); - fclose(fp); - exit(-1); - } - - fclose(fp); -} - - -void write_kernel(unsigned char* img, const char *fname) -{ - FILE *fp; - - fp = fopen(fname, "wb"); - if (fp == NULL) { - perror(app_name); - exit(-1); - } - - if (fwrite(img+KERNEL_START, 1, KERNEL_SIZE, fp) != KERNEL_SIZE) { - fprintf(stderr, "%s: can't write kernel file\n", app_name); - fclose(fp); - exit(-1); - } - - fclose(fp); -} - - -unsigned char* read_rootfs(unsigned char* img, const char *fname) -{ - FILE *fp; - int size; - int i; - - for (i=ROOTFS_START; i<ROOTFS_START+ROOTFS_SIZE; i++) - img[i] = 0xff; - - fp = fopen(fname, "rb"); - if (fp == NULL) { - perror(app_name); - exit(-1); - } - - fseek(fp, 0, SEEK_END); - size = ftell(fp); - - if (size > ROOTFS_SIZE) { - fprintf(stderr, "%s: rootfs image file is too big\n", app_name); - fclose(fp); - exit(-1); - } - - rewind(fp); - - if (fread(img+ROOTFS_START, 1, size, fp) != size) { - fprintf(stderr, "%s: can't read rootfs image file\n", app_name); - fclose(fp); - exit(-1); - } - - fclose(fp); - return img; -} - - -unsigned char* read_kernel(unsigned char* img, const char *fname) -{ - FILE *fp; - int size; - int i; - - for (i=KERNEL_START; i<KERNEL_START+KERNEL_SIZE; i++) - img[i] = 0xff; - - fp = fopen(fname, "rb"); - if (fp == NULL) { - perror(app_name); - exit(-1); - } - - fseek(fp, 0, SEEK_END); - size = ftell(fp); - - if (size > KERNEL_SIZE) { - fprintf(stderr, "%s: kernel binary file is too big\n", app_name); - fclose(fp); - exit(-1); - } - - rewind(fp); - - if (fread(img+KERNEL_START, 1, size, fp) != size) { - fprintf(stderr, "%s: can't read kernel file\n", app_name); - fclose(fp); - exit(-1); - } - - fclose(fp); - return img; -} - - -int get_checksum(unsigned char* img) -{ - short unsigned s; - - s = img[0x3dfffc] + (img[0x3dfffd]<<8); - - return s; -} - - -void set_checksum(unsigned char*img, unsigned short sum) -{ - img[0x3dfffc] = sum & 0xff; - img[0x3dfffd] = (sum>>8) & 0xff; -} - - -int compute_checksum(unsigned char* img) -{ - int i; - short s=0; - - for (i=0; i<0x3dfffc; i++) - s += img[i]; - - return s; -} - - -int main(int argc, char* argv[]) -{ - char *img_fname = NULL; - char *rootfs_fname = NULL; - char *kernel_fname = NULL; - char *new_img_fname = NULL; - - int do_fix_checksum = 0; - int do_write = 0; - int do_write_rootfs = 0; - int do_read_rootfs = 0; - int do_write_kernel = 0; - int do_read_kernel = 0; - - int i; - unsigned char *img; - unsigned short img_checksum; - unsigned short real_checksum; - - app_name = argv[0]; - - for (i=1; i<argc; i++) { - if (!strcmp(argv[i], "-h")) { - print_usage(); - return 0; - } - else if (!strcmp(argv[i], "-f")) { - do_fix_checksum = 1; - } - else if (!strcmp(argv[i], "-x")) { - if (i+1 >= argc) { - fprintf(stderr, "%s: missing argument\n", app_name); - return -1; - } - do_write_rootfs = 1; - rootfs_fname = argv[i+1]; - i++; - } - else if (!strcmp(argv[i], "-xk")) { - if (i+1 >= argc) { - fprintf(stderr, "%s: missing argument\n", app_name); - return -1; - } - do_write_kernel = 1; - kernel_fname = argv[i+1]; - i++; - } - else if (!strcmp(argv[i], "-m")) { - if (i+1 >= argc) { - fprintf(stderr, "%s: missing argument\n", app_name); - return -1; - } - do_read_rootfs = 1; - rootfs_fname = argv[i+1]; - i++; - } - else if (!strcmp(argv[i], "-k")) { - if (i+1 >= argc) { - fprintf(stderr, "%s: missing argument\n", app_name); - return -1; - } - do_read_kernel = 1; - kernel_fname = argv[i+1]; - i++; - } - else if (!strcmp(argv[i], "-w")) { - if (i+1 >= argc) { - fprintf(stderr, "%s: missing argument\n", app_name); - return -1; - } - do_write = 1; - new_img_fname = argv[i+1]; - i++; - } - else if (img_fname != 0) { - fprintf(stderr, "%s: too many arguments\n", app_name); - return -1; - } - else { - img_fname = argv[i]; - } - } - - if (img_fname == NULL) { - fprintf(stderr, "%s: missing argument\n", app_name); - return -1; - } - - if ((do_read_rootfs && do_write_rootfs) || - (do_read_kernel && do_write_kernel)) { - fprintf(stderr, "%s: conflictuous options\n", app_name); - return -1; - } - - printf ("** Read firmware file\n"); - img = read_img(img_fname); - - printf ("Firmware product: %s\n", img+0x3dffbd); - printf ("Firmware version: 1.%02d.%02d\n", (img[0x3dffeb] & 0x7f), img[0x3dffec]); - - if (do_write_rootfs) { - printf ("** Write rootfs file\n"); - write_rootfs(img, rootfs_fname); - } - - if (do_write_kernel) { - printf ("** Write kernel file\n"); - write_kernel(img, kernel_fname); - } - - if (do_read_rootfs) { - printf ("** Read rootfs file\n"); - read_rootfs(img, rootfs_fname); - do_fix_checksum = 1; - } - - if (do_read_kernel) { - printf ("** Read kernel file\n"); - read_kernel(img, kernel_fname); - do_fix_checksum = 1; - } - - img_checksum = get_checksum(img); - real_checksum = compute_checksum(img); - - printf ("image checksum = %04x\n", img_checksum); - printf ("real checksum = %04x\n", real_checksum); - - if (do_fix_checksum) { - if (img_checksum != real_checksum) { - printf ("** Bad Checksum, fix it\n"); - set_checksum(img, real_checksum); - } - else { - printf ("** Checksum is correct, good\n"); - } - } - - if (do_write) { - printf ("** Write image file\n"); - write_img(img, new_img_fname); - } - - free(img); - return 0; -} - diff --git a/tools/firmware-utils/src/dgn3500sum.c b/tools/firmware-utils/src/dgn3500sum.c deleted file mode 100644 index 6c2937ed51..0000000000 --- a/tools/firmware-utils/src/dgn3500sum.c +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* ************************************************************************** - - This program creates a modified 16bit checksum used for the Netgear - DGN3500 series routers. The difference between this and a standard - checksum is that every 0x100 bytes added 0x100 have to be subtracted - from the sum. - - (C) 2013 Marco Antonio Mauro <marcus90 at gmail.com> - - Based on previous unattributed work. - - ************************************************************************* */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> - -unsigned char PidDataWW[70] = -{ - 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32, - 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37, - 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, - 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, -} ; - -unsigned char PidDataDE[70] = -{ - 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32, - 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37, - 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, - 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, -} ; - -unsigned char PidDataNA[70] = -{ - 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32, - 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37, - 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, - 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, -} ; - -/* ******************************************************************* - Reads the file into memory and returns pointer to the buffer. */ -static char *readfile(char *filename, int *size) -{ - FILE *fp; - char *buffer; - struct stat info; - - if (stat(filename,&info)!=0) - return NULL; - - if ((fp=fopen(filename,"r"))==NULL) - return NULL; - - buffer=NULL; - for (;;) - { - if ((buffer=(char *)malloc(info.st_size+1))==NULL) - break; - - if (fread(buffer,1,info.st_size,fp)!=info.st_size) - { - free(buffer); - buffer=NULL; - break; - } - - buffer[info.st_size]='\0'; - if(size) *size = info.st_size; - - break; - } - - (void)fclose(fp); - - return buffer; -} - - -/* ******************************************************************* */ -int main(int argc, char** argv) -{ - unsigned long start, i; - char *endptr, *buffer, *p; - int count; // size of file in bytes - unsigned short sum = 0, sum1 = 0; - char sumbuf[8 + 8 + 1]; - - if(argc < 3) { - printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]); - return 1; - } - - - FILE *fp = fopen(argv[1], "a"); - if(!fp) { - printf("ERROR: File not writeable!\n"); - return 1; - } - if(argc == 4) - { - printf("%s: PID type: %s\n", argv[0], argv[3]); - if(strcmp(argv[3], "DE")==0) - fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */ - else if(strcmp(argv[3], "NA")==0) - fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */ - else /* if(strcmp(argv[3], "WW")) */ - fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */ - } - else - fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */ - - fclose(fp); - - /* Read the file to calculate the checksums */ - buffer = readfile(argv[1], &count); - if(!buffer) { - printf("ERROR: File %s not found!\n", argv[1]); - return 1; - } - - p = buffer; - for(i = 0; i < count; i++) - { - sum += p[i]; - } - - start = strtol(argv[2], &endptr, 16); - p = buffer+start; - for(i = 0; i < count - start; i++) - { - sum1 += p[i]; - } - - sprintf(sumbuf,"%04X%04X",sum1,sum); - /* Append the 2 checksums to end of file */ - fp = fopen(argv[1], "a"); - if(!fp) { - printf("ERROR: File not writeable!\n"); - return 1; - } - fwrite(sumbuf, 8, sizeof(char), fp); - fclose(fp); - free(buffer); - return 0; -} diff --git a/tools/firmware-utils/src/dns313-header.c b/tools/firmware-utils/src/dns313-header.c deleted file mode 100644 index 96e4b6e5c2..0000000000 --- a/tools/firmware-utils/src/dns313-header.c +++ /dev/null @@ -1,237 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * dns313-header.c - * - * Program to add the modified U-Boot header to a binary used with - * the D-Link DNS-313 boot loader when booting directly from an - * EXT2 formatted hard drive. - * - * The DNS313 use the same header on zImage, ramdisk, rootfs. - * - * Written by Linus Walleij <linus.walleij@linaro.org> - */ -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <stdint.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -/* - * This is the U-Boot magic number, so the U-Boot header was used - * (obviously) as a template for this custom header. - */ -#define IH_MAGIC 0x27051956 -#define HEADER_SIZE 0x68 - -#define OFFSET_MAGIC 0x00 -#define OFFSET_HCRC 0x04 -#define OFFSET_TIME 0x08 -#define OFFSET_SIZE 0x0c -#define OFFSET_LOAD 0x10 -#define OFFSET_EP 0x14 -#define OFFSET_DCRC 0x18 -#define OFFSET_OS 0x1c -#define OFFSET_ARCH 0x1d -#define OFFSET_TYPE 0x1e -#define OFFSET_COMP 0x1f -#define OFFSET_NAME 0x20 -#define NAME_LEN 0x20 -#define OFFSET_MODEL 0x40 -#define MODEL_LEN 0x10 -#define OFFSET_VERSION 0x50 -#define VERSION_LEN 0x10 -#define OFFSET_MAC 0x60 -#define MAC_LEN 6 - -static const uint32_t crc32_table[256] = { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -}; - -static uint32_t crc32(uint32_t crc, - const void *data, - unsigned int len) -{ - const uint8_t *buf = data; - - crc = crc ^ 0xffffffffUL; - do { - crc = crc32_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); - } while (--len); - return crc ^ 0xffffffffUL; -} - -static void be_wr(char *buf, uint32_t val) -{ - buf[0] = (val >> 24) & 0xFFU; - buf[1] = (val >> 16) & 0xFFU; - buf[2] = (val >> 8) & 0xFFU; - buf[3] = val & 0xFFU; -} - -int main(int argc, char **argv) -{ - int fdin; - int fdout; - struct stat sb; - uint32_t filesize; - int ret = 0; - const char *pathin; - const char *pathout; - char *buffer; - uint32_t sum; - size_t bufsize; - size_t bytes; - - if (argc < 3) { - printf("Too few arguments.\n"); - printf("%s <infile> <outfile>\n", argv[0]); - } - - pathin = argv[1]; - pathout = argv[2]; - - ret = stat(pathin, &sb); - if (ret < 0) - return ret; - - filesize = sb.st_size; - printf("INFILE: %s, size: %08x bytes\n", pathin, filesize); - /* File + extended header size */ - bufsize = filesize + HEADER_SIZE; - - printf("Allocate %08zx bytes\n", bufsize); - buffer = malloc(bufsize); - if (!buffer) { - printf("OOM: could not allocate buffer\n"); - return 0; - } - - memset(buffer, 0x00, bufsize); - - /* Read file to buffer */ - fdin = open(pathin, O_RDONLY); - if (!fdin) { - printf("ERROR: could not open input file\n"); - free(buffer); - return 0; - } - bytes = read(fdin, buffer + HEADER_SIZE, filesize); - if (bytes < filesize) { - printf("ERROR: could not read entire file\n"); - free(buffer); - close(fdin); - return 0; - } - close(fdin); - - be_wr(buffer + OFFSET_MAGIC, IH_MAGIC); - - /* FIXME: use actual time */ - be_wr(buffer + OFFSET_TIME, 0x4c06738c); - be_wr(buffer + OFFSET_SIZE, filesize); - - /* Load address & entry point */ - be_wr(buffer + OFFSET_LOAD, 0x00008000); - be_wr(buffer + OFFSET_EP, 0x00008000); - - buffer[OFFSET_OS] = 0x05; /* Linux */ - buffer[OFFSET_ARCH] = 0x02; /* ARM */ - buffer[OFFSET_TYPE] = 0x02; /* OS kernel image */ - buffer[OFFSET_COMP] = 0x01; /* gzip */ - - /* The vendor firmware just hardcodes this */ - strncpy(buffer + OFFSET_NAME, "kernel.img", NAME_LEN); - buffer[OFFSET_NAME + NAME_LEN - 1] = '\0'; - strncpy(buffer + OFFSET_MODEL, "dns-313v3", MODEL_LEN); - buffer[OFFSET_MODEL + MODEL_LEN - 1] = '\0'; - strncpy(buffer + OFFSET_VERSION, "2.01b04", VERSION_LEN); - buffer[OFFSET_VERSION + VERSION_LEN - 1] = '\0'; - /* Just some MAC address from the example */ - buffer[OFFSET_MAC] = 0x00; - buffer[OFFSET_MAC + 1] = 0x80; - buffer[OFFSET_MAC + 2] = 0xc8; - buffer[OFFSET_MAC + 3] = 0x16; - buffer[OFFSET_MAC + 4] = 0x81; - buffer[OFFSET_MAC + 5] = 0x68; - - /* Checksum payload */ - sum = crc32(0, buffer + HEADER_SIZE, filesize); - be_wr(buffer + OFFSET_DCRC, sum); - printf("data checksum: 0x%08x\n", sum); - - /* Checksum header, then write that into the header checksum */ - sum = crc32(0, buffer, HEADER_SIZE); - be_wr(buffer + OFFSET_HCRC, sum); - printf("header checksum: 0x%08x\n", sum); - - printf("OUTFILE: %s, size: %08zx bytes\n", pathout, bufsize); - fdout = open(pathout, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU|S_IRGRP); - if (!fdout) { - printf("ERROR: could not open output file\n"); - return 0; - } - bytes = write(fdout, buffer, bufsize); - if (bytes < bufsize) { - printf("ERROR: could not write complete output file\n"); - return 0; - } - close(fdout); - - free(buffer); - - return 0; -} diff --git a/tools/firmware-utils/src/edimax_fw_header.c b/tools/firmware-utils/src/edimax_fw_header.c deleted file mode 100644 index f326f246ba..0000000000 --- a/tools/firmware-utils/src/edimax_fw_header.c +++ /dev/null @@ -1,382 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include <arpa/inet.h> -#include <netinet/in.h> - -#define MAX_MAGIC_LEN 16 -#define MAX_MODEL_LEN 32 -#define MAX_VERSION_LEN 14 -#define MAX_MTD_NAME_LEN 16 - -#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) - -struct edimax_header { - char magic[MAX_MAGIC_LEN]; - char model[MAX_MODEL_LEN]; - unsigned char force; - unsigned char header_csum; - unsigned char data_csum; - uint32_t data_size; - uint32_t start_addr; - uint32_t end_addr; - char fw_version[MAX_VERSION_LEN]; - unsigned char type; - char mtd_name[MAX_MTD_NAME_LEN]; -} __attribute__ ((packed)); - -/* - * Globals - */ -static char *ofname; -static char *ifname; -static char *progname; - -static char *model; -static char *magic = "eDiMaX"; -static char *fw_version = ""; -static char *mtd_name; -static int force; -static uint32_t start_addr; -static uint32_t end_addr; -static uint8_t image_type; -static int data_size; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt " (%s)\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -e <addr> set end addr to <addr>\n" -" -f set force flag\n" -" -h show this screen\n" -" -i <file> read input data from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -m <model> set model to <model>\n" -" -M <magic> set image magic to <magic>\n" -" -n <name> set MTD device name to <name>\n" -" -s <addr> set start address to <addr>\n" -" -t <type> set image type to <type>\n" -" -v <version> set firmware version to <version>\n" - ); - - exit(status); -} - -int -str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - -int -str2u8(char *arg, uint8_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) { - return -1; - } - - *val = t & 0xFF; - return 0; -} - -static int get_file_size(char *name) -{ - struct stat st; - int res; - - res = stat(name, &st); - if (res){ - ERRS("stat failed on %s", name); - return -1; - } - - return st.st_size; -} - -static int read_to_buf(char *name, char *buf, int buflen) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", name); - goto out; - } - - errno = 0; - fread(buf, buflen, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", name); - goto out_close; - } - - ret = EXIT_SUCCESS; - -out_close: - fclose(f); -out: - return ret; -} - -static int check_options(void) -{ -#define CHKSTR(_name, _msg) \ - do { \ - if (_name == NULL) { \ - ERR("no %s specified", _msg); \ - return -1; \ - } \ - } while (0) - -#define CHKSTRLEN(_name, _msg) \ - do { \ - int field_len; \ - CHKSTR(_name, _msg); \ - field_len = FIELD_SIZEOF(struct edimax_header, _name) - 1; \ - if (strlen(_name) > field_len) { \ - ERR("'%s' is too long, max %s length is %d", \ - _name, _msg, field_len); \ - return -1; \ - } \ - } while (0) - - CHKSTR(ofname, "output file"); - CHKSTR(ifname, "input file"); - - CHKSTRLEN(magic, "magic"); - CHKSTRLEN(model, "model"); - CHKSTRLEN(mtd_name, "MTD device name"); - CHKSTRLEN(fw_version, "firware version"); - - data_size = get_file_size(ifname); - if (data_size < 0) - return -1; - - return 0; -} - -static int write_fw(char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - -out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); - } -out: - return ret; -} - -static unsigned char checksum(unsigned char *p, unsigned len) -{ - unsigned char csum = 0; - - while (len--) - csum += *p++; - - csum ^= 0xb9; - - return csum; -} - -static int build_fw(void) -{ - int buflen; - char *buf; - char *data; - struct edimax_header *hdr; - int ret = EXIT_FAILURE; - - buflen = sizeof(struct edimax_header) + data_size; - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - data = buf + sizeof(struct edimax_header); - - /* read input file */ - ret = read_to_buf(ifname, data, data_size); - if (ret) - goto out_free_buf; - - /* fill firmware header */ - hdr = (struct edimax_header *)buf; - memset(hdr, 0, sizeof(struct edimax_header)); - - strncpy(hdr->model, model, sizeof(hdr->model)); - strncpy(hdr->magic, magic, sizeof(hdr->magic)); - strncpy(hdr->fw_version, fw_version, sizeof(hdr->fw_version)); - strncpy(hdr->mtd_name, mtd_name, sizeof(hdr->mtd_name)); - - hdr->force = force; - hdr->start_addr = htonl(start_addr); - hdr->end_addr = htonl(end_addr); - hdr->data_size = htonl(data_size); - hdr->type = image_type; - - hdr->data_csum = checksum((unsigned char *)data, data_size); - hdr->header_csum = checksum((unsigned char *)hdr, - sizeof(struct edimax_header)); - - ret = write_fw(buf, buflen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - -out_free_buf: - free(buf); -out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - - while (1) { - int c; - - c = getopt(argc, argv, "e:fhi:o:m:M:n:s:t:v:"); - if (c == -1) - break; - - switch (c) { - case 'e': - if (str2u32(optarg, &end_addr)) { - ERR("%s is invalid '%s'", - "end address", optarg); - goto out; - } - break; - case 'f': - force = 1; - break; - case 'i': - ifname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - case 'o': - ofname = optarg; - break; - case 'm': - model = optarg; - break; - case 'M': - magic = optarg; - break; - case 'n': - mtd_name = optarg; - break; - case 's': - if (str2u32(optarg, &start_addr)) { - ERR("%s is invalid '%s'", - "start address", optarg); - goto out; - } - break; - case 't': - if (str2u8(optarg, &image_type)) { - ERR("%s is invalid '%s'", - "image type", optarg); - goto out; - } - break; - case 'v': - fw_version = optarg; - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - ret = build_fw(); - -out: - return ret; -} diff --git a/tools/firmware-utils/src/encode_crc.c b/tools/firmware-utils/src/encode_crc.c deleted file mode 100644 index 80f44f133e..0000000000 --- a/tools/firmware-utils/src/encode_crc.c +++ /dev/null @@ -1,138 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* ************************************************************************** - - This program creates a CRC checksum and encodes the file that is named - in the command line. - - Compile with: gcc encode_crc.c -Wall -o encode_crc - - Author: Michael Margraf (michael.margraf@freecom.com) - Copyright: Freecom Technology GmbH, Berlin, 2004 - www.freecom.com - - ************************************************************************* */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> - -// ******************************************************************* -// CCITT polynom G(x)=x^16+x^12+x^5+1 -#define POLYNOM 0x1021 - -// CRC algorithm with MSB first -int make_crc16(int crc, char new) -{ - int i; - crc = crc ^ (((int)new) << 8); - - for(i=0; i<8; i++) { // work on 8 bits in "new" - crc <<= 1; // MSBs first - if(crc & 0x10000) crc ^= POLYNOM; - } - return crc & 0xFFFF; -} - -// ******************************************************************* -// Reads the file "filename" into memory and returns pointer to the buffer. -static char *readfile(char *filename, int *size) -{ - FILE *fp; - char *buffer; - struct stat info; - - if (stat(filename,&info)!=0) - return NULL; - - if ((fp=fopen(filename,"r"))==NULL) - return NULL; - - buffer=NULL; - for (;;) - { - if ((buffer=(char *)malloc(info.st_size+1))==NULL) - break; - - if (fread(buffer,1,info.st_size,fp)!=info.st_size) - { - free(buffer); - buffer=NULL; - break; - } - - buffer[info.st_size]='\0'; - if(size) *size = info.st_size; - - break; - } - - (void)fclose(fp); - - return buffer; -} - - -// ******************************************************************* -int main(int argc, char** argv) -{ - if(argc < 3) { - printf("ERROR: Argument missing!\n\n"); - return 1; - } - - int count; // size of file in bytes - char *p, *master = readfile(argv[1], &count); - if(!master) { - printf("ERROR: File not found!\n"); - return 1; - } - - int crc = 0xFFFF, z; - - p = master; - for(z=0; z<count; z++) - crc = make_crc16(crc, *(p++)); // calculate CRC - short crc16 = (short)crc; - - /* - if(argc > 2) { // with flag for device recognition ? - p = argv[2]; - for(z=strlen(p); z>0; z--) { - crc ^= (int)(*p); - *(p++) = (char)crc; // encode device flag - } - } - */ - - p = master; - for(z=0; z<count; z++) { - crc ^= (int)(*p); - *(p++) = (char)crc; // encode file - } - - - // write encoded file... - FILE *fp = fopen(argv[2], "w"); - if(!fp) { - printf("ERROR: File not writeable!\n"); - return 1; - } - - if(argc > 3) { // add flag for device recognition ? - fwrite(argv[3], strlen(argv[3]), sizeof(char), fp); - } - else { - // Device is an FSG, so byte swap (IXP4xx is big endian) - crc16 = ((crc16 >> 8) & 0xFF) | ((crc16 << 8) & 0xFF00); - } - - fwrite(&crc16, 1, sizeof(short), fp); // first write CRC - - fwrite(master, count, sizeof(char), fp); // write content - fclose(fp); - - free(master); - return 0; -} diff --git a/tools/firmware-utils/src/fix-u-media-header.c b/tools/firmware-utils/src/fix-u-media-header.c deleted file mode 100644 index 8b6a81a5e3..0000000000 --- a/tools/firmware-utils/src/fix-u-media-header.c +++ /dev/null @@ -1,350 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org> - */ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include "cyg_crc.h" - -#include <arpa/inet.h> -#include <netinet/in.h> - -#define IH_MAGIC 0x27051956 /* Image Magic Number */ -#define IH_NMLEN 32 /* Image Name Length */ - -#define UM_MAGIC 0x55525F46 -#define UM_HEADER_LEN 12 - -/* - * all data in network byte order (aka natural aka bigendian) - */ -struct u_media_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 - UM_HEADER_LEN]; /* Image Name */ - - uint32_t ih_UMedia_magic; /* U-Media magic number */ - uint32_t ih_UMedia_boardID; /* U-Media board ID */ - uint8_t ih_UMedia_imageType; /* U-Media image type */ - uint8_t ih_UMedia_LoadDefault; /* U-Media load to factory default setting */ - uint8_t ih_UMedia_temp1; /* U-Media didn't use this tag */ - uint8_t ih_UMedia_temp2; /* U-Media didn't use this tag */ -} __attribute__ ((packed)); - -struct if_info { - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ -}; - -static char *progname; -static char *ofname; -static struct if_info if_info; -static int factory_defaults; -static uint32_t board_id; -static uint8_t image_type; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt " (%s)\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board_id> set board ID to <board_id>\n" -" -i <file> read input from the file <file>\n" -" -F load factory defaults\n" -" -o <file> write output to the file <file>\n" -" -T <type> set image type to <type>\n" -" -h show this screen\n" - ); - - exit(status); -} - -static int str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - -static int str2u8(char *arg, uint8_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - if (t > 255) - return -1; - - *val = t; - return 0; -} - -static int get_file_stat(struct if_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) - return 0; - - res = stat(fdata->file_name, &st); - if (res){ - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - return 0; -} - -static int read_to_buf(struct if_info *fdata, char *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(fdata->file_name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - errno = 0; - fread(buf, fdata->file_size, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - -out_close: - fclose(f); -out: - return ret; -} - -static int check_options(void) -{ - int ret; - - if (ofname == NULL) { - ERR("no %s specified", "output file"); - return -1; - } - - if (if_info.file_name == NULL) { - ERR("no %s specified", "input file"); - return -1; - } - - ret = get_file_stat(&if_info); - if (ret) - return ret; - - return 0; -} - -static int write_fw(char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - ret = EXIT_SUCCESS; - -out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); - } -out: - return ret; -} - -static int fix_header(void) -{ - int buflen; - char *buf; - uint32_t crc, crc_orig; - struct u_media_header *hdr; - int ret = EXIT_FAILURE; - - buflen = if_info.file_size; - if (buflen < sizeof(*hdr)) { - ERR("invalid input file\n"); - return ret; - } - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - ret = read_to_buf(&if_info, buf); - if (ret) - goto out_free_buf; - - hdr = (struct u_media_header *) buf; - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - ERR("invalid input file, bad magic\n"); - goto out_free_buf; - } - - /* verify header CRC */ - crc_orig = ntohl(hdr->ih_hcrc); - hdr->ih_hcrc = 0; - crc = cyg_ether_crc32((unsigned char *)hdr, sizeof(*hdr)); - if (crc != crc_orig) { - ERR("invalid input file, bad header CRC\n"); - goto out_free_buf; - } - - hdr->ih_name[IH_NMLEN - UM_HEADER_LEN - 1] = '\0'; - - /* set U-Media specific fields */ - hdr->ih_UMedia_magic = htonl(UM_MAGIC); - hdr->ih_UMedia_boardID = htonl(board_id); - hdr->ih_UMedia_imageType = image_type; - hdr->ih_UMedia_LoadDefault = (factory_defaults) ? 1 : 0; - - /* update header CRC */ - crc = cyg_ether_crc32((unsigned char *)hdr, sizeof(*hdr)); - hdr->ih_hcrc = htonl(crc); - - ret = write_fw(buf, buflen); - if (ret) - goto out_free_buf; - - DBG("U-Media header fixed in \"%s\"", ofname); - - ret = EXIT_SUCCESS; - -out_free_buf: - free(buf); -out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - - while (1) { - int c; - - c = getopt(argc, argv, "B:Fi:o:T:h"); - if (c == -1) - break; - - switch (c) { - case 'B': - if (str2u32(optarg, &board_id)) { - ERR("%s is invalid '%s'", - "board ID", optarg); - goto out; - } - break; - case 'T': - if (str2u8(optarg, &image_type)) { - ERR("%s is invalid '%s'", - "image type", optarg); - goto out; - } - break; - case 'F': - factory_defaults = 1; - break; - case 'i': - if_info.file_name = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - ret = fix_header(); - -out: - return ret; -} diff --git a/tools/firmware-utils/src/fw.h b/tools/firmware-utils/src/fw.h deleted file mode 100644 index d2be71e983..0000000000 --- a/tools/firmware-utils/src/fw.h +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * * Copyright (C) 2007 Ubiquiti Networks, Inc. - */ - -#ifndef FW_INCLUDED -#define FW_INCLUDED - -#include <stdint.h> -#include <sys/types.h> - -#define MAGIC_HEADER "OPEN" -#define MAGIC_PART "PART" -#define MAGIC_END "END." -#define MAGIC_ENDS "ENDS" - -#define MAGIC_LENGTH 4 -#define PART_NAME_LENGTH 16 - -typedef struct header { - char magic[MAGIC_LENGTH]; - char version[256]; - u_int32_t crc; - u_int32_t pad; -} __attribute__ ((packed)) header_t; - -typedef struct part { - char magic[MAGIC_LENGTH]; - char name[PART_NAME_LENGTH]; - uint8_t pad[12]; - u_int32_t memaddr; - u_int32_t index; - u_int32_t baseaddr; - u_int32_t entryaddr; - u_int32_t data_size; - u_int32_t part_size; -} __attribute__ ((packed)) part_t; - -typedef struct part_crc { - u_int32_t crc; - u_int32_t pad; -} __attribute__ ((packed)) part_crc_t; - -typedef struct signature { - uint8_t magic[MAGIC_LENGTH]; - u_int32_t crc; - u_int32_t pad; -} __attribute__ ((packed)) signature_t; - -typedef struct signature_rsa { - uint8_t magic[MAGIC_LENGTH]; -// u_int32_t crc; - unsigned char rsa_signature[256]; - u_int32_t pad; -} __attribute__ ((packed)) signature_rsa_t; - -#define VERSION "1.2" - -#define INFO(...) fprintf(stdout, __VA_ARGS__) -#define ERROR(...) fprintf(stderr, "ERROR: "__VA_ARGS__) -#define WARN(...) fprintf(stderr, "WARN: "__VA_ARGS__) -#define DEBUG(...) do {\ - if (debug) \ - fprintf(stdout, "DEBUG: "__VA_ARGS__); \ -} while (0); - -#endif diff --git a/tools/firmware-utils/src/hcsmakeimage.c b/tools/firmware-utils/src/hcsmakeimage.c deleted file mode 100644 index ce954cfcc9..0000000000 --- a/tools/firmware-utils/src/hcsmakeimage.c +++ /dev/null @@ -1,208 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdlib.h> -#include <sys/types.h> -#include <stdio.h> -#include <inttypes.h> -#include <string.h> -#include <getopt.h> -#include <unistd.h> -#include <errno.h> -#include <time.h> -#include <sys/stat.h> -#include <libgen.h> -#include "bcmalgo.h" - - -int flag_print_version; -int flag_print_help; -int flag_compress; - -uint16_t sa2100_magic = 0x2100; -uint16_t sa3349_magic = 0x3349; -uint32_t default_date = 0x00000000; //A long time ago in a galaxy far far away.... -uint32_t default_load_address = 0x80010000; //The default load_address for the firmware image - -static void print_help ( const char* ename ) -{ - printf ( "Firmware image packer and calculator for broadcom-based modems.\n" ); - printf ( "Part of bcm-utils package.\n" ); - printf ( "(c) 2009 Necromant (http://necromant.ath.cx). Thanks to Luke-jr for his initial work.\n" ); - printf ( "usage: %s [options]\n", ename ); - printf ( "Valid options are:\n" ); - printf ( "--magic_bytes=value \t- specify magic bytes at the beginning of the image. default - 3349\n" ); - printf ( "\t\t\t these can be sa2100 (for DPC2100 modem),\n\t\t\t sa3349 (haxorware guys use this one for some reason),\n\t\t\t or a custom hex value e.g. 0xFFFF\n" ); - printf ( "--compress \t\t - Make use of LZMA (weird!) compression (Doesn't work yet).\n" ); - printf ( "--rev_maj=value\t\t - major revision number. default 0\n" ); - printf ( "--rev_min=value\t\t - minor revision number default 0\n" ); - printf ( "--filename=value\t - use this filename in header instead of default (input filename)\n" ); - printf ( "--ldaddress=value\t - hex value of the target load address. defaults to 0x80010000\n" ); - printf ( "--input_file=value\t - What file are we packing?\n" ); - printf ( "--output_file=value\t - What file shall we write? (default: image.bin)\n" ); -#ifdef _HAX0RSTYLE - printf ( "--credz\t - Give some credz!\n" ); -#endif - printf ( "\n" ); -} - -static time_t source_date_epoch = -1; -static void set_source_date_epoch() { - char *env = getenv("SOURCE_DATE_EPOCH"); - char *endptr = env; - errno = 0; - if (env && *env) { - source_date_epoch = strtoull(env, &endptr, 10); - if (errno || (endptr && *endptr != '\0')) { - fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); - exit(1); - } - } -} - -int main ( int argc, char** argv ) -{ - if ( argc<2 ) - { - print_help ( argv[0] ); - } - - static struct option long_options[] = - { - {"magic_bytes", required_argument, 0, 'm'}, - {"rev_maj", required_argument, 0, 'j'}, - {"rev_min", required_argument, 0, 'n'}, - {"ldaddress", required_argument, 0, 'l'}, - {"filename", required_argument, 0, 'f'}, - {"input_file", required_argument, 0, 'i'}, - {"output_file", required_argument, 0, 'o'}, - {"compress", no_argument, &flag_compress, 'c'}, - {"version", no_argument, &flag_print_version, 'v'}, - {"help", no_argument, &flag_print_help, 'h'}, - {0, 0, 0, 0} - }; - int option_index = 0; - int opt_result=0; - char* filename=NULL; - char* input=NULL; - char* magic=NULL; - char* major=NULL; - char* minor=NULL; - char* ldaddr=NULL; - char* output=NULL; - - while ( opt_result>=0 ) - { - opt_result = getopt_long ( argc, argv, "m:j:n:f:i:o:vh", long_options, &option_index ); - switch ( opt_result ) - { - case 0: - printf ( "o!\n" ); - break; - case 'h': - print_help ( argv[0] ); - break; - case 'l': - ldaddr=optarg; - break; - case 'f': - filename=optarg; - break; - case 'i': - input=optarg; - break; - case 'o': - output=optarg; - break; - case 'm': - magic=optarg; - break; - case 'j': - major=optarg; - break; - case 'n': - minor=optarg; - break; - } - } - if ( input==NULL ) - { - printf ( "Telepaths are still on holidays. I guess you should tell me what file should I process.\n\n" ); - exit ( 1 ); - } - if ( access ( input,R_OK ) !=0 ) - { - printf ( "I cannot access the file %s. Is it there? Am I allowed?\n\n", input ); - exit ( 1 ); - } - uint32_t magicnum=sa2100_magic; - - if ( magic ) - { - if ( strcmp ( magic,"sa2100" ) ==0 ) magicnum=sa2100_magic; else - if ( strcmp ( magic,"sa3349" ) ==0 ) magicnum=sa3349_magic; else - { - sscanf ( magic, "0x%04X", &magicnum ); - } - } - unsigned int majrev=0; - if ( major ) - { - sscanf ( major, "%d", &majrev ); - } - unsigned int minrev=0; - if ( minor ) - { - sscanf ( minor, "%d", &minrev ); - } - uint32_t ldaddress = default_load_address; - if ( ldaddr ) - { - sscanf ( ldaddr, "0x%08X", &ldaddress ); - } - char* dupe = strdup(input); - char* fname = basename ( dupe ); - if ( filename ) - { - fname = filename; - } - - time_t t = -1; - set_source_date_epoch(); - if (source_date_epoch != -1) { - t = source_date_epoch; - } else if ((time(&t) == (time_t)(-1))) { - fprintf(stderr, "time call failed\n"); - return EXIT_FAILURE; - } - - struct stat buf; - stat ( input,&buf ); - ldr_header_t* head = construct_header ( magicnum, (uint16_t) majrev, (uint16_t) minrev, ( uint32_t ) t, ( uint32_t ) buf.st_size, ldaddress, fname, get_file_crc ( input ) ); - free(dupe); - //uint32_t magic, uint16_t rev_maj,uint16_t rev_min, uint32_t build_date, uint32_t filelen, uint32_t ldaddress, const char* filename, uint32_t crc - //FILE* fd = fopen ("/tftpboot/haxorware11rev32.bin","r"); - //fread(head,sizeof(ldr_header_t),1,fd); - char* filebuffer = malloc ( buf.st_size+10 ); - FILE* fd = fopen ( input,"r" ); - fread ( filebuffer, 1, buf.st_size,fd ); - fclose (fd); - if (!output) - { - output = malloc(strlen(input+5)); - strcpy(output,input); - strcat(output,".bin"); - } - dump_header ( head ); - FILE* fd_out = fopen ( output,"w+" ); - if (!fd_out) - { - fprintf(stderr, "Failed to open output file: %s\n", output); - free(filebuffer); - exit(1); - } - fwrite ( head,1,sizeof ( ldr_header_t ),fd_out ); - fwrite ( filebuffer,1,buf.st_size,fd_out ); - printf("Firmware image %s is ready\n", output); - free(filebuffer); - fclose(fd_out); - return 0; -} diff --git a/tools/firmware-utils/src/imagetag.c b/tools/firmware-utils/src/imagetag.c deleted file mode 100644 index 6b06bd785a..0000000000 --- a/tools/firmware-utils/src/imagetag.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2008 Axel Gembe <ago@bastart.eu.org> - * Copyright (C) 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <inttypes.h> - -#include "bcm_tag.h" -#include "imagetag_cmdline.h" -#include "cyg_crc.h" - -#define DEADCODE 0xDEADC0DE - -/* Kernel header */ -struct kernelhdr { - uint32_t loadaddr; /* Kernel load address */ - uint32_t entry; /* Kernel entry point address */ - uint32_t lzmalen; /* Compressed length of the LZMA data that follows */ -}; - -static char pirellitab[NUM_PIRELLI][BOARDID_LEN] = PIRELLI_BOARDS; - -void int2tag(char *tag, uint32_t value) { - uint32_t network = htonl(value); - memcpy(tag, (char *)(&network), 4); -} - -uint32_t compute_crc32(uint32_t crc, FILE *binfile, size_t compute_start, size_t compute_len) -{ - uint8_t readbuf[1024]; - size_t read; - - fseek(binfile, compute_start, SEEK_SET); - - /* read block of 1024 bytes */ - while (binfile && !feof(binfile) && !ferror(binfile) && (compute_len >= sizeof(readbuf))) { - read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), binfile); - crc = cyg_crc32_accumulate(crc, readbuf, read); - compute_len = compute_len - read; - } - - /* Less than 1024 bytes remains, read compute_len bytes */ - if (binfile && !feof(binfile) && !ferror(binfile) && (compute_len > 0)) { - read = fread(readbuf, sizeof(uint8_t), compute_len, binfile); - crc = cyg_crc32_accumulate(crc, readbuf, read); - } - - return crc; -} - -size_t getlen(FILE *fp) -{ - size_t retval, curpos; - - if (!fp) - return 0; - - curpos = ftell(fp); - fseek(fp, 0, SEEK_END); - retval = ftell(fp); - fseek(fp, curpos, SEEK_SET); - - return retval; -} - -int tagfile(const char *kernel, const char *rootfs, const char *bin, \ - const struct gengetopt_args_info *args, \ - uint32_t flash_start, uint32_t image_offset, \ - uint32_t block_size, uint32_t load_address, uint32_t entry) -{ - struct bcm_tag tag; - struct kernelhdr khdr; - FILE *kernelfile = NULL, *rootfsfile = NULL, *binfile = NULL, *cfefile = NULL; - size_t cfelen, kerneloff, kernellen, rootfsoff, rootfslen, \ - read, imagelen, rootfsoffpadlen = 0, oldrootfslen, \ - rootfsend; - uint8_t readbuf[1024]; - uint32_t imagecrc = IMAGETAG_CRC_START; - uint32_t kernelcrc = IMAGETAG_CRC_START; - uint32_t rootfscrc = IMAGETAG_CRC_START; - uint32_t kernelfscrc = IMAGETAG_CRC_START; - uint32_t fwaddr = 0; - const uint32_t deadcode = htonl(DEADCODE); - int i; - int is_pirelli = 0; - - - memset(&tag, 0, sizeof(struct bcm_tag)); - - if (!kernel || !rootfs) { - fprintf(stderr, "imagetag can't create an image without both kernel and rootfs\n"); - } - - if (kernel && !(kernelfile = fopen(kernel, "rb"))) { - fprintf(stderr, "Unable to open kernel \"%s\"\n", kernel); - return 1; - } - - if (rootfs && !(rootfsfile = fopen(rootfs, "rb"))) { - fprintf(stderr, "Unable to open rootfs \"%s\"\n", rootfs); - return 1; - } - - if (!bin || !(binfile = fopen(bin, "wb+"))) { - fprintf(stderr, "Unable to open output file \"%s\"\n", bin); - return 1; - } - - if ((args->cfe_given) && (args->cfe_arg)) { - if (!(cfefile = fopen(args->cfe_arg, "rb"))) { - fprintf(stderr, "Unable to open CFE file \"%s\"\n", args->cfe_arg); - } - } - - fwaddr = flash_start + image_offset; - if (cfefile) { - cfelen = getlen(cfefile); - /* Seek to the start of the file after tag */ - fseek(binfile, sizeof(tag), SEEK_SET); - - /* Write the cfe */ - while (cfefile && !feof(cfefile) && !ferror(cfefile)) { - read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), cfefile); - fwrite(readbuf, sizeof(uint8_t), read, binfile); - } - - } else { - cfelen = 0; - } - - if (!args->root_first_flag) { - /* Build the kernel address and length (doesn't need to be aligned, read only) */ - kerneloff = fwaddr + sizeof(tag); - - kernellen = getlen(kernelfile); - - if (!args->kernel_file_has_header_flag) { - /* Build the kernel header */ - khdr.loadaddr = htonl(load_address); - khdr.entry = htonl(entry); - khdr.lzmalen = htonl(kernellen); - - /* Increase the kernel size by the header size */ - kernellen += sizeof(khdr); - } - - /* Build the rootfs address and length */ - rootfsoff = kerneloff + kernellen; - /* align the start if requested */ - if (args->align_rootfs_flag) - rootfsoff = (rootfsoff % block_size) > 0 ? (((rootfsoff / block_size) + 1) * block_size) : rootfsoff; - else - rootfsoff = (rootfsoff % 4) > 0 ? (((rootfsoff / 4) + 1) * 4) : rootfsoff; - - /* align the end */ - rootfsend = rootfsoff + getlen(rootfsfile); - if ((rootfsend % block_size) > 0) - rootfsend = (((rootfsend / block_size) + 1) * block_size); - rootfslen = rootfsend - rootfsoff; - imagelen = rootfsoff + rootfslen - kerneloff + sizeof(deadcode); - rootfsoffpadlen = rootfsoff - (kerneloff + kernellen); - - /* Seek to the start of the kernel */ - fseek(binfile, kerneloff - fwaddr + cfelen, SEEK_SET); - - /* Write the kernel header */ - fwrite(&khdr, sizeof(khdr), 1, binfile); - - /* Write the kernel */ - while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { - read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile); - fwrite(readbuf, sizeof(uint8_t), read, binfile); - } - - /* Write the RootFS */ - fseek(binfile, rootfsoff - fwaddr + cfelen, SEEK_SET); - while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { - read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile); - fwrite(readbuf, sizeof(uint8_t), read, binfile); - } - - /* Align image to specified erase block size and append deadc0de */ - printf("Data alignment to %dk with 'deadc0de' appended\n", block_size/1024); - fseek(binfile, rootfsoff + rootfslen - fwaddr + cfelen, SEEK_SET); - fwrite(&deadcode, sizeof(uint32_t), 1, binfile); - - oldrootfslen = rootfslen; - if (args->pad_given) { - uint32_t allfs = 0xffffffff; - uint32_t pad_size = args->pad_arg * 1024 * 1024; - - printf("Padding image to %d bytes ...\n", pad_size); - while (imagelen < pad_size) { - fwrite(&allfs, sizeof(uint32_t), 1, binfile); - imagelen += 4; - rootfslen += 4; - } - } - - /* Flush the binfile buffer so that when we read from file, it contains - * everything in the buffer - */ - fflush(binfile); - - /* Compute the crc32 of the entire image (deadC0de included) */ - imagecrc = compute_crc32(imagecrc, binfile, kerneloff - fwaddr + cfelen, imagelen); - /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ - kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen); - /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ - kernelfscrc = compute_crc32(kernelfscrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen + rootfslen + sizeof(deadcode)); - /* Compute the crc32 of the flashImageStart to rootLength. - * The broadcom firmware assumes the rootfs starts the image, - * therefore uses the rootfs start to determine where to flash - * the image. Since we have the kernel first we have to give - * it the kernel address, but the crc uses the length - * associated with this address, which is added to the kernel - * length to determine the length of image to flash and thus - * needs to be rootfs + deadcode - */ - rootfscrc = compute_crc32(rootfscrc, binfile, kerneloff - fwaddr + cfelen, rootfslen + sizeof(deadcode)); - - } else { - /* Build the kernel address and length (doesn't need to be aligned, read only) */ - rootfsoff = fwaddr + sizeof(tag); - oldrootfslen = getlen(rootfsfile); - rootfslen = oldrootfslen; - rootfslen = ( (rootfslen % block_size) > 0 ? (((rootfslen / block_size) + 1) * block_size) : rootfslen ); - oldrootfslen = rootfslen; - - kerneloff = rootfsoff + rootfslen; - kernellen = getlen(kernelfile); - - imagelen = cfelen + rootfslen + kernellen; - - /* Seek to the start of the kernel */ - fseek(binfile, kerneloff - fwaddr + cfelen, SEEK_SET); - - if (!args->kernel_file_has_header_flag) { - /* Build the kernel header */ - khdr.loadaddr = htonl(load_address); - khdr.entry = htonl(entry); - khdr.lzmalen = htonl(kernellen); - - /* Write the kernel header */ - fwrite(&khdr, sizeof(khdr), 1, binfile); - - /* Increase the kernel size by the header size */ - kernellen += sizeof(khdr); - } - - /* Write the kernel */ - while (kernelfile && !feof(kernelfile) && !ferror(kernelfile)) { - read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), kernelfile); - fwrite(readbuf, sizeof(uint8_t), read, binfile); - } - - /* Write the RootFS */ - fseek(binfile, rootfsoff - fwaddr + cfelen, SEEK_SET); - while (rootfsfile && !feof(rootfsfile) && !ferror(rootfsfile)) { - read = fread(readbuf, sizeof(uint8_t), sizeof(readbuf), rootfsfile); - fwrite(readbuf, sizeof(uint8_t), read, binfile); - } - - /* Flush the binfile buffer so that when we read from file, it contains - * everything in the buffer - */ - fflush(binfile); - - /* Compute the crc32 of the entire image (deadC0de included) */ - imagecrc = compute_crc32(imagecrc, binfile, sizeof(tag), imagelen); - /* Compute the crc32 of the kernel and padding between kernel and rootfs) */ - kernelcrc = compute_crc32(kernelcrc, binfile, kerneloff - fwaddr + cfelen, kernellen + rootfsoffpadlen); - kernelfscrc = compute_crc32(kernelfscrc, binfile, rootfsoff - fwaddr + cfelen, kernellen + rootfslen); - rootfscrc = compute_crc32(rootfscrc, binfile, rootfsoff - fwaddr + cfelen, rootfslen); - } - - /* Close the files */ - if (cfefile) { - fclose(cfefile); - } - fclose(kernelfile); - fclose(rootfsfile); - - /* Build the tag */ - strncpy(tag.tagVersion, args->tag_version_arg, sizeof(tag.tagVersion) - 1); - strncpy(tag.sig_1, args->signature_arg, sizeof(tag.sig_1) - 1); - strncpy(tag.sig_2, args->signature2_arg, sizeof(tag.sig_2) - 1); - strncpy(tag.chipid, args->chipid_arg, sizeof(tag.chipid) - 1); - strncpy(tag.boardid, args->boardid_arg, sizeof(tag.boardid) - 1); - strcpy(tag.big_endian, "1"); - sprintf(tag.totalLength, "%lu", imagelen); - - if (args->cfe_given) { - sprintf(tag.cfeAddress, "%" PRIu32, flash_start); - sprintf(tag.cfeLength, "%lu", cfelen); - } else { - /* We don't include CFE */ - strcpy(tag.cfeAddress, "0"); - strcpy(tag.cfeLength, "0"); - } - - sprintf(tag.kernelAddress, "%lu", kerneloff); - sprintf(tag.kernelLength, "%lu", kernellen + rootfsoffpadlen); - - if (args->root_first_flag) { - sprintf(tag.flashImageStart, "%lu", rootfsoff); - sprintf(tag.flashRootLength, "%lu", rootfslen); - } else { - sprintf(tag.flashImageStart, "%lu", kerneloff); - sprintf(tag.flashRootLength, "%lu", rootfslen + sizeof(deadcode)); - } - int2tag(tag.rootLength, oldrootfslen + sizeof(deadcode)); - - if (args->rsa_signature_given) { - strncpy(tag.rsa_signature, args->rsa_signature_arg, RSASIG_LEN); - } - - if (args->layoutver_given) { - strncpy(tag.flashLayoutVer, args->layoutver_arg, TAGLAYOUT_LEN); - } - - if (args->info1_given) { - strncpy(tag.information1, args->info1_arg, TAGINFO1_LEN); - } - - if (args->info2_given) { - strncpy(tag.information2, args->info2_arg, TAGINFO2_LEN); - } - - if (args->reserved2_given) { - strncpy(tag.reserved2, args->reserved2_arg, 16); - } - - if (args->altinfo_given) { - strncpy(tag.information1, args->altinfo_arg, TAGINFO1_LEN); - } - - if (args->second_image_flag_given) { - if (strncmp(args->second_image_flag_arg, "2", DUALFLAG_LEN) != 0) { - strncpy(tag.dualImage, args->second_image_flag_arg, DUALFLAG_LEN); - } - } - - if (args->inactive_given) { - if (strncmp(args->inactive_arg, "2", INACTIVEFLAG_LEN) != 0) { - strncpy(tag.inactiveFlag, args->second_image_flag_arg, INACTIVEFLAG_LEN); - } - } - - for (i = 0; i < NUM_PIRELLI; i++) { - if (strncmp(args->boardid_arg, pirellitab[i], BOARDID_LEN) == 0) { - is_pirelli = 1; - break; - } - } - - if ( !is_pirelli ) { - int2tag(tag.imageCRC, kernelfscrc); - } else { - int2tag(tag.imageCRC, kernelcrc); - } - - int2tag(&(tag.rootfsCRC[0]), rootfscrc); - int2tag(tag.kernelCRC, kernelcrc); - int2tag(tag.fskernelCRC, kernelfscrc); - int2tag(tag.headerCRC, cyg_crc32_accumulate(IMAGETAG_CRC_START, (uint8_t*)&tag, sizeof(tag) - 20)); - - fseek(binfile, 0L, SEEK_SET); - fwrite(&tag, sizeof(uint8_t), sizeof(tag), binfile); - - fflush(binfile); - fclose(binfile); - - return 0; -} - -int main(int argc, char **argv) -{ - char *kernel, *rootfs, *bin; - uint32_t flash_start, image_offset, block_size, load_address, entry; - flash_start = image_offset = block_size = load_address = entry = 0; - struct gengetopt_args_info parsed_args; - - kernel = rootfs = bin = NULL; - - if (imagetag_cmdline(argc, argv, &parsed_args)) { - exit(1); - } - - printf("Broadcom 63xx image tagger - v2.0.0\n"); - printf("Copyright (C) 2008 Axel Gembe\n"); - printf("Copyright (C) 2009-2010 Daniel Dickinson\n"); - printf("Licensed under the terms of the Gnu General Public License\n"); - - kernel = parsed_args.kernel_arg; - rootfs = parsed_args.rootfs_arg; - bin = parsed_args.output_arg; - if (strlen(parsed_args.tag_version_arg) >= TAGVER_LEN) { - fprintf(stderr, "Error: Tag Version (tag_version,v) too long.\n"); - exit(1); - } - if (strlen(parsed_args.boardid_arg) >= BOARDID_LEN) { - fprintf(stderr, "Error: Board ID (boardid,b) too long.\n"); - exit(1); - } - if (strlen(parsed_args.chipid_arg) >= CHIPID_LEN) { - fprintf(stderr, "Error: Chip ID (chipid,c) too long.\n"); - exit(1); - } - if (strlen(parsed_args.signature_arg) >= SIG1_LEN) { - fprintf(stderr, "Error: Magic string (signature,a) too long.\n"); - exit(1); - } - if (strlen(parsed_args.signature2_arg) >= SIG2_LEN) { - fprintf(stderr, "Error: Second magic string (signature2,m) too long.\n"); - exit(1); - } - if (parsed_args.layoutver_given) { - if (strlen(parsed_args.layoutver_arg) > FLASHLAYOUTVER_LEN) { - fprintf(stderr, "Error: Flash layout version (layoutver,y) too long.\n"); - exit(1); - } - } - if (parsed_args.rsa_signature_given) { - if (strlen(parsed_args.rsa_signature_arg) > RSASIG_LEN) { - fprintf(stderr, "Error: RSA Signature (rsa_signature,r) too long.\n"); - exit(1); - } - } - - if (parsed_args.info1_given) { - if (strlen(parsed_args.info1_arg) >= TAGINFO1_LEN) { - fprintf(stderr, "Error: Vendor Information 1 (info1) too long.\n"); - exit(1); - } - } - - if (parsed_args.info2_given) { - if (strlen(parsed_args.info2_arg) >= TAGINFO2_LEN) { - fprintf(stderr, "Error: Vendor Information 2 (info2) too long.\n"); - exit(1); - } - } - - if (parsed_args.altinfo_given) { - if (strlen(parsed_args.altinfo_arg) >= ALTTAGINFO_LEN) { - fprintf(stderr, "Error: Vendor Information 1 (info1) too long.\n"); - exit(1); - } - } - - if (parsed_args.pad_given) { - if (parsed_args.pad_arg < 0) { - fprintf(stderr, "Error: pad size must be positive.\r"); - exit(1); - } - } - - flash_start = strtoul(parsed_args.flash_start_arg, NULL, 16); - image_offset = strtoul(parsed_args.image_offset_arg, NULL, 16); - block_size = strtoul(parsed_args.block_size_arg, NULL, 16); - - if (!parsed_args.kernel_file_has_header_flag) { - load_address = strtoul(parsed_args.load_addr_arg, NULL, 16); - entry = strtoul(parsed_args.entry_arg, NULL, 16); - if (load_address == 0) { - fprintf(stderr, "Error: Invalid value for load address\n"); - } - if (entry == 0) { - fprintf(stderr, "Error: Invalid value for entry\n"); - } - } - - return tagfile(kernel, rootfs, bin, &parsed_args, flash_start, image_offset, block_size, load_address, entry); -} diff --git a/tools/firmware-utils/src/imagetag.ggo b/tools/firmware-utils/src/imagetag.ggo deleted file mode 100644 index 7318485293..0000000000 --- a/tools/firmware-utils/src/imagetag.ggo +++ /dev/null @@ -1,46 +0,0 @@ -# Command line option parsing generator file for imagetag -# Supplied-To: gengetopt -# -# Copyright 2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# - -package "imagetag" -version "2.0.0" -purpose "Generate image with CFE imagetag for Broadcom 63xx routers." -description "Copyright (C) 2008 Axel Gembe -Copyright (C) 2009-2010 Daniel Dickinson -Licensed unter the terms of the Gnu General Public License. - -Given a root filesystem, a linux kernel, and an optional CFE, generates an image with an imagetag for a Broadcom 63xx-based router. Additional parameters to be specified depend on the specfic brand and model of router." -args "--file-name=imagetag_cmdline" - -option "kernel" i "File with LZMA compressed kernel to include in the image." string typestr="filename" required -option "rootfs" f "File with RootFS to include in the image." string typestr="filename" required -option "output" o "Name of output file." string typestr="filename" required -option "cfe" - "File with CFE to include in the image." string typestr="filename" optional -option "boardid" b "Board ID to set in the image (must match what router expects, e.g. \"96345GW2\")." string required -option "chipid" c "Chip ID to set in the image (must match the actual hardware, e.g. \"6345\")." string required -option "flash-start" s "Flash start address." string typestr="address" optional default="0xBFC00000" -option "image-offset" n "Offset from start address for the first byte after the CFE (in memory)." string typestr="offset" default="0x10000" optional -option "tag-version" v "Version number for imagetag format." string default="6" optional -option "signature" a "Magic string (signature), for boards that need it." string default="Broadcom Corporatio" optional -option "signature2" m "Second magic string (signature2)." string default="ver. 2.0" optional -option "block-size" k "Flash erase block size." string optional default="0x10000" -option "load-addr" l "Kernel load address." string typestr="address" required -option "entry" e "Address where the kernel entry point will be for booting." string typestr="address" required -option "layoutver" y "Flash layout version (version 2.2x of the Broadcom code requires this)." string optional -option "info1" 1 "String for first vendor information section." string optional -option "altinfo" - "String for vendor information section (alternate/pirelli)." string optional -option "info2" 2 "String for second vendor information section." string optional -option "root-first" - "Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory)." flag off -option "rsa-signature" r "String for RSA Signature section." string optional -option "second-image-flag" - "Dual Image Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional -option "inactive" - "Inactive Flag (2=not-specified)." values="0", "1", "2" default="2" typestr="flag-value" optional -option "reserved2" - "String for second reserved section." string optional -option "kernel-file-has-header" - "Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed" flag off -option "pad" p "Pad the image to this size if smaller (in MiB)" int typestr="size (in MiB)" optional -option "align-rootfs" - "Align the rootfs start to erase block size" flag off diff --git a/tools/firmware-utils/src/imagetag_cmdline.c b/tools/firmware-utils/src/imagetag_cmdline.c deleted file mode 100644 index 86c90bbb67..0000000000 --- a/tools/firmware-utils/src/imagetag_cmdline.c +++ /dev/null @@ -1,1193 +0,0 @@ -/* - File autogenerated by gengetopt version 2.22.5 - generated with the following command: - gengetopt -i imagetag.ggo -f imagetag_cmdline --file-name=imagetag_cmdline - - The developers of gengetopt consider the fixed text that goes in all - gengetopt output files to be in the public domain: - we make no copyright claims on it. -*/ - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifndef FIX_UNUSED -#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ -#endif - -#include <getopt.h> - -#include "imagetag_cmdline.h" - -const char *gengetopt_args_info_purpose = "Generate image with CFE imagetag for Broadcom 63xx routers."; - -const char *gengetopt_args_info_usage = "Usage: imagetag [OPTIONS]..."; - -const char *gengetopt_args_info_description = "Copyright (C) 2008 Axel Gembe\nCopyright (C) 2009-2010 Daniel Dickinson\nLicensed unter the terms of the Gnu General Public License.\n\nGiven a root filesystem, a linux kernel, and an optional CFE, generates an \nimage with an imagetag for a Broadcom 63xx-based router. Additional parameters \nto be specified depend on the specfic brand and model of router."; - -const char *gengetopt_args_info_help[] = { - " -h, --help Print help and exit", - " -V, --version Print version and exit", - " -i, --kernel=filename File with LZMA compressed kernel to include in \n the image.", - " -f, --rootfs=filename File with RootFS to include in the image.", - " -o, --output=filename Name of output file.", - " --cfe=filename File with CFE to include in the image.", - " -b, --boardid=STRING Board ID to set in the image (must match what \n router expects, e.g. \"96345GW2\").", - " -c, --chipid=STRING Chip ID to set in the image (must match the \n actual hardware, e.g. \"6345\").", - " -s, --flash-start=address Flash start address. (default=`0xBFC00000')", - " -n, --image-offset=offset Offset from start address for the first byte \n after the CFE (in memory). \n (default=`0x10000')", - " -v, --tag-version=STRING Version number for imagetag format. \n (default=`6')", - " -a, --signature=STRING Magic string (signature), for boards that need \n it. (default=`Broadcom Corporatio')", - " -m, --signature2=STRING Second magic string (signature2). \n (default=`ver. 2.0')", - " -k, --block-size=STRING Flash erase block size. (default=`0x10000')", - " -l, --load-addr=address Kernel load address.", - " -e, --entry=address Address where the kernel entry point will be \n for booting.", - " -y, --layoutver=STRING Flash layout version (version 2.2x of the \n Broadcom code requires this).", - " -1, --info1=STRING String for first vendor information section.", - " --altinfo=STRING String for vendor information section \n (alternate/pirelli).", - " -2, --info2=STRING String for second vendor information section.", - " --root-first Put the rootfs before the kernel (only for \n stock images, e.g. captured from the router's \n flash memory). (default=off)", - " -r, --rsa-signature=STRING String for RSA Signature section.", - " --second-image-flag=flag-value\n Dual Image Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')", - " --inactive=flag-value Inactive Flag (2=not-specified). (possible \n values=\"0\", \"1\", \"2\" default=`2')", - " --reserved2=STRING String for second reserved section.", - " --kernel-file-has-header Indicates that the kernel file includes the \n kernel header with correct load address and \n entry point, so no changes are needed \n (default=off)", - " -p, --pad=size (in MiB) Pad the image to this size if smaller (in MiB)", - " --align-rootfs Align the rootfs start to erase block size \n (default=off)", - 0 -}; - -typedef enum {ARG_NO - , ARG_FLAG - , ARG_STRING - , ARG_INT -} imagetag_cmdline_arg_type; - -static -void clear_given (struct gengetopt_args_info *args_info); -static -void clear_args (struct gengetopt_args_info *args_info); - -static int -imagetag_cmdline_internal (int argc, char **argv, struct gengetopt_args_info *args_info, - struct imagetag_cmdline_params *params, const char *additional_error); - -static int -imagetag_cmdline_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); - -const char *imagetag_cmdline_second_image_flag_values[] = {"0", "1", "2", 0}; /*< Possible values for second-image-flag. */ -const char *imagetag_cmdline_inactive_values[] = {"0", "1", "2", 0}; /*< Possible values for inactive. */ - -static char * -gengetopt_strdup (const char *s); - -static -void clear_given (struct gengetopt_args_info *args_info) -{ - args_info->help_given = 0 ; - args_info->version_given = 0 ; - args_info->kernel_given = 0 ; - args_info->rootfs_given = 0 ; - args_info->output_given = 0 ; - args_info->cfe_given = 0 ; - args_info->boardid_given = 0 ; - args_info->chipid_given = 0 ; - args_info->flash_start_given = 0 ; - args_info->image_offset_given = 0 ; - args_info->tag_version_given = 0 ; - args_info->signature_given = 0 ; - args_info->signature2_given = 0 ; - args_info->block_size_given = 0 ; - args_info->load_addr_given = 0 ; - args_info->entry_given = 0 ; - args_info->layoutver_given = 0 ; - args_info->info1_given = 0 ; - args_info->altinfo_given = 0 ; - args_info->info2_given = 0 ; - args_info->root_first_given = 0 ; - args_info->rsa_signature_given = 0 ; - args_info->second_image_flag_given = 0 ; - args_info->inactive_given = 0 ; - args_info->reserved2_given = 0 ; - args_info->kernel_file_has_header_given = 0 ; - args_info->pad_given = 0 ; - args_info->align_rootfs_given = 0 ; -} - -static -void clear_args (struct gengetopt_args_info *args_info) -{ - FIX_UNUSED (args_info); - args_info->kernel_arg = NULL; - args_info->kernel_orig = NULL; - args_info->rootfs_arg = NULL; - args_info->rootfs_orig = NULL; - args_info->output_arg = NULL; - args_info->output_orig = NULL; - args_info->cfe_arg = NULL; - args_info->cfe_orig = NULL; - args_info->boardid_arg = NULL; - args_info->boardid_orig = NULL; - args_info->chipid_arg = NULL; - args_info->chipid_orig = NULL; - args_info->flash_start_arg = gengetopt_strdup ("0xBFC00000"); - args_info->flash_start_orig = NULL; - args_info->image_offset_arg = gengetopt_strdup ("0x10000"); - args_info->image_offset_orig = NULL; - args_info->tag_version_arg = gengetopt_strdup ("6"); - args_info->tag_version_orig = NULL; - args_info->signature_arg = gengetopt_strdup ("Broadcom Corporatio"); - args_info->signature_orig = NULL; - args_info->signature2_arg = gengetopt_strdup ("ver. 2.0"); - args_info->signature2_orig = NULL; - args_info->block_size_arg = gengetopt_strdup ("0x10000"); - args_info->block_size_orig = NULL; - args_info->load_addr_arg = NULL; - args_info->load_addr_orig = NULL; - args_info->entry_arg = NULL; - args_info->entry_orig = NULL; - args_info->layoutver_arg = NULL; - args_info->layoutver_orig = NULL; - args_info->info1_arg = NULL; - args_info->info1_orig = NULL; - args_info->altinfo_arg = NULL; - args_info->altinfo_orig = NULL; - args_info->info2_arg = NULL; - args_info->info2_orig = NULL; - args_info->root_first_flag = 0; - args_info->rsa_signature_arg = NULL; - args_info->rsa_signature_orig = NULL; - args_info->second_image_flag_arg = gengetopt_strdup ("2"); - args_info->second_image_flag_orig = NULL; - args_info->inactive_arg = gengetopt_strdup ("2"); - args_info->inactive_orig = NULL; - args_info->reserved2_arg = NULL; - args_info->reserved2_orig = NULL; - args_info->kernel_file_has_header_flag = 0; - args_info->pad_orig = NULL; - args_info->align_rootfs_flag = 0; - -} - -static -void init_args_info(struct gengetopt_args_info *args_info) -{ - - - args_info->help_help = gengetopt_args_info_help[0] ; - args_info->version_help = gengetopt_args_info_help[1] ; - args_info->kernel_help = gengetopt_args_info_help[2] ; - args_info->rootfs_help = gengetopt_args_info_help[3] ; - args_info->output_help = gengetopt_args_info_help[4] ; - args_info->cfe_help = gengetopt_args_info_help[5] ; - args_info->boardid_help = gengetopt_args_info_help[6] ; - args_info->chipid_help = gengetopt_args_info_help[7] ; - args_info->flash_start_help = gengetopt_args_info_help[8] ; - args_info->image_offset_help = gengetopt_args_info_help[9] ; - args_info->tag_version_help = gengetopt_args_info_help[10] ; - args_info->signature_help = gengetopt_args_info_help[11] ; - args_info->signature2_help = gengetopt_args_info_help[12] ; - args_info->block_size_help = gengetopt_args_info_help[13] ; - args_info->load_addr_help = gengetopt_args_info_help[14] ; - args_info->entry_help = gengetopt_args_info_help[15] ; - args_info->layoutver_help = gengetopt_args_info_help[16] ; - args_info->info1_help = gengetopt_args_info_help[17] ; - args_info->altinfo_help = gengetopt_args_info_help[18] ; - args_info->info2_help = gengetopt_args_info_help[19] ; - args_info->root_first_help = gengetopt_args_info_help[20] ; - args_info->rsa_signature_help = gengetopt_args_info_help[21] ; - args_info->second_image_flag_help = gengetopt_args_info_help[22] ; - args_info->inactive_help = gengetopt_args_info_help[23] ; - args_info->reserved2_help = gengetopt_args_info_help[24] ; - args_info->kernel_file_has_header_help = gengetopt_args_info_help[25] ; - args_info->pad_help = gengetopt_args_info_help[26] ; - args_info->align_rootfs_help = gengetopt_args_info_help[27] ; - -} - -void -imagetag_cmdline_print_version (void) -{ - printf ("%s %s\n", - (strlen(IMAGETAG_CMDLINE_PACKAGE_NAME) ? IMAGETAG_CMDLINE_PACKAGE_NAME : IMAGETAG_CMDLINE_PACKAGE), - IMAGETAG_CMDLINE_VERSION); -} - -static void print_help_common(void) { - imagetag_cmdline_print_version (); - - if (strlen(gengetopt_args_info_purpose) > 0) - printf("\n%s\n", gengetopt_args_info_purpose); - - if (strlen(gengetopt_args_info_usage) > 0) - printf("\n%s\n", gengetopt_args_info_usage); - - printf("\n"); - - if (strlen(gengetopt_args_info_description) > 0) - printf("%s\n\n", gengetopt_args_info_description); -} - -void -imagetag_cmdline_print_help (void) -{ - int i = 0; - print_help_common(); - while (gengetopt_args_info_help[i]) - printf("%s\n", gengetopt_args_info_help[i++]); -} - -void -imagetag_cmdline_init (struct gengetopt_args_info *args_info) -{ - clear_given (args_info); - clear_args (args_info); - init_args_info (args_info); -} - -void -imagetag_cmdline_params_init(struct imagetag_cmdline_params *params) -{ - if (params) - { - params->override = 0; - params->initialize = 1; - params->check_required = 1; - params->check_ambiguity = 0; - params->print_errors = 1; - } -} - -struct imagetag_cmdline_params * -imagetag_cmdline_params_create(void) -{ - struct imagetag_cmdline_params *params = - (struct imagetag_cmdline_params *)malloc(sizeof(struct imagetag_cmdline_params)); - imagetag_cmdline_params_init(params); - return params; -} - -static void -free_string_field (char **s) -{ - if (*s) - { - free (*s); - *s = 0; - } -} - - -static void -imagetag_cmdline_release (struct gengetopt_args_info *args_info) -{ - - free_string_field (&(args_info->kernel_arg)); - free_string_field (&(args_info->kernel_orig)); - free_string_field (&(args_info->rootfs_arg)); - free_string_field (&(args_info->rootfs_orig)); - free_string_field (&(args_info->output_arg)); - free_string_field (&(args_info->output_orig)); - free_string_field (&(args_info->cfe_arg)); - free_string_field (&(args_info->cfe_orig)); - free_string_field (&(args_info->boardid_arg)); - free_string_field (&(args_info->boardid_orig)); - free_string_field (&(args_info->chipid_arg)); - free_string_field (&(args_info->chipid_orig)); - free_string_field (&(args_info->flash_start_arg)); - free_string_field (&(args_info->flash_start_orig)); - free_string_field (&(args_info->image_offset_arg)); - free_string_field (&(args_info->image_offset_orig)); - free_string_field (&(args_info->tag_version_arg)); - free_string_field (&(args_info->tag_version_orig)); - free_string_field (&(args_info->signature_arg)); - free_string_field (&(args_info->signature_orig)); - free_string_field (&(args_info->signature2_arg)); - free_string_field (&(args_info->signature2_orig)); - free_string_field (&(args_info->block_size_arg)); - free_string_field (&(args_info->block_size_orig)); - free_string_field (&(args_info->load_addr_arg)); - free_string_field (&(args_info->load_addr_orig)); - free_string_field (&(args_info->entry_arg)); - free_string_field (&(args_info->entry_orig)); - free_string_field (&(args_info->layoutver_arg)); - free_string_field (&(args_info->layoutver_orig)); - free_string_field (&(args_info->info1_arg)); - free_string_field (&(args_info->info1_orig)); - free_string_field (&(args_info->altinfo_arg)); - free_string_field (&(args_info->altinfo_orig)); - free_string_field (&(args_info->info2_arg)); - free_string_field (&(args_info->info2_orig)); - free_string_field (&(args_info->rsa_signature_arg)); - free_string_field (&(args_info->rsa_signature_orig)); - free_string_field (&(args_info->second_image_flag_arg)); - free_string_field (&(args_info->second_image_flag_orig)); - free_string_field (&(args_info->inactive_arg)); - free_string_field (&(args_info->inactive_orig)); - free_string_field (&(args_info->reserved2_arg)); - free_string_field (&(args_info->reserved2_orig)); - free_string_field (&(args_info->pad_orig)); - - - - clear_given (args_info); -} - -/** - * @param val the value to check - * @param values the possible values - * @return the index of the matched value: - * -1 if no value matched, - * -2 if more than one value has matched - */ -static int -check_possible_values(const char *val, const char *values[]) -{ - int i, found, last; - size_t len; - - if (!val) /* otherwise strlen() crashes below */ - return -1; /* -1 means no argument for the option */ - - found = last = 0; - - for (i = 0, len = strlen(val); values[i]; ++i) - { - if (strncmp(val, values[i], len) == 0) - { - ++found; - last = i; - if (strlen(values[i]) == len) - return i; /* exact macth no need to check more */ - } - } - - if (found == 1) /* one match: OK */ - return last; - - return (found ? -2 : -1); /* return many values or none matched */ -} - - -static void -write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) -{ - int found = -1; - if (arg) { - if (values) { - found = check_possible_values(arg, values); - } - if (found >= 0) - fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]); - else - fprintf(outfile, "%s=\"%s\"\n", opt, arg); - } else { - fprintf(outfile, "%s\n", opt); - } -} - - -int -imagetag_cmdline_dump(FILE *outfile, struct gengetopt_args_info *args_info) -{ - int i = 0; - - if (!outfile) - { - fprintf (stderr, "%s: cannot dump options to stream\n", IMAGETAG_CMDLINE_PACKAGE); - return EXIT_FAILURE; - } - - if (args_info->help_given) - write_into_file(outfile, "help", 0, 0 ); - if (args_info->version_given) - write_into_file(outfile, "version", 0, 0 ); - if (args_info->kernel_given) - write_into_file(outfile, "kernel", args_info->kernel_orig, 0); - if (args_info->rootfs_given) - write_into_file(outfile, "rootfs", args_info->rootfs_orig, 0); - if (args_info->output_given) - write_into_file(outfile, "output", args_info->output_orig, 0); - if (args_info->cfe_given) - write_into_file(outfile, "cfe", args_info->cfe_orig, 0); - if (args_info->boardid_given) - write_into_file(outfile, "boardid", args_info->boardid_orig, 0); - if (args_info->chipid_given) - write_into_file(outfile, "chipid", args_info->chipid_orig, 0); - if (args_info->flash_start_given) - write_into_file(outfile, "flash-start", args_info->flash_start_orig, 0); - if (args_info->image_offset_given) - write_into_file(outfile, "image-offset", args_info->image_offset_orig, 0); - if (args_info->tag_version_given) - write_into_file(outfile, "tag-version", args_info->tag_version_orig, 0); - if (args_info->signature_given) - write_into_file(outfile, "signature", args_info->signature_orig, 0); - if (args_info->signature2_given) - write_into_file(outfile, "signature2", args_info->signature2_orig, 0); - if (args_info->block_size_given) - write_into_file(outfile, "block-size", args_info->block_size_orig, 0); - if (args_info->load_addr_given) - write_into_file(outfile, "load-addr", args_info->load_addr_orig, 0); - if (args_info->entry_given) - write_into_file(outfile, "entry", args_info->entry_orig, 0); - if (args_info->layoutver_given) - write_into_file(outfile, "layoutver", args_info->layoutver_orig, 0); - if (args_info->info1_given) - write_into_file(outfile, "info1", args_info->info1_orig, 0); - if (args_info->altinfo_given) - write_into_file(outfile, "altinfo", args_info->altinfo_orig, 0); - if (args_info->info2_given) - write_into_file(outfile, "info2", args_info->info2_orig, 0); - if (args_info->root_first_given) - write_into_file(outfile, "root-first", 0, 0 ); - if (args_info->rsa_signature_given) - write_into_file(outfile, "rsa-signature", args_info->rsa_signature_orig, 0); - if (args_info->second_image_flag_given) - write_into_file(outfile, "second-image-flag", args_info->second_image_flag_orig, imagetag_cmdline_second_image_flag_values); - if (args_info->inactive_given) - write_into_file(outfile, "inactive", args_info->inactive_orig, imagetag_cmdline_inactive_values); - if (args_info->reserved2_given) - write_into_file(outfile, "reserved2", args_info->reserved2_orig, 0); - if (args_info->kernel_file_has_header_given) - write_into_file(outfile, "kernel-file-has-header", 0, 0 ); - if (args_info->pad_given) - write_into_file(outfile, "pad", args_info->pad_orig, 0); - if (args_info->align_rootfs_given) - write_into_file(outfile, "align-rootfs", 0, 0 ); - - - i = EXIT_SUCCESS; - return i; -} - -int -imagetag_cmdline_file_save(const char *filename, struct gengetopt_args_info *args_info) -{ - FILE *outfile; - int i = 0; - - outfile = fopen(filename, "w"); - - if (!outfile) - { - fprintf (stderr, "%s: cannot open file for writing: %s\n", IMAGETAG_CMDLINE_PACKAGE, filename); - return EXIT_FAILURE; - } - - i = imagetag_cmdline_dump(outfile, args_info); - fclose (outfile); - - return i; -} - -void -imagetag_cmdline_free (struct gengetopt_args_info *args_info) -{ - imagetag_cmdline_release (args_info); -} - -/** @brief replacement of strdup, which is not standard */ -char * -gengetopt_strdup (const char *s) -{ - char *result = 0; - if (!s) - return result; - - result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} - -int -imagetag_cmdline (int argc, char **argv, struct gengetopt_args_info *args_info) -{ - return imagetag_cmdline2 (argc, argv, args_info, 0, 1, 1); -} - -int -imagetag_cmdline_ext (int argc, char **argv, struct gengetopt_args_info *args_info, - struct imagetag_cmdline_params *params) -{ - int result; - result = imagetag_cmdline_internal (argc, argv, args_info, params, 0); - - if (result == EXIT_FAILURE) - { - imagetag_cmdline_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -imagetag_cmdline2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) -{ - int result; - struct imagetag_cmdline_params params; - - params.override = override; - params.initialize = initialize; - params.check_required = check_required; - params.check_ambiguity = 0; - params.print_errors = 1; - - result = imagetag_cmdline_internal (argc, argv, args_info, ¶ms, 0); - - if (result == EXIT_FAILURE) - { - imagetag_cmdline_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -imagetag_cmdline_required (struct gengetopt_args_info *args_info, const char *prog_name) -{ - int result = EXIT_SUCCESS; - - if (imagetag_cmdline_required2(args_info, prog_name, 0) > 0) - result = EXIT_FAILURE; - - if (result == EXIT_FAILURE) - { - imagetag_cmdline_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -imagetag_cmdline_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) -{ - int error = 0; - FIX_UNUSED (additional_error); - - /* checks for required options */ - if (! args_info->kernel_given) - { - fprintf (stderr, "%s: '--kernel' ('-i') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - if (! args_info->rootfs_given) - { - fprintf (stderr, "%s: '--rootfs' ('-f') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - if (! args_info->output_given) - { - fprintf (stderr, "%s: '--output' ('-o') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - if (! args_info->boardid_given) - { - fprintf (stderr, "%s: '--boardid' ('-b') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - if (! args_info->chipid_given) - { - fprintf (stderr, "%s: '--chipid' ('-c') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - if (! args_info->load_addr_given) - { - fprintf (stderr, "%s: '--load-addr' ('-l') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - if (! args_info->entry_given) - { - fprintf (stderr, "%s: '--entry' ('-e') option required%s\n", prog_name, (additional_error ? additional_error : "")); - error = 1; - } - - - /* checks for dependences among options */ - - return error; -} - - -static char *package_name = 0; - -/** - * @brief updates an option - * @param field the generic pointer to the field to update - * @param orig_field the pointer to the orig field - * @param field_given the pointer to the number of occurrence of this option - * @param prev_given the pointer to the number of occurrence already seen - * @param value the argument for this option (if null no arg was specified) - * @param possible_values the possible values for this option (if specified) - * @param default_value the default value (in case the option only accepts fixed values) - * @param arg_type the type of this option - * @param check_ambiguity @see imagetag_cmdline_params.check_ambiguity - * @param override @see imagetag_cmdline_params.override - * @param no_free whether to free a possible previous value - * @param multiple_option whether this is a multiple option - * @param long_opt the corresponding long option - * @param short_opt the corresponding short option (or '-' if none) - * @param additional_error possible further error specification - */ -static -int update_arg(void *field, char **orig_field, - unsigned int *field_given, unsigned int *prev_given, - char *value, const char *possible_values[], - const char *default_value, - imagetag_cmdline_arg_type arg_type, - int check_ambiguity, int override, - int no_free, int multiple_option, - const char *long_opt, char short_opt, - const char *additional_error) -{ - char *stop_char = 0; - const char *val = value; - int found; - char **string_field; - FIX_UNUSED (field); - - stop_char = 0; - found = 0; - - if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) - { - if (short_opt != '-') - fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", - package_name, long_opt, short_opt, - (additional_error ? additional_error : "")); - else - fprintf (stderr, "%s: `--%s' option given more than once%s\n", - package_name, long_opt, - (additional_error ? additional_error : "")); - return 1; /* failure */ - } - - if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0) - { - if (short_opt != '-') - fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n", - package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt, - (additional_error ? additional_error : "")); - else - fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n", - package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, - (additional_error ? additional_error : "")); - return 1; /* failure */ - } - - if (field_given && *field_given && ! override) - return 0; - if (prev_given) - (*prev_given)++; - if (field_given) - (*field_given)++; - if (possible_values) - val = possible_values[found]; - - switch(arg_type) { - case ARG_FLAG: - *((int *)field) = !*((int *)field); - break; - case ARG_INT: - if (val) *((int *)field) = strtol (val, &stop_char, 0); - break; - case ARG_STRING: - if (val) { - string_field = (char **)field; - if (!no_free && *string_field) - free (*string_field); /* free previous string */ - *string_field = gengetopt_strdup (val); - } - break; - default: - break; - }; - - /* check numeric conversion */ - switch(arg_type) { - case ARG_INT: - if (val && !(stop_char && *stop_char == '\0')) { - fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); - return 1; /* failure */ - } - break; - default: - ; - }; - - /* store the original value */ - switch(arg_type) { - case ARG_NO: - case ARG_FLAG: - break; - default: - if (value && orig_field) { - if (no_free) { - *orig_field = value; - } else { - if (*orig_field) - free (*orig_field); /* free previous string */ - *orig_field = gengetopt_strdup (value); - } - } - }; - - return 0; /* OK */ -} - - -int -imagetag_cmdline_internal ( - int argc, char **argv, struct gengetopt_args_info *args_info, - struct imagetag_cmdline_params *params, const char *additional_error) -{ - int c; /* Character of the parsed option. */ - - int error = 0; - struct gengetopt_args_info local_args_info; - - int override; - int initialize; - int check_required; - int check_ambiguity; - - package_name = argv[0]; - - override = params->override; - initialize = params->initialize; - check_required = params->check_required; - check_ambiguity = params->check_ambiguity; - - if (initialize) - imagetag_cmdline_init (args_info); - - imagetag_cmdline_init (&local_args_info); - - optarg = 0; - optind = 0; - opterr = params->print_errors; - optopt = '?'; - - while (1) - { - int option_index = 0; - - static struct option long_options[] = { - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { "kernel", 1, NULL, 'i' }, - { "rootfs", 1, NULL, 'f' }, - { "output", 1, NULL, 'o' }, - { "cfe", 1, NULL, 0 }, - { "boardid", 1, NULL, 'b' }, - { "chipid", 1, NULL, 'c' }, - { "flash-start", 1, NULL, 's' }, - { "image-offset", 1, NULL, 'n' }, - { "tag-version", 1, NULL, 'v' }, - { "signature", 1, NULL, 'a' }, - { "signature2", 1, NULL, 'm' }, - { "block-size", 1, NULL, 'k' }, - { "load-addr", 1, NULL, 'l' }, - { "entry", 1, NULL, 'e' }, - { "layoutver", 1, NULL, 'y' }, - { "info1", 1, NULL, '1' }, - { "altinfo", 1, NULL, 0 }, - { "info2", 1, NULL, '2' }, - { "root-first", 0, NULL, 0 }, - { "rsa-signature", 1, NULL, 'r' }, - { "second-image-flag", 1, NULL, 0 }, - { "inactive", 1, NULL, 0 }, - { "reserved2", 1, NULL, 0 }, - { "kernel-file-has-header", 0, NULL, 0 }, - { "pad", 1, NULL, 'p' }, - { "align-rootfs", 0, NULL, 0 }, - { 0, 0, 0, 0 } - }; - - c = getopt_long (argc, argv, "hVi:f:o:b:c:s:n:v:a:m:k:l:e:y:1:2:r:p:", long_options, &option_index); - - if (c == -1) break; /* Exit from `while (1)' loop. */ - - switch (c) - { - case 'h': /* Print help and exit. */ - imagetag_cmdline_print_help (); - imagetag_cmdline_free (&local_args_info); - exit (EXIT_SUCCESS); - - case 'V': /* Print version and exit. */ - imagetag_cmdline_print_version (); - imagetag_cmdline_free (&local_args_info); - exit (EXIT_SUCCESS); - - case 'i': /* File with LZMA compressed kernel to include in the image.. */ - - - if (update_arg( (void *)&(args_info->kernel_arg), - &(args_info->kernel_orig), &(args_info->kernel_given), - &(local_args_info.kernel_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "kernel", 'i', - additional_error)) - goto failure; - - break; - case 'f': /* File with RootFS to include in the image.. */ - - - if (update_arg( (void *)&(args_info->rootfs_arg), - &(args_info->rootfs_orig), &(args_info->rootfs_given), - &(local_args_info.rootfs_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "rootfs", 'f', - additional_error)) - goto failure; - - break; - case 'o': /* Name of output file.. */ - - - if (update_arg( (void *)&(args_info->output_arg), - &(args_info->output_orig), &(args_info->output_given), - &(local_args_info.output_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "output", 'o', - additional_error)) - goto failure; - - break; - case 'b': /* Board ID to set in the image (must match what router expects, e.g. \"96345GW2\").. */ - - - if (update_arg( (void *)&(args_info->boardid_arg), - &(args_info->boardid_orig), &(args_info->boardid_given), - &(local_args_info.boardid_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "boardid", 'b', - additional_error)) - goto failure; - - break; - case 'c': /* Chip ID to set in the image (must match the actual hardware, e.g. \"6345\").. */ - - - if (update_arg( (void *)&(args_info->chipid_arg), - &(args_info->chipid_orig), &(args_info->chipid_given), - &(local_args_info.chipid_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "chipid", 'c', - additional_error)) - goto failure; - - break; - case 's': /* Flash start address.. */ - - - if (update_arg( (void *)&(args_info->flash_start_arg), - &(args_info->flash_start_orig), &(args_info->flash_start_given), - &(local_args_info.flash_start_given), optarg, 0, "0xBFC00000", ARG_STRING, - check_ambiguity, override, 0, 0, - "flash-start", 's', - additional_error)) - goto failure; - - break; - case 'n': /* Offset from start address for the first byte after the CFE (in memory).. */ - - - if (update_arg( (void *)&(args_info->image_offset_arg), - &(args_info->image_offset_orig), &(args_info->image_offset_given), - &(local_args_info.image_offset_given), optarg, 0, "0x10000", ARG_STRING, - check_ambiguity, override, 0, 0, - "image-offset", 'n', - additional_error)) - goto failure; - - break; - case 'v': /* Version number for imagetag format.. */ - - - if (update_arg( (void *)&(args_info->tag_version_arg), - &(args_info->tag_version_orig), &(args_info->tag_version_given), - &(local_args_info.tag_version_given), optarg, 0, "6", ARG_STRING, - check_ambiguity, override, 0, 0, - "tag-version", 'v', - additional_error)) - goto failure; - - break; - case 'a': /* Magic string (signature), for boards that need it.. */ - - - if (update_arg( (void *)&(args_info->signature_arg), - &(args_info->signature_orig), &(args_info->signature_given), - &(local_args_info.signature_given), optarg, 0, "Broadcom Corporatio", ARG_STRING, - check_ambiguity, override, 0, 0, - "signature", 'a', - additional_error)) - goto failure; - - break; - case 'm': /* Second magic string (signature2).. */ - - - if (update_arg( (void *)&(args_info->signature2_arg), - &(args_info->signature2_orig), &(args_info->signature2_given), - &(local_args_info.signature2_given), optarg, 0, "ver. 2.0", ARG_STRING, - check_ambiguity, override, 0, 0, - "signature2", 'm', - additional_error)) - goto failure; - - break; - case 'k': /* Flash erase block size.. */ - - - if (update_arg( (void *)&(args_info->block_size_arg), - &(args_info->block_size_orig), &(args_info->block_size_given), - &(local_args_info.block_size_given), optarg, 0, "0x10000", ARG_STRING, - check_ambiguity, override, 0, 0, - "block-size", 'k', - additional_error)) - goto failure; - - break; - case 'l': /* Kernel load address.. */ - - - if (update_arg( (void *)&(args_info->load_addr_arg), - &(args_info->load_addr_orig), &(args_info->load_addr_given), - &(local_args_info.load_addr_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "load-addr", 'l', - additional_error)) - goto failure; - - break; - case 'e': /* Address where the kernel entry point will be for booting.. */ - - - if (update_arg( (void *)&(args_info->entry_arg), - &(args_info->entry_orig), &(args_info->entry_given), - &(local_args_info.entry_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "entry", 'e', - additional_error)) - goto failure; - - break; - case 'y': /* Flash layout version (version 2.2x of the Broadcom code requires this).. */ - - - if (update_arg( (void *)&(args_info->layoutver_arg), - &(args_info->layoutver_orig), &(args_info->layoutver_given), - &(local_args_info.layoutver_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "layoutver", 'y', - additional_error)) - goto failure; - - break; - case '1': /* String for first vendor information section.. */ - - - if (update_arg( (void *)&(args_info->info1_arg), - &(args_info->info1_orig), &(args_info->info1_given), - &(local_args_info.info1_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "info1", '1', - additional_error)) - goto failure; - - break; - case '2': /* String for second vendor information section.. */ - - - if (update_arg( (void *)&(args_info->info2_arg), - &(args_info->info2_orig), &(args_info->info2_given), - &(local_args_info.info2_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "info2", '2', - additional_error)) - goto failure; - - break; - case 'r': /* String for RSA Signature section.. */ - - - if (update_arg( (void *)&(args_info->rsa_signature_arg), - &(args_info->rsa_signature_orig), &(args_info->rsa_signature_given), - &(local_args_info.rsa_signature_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "rsa-signature", 'r', - additional_error)) - goto failure; - - break; - case 'p': /* Pad the image to this size if smaller (in MiB). */ - - - if (update_arg( (void *)&(args_info->pad_arg), - &(args_info->pad_orig), &(args_info->pad_given), - &(local_args_info.pad_given), optarg, 0, 0, ARG_INT, - check_ambiguity, override, 0, 0, - "pad", 'p', - additional_error)) - goto failure; - - break; - - case 0: /* Long option with no short option */ - /* File with CFE to include in the image.. */ - if (strcmp (long_options[option_index].name, "cfe") == 0) - { - - - if (update_arg( (void *)&(args_info->cfe_arg), - &(args_info->cfe_orig), &(args_info->cfe_given), - &(local_args_info.cfe_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "cfe", '-', - additional_error)) - goto failure; - - } - /* String for vendor information section (alternate/pirelli).. */ - else if (strcmp (long_options[option_index].name, "altinfo") == 0) - { - - - if (update_arg( (void *)&(args_info->altinfo_arg), - &(args_info->altinfo_orig), &(args_info->altinfo_given), - &(local_args_info.altinfo_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "altinfo", '-', - additional_error)) - goto failure; - - } - /* Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory).. */ - else if (strcmp (long_options[option_index].name, "root-first") == 0) - { - - - if (update_arg((void *)&(args_info->root_first_flag), 0, &(args_info->root_first_given), - &(local_args_info.root_first_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "root-first", '-', - additional_error)) - goto failure; - - } - /* Dual Image Flag (2=not-specified).. */ - else if (strcmp (long_options[option_index].name, "second-image-flag") == 0) - { - - - if (update_arg( (void *)&(args_info->second_image_flag_arg), - &(args_info->second_image_flag_orig), &(args_info->second_image_flag_given), - &(local_args_info.second_image_flag_given), optarg, imagetag_cmdline_second_image_flag_values, "2", ARG_STRING, - check_ambiguity, override, 0, 0, - "second-image-flag", '-', - additional_error)) - goto failure; - - } - /* Inactive Flag (2=not-specified).. */ - else if (strcmp (long_options[option_index].name, "inactive") == 0) - { - - - if (update_arg( (void *)&(args_info->inactive_arg), - &(args_info->inactive_orig), &(args_info->inactive_given), - &(local_args_info.inactive_given), optarg, imagetag_cmdline_inactive_values, "2", ARG_STRING, - check_ambiguity, override, 0, 0, - "inactive", '-', - additional_error)) - goto failure; - - } - /* String for second reserved section.. */ - else if (strcmp (long_options[option_index].name, "reserved2") == 0) - { - - - if (update_arg( (void *)&(args_info->reserved2_arg), - &(args_info->reserved2_orig), &(args_info->reserved2_given), - &(local_args_info.reserved2_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "reserved2", '-', - additional_error)) - goto failure; - - } - /* Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed. */ - else if (strcmp (long_options[option_index].name, "kernel-file-has-header") == 0) - { - - - if (update_arg((void *)&(args_info->kernel_file_has_header_flag), 0, &(args_info->kernel_file_has_header_given), - &(local_args_info.kernel_file_has_header_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "kernel-file-has-header", '-', - additional_error)) - goto failure; - - } - /* Align the rootfs start to erase block size. */ - else if (strcmp (long_options[option_index].name, "align-rootfs") == 0) - { - - - if (update_arg((void *)&(args_info->align_rootfs_flag), 0, &(args_info->align_rootfs_given), - &(local_args_info.align_rootfs_given), optarg, 0, 0, ARG_FLAG, - check_ambiguity, override, 1, 0, "align-rootfs", '-', - additional_error)) - goto failure; - - } - - break; - case '?': /* Invalid option. */ - /* `getopt_long' already printed an error message. */ - goto failure; - - default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c%s\n", IMAGETAG_CMDLINE_PACKAGE, c, (additional_error ? additional_error : "")); - abort (); - } /* switch */ - } /* while */ - - - - if (check_required) - { - error += imagetag_cmdline_required2 (args_info, argv[0], additional_error); - } - - imagetag_cmdline_release (&local_args_info); - - if ( error ) - return (EXIT_FAILURE); - - return 0; - -failure: - - imagetag_cmdline_release (&local_args_info); - return (EXIT_FAILURE); -} diff --git a/tools/firmware-utils/src/imagetag_cmdline.h b/tools/firmware-utils/src/imagetag_cmdline.h deleted file mode 100644 index 3f55c509bb..0000000000 --- a/tools/firmware-utils/src/imagetag_cmdline.h +++ /dev/null @@ -1,275 +0,0 @@ -/** @file imagetag_cmdline.h - * @brief The header file for the command line option parser - * generated by GNU Gengetopt version 2.22.5 - * http://www.gnu.org/software/gengetopt. - * DO NOT modify this file, since it can be overwritten - * @author GNU Gengetopt by Lorenzo Bettini */ - -#ifndef IMAGETAG_CMDLINE_H -#define IMAGETAG_CMDLINE_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> /* for FILE */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef IMAGETAG_CMDLINE_PACKAGE -/** @brief the program name (used for printing errors) */ -#define IMAGETAG_CMDLINE_PACKAGE "imagetag" -#endif - -#ifndef IMAGETAG_CMDLINE_PACKAGE_NAME -/** @brief the complete program name (used for help and version) */ -#define IMAGETAG_CMDLINE_PACKAGE_NAME "imagetag" -#endif - -#ifndef IMAGETAG_CMDLINE_VERSION -/** @brief the program version */ -#define IMAGETAG_CMDLINE_VERSION "2.0.0" -#endif - -/** @brief Where the command line options are stored */ -struct gengetopt_args_info -{ - const char *help_help; /**< @brief Print help and exit help description. */ - const char *version_help; /**< @brief Print version and exit help description. */ - char * kernel_arg; /**< @brief File with LZMA compressed kernel to include in the image.. */ - char * kernel_orig; /**< @brief File with LZMA compressed kernel to include in the image. original value given at command line. */ - const char *kernel_help; /**< @brief File with LZMA compressed kernel to include in the image. help description. */ - char * rootfs_arg; /**< @brief File with RootFS to include in the image.. */ - char * rootfs_orig; /**< @brief File with RootFS to include in the image. original value given at command line. */ - const char *rootfs_help; /**< @brief File with RootFS to include in the image. help description. */ - char * output_arg; /**< @brief Name of output file.. */ - char * output_orig; /**< @brief Name of output file. original value given at command line. */ - const char *output_help; /**< @brief Name of output file. help description. */ - char * cfe_arg; /**< @brief File with CFE to include in the image.. */ - char * cfe_orig; /**< @brief File with CFE to include in the image. original value given at command line. */ - const char *cfe_help; /**< @brief File with CFE to include in the image. help description. */ - char * boardid_arg; /**< @brief Board ID to set in the image (must match what router expects, e.g. \"96345GW2\").. */ - char * boardid_orig; /**< @brief Board ID to set in the image (must match what router expects, e.g. \"96345GW2\"). original value given at command line. */ - const char *boardid_help; /**< @brief Board ID to set in the image (must match what router expects, e.g. \"96345GW2\"). help description. */ - char * chipid_arg; /**< @brief Chip ID to set in the image (must match the actual hardware, e.g. \"6345\").. */ - char * chipid_orig; /**< @brief Chip ID to set in the image (must match the actual hardware, e.g. \"6345\"). original value given at command line. */ - const char *chipid_help; /**< @brief Chip ID to set in the image (must match the actual hardware, e.g. \"6345\"). help description. */ - char * flash_start_arg; /**< @brief Flash start address. (default='0xBFC00000'). */ - char * flash_start_orig; /**< @brief Flash start address. original value given at command line. */ - const char *flash_start_help; /**< @brief Flash start address. help description. */ - char * image_offset_arg; /**< @brief Offset from start address for the first byte after the CFE (in memory). (default='0x10000'). */ - char * image_offset_orig; /**< @brief Offset from start address for the first byte after the CFE (in memory). original value given at command line. */ - const char *image_offset_help; /**< @brief Offset from start address for the first byte after the CFE (in memory). help description. */ - char * tag_version_arg; /**< @brief Version number for imagetag format. (default='6'). */ - char * tag_version_orig; /**< @brief Version number for imagetag format. original value given at command line. */ - const char *tag_version_help; /**< @brief Version number for imagetag format. help description. */ - char * signature_arg; /**< @brief Magic string (signature), for boards that need it. (default='Broadcom Corporatio'). */ - char * signature_orig; /**< @brief Magic string (signature), for boards that need it. original value given at command line. */ - const char *signature_help; /**< @brief Magic string (signature), for boards that need it. help description. */ - char * signature2_arg; /**< @brief Second magic string (signature2). (default='ver. 2.0'). */ - char * signature2_orig; /**< @brief Second magic string (signature2). original value given at command line. */ - const char *signature2_help; /**< @brief Second magic string (signature2). help description. */ - char * block_size_arg; /**< @brief Flash erase block size. (default='0x10000'). */ - char * block_size_orig; /**< @brief Flash erase block size. original value given at command line. */ - const char *block_size_help; /**< @brief Flash erase block size. help description. */ - char * load_addr_arg; /**< @brief Kernel load address.. */ - char * load_addr_orig; /**< @brief Kernel load address. original value given at command line. */ - const char *load_addr_help; /**< @brief Kernel load address. help description. */ - char * entry_arg; /**< @brief Address where the kernel entry point will be for booting.. */ - char * entry_orig; /**< @brief Address where the kernel entry point will be for booting. original value given at command line. */ - const char *entry_help; /**< @brief Address where the kernel entry point will be for booting. help description. */ - char * layoutver_arg; /**< @brief Flash layout version (version 2.2x of the Broadcom code requires this).. */ - char * layoutver_orig; /**< @brief Flash layout version (version 2.2x of the Broadcom code requires this). original value given at command line. */ - const char *layoutver_help; /**< @brief Flash layout version (version 2.2x of the Broadcom code requires this). help description. */ - char * info1_arg; /**< @brief String for first vendor information section.. */ - char * info1_orig; /**< @brief String for first vendor information section. original value given at command line. */ - const char *info1_help; /**< @brief String for first vendor information section. help description. */ - char * altinfo_arg; /**< @brief String for vendor information section (alternate/pirelli).. */ - char * altinfo_orig; /**< @brief String for vendor information section (alternate/pirelli). original value given at command line. */ - const char *altinfo_help; /**< @brief String for vendor information section (alternate/pirelli). help description. */ - char * info2_arg; /**< @brief String for second vendor information section.. */ - char * info2_orig; /**< @brief String for second vendor information section. original value given at command line. */ - const char *info2_help; /**< @brief String for second vendor information section. help description. */ - int root_first_flag; /**< @brief Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory). (default=off). */ - const char *root_first_help; /**< @brief Put the rootfs before the kernel (only for stock images, e.g. captured from the router's flash memory). help description. */ - char * rsa_signature_arg; /**< @brief String for RSA Signature section.. */ - char * rsa_signature_orig; /**< @brief String for RSA Signature section. original value given at command line. */ - const char *rsa_signature_help; /**< @brief String for RSA Signature section. help description. */ - char * second_image_flag_arg; /**< @brief Dual Image Flag (2=not-specified). (default='2'). */ - char * second_image_flag_orig; /**< @brief Dual Image Flag (2=not-specified). original value given at command line. */ - const char *second_image_flag_help; /**< @brief Dual Image Flag (2=not-specified). help description. */ - char * inactive_arg; /**< @brief Inactive Flag (2=not-specified). (default='2'). */ - char * inactive_orig; /**< @brief Inactive Flag (2=not-specified). original value given at command line. */ - const char *inactive_help; /**< @brief Inactive Flag (2=not-specified). help description. */ - char * reserved2_arg; /**< @brief String for second reserved section.. */ - char * reserved2_orig; /**< @brief String for second reserved section. original value given at command line. */ - const char *reserved2_help; /**< @brief String for second reserved section. help description. */ - int kernel_file_has_header_flag; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed (default=off). */ - const char *kernel_file_has_header_help; /**< @brief Indicates that the kernel file includes the kernel header with correct load address and entry point, so no changes are needed help description. */ - int pad_arg; /**< @brief Pad the image to this size if smaller (in MiB). */ - char * pad_orig; /**< @brief Pad the image to this size if smaller (in MiB) original value given at command line. */ - const char *pad_help; /**< @brief Pad the image to this size if smaller (in MiB) help description. */ - int align_rootfs_flag; /**< @brief Align the rootfs start to erase block size (default=off). */ - const char *align_rootfs_help; /**< @brief Align the rootfs start to erase block size help description. */ - - unsigned int help_given ; /**< @brief Whether help was given. */ - unsigned int version_given ; /**< @brief Whether version was given. */ - unsigned int kernel_given ; /**< @brief Whether kernel was given. */ - unsigned int rootfs_given ; /**< @brief Whether rootfs was given. */ - unsigned int output_given ; /**< @brief Whether output was given. */ - unsigned int cfe_given ; /**< @brief Whether cfe was given. */ - unsigned int boardid_given ; /**< @brief Whether boardid was given. */ - unsigned int chipid_given ; /**< @brief Whether chipid was given. */ - unsigned int flash_start_given ; /**< @brief Whether flash-start was given. */ - unsigned int image_offset_given ; /**< @brief Whether image-offset was given. */ - unsigned int tag_version_given ; /**< @brief Whether tag-version was given. */ - unsigned int signature_given ; /**< @brief Whether signature was given. */ - unsigned int signature2_given ; /**< @brief Whether signature2 was given. */ - unsigned int block_size_given ; /**< @brief Whether block-size was given. */ - unsigned int load_addr_given ; /**< @brief Whether load-addr was given. */ - unsigned int entry_given ; /**< @brief Whether entry was given. */ - unsigned int layoutver_given ; /**< @brief Whether layoutver was given. */ - unsigned int info1_given ; /**< @brief Whether info1 was given. */ - unsigned int altinfo_given ; /**< @brief Whether altinfo was given. */ - unsigned int info2_given ; /**< @brief Whether info2 was given. */ - unsigned int root_first_given ; /**< @brief Whether root-first was given. */ - unsigned int rsa_signature_given ; /**< @brief Whether rsa-signature was given. */ - unsigned int second_image_flag_given ; /**< @brief Whether second-image-flag was given. */ - unsigned int inactive_given ; /**< @brief Whether inactive was given. */ - unsigned int reserved2_given ; /**< @brief Whether reserved2 was given. */ - unsigned int kernel_file_has_header_given ; /**< @brief Whether kernel-file-has-header was given. */ - unsigned int pad_given ; /**< @brief Whether pad was given. */ - unsigned int align_rootfs_given ; /**< @brief Whether align-rootfs was given. */ - -} ; - -/** @brief The additional parameters to pass to parser functions */ -struct imagetag_cmdline_params -{ - int override; /**< @brief whether to override possibly already present options (default 0) */ - int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ - int check_required; /**< @brief whether to check that all required options were provided (default 1) */ - int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ - int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ -} ; - -/** @brief the purpose string of the program */ -extern const char *gengetopt_args_info_purpose; -/** @brief the usage string of the program */ -extern const char *gengetopt_args_info_usage; -/** @brief all the lines making the help output */ -extern const char *gengetopt_args_info_help[]; - -/** - * The command line parser - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @return 0 if everything went fine, NON 0 if an error took place - */ -int imagetag_cmdline (int argc, char **argv, - struct gengetopt_args_info *args_info); - -/** - * The command line parser (version with additional parameters - deprecated) - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @param override whether to override possibly already present options - * @param initialize whether to initialize the option structure my_args_info - * @param check_required whether to check that all required options were provided - * @return 0 if everything went fine, NON 0 if an error took place - * @deprecated use imagetag_cmdline_ext() instead - */ -int imagetag_cmdline2 (int argc, char **argv, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required); - -/** - * The command line parser (version with additional parameters) - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @param params additional parameters for the parser - * @return 0 if everything went fine, NON 0 if an error took place - */ -int imagetag_cmdline_ext (int argc, char **argv, - struct gengetopt_args_info *args_info, - struct imagetag_cmdline_params *params); - -/** - * Save the contents of the option struct into an already open FILE stream. - * @param outfile the stream where to dump options - * @param args_info the option struct to dump - * @return 0 if everything went fine, NON 0 if an error took place - */ -int imagetag_cmdline_dump(FILE *outfile, - struct gengetopt_args_info *args_info); - -/** - * Save the contents of the option struct into a (text) file. - * This file can be read by the config file parser (if generated by gengetopt) - * @param filename the file where to save - * @param args_info the option struct to save - * @return 0 if everything went fine, NON 0 if an error took place - */ -int imagetag_cmdline_file_save(const char *filename, - struct gengetopt_args_info *args_info); - -/** - * Print the help - */ -void imagetag_cmdline_print_help(void); -/** - * Print the version - */ -void imagetag_cmdline_print_version(void); - -/** - * Initializes all the fields a imagetag_cmdline_params structure - * to their default values - * @param params the structure to initialize - */ -void imagetag_cmdline_params_init(struct imagetag_cmdline_params *params); - -/** - * Allocates dynamically a imagetag_cmdline_params structure and initializes - * all its fields to their default values - * @return the created and initialized imagetag_cmdline_params structure - */ -struct imagetag_cmdline_params *imagetag_cmdline_params_create(void); - -/** - * Initializes the passed gengetopt_args_info structure's fields - * (also set default values for options that have a default) - * @param args_info the structure to initialize - */ -void imagetag_cmdline_init (struct gengetopt_args_info *args_info); -/** - * Deallocates the string fields of the gengetopt_args_info structure - * (but does not deallocate the structure itself) - * @param args_info the structure to deallocate - */ -void imagetag_cmdline_free (struct gengetopt_args_info *args_info); - -/** - * Checks that all the required options were specified - * @param args_info the structure to check - * @param prog_name the name of the program that will be used to print - * possible errors - * @return - */ -int imagetag_cmdline_required (struct gengetopt_args_info *args_info, - const char *prog_name); - -extern const char *imagetag_cmdline_second_image_flag_values[]; /**< @brief Possible values for second-image-flag. */ -extern const char *imagetag_cmdline_inactive_values[]; /**< @brief Possible values for inactive. */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* IMAGETAG_CMDLINE_H */ diff --git a/tools/firmware-utils/src/jcgimage.c b/tools/firmware-utils/src/jcgimage.c deleted file mode 100644 index 59a6ac4de5..0000000000 --- a/tools/firmware-utils/src/jcgimage.c +++ /dev/null @@ -1,423 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * jcgimage - Create a JCG firmware image - * - * Copyright (C) 2015 Reinhard Max <reinhard@m4x.de> - * Copyright (C) 2019 Davide Fioravanti <pantanastyle@gmail.com> - */ - -/* - * JCG firmware update images consist of a 512 byte header and a - * modified uImage (details below) as the payload. - * - * The payload is obfuscated by XORing it with a key that is generated - * from parts of the header. Fortunately only non-essential parts of - * the header are used for this and zeroing them results in a zero - * key, effectively disabling the obfuscation and allowing us to use - * clear text payloads. - * - * The mandatory parts of the header are: - * - * - A magic string of "YSZJ" at offset 0. - * - A value of 1 at offset 39 (header format version?) - * - A CRC32 checksum of the payload at offset 504. - * - A CRC32 checksum of the header at offset 508. - * - * An image constructed by these rules will be accepted by JCG's - * U-Boot in resuce mode via TFTP and the payload will be written to - * the flash starting at offset 0x00050000. - * - * JCG's U-Boot does check the content or size of the payload - * image. If it is too large, it wraps around and overwrites U-Boot, - * requiring JTAG to revive the board. To prevent such bricking from - * happening, this tool refuses to build such overlong images. - * - * Using -m is possible to set the maximum size of the payload. - * Otherwise the default MAXSIZE will be used. - * For an 8Mb flash, the corresponding maxsize is: - * 8 * 1024 * 1024 - 5 * 64 * 1024 = 8388608 - 327680 = 8060928 - * - * Two more conditions have to be met for a JCG image to be accepted - * as a valid update by the web interface of the stock firware: - * - * - The bytes at offsets 109 and 111 in the header must be a binary - * representation of the first two components of the firmware - * version as displayed in the update web form, or it will be - * rejected as "incorrect product". - * - * - The payload must start with a valid uImage header whose data - * CRC checksum matches the whole rest of the update file rather - * than just the number of bytes specified in the size field of the - * header. - * - * This last condition is met by JCG's original firmware images, - * because they have both, kernel and rootfs inside the uImage and - * abuse the last four bytes of the name field to record the offset of - * the file system from the start of the uImage header. This tool - * produces such images when called with -k and -r, which are meant to - * repack the original firmware after modifying the file systen, - * e.g. to add debugging tools and enable shell access. - * - * In contrast, OpenWrt sysupgrade images consist of a uImage that - * only contains the kernel and has the rootfs appended to it. Hence, - * the CRC over kernel and file system does not match the one in the - * uImage header. Fixing this by adjusting the uImage header is not - * possible, because it makes the uImage unusable for booting. Instead - * we append four "patch" bytes to the end of the file system, that - * are calculated to force the checksum of kernel+fs to be the same as - * for the kernel alone. - * - */ - -#include <zlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <libgen.h> -#include <stdlib.h> -#include <errno.h> -#include <err.h> -#include <time.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <assert.h> -#include <inttypes.h> - -/* - * JCG Firmware image header - */ -#define JH_MAGIC 0x59535a4a /* "YSZJ" */ -struct jcg_header { - uint32_t jh_magic; - uint8_t jh_version[32]; /* Firmware version string. - Fill with zeros to avoid encryption */ - uint32_t jh_type; /* must be 1 */ - uint8_t jh_info[64]; /* Firmware info string. Fill with - zeros to avoid encryption */ - uint32_t jh_time; /* Image creation time in seconds since - * the Epoch. Does not seem to be used - * by the stock firmware. */ - uint16_t jh_major; /* Major fimware version */ - uint16_t jh_minor; /* Minor fimrmware version */ - uint8_t jh_unknown[392]; /* Apparently unused and all zeros */ - uint32_t jh_dcrc; /* CRC checksum of the payload */ - uint32_t jh_hcrc; /* CRC checksum of the header */ -}; - -/* - * JCG uses a modified uImage header that replaces the last four bytes - * of the image name with the length of the kernel in the image. - */ -#define IH_MAGIC 0x27051956 /* Image Magic Number */ -#define IH_NMLEN 28 /* Image Name Length */ - -struct uimage_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 */ - uint32_t ih_fsoff; /* Offset of the file system - partition from the start of - the header */ -}; - -/* - * Open the named file and return its size and file descriptor. - * Exit in case of errors. - */ -int -opensize(char *name, size_t *size) -{ - struct stat s; - int fd = open(name, O_RDONLY); - if (fd < 0) - err(1, "cannot open \"%s\"", name); - - if (fstat(fd, &s) == -1) - err(1, "cannot stat \"%s\"", name); - - *size = s.st_size; - return fd; -} - -static time_t source_date_epoch = -1; -static void set_source_date_epoch() { - char *env = getenv("SOURCE_DATE_EPOCH"); - char *endptr = env; - errno = 0; - if (env && *env) { - source_date_epoch = strtoull(env, &endptr, 10); - if (errno || (endptr && *endptr != '\0')) { - fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); - exit(1); - } - } -} - -/* - * Write the JCG header - */ -void -mkjcgheader(struct jcg_header *h, size_t psize, char *version) -{ - uLong crc; - uint16_t major = 0, minor = 0; - void *payload = (void *)h + sizeof(*h); - time_t t; - - if (source_date_epoch != -1) - t = source_date_epoch; - else if ((time(&t) == (time_t)(-1))) - err(1, "time call failed"); - - - if (version != NULL) - if (sscanf(version, "%hu.%hu", &major, &minor) != 2) - err(1, "cannot parse version \"%s\"", version); - - memset(h, 0, sizeof(*h)); - h->jh_magic = htonl(JH_MAGIC); - h->jh_type = htonl(1); - h->jh_time = htonl(t); - h->jh_major = htons(major); - h->jh_minor = htons(minor); - - /* CRC over JCG payload (uImage) */ - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, payload, psize); - h->jh_dcrc = htonl(crc); - - /* CRC over JCG header */ - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, (void *)h, sizeof(*h)); - h->jh_hcrc = htonl(crc); -} - -/* - * Write the uImage header - */ -void -mkuheader(struct uimage_header *h, size_t ksize, size_t fsize) -{ - uLong crc; - void *payload = (void *)h + sizeof(*h); - - // printf("mkuheader: %p, %zd, %zd\n", h, ksize, fsize); - memset(h, 0, sizeof(*h)); - h->ih_magic = htonl(IH_MAGIC); - h->ih_time = htonl(time(NULL)); - h->ih_size = htonl(ksize + fsize); - h->ih_load = htonl(0x80000000); - h->ih_ep = htonl(0x80292000); - h->ih_os = 0x05; - h->ih_arch = 0x05; - h->ih_type = 0x02; - h->ih_comp = 0x03; - h->ih_fsoff = htonl(sizeof(*h) + ksize); - strcpy((char *)h->ih_name, "Linux Kernel Image"); - - /* CRC over uImage payload (kernel and file system) */ - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, payload, ntohl(h->ih_size)); - h->ih_dcrc = htonl(crc); - printf("CRC1: %08lx\n", crc); - - /* CRC over uImage header */ - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, (void *)h, sizeof(*h)); - h->ih_hcrc = htonl(crc); - printf("CRC2: %08lx\n", crc); -} - -/* - * Calculate a "patch" value and write it into the last four bytes of - * buf, so that the CRC32 checksum of the whole buffer is dcrc. - * - * Based on: SAR-PR-2006-05: Reversing CRC – Theory and Practice. - * Martin Stigge, Henryk Plötz, Wolf Müller, Jens-Peter Redlich. - * http://sar.informatik.hu-berlin.de/research/publications/#SAR-PR-2006-05 - */ -void -craftcrc(uint32_t dcrc, uint8_t *buf, size_t len) -{ - int i; - uint32_t a; - uint32_t patch = 0; - uint32_t crc = crc32(0L, Z_NULL, 0); - - a = ~dcrc; - for (i = 0; i < 32; i++) { - if (patch & 1) - patch = (patch >> 1) ^ 0xedb88320L; - else - patch >>= 1; - - if (a & 1) - patch ^= 0x5b358fd3L; - - a >>= 1; - } - patch ^= ~crc32(crc, buf, len - 4); - for (i = 0; i < 4; i++) { - buf[len - 4 + i] = patch & 0xff; - patch >>= 8; - } - /* Verify that we actually get the desired result */ - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, buf, len); - if (crc != dcrc) - errx(1, "CRC patching is broken: wanted %08x, but got %08x.", - dcrc, crc); - -} - -void -usage() { - fprintf(stderr, "Usage:\n" - "jcgimage -o outfile -u uImage [-m maxsize] [-v version]\n" - "jcgimage -o outfile -k kernel -f rootfs [-m maxsize] [-v version]\n"); - exit(1); -} - -#define MODE_UNKNOWN 0 -#define MODE_UIMAGE 1 -#define MODE_KR 2 - -/* The output image must not be larger than 4MiB - 5*64kiB */ -#define MAXSIZE (size_t)(4 * 1024 * 1024 - 5 * 64 * 1024) - -int -main(int argc, char **argv) -{ - struct jcg_header *jh; - struct uimage_header *uh; - int c; - char *imagefile = NULL; - char *file1 = NULL; - char *file2 = NULL; - char *version = NULL; - size_t maxsize = MAXSIZE; - char *endptr; - int mode = MODE_UNKNOWN; - int fdo, fd1, fd2; - size_t size1, size2, sizeu, sizeo, off1, off2; - void *map; - - /* Make sure the headers have the right size */ - assert(sizeof(struct jcg_header) == 512); - assert(sizeof(struct uimage_header) == 64); - set_source_date_epoch(); - - while ((c = getopt(argc, argv, "o:k:f:u:v:m:h")) != -1) { - switch (c) { - case 'o': - imagefile = optarg; - break; - case 'k': - if (mode == MODE_UIMAGE) - errx(1,"-k cannot be combined with -u"); - - mode = MODE_KR; - file1 = optarg; - break; - case 'f': - if (mode == MODE_UIMAGE) - errx(1,"-f cannot be combined with -u"); - - mode = MODE_KR; - file2 = optarg; - break; - case 'u': - if (mode == MODE_KR) - errx(1,"-u cannot be combined with -k and -r"); - - mode = MODE_UIMAGE; - file1 = optarg; - break; - case 'm': - if (optarg != NULL) - maxsize = strtoimax(optarg, &endptr, 10); - - break; - case 'v': - version = optarg; - break; - case 'h': - default: - usage(); - } - } - if (optind != argc) - errx(1, "illegal arg \"%s\"", argv[optind]); - - if (imagefile == NULL) - errx(1, "no output file specified"); - - if (mode == MODE_UNKNOWN) - errx(1, "specify either -u or -k and -r"); - - if (mode == MODE_KR) { - if (file1 == NULL || file2 == NULL) - errx(1, "need -k and -r"); - - fd2 = opensize(file2, &size2); - } - fd1 = opensize(file1, &size1); - if (mode == MODE_UIMAGE) { - off1 = sizeof(*jh); - sizeu = size1 + 4; - sizeo = sizeof(*jh) + sizeu; - } else { - off1 = sizeof(*jh) + sizeof(*uh); - off2 = sizeof(*jh) + sizeof(*uh) + size1; - sizeu = sizeof(*uh) + size1 + size2; - sizeo = sizeof(*jh) + sizeu; - } - - if (sizeo > maxsize) - errx(1, "payload too large: %zd > %zd\n", sizeo, maxsize); - - - fdo = open(imagefile, O_RDWR | O_CREAT | O_TRUNC, 00644); - if (fdo < 0) - err(1, "cannot open \"%s\"", imagefile); - - - if (ftruncate(fdo, sizeo) == -1) - err(1, "cannot grow \"%s\" to %zd bytes", imagefile, sizeo); - - map = mmap(NULL, sizeo, PROT_READ|PROT_WRITE, MAP_SHARED, fdo, 0); - uh = map + sizeof(*jh); - if (map == MAP_FAILED) - err(1, "cannot mmap \"%s\"", imagefile); - - - if (read(fd1, map + off1, size1) != size1) - err(1, "cannot copy %s", file1); - - - if (mode == MODE_KR) { - if (read(fd2, map+off2, size2) != size2) - err(1, "cannot copy %s", file2); - - mkuheader(uh, size1, size2); - } else if (mode == MODE_UIMAGE) - craftcrc(ntohl(uh->ih_dcrc), (void*)uh + sizeof(*uh), - sizeu - sizeof(*uh)); - - mkjcgheader(map, sizeu, version); - munmap(map, sizeo); - close(fdo); - return 0; -} diff --git a/tools/firmware-utils/src/lxlfw.c b/tools/firmware-utils/src/lxlfw.c deleted file mode 100644 index 15678b8736..0000000000 --- a/tools/firmware-utils/src/lxlfw.c +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT -/* - * Luxul's firmware container format - * - * Copyright 2020 Legrand AV Inc. - */ - -#define _GNU_SOURCE - -#include <byteswap.h> -#include <endian.h> -#include <errno.h> -#include <libgen.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le32(x) bswap_32(x) -#define cpu_to_le16(x) bswap_16(x) -#define le32_to_cpu(x) bswap_32(x) -#define le16_to_cpu(x) bswap_16(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le32(x) (x) -#define cpu_to_le16(x) (x) -#define le32_to_cpu(x) (x) -#define le16_to_cpu(x) (x) -#endif - -#define min(a, b) \ - ({ \ - __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; \ - }) - -#define max(a, b) \ - ({ \ - __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; \ - }) - -#define LXL_FLAGS_VENDOR_LUXUL 0x00000001 - -struct lxl_hdr { - char magic[4]; /* "LXL#" */ - uint32_t version; - uint32_t hdr_len; - uint8_t v0_end[0]; - /* Version: 1+ */ - uint32_t flags; - char board[16]; - uint8_t v1_end[0]; - /* Version: 2+ */ - uint8_t release[4]; - uint8_t v2_end[0]; -} __packed; - -static uint32_t lxlfw_hdr_len(uint32_t version) -{ - switch (version) { - case 0: - return offsetof(struct lxl_hdr, v0_end); - case 1: - return offsetof(struct lxl_hdr, v1_end); - case 2: - return offsetof(struct lxl_hdr, v2_end); - default: - fprintf(stderr, "Unsupported version %d\n", version); - return 0; - } -} - -/************************************************** - * Info - **************************************************/ - -static int lxlfw_info(int argc, char **argv) { - struct lxl_hdr hdr; - uint32_t version; - uint32_t hdr_len; - char board[17]; - size_t bytes; - int err = 0; - FILE *lxl; - int flags; - - if (argc < 3) { - fprintf(stderr, "Missing <file> argument\n"); - err = -EINVAL; - goto out; - } - - lxl = fopen(argv[2], "r"); - if (!lxl) { - fprintf(stderr, "Could not open \"%s\" file\n", argv[2]); - err = -ENOENT; - goto out; - } - - bytes = fread(&hdr, 1, sizeof(hdr), lxl); - if (bytes < offsetof(struct lxl_hdr, v0_end)) { - fprintf(stderr, "Input file too small to use Luxul format\n"); - err = -ENXIO; - goto err_close; - } - - if (memcmp(hdr.magic, "LXL#", 4)) { - fprintf(stderr, "File <file> does not use Luxul's format\n"); - err = -EINVAL; - goto err_close; - } - - version = le32_to_cpu(hdr.version); - hdr_len = lxlfw_hdr_len(version); - if (bytes < hdr_len) { - fprintf(stderr, "Input file too small for header version %d\n", version); - err = -ENXIO; - goto err_close; - } - - printf("Format version:\t%d\n", version); - printf("Header length:\t%d\n", le32_to_cpu(hdr.hdr_len)); - if (version >= 1) { - printf("Flags:\t\t"); - flags = le32_to_cpu(hdr.flags); - if (flags & LXL_FLAGS_VENDOR_LUXUL) - printf("VENDOR_LUXUL "); - printf("\n"); - memcpy(board, hdr.board, sizeof(hdr.board)); - board[16] = '\0'; - printf("Board:\t\t%s\n", board); - } - if (version >= 2) { - printf("Release:\t"); - if (hdr.release[0] || hdr.release[1] || hdr.release[2] || hdr.release[3]) { - printf("%hu.%hu.%hu", hdr.release[0], hdr.release[1], hdr.release[2]); - if (hdr.release[3]) - printf(".%hu", hdr.release[3]); - } - printf("\n"); - } - -err_close: - fclose(lxl); -out: - return err; -} - -/************************************************** - * Create - **************************************************/ - -static int lxlfw_create(int argc, char **argv) { - struct lxl_hdr hdr = { - .magic = { 'L', 'X', 'L', '#' }, - }; - char *in_path = NULL; - uint32_t version = 0; - uint32_t hdr_len; - ssize_t bytes; - char buf[512]; - int err = 0; - FILE *lxl; - FILE *in; - int c; - - if (argc < 3) { - fprintf(stderr, "Missing <file> argument\n"); - err = -EINVAL; - goto out; - } - - optind = 3; - while ((c = getopt(argc, argv, "i:lb:r:")) != -1) { - switch (c) { - case 'i': - in_path = optarg; - break; - case 'l': - hdr.flags |= cpu_to_le32(LXL_FLAGS_VENDOR_LUXUL); - version = max(version, 1); - break; - case 'b': - memcpy(hdr.board, optarg, strlen(optarg) > 16 ? 16 : strlen(optarg)); - version = max(version, 1); - break; - case 'r': - if (sscanf(optarg, "%hhu.%hhu.%hhu.%hhu", &hdr.release[0], &hdr.release[1], &hdr.release[2], &hdr.release[3]) < 1) { - fprintf(stderr, "Failed to parse release number \"%s\"\n", optarg); - err = -EINVAL; - goto out; - } - version = max(version, 2); - break; - } - } - - hdr.version = cpu_to_le32(version); - hdr_len = lxlfw_hdr_len(version); - if (!hdr_len) { - err = -EINVAL; - goto out; - } - hdr.hdr_len = cpu_to_le32(hdr_len); - - if (!in_path) { - fprintf(stderr, "Missing input file argument\n"); - err = -EINVAL; - goto out; - } - - in = fopen(in_path, "r"); - if (!in) { - fprintf(stderr, "Could not open input file %s\n", in_path); - err = -EIO; - goto out; - } - - lxl = fopen(argv[2], "w+"); - if (!lxl) { - fprintf(stderr, "Could not open \"%s\" file\n", argv[2]); - err = -EIO; - goto err_close_in; - } - - bytes = fwrite(&hdr, 1, hdr_len, lxl); - if (bytes != hdr_len) { - fprintf(stderr, "Could not write Luxul's header\n"); - err = -EIO; - goto err_close_lxl; - } - - while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { - if (fwrite(buf, 1, bytes, lxl) != bytes) { - fprintf(stderr, "Could not copy %zu bytes from input file\n", bytes); - err = -EIO; - goto err_close_lxl; - } - } - -err_close_lxl: - fclose(lxl); -err_close_in: - fclose(in); -out: - return err; -} - -/************************************************** - * Start - **************************************************/ - -static void usage() { - printf("Usage:\n"); - printf("\n"); - printf("Get info about Luxul firmware:\n"); - printf("\tlxlfw info <file>\n"); - printf("\n"); - printf("Create new Luxul firmware:\n"); - printf("\tlxlfw create <file> [options]\n"); - printf("\t-i file\t\t\t\tinput file for Luxul's firmware container\n"); - printf("\t-l\t\t\t\tmark firmware as created by Luxul company (DON'T USE)\n"); - printf("\t-b board\t\t\tboard (device) name\n"); - printf("\t-r release\t\t\trelease number (e.g. 5.1.0, 7.1.0.2)\n"); -} - -int main(int argc, char **argv) { - if (argc > 1) { - if (!strcmp(argv[1], "info")) - return lxlfw_info(argc, argv); - else if (!strcmp(argv[1], "create")) - return lxlfw_create(argc, argv); - } - - usage(); - return 0; -} diff --git a/tools/firmware-utils/src/lzma2eva.c b/tools/firmware-utils/src/lzma2eva.c deleted file mode 100644 index f72ec74c19..0000000000 --- a/tools/firmware-utils/src/lzma2eva.c +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - lzma2eva - convert lzma-compressed file to AVM EVA bootloader format - Copyright (C) 2007 Enrik Berkhan <Enrik.Berkhan@inka.de> -*/ - -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <zlib.h> /* crc32 */ - -#define checksum_add32(csum, data) \ - csum += ((uint8_t *)&data)[0]; \ - csum += ((uint8_t *)&data)[1]; \ - csum += ((uint8_t *)&data)[2]; \ - csum += ((uint8_t *)&data)[3]; - -void -usage(void) -{ - fprintf(stderr, "usage: lzma2eva <loadadddr> <entry> <lzmafile> <evafile>\n"); - exit(1); -} - -void -pexit(const char *msg) -{ - perror(msg); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - - const char *infile, *outfile; - FILE *in, *out; - static uint8_t buf[4096]; - size_t elems; - - uint8_t properties; - uint32_t dictsize; - uint64_t datasize; - - uint32_t magic = 0xfeed1281L; - uint32_t reclength = 0; - fpos_t reclengthpos; - uint32_t loadaddress = 0; - uint32_t type = 0x075a0201L; /* might be 7Z 2.1? */ - uint32_t checksum = 0; - - uint32_t compsize = 0; - fpos_t compsizepos; - uint32_t datasize32 = 0; - uint32_t datacrc32 = crc32(0, 0, 0); - - uint32_t zero = 0; - uint32_t entry = 0; - - if (argc != 5) - usage(); - - /* "parse" command line */ - loadaddress = strtoul(argv[1], 0, 0); - entry = strtoul(argv[2], 0, 0); - infile = argv[3]; - outfile = argv[4]; - - in = fopen(infile, "rb"); - if (!in) - pexit("fopen"); - out = fopen(outfile, "w+b"); - if (!out) - pexit("fopen"); - - /* read LZMA header */ - if (1 != fread(&properties, sizeof properties, 1, in)) - pexit("fread"); - if (1 != fread(&dictsize, sizeof dictsize, 1, in)) - pexit("fread"); - if (1 != fread(&datasize, sizeof datasize, 1, in)) - pexit("fread"); - - /* write EVA header */ - if (1 != fwrite(&magic, sizeof magic, 1, out)) - pexit("fwrite"); - if (fgetpos(out, &reclengthpos)) - pexit("fgetpos"); - if (1 != fwrite(&reclength, sizeof reclength, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&loadaddress, sizeof loadaddress, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&type, sizeof type, 1, out)) - pexit("fwrite"); - - /* write EVA LZMA header */ - if (fgetpos(out, &compsizepos)) - pexit("fgetpos"); - if (1 != fwrite(&compsize, sizeof compsize, 1, out)) - pexit("fwrite"); - /* XXX check length */ - datasize32 = (uint32_t)datasize; - if (1 != fwrite(&datasize32, sizeof datasize32, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&datacrc32, sizeof datacrc32, 1, out)) - pexit("fwrite"); - - /* write modified LZMA header */ - if (1 != fwrite(&properties, sizeof properties, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&dictsize, sizeof dictsize, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&zero, 3, 1, out)) - pexit("fwrite"); - - /* copy compressed data, calculate crc32 */ - while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, in))) { - compsize += elems; - if (elems != fwrite(&buf, sizeof buf[0], elems, out)) - pexit("fwrite"); - datacrc32 = crc32(datacrc32, buf, elems); - } - if (ferror(in)) - pexit("fread"); - fclose(in); - - /* re-write record length */ - reclength = compsize + 24; - if (fsetpos(out, &reclengthpos)) - pexit("fsetpos"); - if (1 != fwrite(&reclength, sizeof reclength, 1, out)) - pexit("fwrite"); - - /* re-write EVA LZMA header including size and data crc */ - if (fsetpos(out, &compsizepos)) - pexit("fsetpos"); - if (1 != fwrite(&compsize, sizeof compsize, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&datasize32, sizeof datasize32, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&datacrc32, sizeof datacrc32, 1, out)) - pexit("fwrite"); - - /* calculate record checksum */ - checksum += reclength; - checksum += loadaddress; - checksum_add32(checksum, type); - checksum_add32(checksum, compsize); - checksum_add32(checksum, datasize32); - checksum_add32(checksum, datacrc32); - if (fseek(out, 0, SEEK_CUR)) - pexit("fseek"); - while (0 < (elems = fread(&buf, sizeof buf[0], sizeof buf, out))) { - size_t i; - for (i = 0; i < elems; ++i) - checksum += buf[i]; - } - if (ferror(out)) - pexit("fread"); - if (fseek(out, 0, SEEK_CUR)) - pexit("fseek"); - - checksum = ~checksum + 1; - if (1 != fwrite(&checksum, sizeof checksum, 1, out)) - pexit("fwrite"); - - /* write entry record */ - if (1 != fwrite(&zero, sizeof zero, 1, out)) - pexit("fwrite"); - if (1 != fwrite(&entry, sizeof entry, 1, out)) - pexit("fwrite"); - - if (fclose(out)) - pexit("fclose"); - - return 0; -} diff --git a/tools/firmware-utils/src/makeamitbin.c b/tools/firmware-utils/src/makeamitbin.c deleted file mode 100644 index c626d5ce6a..0000000000 --- a/tools/firmware-utils/src/makeamitbin.c +++ /dev/null @@ -1,302 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * makeamitbin - create firmware binaries for MGB100 - * - * Copyright (C) 2007 Volker Weiss <dev@tintuc.de> - * Christian Welzel <dev@welzel-online.ch> - */ - - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - - -/* defaults: Level One WAP-0007 */ -static char *ascii1 = "DDC_RUS001"; -static char *ascii2 = "Queen"; - -static struct hdrinfo { - char *name; - unsigned long unknown; /* can probably be any number, maybe version number */ - int topalign; - unsigned int addr; - unsigned int size; -} hdrinfo[] = { - { "bios", 0xc76be111, 1, 0x3fa000, 0x006000 }, /* BIOS */ - { "recovery", 0xc76be222, 0, 0x3f0000, 0x004000 }, /* Recovery Loader */ - { "linux", 0xc76bee9d, 0, 0x000000, 0x100000 }, /* Linux */ - { "ramdisk", 0xc76bee9d, 0, 0x100000, 0x280000 }, /* ramdisk */ - { "amitconfig", 0xc76bee8b, 0, 0x380000, 0x060000 }, /* AMIT config */ - { "redboot", 0x00000000, 1, 0x3d0000, 0x030000 }, /* Redboot 128kB image */ - { "redbootlow", 0, 0, 0x3e0000, 0x18000 }, /* Redboot 1. part */ - { "redboothigh", 0, 0, 0x3fa000, 0x6000 }, /* Redboot 2. part */ - { "linux3g", 0xcb5f06b5, 0, 0x000000, 0x100000 }, /* Linux */ - { "ramdisk3g", 0xcb5f06b5, 0, 0x100000, 0x280000 }, /* ramdisk */ - { NULL } -}; - -/* -CHD2WLANU_R400b7 - -11e1 6bc7 -22e2 6bc7 -5dc3 47c8 -5cc3 47c8 -21c3 47c8 -*/ - -/* -20060106_DDC_WAP-0007_R400b4 - -11e1 6bc7 -22e2 6bc7 -9dee 6bc7 -9dee 6bc7 -8bee 6bc7 -*/ - -/* -WMU-6000FS_R400b6 - -11e1 6bc7 -22e2 6bc7 -6d2d 0fc8 -6c2d 0fc8 -542d 0fc8 -*/ - -/* -WAP-0007(R4.00b8)_2006-10-02 - -9979 5fc8 -22e2 6bc7 -c46e cec8 -c36e cec8 -a76e cec8 -*/ - - - -#define HDRSIZE 80 - -#define COPY_SHORT(d, o, v) d[o+0] = (unsigned char)((v) & 0xff); \ - d[o+1] = (unsigned char)(((v) >> 8) & 0xff) -#define COPY_LONG(d, o, v) d[o+0] = (unsigned char)((v) & 0xff); \ - d[o+1] = (unsigned char)(((v) >> 8) & 0xff); \ - d[o+2] = (unsigned char)(((v) >> 16) & 0xff); \ - d[o+3] = (unsigned char)(((v) >> 24) & 0xff) -#define READ_SHORT(d, o) ((unsigned short)(d[o+0]) + \ - (((unsigned short)(d[o+1])) << 8)) - -/* -00..0d ASCII product ID -0e..0f checksum of payload -10..1b ASCII Queen -1c..1f AMIT BIOS: 11e1 6bc7, Recovery Tool: 22e2 6bc7 - Linux: 5dc3 47c8, ramdisk: 5cc3 47c8 - AMIT FS: 21c3 47c8 VERSION NUMBER?????? -20..23 offset in flash aligned to segment boundary -24..27 length in flash aligned to segment boundary -28..2b offset in flash (payload) -2c..2f length (payload) -30..3f always 0 -40..47 always 4248 0101 5000 0001 (last maybe .....0501) -48..4b same as 20..23 -4c..4d always 0b00 -4e..4f inverted checksum of header -*/ - -unsigned short checksum(unsigned char *data, long size) -{ - long n; - unsigned short d, cs = 0; - for (n = 0; n < size; n += 2) - { - d = READ_SHORT(data, n); - cs += d; - if (cs < d) - cs++; - } - if (size & 1) - { - d = data[n]; - cs += d; - if (cs < d) - cs++; - } - return cs; -} - -void showhdr(unsigned char *hdr) -{ - int i, j; - for (j = 0; j < 5; j++) - { - for (i = 0; i < 16; i++) - { - printf("%02x ", (unsigned int)(hdr[j * 16 + i])); - } - printf(" "); - for (i = 0; i < 16; i++) - { - unsigned char d = hdr[j * 16 + i]; - printf("%c", (d >= ' ' && d < 127) ? d : '.'); - } - printf("\n"); - } -} - -void makehdr(unsigned char *hdr, struct hdrinfo *info, - unsigned char *data, long size, int last) -{ - unsigned int offset = info->addr + 0x10; - memset(hdr, 0, HDRSIZE); - if (info->topalign) - offset = info->addr + info->size - size; /* top align */ - strncpy((char *)hdr + 0x00, ascii1, 14); - strncpy((char *)hdr + 0x10, ascii2, 12); - COPY_LONG(hdr, 0x1c, info->unknown); - COPY_LONG(hdr, 0x20, info->addr); - COPY_LONG(hdr, 0x24, info->size); - COPY_LONG(hdr, 0x28, offset); - COPY_LONG(hdr, 0x2c, size); - COPY_LONG(hdr, 0x40, 0x01014842); - COPY_LONG(hdr, 0x44, last ? 0x01050050 : 0x01000050); - COPY_LONG(hdr, 0x48, info->addr); - COPY_SHORT(hdr, 0x4c, info->unknown == 0xcb5f06b5 ? 0x0016 : 0x000b); - COPY_SHORT(hdr, 0x0e, checksum(data, size)); - COPY_SHORT(hdr, 0x4e, ~checksum(hdr, HDRSIZE)); -} - -unsigned char *read_file(const char *name, long *size) -{ - FILE *f; - unsigned char *data = NULL; - *size = 0; - f = fopen(name, "r"); - if (f != NULL) - { - if (fseek(f, 0, SEEK_END) == 0) - { - *size = ftell(f); - if (*size != -1) - { - if (fseek(f, 0, SEEK_SET) == 0) - { - data = (unsigned char *)malloc(*size); - if (data != NULL) - { - if (fread(data, sizeof(char), *size, f) != *size) - { - free(data); - data = NULL; - } - } - } - } - } - fclose(f); - } - return data; -} - -struct hdrinfo *find_hdrinfo(const char *name) -{ - int n; - for (n = 0; hdrinfo[n].name != NULL; n++) - { - if (strcmp(name, hdrinfo[n].name) == 0) - return &hdrinfo[n]; - } - return NULL; -} - -void oferror(FILE *f) -{ - printf("file error\n"); - exit(2); -} - -void showhelp(void) -{ - printf("Syntax: makeamitbin [options]\n"); - printf("Options:\n"); - printf(" -1 ID1\tFirmware identifier 1, e.g. 'DDC_RUS001' for manufacturer LevelOne\n"); - printf(" -2 ID2\tFirmware identifier 2, 'Queen' in all known cases\n"); - printf(" -o FILE\tOutput file\n"); - printf(" -ids\t\tShow a list of known firmware identifiers.\n"); - exit(1); -} - -void show_fwids(void) -{ - printf("List of known firmware identifiers:\n"); - printf("Manufacturer\t\tProduct\t\tIdentifier\n"); - printf("=====================================================\n"); - printf("Conceptronic\t\tCHD2WLANU\tLLM_RUS001\n"); - printf("Pearl\t\t\tPE6643\t\tQueen\n"); - printf("Micronica\t\tMGB100\t\tQueen\n"); - printf("LevelOne\t\tWAP-0007\tDDC_RUS001\n"); - printf("SMC\t\t\tWAPS-G\t\tSMC_RUS001\n"); - printf("OvisLink (AirLive)\tWMU-6\t\tOVS_RUS001\n"); - printf("SafeCom SWSAPUR-5\tFMW\t\tSafeco_RPS001\n"); - exit(1); -} - -int main(int argc, char *argv[]) -{ - unsigned char hdr[HDRSIZE]; - unsigned char *data; - FILE *of; - char *outfile = NULL; - char *type; - struct hdrinfo *info; - long size; - int last = 0; - int n; - for (n = 1; n < argc; n++) - { - if (strcmp(argv[n], "-1") == 0) - ascii1 = argv[n+1]; - if (strcmp(argv[n], "-2") == 0) - ascii2 = argv[n+1]; - if (strcmp(argv[n], "-o") == 0) - outfile = argv[n+1]; - if (strcmp(argv[n], "-ids") == 0) - show_fwids(); - } - if (ascii1 == NULL || ascii2 == NULL || outfile == NULL) - showhelp(); - of = fopen(outfile, "w"); - if (of == NULL) - oferror(of); - for (n = 1; n < argc; n++) - { - if (strncmp(argv[n], "-", 1) != 0) - { - type = argv[n++]; - if (n >= argc) - showhelp(); - last = ((n + 1) >= argc); /* dirty, options first! */ - info = find_hdrinfo(type); - if (info == NULL) - showhelp(); - data = read_file(argv[n], &size); - if (data == NULL) - showhelp(); - makehdr(hdr, info, data, size, last); - /* showhdr(hdr); */ - if (fwrite(hdr, HDRSIZE, 1, of) != 1) - oferror(of); - if (fwrite(data, size, 1, of) != 1) - oferror(of); - free(data); - } - else - n++; - } - if (fclose(of) != 0) - oferror(NULL); - return 0; -} diff --git a/tools/firmware-utils/src/md5.c b/tools/firmware-utils/src/md5.c deleted file mode 100644 index 52d96accd3..0000000000 --- a/tools/firmware-utils/src/md5.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - * - * This differs from Colin Plumb's older public domain implementation in that - * no exactly 32-bit integer data type is required (any 32-bit or wider - * unsigned integer data type will do), there's no compile-time endianness - * configuration, and the function prototypes match OpenSSL's. No code from - * Colin Plumb's implementation has been reused; this comment merely compares - * the properties of the two independent implementations. - * - * The primary goals of this implementation are portability and ease of use. - * It is meant to be fast, but not as fast as possible. Some known - * optimizations are not included to reduce source code size and avoid - * compile-time configuration. - */ - -#ifndef HAVE_OPENSSL - -#include <string.h> - -#include "md5.h" - -/* - * The basic MD5 functions. - * - * F and G are optimized compared to their RFC 1321 definitions for - * architectures that lack an AND-NOT instruction, just like in Colin Plumb's - * implementation. - */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) (((x) ^ (y)) ^ (z)) -#define H2(x, y, z) ((x) ^ ((y) ^ (z))) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) - -/* - * The MD5 transformation for all four rounds. - */ -#define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) -#define GET(n) \ - SET(n) -#else -#define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) -#define GET(n) \ - (ctx->block[(n)]) -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. - */ -static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) -{ - const unsigned char *ptr; - MD5_u32plus a, b, c, d; - MD5_u32plus saved_a, saved_b, saved_c, saved_d; - - ptr = (const unsigned char *)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - -/* Round 1 */ - STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) - -/* Round 2 */ - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) - -/* Round 3 */ - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) - -/* Round 4 */ - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while (size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -void MD5_Init(MD5_CTX *ctx) -{ - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; -} - -void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) -{ - MD5_u32plus saved_lo; - unsigned long used, available; - - saved_lo = ctx->lo; - if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) - ctx->hi++; - ctx->hi += size >> 29; - - used = saved_lo & 0x3f; - - if (used) { - available = 64 - used; - - if (size < available) { - memcpy(&ctx->buffer[used], data, size); - return; - } - - memcpy(&ctx->buffer[used], data, available); - data = (const unsigned char *)data + available; - size -= available; - body(ctx, ctx->buffer, 64); - } - - if (size >= 64) { - data = body(ctx, data, size & ~(unsigned long)0x3f); - size &= 0x3f; - } - - memcpy(ctx->buffer, data, size); -} - -void MD5_Final(unsigned char *result, MD5_CTX *ctx) -{ - unsigned long used, available; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if (available < 8) { - memset(&ctx->buffer[used], 0, available); - body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = ctx->lo; - ctx->buffer[57] = ctx->lo >> 8; - ctx->buffer[58] = ctx->lo >> 16; - ctx->buffer[59] = ctx->lo >> 24; - ctx->buffer[60] = ctx->hi; - ctx->buffer[61] = ctx->hi >> 8; - ctx->buffer[62] = ctx->hi >> 16; - ctx->buffer[63] = ctx->hi >> 24; - - body(ctx, ctx->buffer, 64); - - result[0] = ctx->a; - result[1] = ctx->a >> 8; - result[2] = ctx->a >> 16; - result[3] = ctx->a >> 24; - result[4] = ctx->b; - result[5] = ctx->b >> 8; - result[6] = ctx->b >> 16; - result[7] = ctx->b >> 24; - result[8] = ctx->c; - result[9] = ctx->c >> 8; - result[10] = ctx->c >> 16; - result[11] = ctx->c >> 24; - result[12] = ctx->d; - result[13] = ctx->d >> 8; - result[14] = ctx->d >> 16; - result[15] = ctx->d >> 24; - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif diff --git a/tools/firmware-utils/src/md5.h b/tools/firmware-utils/src/md5.h deleted file mode 100644 index 2da44bf355..0000000000 --- a/tools/firmware-utils/src/md5.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * See md5.c for more information. - */ - -#ifdef HAVE_OPENSSL -#include <openssl/md5.h> -#elif !defined(_MD5_H) -#define _MD5_H - -/* Any 32-bit or wider unsigned integer data type will do */ -typedef unsigned int MD5_u32plus; - -typedef struct { - MD5_u32plus lo, hi; - MD5_u32plus a, b, c, d; - unsigned char buffer[64]; - MD5_u32plus block[16]; -} MD5_CTX; - -extern void MD5_Init(MD5_CTX *ctx); -extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); -extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); - -#endif diff --git a/tools/firmware-utils/src/mkbrncmdline.c b/tools/firmware-utils/src/mkbrncmdline.c deleted file mode 100644 index bcb72b03e7..0000000000 --- a/tools/firmware-utils/src/mkbrncmdline.c +++ /dev/null @@ -1,156 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * mkbrncmdline.c - partially based on OpenWrt's wndr3700.c - * - * Copyright (C) 2011 Tobias Diedrich <ranma+openwrt@tdiedrich.de> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <netinet/in.h> -#include <inttypes.h> - -static void usage(const char *) __attribute__ (( __noreturn__ )); - -static void usage(const char *mess) -{ - fprintf(stderr, "Error: %s\n", mess); - fprintf(stderr, "Usage: mkbrncmdline -i input_file -o output_file [-a loadaddress] arg1 [argx ...]\n"); - fprintf(stderr, "\n"); - exit(1); -} - -static char *input_file = NULL; -static char *output_file = NULL; -static unsigned loadaddr = 0x80002000; - -static void parseopts(int *argc, char ***argv) -{ - char *endptr; - int res; - - while ((res = getopt(*argc, *argv, "a:i:o:")) != -1) { - switch (res) { - default: - usage("Unknown option"); - break; - case 'a': - loadaddr = strtoul(optarg, &endptr, 0); - if (endptr == optarg || *endptr != 0) - usage("loadaddress must be a decimal or hexadecimal 32-bit value"); - break; - case 'i': - input_file = optarg; - break; - case 'o': - output_file = optarg; - break; - } - } - *argc -= optind; - *argv += optind; -} - -static void emitload(int outfd, int reg, unsigned value) -{ - char buf[8] = { - 0x3c, 0x04 + reg, - value >> 24, value >> 16, - 0x34, 0x84 + reg + (reg << 5), - value >> 8, value, - }; - if (write(outfd, buf, sizeof(buf)) != sizeof(buf)) { - fprintf(stderr, "write: %s\n", strerror(errno)); - exit(1); - } -} - -int main(int argc, char **argv) -{ - int outfd; - int i; - int fd; - size_t len, skip, buf_len; - unsigned cmdline_addr; - unsigned s_ofs; - char *buf; - - parseopts(&argc, &argv); - - if (argc < 1) - usage("must specify at least one kernel cmdline argument"); - - if (input_file == NULL || output_file == NULL) - usage("must specify input and output file"); - - if ((outfd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) - { - fprintf(stderr, "Error opening '%s' for writing: %s\n", output_file, strerror(errno)); - exit(1); - } - - // mmap input_file - if ((fd = open(input_file, O_RDONLY)) < 0 - || (len = lseek(fd, 0, SEEK_END)) < 0 - || (input_file = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1) - || close(fd) < 0) - { - fprintf(stderr, "Error mapping file '%s': %s\n", input_file, strerror(errno)); - exit(1); - } - - cmdline_addr = loadaddr + len; - - // Kernel args are passed in registers a0,a1,a2 and a3 - emitload(outfd, 0, 0); /* a0 = 0 */ - emitload(outfd, 1, 0); /* a1 = 0 */ - emitload(outfd, 2, cmdline_addr); /* a2 = &cmdline */ - emitload(outfd, 3, 0); /* a3 = 0 */ - skip = lseek(outfd, 0, SEEK_END); - - // write the kernel - if (write(outfd, input_file + skip, len - skip) != len -skip) { - fprintf(stderr, "write: %s\n", strerror(errno)); - exit(1); - } - - // write cmdline structure - buf_len = (argc + 1) * 4; - for (i=0; i<argc; i++) { - buf_len += strlen(argv[i]) + 1; - } - buf = malloc(buf_len + 16); - if (!buf) { - fprintf(stderr, "Could not allocate memory for cmdline buffer\n"); - exit(1); - } - memset(buf, 0, buf_len); - - s_ofs = 4 * (argc + 1); - for (i=0; i<argc; i++) { - unsigned s_ptr = cmdline_addr + s_ofs; - buf[i * 4 + 0] = s_ptr >> 24; - buf[i * 4 + 1] = s_ptr >> 16; - buf[i * 4 + 2] = s_ptr >> 8; - buf[i * 4 + 3] = s_ptr >> 0; - memcpy(&buf[s_ofs], argv[i], strlen(argv[i])); - s_ofs += strlen(argv[i]) + 1; - } - if (write(outfd, buf, buf_len) != buf_len) { - fprintf(stderr, "write: %s\n", strerror(errno)); - exit(1); - } - - - munmap(input_file, len); - close(outfd); - free(buf); - - return 0; -} diff --git a/tools/firmware-utils/src/mkbrnimg.c b/tools/firmware-utils/src/mkbrnimg.c deleted file mode 100644 index 1c575c6aa7..0000000000 --- a/tools/firmware-utils/src/mkbrnimg.c +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * mkbrnimg.c - partially based on OpenWrt's wndr3700.c - * - * Copyright (C) 2011 Tobias Diedrich <ranma+openwrt@tdiedrich.de> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <netinet/in.h> -#include <inttypes.h> - -#define BPB 8 /* bits/byte */ - -static uint32_t crc32[1<<BPB]; - -static char *output_file = "default-brnImage"; -static uint32_t magic = 0x12345678; -static char *signature = "BRNDTW502"; -static uint32_t crc32_poly = 0x2083b8ed; - -static void init_crc32() -{ - const uint32_t poly = ntohl(crc32_poly); - int n; - - for (n = 0; n < 1<<BPB; n++) { - uint32_t crc = n; - int bit; - - for (bit = 0; bit < BPB; bit++) - crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); - crc32[n] = crc; - } -} - -static uint32_t crc32buf(const void *buf, size_t len) -{ - uint32_t crc = 0xFFFFFFFF; - const uint8_t *in = buf; - - for (; len; len--, in++) - crc = crc32[(uint8_t)crc ^ *in] ^ (crc >> BPB); - return ~crc; -} - -static void usage(const char *) __attribute__ (( __noreturn__ )); - -static void usage(const char *mess) -{ - fprintf(stderr, "Error: %s\n", mess); - fprintf(stderr, "Usage: mkbrnimg [-o output_file] [-m magic] [-s signature] [-p crc32 poly] kernel_file [additional files]\n"); - fprintf(stderr, "\n"); - exit(1); -} - -static void parseopts(int *argc, char ***argv) -{ - char *endptr; - int res; - - while ((res = getopt(*argc, *argv, "o:m:s:p:")) != -1) { - switch (res) { - default: - usage("Unknown option"); - break; - case 'o': - output_file = optarg; - break; - case 'm': - magic = strtoul(optarg, &endptr, 0); - if (endptr == optarg || *endptr != 0) - usage("magic must be a decimal or hexadecimal 32-bit value"); - break; - case 's': - signature = optarg; - break; - case 'p': - crc32_poly = strtoul(optarg, &endptr, 0); - if (endptr == optarg || *endptr != 0) - usage("'crc32 poly' must be a decimal or hexadecimal 32-bit value"); - break; - } - } - *argc -= optind; - *argv += optind; -} - -static void appendfile(int outfd, char *path, int kernel) { - int fd; - size_t len, padded_len; - char *input_file; - uint32_t crc; - char padding[0x400]; - char footer[12]; - - memset(padding, 0xff, sizeof(padding)); - - // mmap input_file - if ((fd = open(path, O_RDONLY)) < 0 - || (len = lseek(fd, 0, SEEK_END)) < 0 - || (input_file = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1) - || close(fd) < 0) - { - fprintf(stderr, "Error mapping file '%s': %s\n", path, strerror(errno)); - exit(1); - } - - // kernel should be lzma compressed image, not uImage - if (kernel && - (input_file[0] != (char)0x5d || - input_file[1] != (char)0x00 || - input_file[2] != (char)0x00 || - input_file[3] != (char)0x80)) { - fprintf(stderr, "lzma signature not found on kernel image.\n"); - exit(1); - } - - init_crc32(); - crc = crc32buf(input_file, len); - fprintf(stderr, "crc32 for '%s' is %08x.\n", path, crc); - - // write the file - write(outfd, input_file, len); - - // write padding - padded_len = ((len + sizeof(footer) + sizeof(padding) - 1) & ~(sizeof(padding) - 1)) - sizeof(footer); - fprintf(stderr, "len=%08zx padded_len=%08zx\n", len, padded_len); - write(outfd, padding, padded_len - len); - - // write footer - footer[0] = (len >> 0) & 0xff; - footer[1] = (len >> 8) & 0xff; - footer[2] = (len >> 16) & 0xff; - footer[3] = (len >> 24) & 0xff; - footer[4] = (magic >> 0) & 0xff; - footer[5] = (magic >> 8) & 0xff; - footer[6] = (magic >> 16) & 0xff; - footer[7] = (magic >> 24) & 0xff; - footer[8] = (crc >> 0) & 0xff; - footer[9] = (crc >> 8) & 0xff; - footer[10] = (crc >> 16) & 0xff; - footer[11] = (crc >> 24) & 0xff; - write(outfd, footer, sizeof(footer)); - - munmap(input_file, len); -} - -int main(int argc, char **argv) -{ - int outfd; - int i; - - parseopts(&argc, &argv); - - if (argc < 1) - usage("wrong number of arguments"); - - if ((outfd = open(output_file, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) - { - fprintf(stderr, "Error opening '%s' for writing: %s\n", output_file, strerror(errno)); - exit(1); - } - - for (i=0; i<argc; i++) { - appendfile(outfd, argv[i], i == 0); - } - write(outfd, signature, strlen(signature)+1); - close(outfd); - - return 0; -} diff --git a/tools/firmware-utils/src/mkbuffaloimg.c b/tools/firmware-utils/src/mkbuffaloimg.c deleted file mode 100644 index 1a15fe1b55..0000000000 --- a/tools/firmware-utils/src/mkbuffaloimg.c +++ /dev/null @@ -1,219 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2016 FUKAUMI Naoki <naobsd@gmail.com> - * - * Based on mkdniimg.c - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#define DNI_HDR_LEN 128 - -/* - * Globals - */ -static char *ifname; -static char *progname; -static char *ofname; -static char *version = "0.00_0.00"; -static char *region = "JP"; -static char *rootfs_size; -static char *kernel_size; - -static char *board_id; -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -v <version> set image version to <version>\n" -" -r <region> set image region to <region>\n" -" -R <rootfs_size> set RootfsSize to <rootfs_size>\n" -" -K <kernel_size> set KernelSize to <kernel_size>\n" -" -h show this screen\n" - ); - - exit(status); -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int buflen; - int err; - struct stat st; - char *buf; - int i; - uint8_t csum; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "B:i:o:v:r:R:K:h"); - if (c == -1) - break; - - switch (c) { - case 'B': - board_id = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'v': - version = optarg; - break; - case 'r': - region = optarg; - break; - case 'R': - rootfs_size = optarg; - break; - case 'K': - kernel_size = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (board_id == NULL) { - ERR("no board specified"); - goto err; - } - - if (rootfs_size == NULL) { - ERR("no rootfs_size specified"); - goto err; - } - - if (kernel_size == NULL) { - ERR("no kernel_size specified"); - goto err; - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - buflen = st.st_size + DNI_HDR_LEN + 1; - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - memset(buf, 0, DNI_HDR_LEN); - snprintf(buf, DNI_HDR_LEN, "device:%s\nversion:%s\nregion:%s\n" - "RootfsSize:%s\nKernelSize:%s\nInfoHeadSize:128\n", - board_id, version, region, rootfs_size, kernel_size); - buf[DNI_HDR_LEN - 2] = 0x12; - buf[DNI_HDR_LEN - 1] = 0x32; - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - errno = 0; - fread(buf + DNI_HDR_LEN, st.st_size, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto err_close_in; - } - - csum = 0; - for (i = 0; i < (st.st_size + DNI_HDR_LEN); i++) - csum += buf[i]; - - csum = 0xff - csum; - buf[st.st_size + DNI_HDR_LEN] = csum; - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto err_close_in; - } - - errno = 0; - fwrite(buf, buflen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto err_close_out; - } - - res = EXIT_SUCCESS; - - fflush(outfile); - - err_close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } - - err_close_in: - fclose(infile); - - err_free: - free(buf); - - err: - return res; -} diff --git a/tools/firmware-utils/src/mkcameofw.c b/tools/firmware-utils/src/mkcameofw.c deleted file mode 100644 index 71fb7a2756..0000000000 --- a/tools/firmware-utils/src/mkcameofw.c +++ /dev/null @@ -1,429 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include <arpa/inet.h> -#include <netinet/in.h> - -#define MAX_MODEL_LEN 20 -#define MAX_SIGNATURE_LEN 30 -#define MAX_REGION_LEN 4 -#define MAX_VERSION_LEN 12 - -#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) - -struct file_info { - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ - uint32_t write_size; -}; - -struct img_header { - uint32_t checksum; - uint32_t image_size; - uint32_t kernel_size; - char model[MAX_MODEL_LEN]; - char signature[MAX_SIGNATURE_LEN]; - char region[MAX_REGION_LEN]; - char version[MAX_VERSION_LEN]; - unsigned char header_len; - unsigned char is_tgz; - unsigned char pad[4]; -} __attribute__ ((packed)); - -/* - * Globals - */ -static char *ofname; -static char *progname; - -static char *model; -static char *signature; -static char *region = "DEF"; -static char *version; -static struct file_info kernel_info; -static struct file_info rootfs_info; -static uint32_t kernel_size; -static uint32_t image_size; -static int combined; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt " (%s)\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -k <file> read kernel image from the file <file>\n" -" -c use the kernel image as a combined image\n" -" -M <model> set model to <model>\n" -" -o <file> write output to the file <file>\n" -" -r <file> read rootfs image from the file <file>\n" -" -S <signature> set image signature to <signature>\n" -" -R <region> set image region to <region>\n" -" -V <version> set image version to <version>\n" -" -I <size> set image size to <size>\n" -" -K <size> set kernel size to <size>\n" -" -h show this screen\n" - ); - - exit(status); -} - -int -str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - -static int get_file_stat(struct file_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) - return 0; - - res = stat(fdata->file_name, &st); - if (res){ - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - fdata->write_size = fdata->file_size; - return 0; -} - -static int read_to_buf(struct file_info *fdata, char *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(fdata->file_name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - errno = 0; - fread(buf, fdata->file_size, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - -out_close: - fclose(f); -out: - return ret; -} - -static int check_options(void) -{ - int ret; - -#define CHKSTR(_name, _msg) \ - do { \ - if (_name == NULL) { \ - ERR("no %s specified", _msg); \ - return -1; \ - } \ - } while (0) - -#define CHKSTRLEN(_name, _msg) \ - do { \ - int field_len; \ - CHKSTR(_name, _msg); \ - field_len = FIELD_SIZEOF(struct img_header, _name) - 1; \ - if (strlen(_name) > field_len) { \ - ERR("%s is too long, max length is %d", \ - _msg, field_len); \ - return -1; \ - } \ - } while (0) - - CHKSTRLEN(model, "model"); - CHKSTRLEN(signature, "signature"); - CHKSTRLEN(region, "region"); - CHKSTRLEN(version, "version"); - CHKSTR(ofname, "output file"); - CHKSTR(kernel_info.file_name, "kernel image"); - - ret = get_file_stat(&kernel_info); - if (ret) - return ret; - - if (combined) { - if (!kernel_size) { - ERR("kernel size must be specified for combined images"); - return -1; \ - } - - if (!image_size) - image_size = kernel_info.file_size; - - if (kernel_info.file_size > image_size) { - ERR("kernel image is too big"); - return -1; - } - - kernel_info.write_size = image_size; - } else { - CHKSTR(rootfs_info.file_name, "rootfs image"); - - ret = get_file_stat(&rootfs_info); - if (ret) - return ret; - - if (kernel_size) { - /* override kernel size */ - kernel_info.write_size = kernel_size; - } - - if (image_size) { - if (image_size < kernel_info.write_size) - kernel_info.write_size = image_size; - - /* override rootfs size */ - rootfs_info.write_size = image_size - kernel_info.write_size; - } - - if (kernel_info.file_size > kernel_info.write_size) { - ERR("kernel image is too big"); - return -1; - } - - if (rootfs_info.file_size > rootfs_info.write_size) { - ERR("rootfs image is too big"); - return -1; - } - } - - return 0; -} - -static int write_fw(char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - -out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); - } -out: - return ret; -} - -static uint32_t get_csum(unsigned char *p, uint32_t len) -{ - uint32_t csum = 0; - - while (len--) - csum += *p++; - - return csum; -} - -static int build_fw(void) -{ - int buflen; - char *buf; - char *p; - uint32_t csum; - struct img_header *hdr; - int ret = EXIT_FAILURE; - - buflen = sizeof(struct img_header) + - kernel_info.write_size + rootfs_info.write_size; - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - memset(buf, 0, buflen); - - p = buf + sizeof(struct img_header); - - /* read kernel data */ - ret = read_to_buf(&kernel_info, p); - if (ret) - goto out_free_buf; - - if (!combined) { - p += kernel_info.write_size; - - /* read rootfs data */ - ret = read_to_buf(&rootfs_info, p); - if (ret) - goto out_free_buf; - } - - csum = get_csum((unsigned char *)(buf + sizeof(struct img_header)), - buflen - sizeof(struct img_header)); - - /* fill firmware header */ - hdr = (struct img_header *) buf; - - hdr->checksum = htonl(csum); - hdr->image_size = htonl(buflen - sizeof(struct img_header)); - if (!combined) - hdr->kernel_size = htonl(kernel_info.write_size); - else - hdr->kernel_size = htonl(kernel_size); - hdr->header_len = sizeof(struct img_header); - strncpy(hdr->model, model, sizeof(hdr->model)); - strncpy(hdr->signature, signature, sizeof(hdr->signature)); - strncpy(hdr->version, version, sizeof(hdr->version)); - strncpy(hdr->region, region, sizeof(hdr->region)); - - ret = write_fw(buf, buflen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - -out_free_buf: - free(buf); -out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - - while (1) { - int c; - - c = getopt(argc, argv, "M:S:V:R:k:K:I:r:o:hc"); - if (c == -1) - break; - - switch (c) { - case 'M': - model = optarg; - break; - case 'S': - signature = optarg; - break; - case 'V': - version = optarg; - break; - case 'R': - region = optarg; - break; - case 'k': - kernel_info.file_name = optarg; - break; - case 'K': - if (str2u32(optarg, &kernel_size)) { - ERR("%s is invalid '%s'", - "kernel size", optarg); - goto out; - } - break; - case 'I': - if (str2u32(optarg, &image_size)) { - ERR("%s is invalid '%s'", - "image size", optarg); - goto out; - } - break; - case 'r': - rootfs_info.file_name = optarg; - break; - case 'c': - combined = 1; - break; - case 'o': - ofname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - ret = build_fw(); - -out: - return ret; -} - diff --git a/tools/firmware-utils/src/mkcasfw.c b/tools/firmware-utils/src/mkcasfw.c deleted file mode 100644 index 8d3ea40509..0000000000 --- a/tools/firmware-utils/src/mkcasfw.c +++ /dev/null @@ -1,1033 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * Copyright (C) 2007 OpenWrt.org - * Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> -#include <endian.h> /* for __BYTE_ORDER */ -#if defined(__CYGWIN__) -# include <byteswap.h> -#endif - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define HOST_TO_LE16(x) (x) -# define HOST_TO_LE32(x) (x) -# define LE16_TO_HOST(x) (x) -# define LE32_TO_HOST(x) (x) -#else -# define HOST_TO_LE16(x) bswap_16(x) -# define HOST_TO_LE32(x) bswap_32(x) -# define LE16_TO_HOST(x) bswap_16(x) -# define LE32_TO_HOST(x) bswap_32(x) -#endif - -#define MAX_NUM_BLOCKS 2 -#define MAX_ARG_COUNT 32 -#define MAX_ARG_LEN 1024 -#define FILE_BUF_LEN (16*1024) -#define DEFAULT_PADC 0xFF - -#define DEFAULT_BLOCK_ALIGN 0x10000U - -#define CSUM_TYPE_NONE 0 -#define CSUM_TYPE_8 1 -#define CSUM_TYPE_16 2 -#define CSUM_TYPE_32 3 - -struct csum_state{ - int size; - uint32_t val; - uint32_t tmp; - int odd; -}; - -struct image_desc { - int need_file; - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ - - uint32_t csum; - uint32_t out_size; - uint8_t padc; -}; - -struct fwhdr_nfs { - uint32_t type; - uint32_t kernel_offs; - uint32_t kernel_size; - uint32_t fs_offs; - uint32_t fs_size; - uint32_t kernel_csum; - uint32_t fs_csum; - uint32_t id; -} __attribute__ ((packed)); - -struct fwhdr_cas { - uint32_t type; - uint32_t kernel_offs; - uint32_t kernel_size; - uint32_t id; - uint32_t kernel_csum; - uint32_t magic1; - uint32_t magic2; - uint32_t magic3; -} __attribute__ ((packed)); - -union file_hdr { - struct fwhdr_cas cas; - struct fwhdr_nfs nfs; -}; - -struct board_info { - char *model; - char *name; - int header_type; - uint32_t id; - uint32_t max_kernel_size; - uint32_t max_fs_size; -}; - -#define HEADER_TYPE_NFS 0 -#define HEADER_TYPE_CAS 1 - -#define KERNEL_SIZE_CAS (61*64*1024) -#define KERNEL_SIZE_NFS (52*64*1024) -#define FS_SIZE_NFS (9*64*1024) - -#define CAS_MAGIC1 0x5241AA55 -#define CAS_MAGIC2 0x524F4741 -#define CAS_MAGIC3 0xD3F22D4E - -/* Cellvision/SparkLAN products */ -#define MODEL_CAS_630 0x01000000 -#define MODEL_CAS_630W 0x01000000 -#define MODEL_CAS_670 0x01000000 -#define MODEL_CAS_670W 0x01000000 -#define MODEL_NFS_101U 0x01000000 -#define MODEL_NFS_101WU 0x01000003 -#define MODEL_NFS_202U 0x01000001 -#define MODEL_NFS_202WU 0x01000002 - -/* Corega products */ -#define MODEL_CG_NSADP 0x01000020 /* NFS-101U */ -#define MODEL_CG_NSADPCR 0x01000021 /* NFS-202U */ - -/* D-Link products */ -#define MODEL_DCS_950 0x01010102 /* CAS-630 */ -#define MODEL_DCS_950G 0x01020102 /* CAS-630W */ -#define MODEL_DNS_120 0x01000030 /* NFS-101U */ -#define MODEL_DNS_G120 0x01000032 /* NFS-101WU */ - -/* Digitus products */ -#define MODEL_DN_16021 MODEL_CAS_630 -#define MODEL_DN_16022 MODEL_CAS_630W -#define MODEL_DN_16030 MODEL_CAS_670 -#define MODEL_DN_16031 MODEL_CAS_670W -#define MODEL_DN_7013 MODEL_NFS_101U - -/* Lobos products */ -#define MODEL_LB_SS01TXU 0x00000000 - -/* Neu-Fusion products */ - -/* Ovislink products */ -#define MODEL_MU_5000FS 0x01000040 /* NFS-101U */ -#define MODEL_WL_5420CAM 0x020B0101 /* CAS-630W? */ -#define MODEL_WL_5460CAM 0x020B0001 /* CAS-670W */ - -/* Repotec products */ - -/* Sitecom products */ -#define MODEL_LN_350 /* unknown */ -#define MODEL_LN_403 0x01020402 -#define MODEL_WL_401 0x01010402 - -/* Surecom products */ -#define MODEL_EP_4001_MM 0x01030A02 /* CAS-630 */ -#define MODEL_EP_4002_MM 0x01020A02 /* CAS-630W */ -#define MODEL_EP_4011_MM 0x01010A02 /* CAS-670 */ -#define MODEL_EP_4012_MM 0x01000A02 /* CAS-670W */ -#define MODEL_EP_9812_U /* unknown */ - -/* Trendnet products */ -#define MODEL_TN_U100 0x01000081 /* NFS-101U */ -#define MODEL_TN_U200 0x01000082 /* NFS-202U */ - -/* - * Globals - */ -char *progname; -char *ofname; -int verblevel; -int keep_invalid_images; -int invalid_causes_error = 1; -union file_hdr header; - -struct image_desc kernel_image; -struct image_desc fs_image; - -struct board_info *board = NULL; - -#define BOARD(m, n, i, ks, fs, h) { \ - .model = (m), \ - .name = (n), \ - .id = (i), \ - .max_kernel_size = (ks), \ - .max_fs_size = (fs), \ - .header_type = (h) \ - } - -#define BOARD_CAS(m,n,i) \ - BOARD(m, n, i, KERNEL_SIZE_CAS, 0, HEADER_TYPE_CAS) -#define BOARD_NFS(m,n,i) \ - BOARD(m, n, i, KERNEL_SIZE_NFS, FS_SIZE_NFS, HEADER_TYPE_NFS) - -static struct board_info boards[] = { - /* Cellvision/Sparklan products */ - BOARD_CAS("CAS-630", "Cellvision CAS-630", MODEL_CAS_630), - BOARD_CAS("CAS-630W", "Cellvision CAS-630W", MODEL_CAS_630W), - BOARD_CAS("CAS-670", "Cellvision CAS-670", MODEL_CAS_670), - BOARD_CAS("CAS-670W", "Cellvision CAS-670W", MODEL_CAS_670W), - BOARD_NFS("NFS-101U", "Cellvision NFS-101U", MODEL_NFS_101U), - BOARD_NFS("NFS-101WU", "Cellvision NFS-101WU", MODEL_NFS_101WU), - BOARD_NFS("NFS-202U", "Cellvision NFS-202U", MODEL_NFS_202U), - BOARD_NFS("NFS-202WU", "Cellvision NFS-202WU", MODEL_NFS_202WU), - - /* Corega products */ - BOARD_NFS("CG-NSADP", "Corega CG-NSADP", MODEL_CG_NSADP), - BOARD_NFS("CG-NSADPCR", "Corega CG-NSADPCR", MODEL_CG_NSADPCR), - - /* D-Link products */ - BOARD_CAS("DCS-950", "D-Link DCS-950", MODEL_DCS_950), - BOARD_CAS("DCS-950G", "D-Link DCS-950G", MODEL_DCS_950G), - BOARD_NFS("DNS-120", "D-Link DNS-120", MODEL_DNS_120), - BOARD_NFS("DNS-G120", "D-Link DNS-G120", MODEL_DNS_G120), - - /* Digitus products */ - BOARD_NFS("DN-7013", "Digitus DN-7013", MODEL_DN_7013), - - /* Lobos products */ - BOARD_NFS("LB-SS01TXU", "Lobos LB-SS01TXU", MODEL_LB_SS01TXU), - - /* Ovislink products */ - BOARD_NFS("MU-5000FS", "Ovislink MU-5000FS", MODEL_MU_5000FS), - BOARD_CAS("WL-5420CAM", "Ovislink WL-5420 CAM", MODEL_WL_5420CAM), - BOARD_CAS("WL-5460CAM", "Ovislink WL-5460 CAM", MODEL_WL_5460CAM), - - /* Sitecom products */ - BOARD_CAS("LN-403", "Sitecom LN-403", MODEL_LN_403), - BOARD_CAS("WL-401", "Sitecom WL-401", MODEL_WL_401), - - /* Surecom products */ - BOARD_CAS("EP-4001-MM", "Surecom EP-4001-MM", MODEL_EP_4001_MM), - BOARD_CAS("EP-4002-MM", "Surecom EP-4002-MM", MODEL_EP_4002_MM), - BOARD_CAS("EP-4011-MM", "Surecom EP-4011-MM", MODEL_EP_4011_MM), - BOARD_CAS("EP-4012-MM", "Surecom EP-4012-MM", MODEL_EP_4012_MM), - - /* TrendNET products */ - BOARD_NFS("TN-U100", "TrendNET TN-U100", MODEL_TN_U100), - BOARD_NFS("TN-U200", "TrendNET TN-U200", MODEL_TN_U200), - - {.model = NULL} -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define WARN(fmt, ...) do { \ - fprintf(stderr, "[%s] *** warning: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define DBG(lev, fmt, ...) do { \ - if (verblevel < lev) \ - break;\ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERR_FATAL -1 -#define ERR_INVALID_IMAGE -2 - -void -usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - struct board_info *board; - - fprintf(stream, "Usage: %s [OPTIONS...] <file>\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>.\n" -" valid <board> values:\n" - ); - for (board = boards; board->model != NULL; board++){ - fprintf(stream, -" %-12s: %s\n", - board->model, board->name); - }; - fprintf(stream, -" -d don't throw error on invalid images\n" -" -k keep invalid images\n" -" -K <file> add kernel to the image\n" -" -C <file> add custom filesystem to the image\n" -" -h show this screen\n" -"Parameters:\n" -" <file> write output to the file <file>\n" - ); - - exit(status); -} - -static inline uint32_t align(uint32_t base, uint32_t alignment) -{ - uint32_t ret; - - if (alignment) { - ret = (base + alignment - 1); - ret &= ~(alignment-1); - } else { - ret = base; - } - - return ret; -} - -/* - * argument parsing - */ -int -str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - - -int -str2u16(char *arg, uint16_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x10000)) { - return -1; - } - - *val = t & 0xFFFF; - return 0; -} - -int -str2u8(char *arg, uint8_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) { - return -1; - } - - *val = t & 0xFF; - return 0; -} - -int -parse_arg(char *arg, char *buf, char *argv[]) -{ - int res = 0; - size_t argl; - char *tok; - char **ap = &buf; - int i; - - memset(argv, 0, MAX_ARG_COUNT * sizeof(void *)); - - if ((arg == NULL)) { - /* no arguments */ - return 0; - } - - argl = strlen(arg); - if (argl == 0) { - /* no arguments */ - return 0; - } - - if (argl >= MAX_ARG_LEN) { - /* argument is too long */ - argl = MAX_ARG_LEN-1; - } - - memcpy(buf, arg, argl); - buf[argl] = '\0'; - - for (i = 0; i < MAX_ARG_COUNT; i++) { - tok = strsep(ap, ":"); - if (tok == NULL) { - break; - } -#if 0 - else if (tok[0] == '\0') { - break; - } -#endif - argv[i] = tok; - res++; - } - - return res; -} - - -int -required_arg(char c, char *arg) -{ - if (arg == NULL || *arg != '-') - return 0; - - ERR("option -%c requires an argument\n", c); - return ERR_FATAL; -} - - -int -is_empty_arg(char *arg) -{ - int ret = 1; - if (arg != NULL) { - if (*arg) ret = 0; - }; - return ret; -} - - -void -csum8_update(uint8_t *p, uint32_t len, struct csum_state *css) -{ - for ( ; len > 0; len --) { - css->val += *p++; - } -} - - -uint16_t -csum8_get(struct csum_state *css) -{ - uint8_t t; - - t = css->val; - return ~t + 1; -} - - -void -csum16_update(void *data, uint32_t len, struct csum_state *css) -{ - uint8_t *p = data; - uint16_t t; - - if (css->odd) { - t = css->tmp + (p[0]<<8); - css->val += LE16_TO_HOST(t); - css->odd = 0; - len--; - p++; - } - - for ( ; len > 1; len -= 2, p +=2 ) { - t = p[0] + (p[1] << 8); - css->val += LE16_TO_HOST(t); - } - - if (len == 1) { - css->tmp = p[0]; - css->odd = 1; - } -} - - -uint16_t -csum16_get(struct csum_state *css) -{ - char pad = 0; - - csum16_update(&pad, 1, css); - return ~css->val + 1; -} - -void -csum32_update(uint8_t *p, uint32_t len, struct csum_state *css) -{ - uint32_t t; - - for ( ; len > 3; len -= 4, p += 4 ) { - t = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); - css->val ^= t; - } -} - -uint32_t -csum32_get(struct csum_state *css) -{ - return css->val; -} - - -void -csum_init(struct csum_state *css, int size) -{ - css->val = 0; - css->tmp = 0; - css->odd = 0; - css->size = size; -} - -void -csum_update(void *data, uint32_t len, struct csum_state *css) -{ - uint8_t *p = data; - - switch (css->size) { - case CSUM_TYPE_8: - csum8_update(p,len,css); - break; - case CSUM_TYPE_16: - csum16_update(p,len,css); - break; - case CSUM_TYPE_32: - csum32_update(p,len,css); - break; - } -} - - -uint32_t -csum_get(struct csum_state *css) -{ - uint32_t ret; - - switch (css->size) { - case CSUM_TYPE_8: - ret = csum8_get(css); - break; - case CSUM_TYPE_16: - ret = csum16_get(css); - break; - case CSUM_TYPE_32: - ret = csum32_get(css); - break; - default: - ERR("invalid checksum size\n"); - return 0; - } - - return ret; -} - - -/* - * routines to write data to the output file - */ -int -write_out_data(FILE *outfile, void *data, size_t len, - struct csum_state *css) -{ - uint8_t *ptr = data; - - errno = 0; - - fwrite(ptr, len, 1, outfile); - if (errno) { - ERRS("unable to write output file"); - return ERR_FATAL; - } - - if (css) { - csum_update(ptr, len, css); - } - - return 0; -} - - -int -write_out_padding(FILE *outfile, size_t len, uint8_t padc, - struct csum_state *css) -{ - uint8_t buf[512]; - size_t buflen = sizeof(buf); - int err; - - memset(buf, padc, buflen); - while (len > 0) { - if (len < buflen) - buflen = len; - - err = write_out_data(outfile, buf, buflen, css); - if (err) - return err; - - len -= buflen; - } - - return 0; -} - - -int -image_stat_file(struct image_desc *desc) -{ - struct stat st; - int err; - - if (desc->file_name == NULL) - return 0; - - err = stat(desc->file_name, &st); - if (err){ - ERRS("stat failed on %s", desc->file_name); - return ERR_FATAL; - } - - if (st.st_size > desc->out_size) { - WARN("file %s is too big, will be truncated to %d bytes\n", - desc->file_name, desc->out_size); - desc->file_size = desc->out_size; - return ERR_INVALID_IMAGE; - } - - - desc->file_size = st.st_size; - desc->out_size = align(desc->file_size,1); - return 0; -} - - -int -image_writeout_file(FILE *outfile, struct image_desc *desc, - struct csum_state *css) -{ - char buf[FILE_BUF_LEN]; - size_t buflen = sizeof(buf); - FILE *f; - size_t len; - int res; - - if (desc->file_name == NULL) - return 0; - - if (desc->file_size == 0) - return 0; - - errno = 0; - f = fopen(desc->file_name,"r"); - if (errno) { - ERRS("unable to open file: %s", desc->file_name); - return ERR_FATAL; - } - - len = desc->file_size; - while (len > 0) { - if (len < buflen) - buflen = len; - - /* read data from source file */ - errno = 0; - fread(buf, buflen, 1, f); - if (errno != 0) { - ERRS("unable to read from file: %s", desc->file_name); - res = ERR_FATAL; - break; - } - - res = write_out_data(outfile, buf, buflen, css); - if (res) - break; - - len -= buflen; - } - - fclose(f); - return res; -} - - -int -image_writeout(FILE *outfile, struct image_desc *desc) -{ - int res; - struct csum_state css; - size_t padlen; - - res = 0; - - if (!desc->file_size) - return 0; - - DBG(2, "writing image, file=%s, file_size=%d\n", - desc->file_name, desc->file_size); - - csum_init(&css, CSUM_TYPE_32); - - res = image_writeout_file(outfile, desc, &css); - if (res) - return res; - - /* write padding data if neccesary */ - padlen = desc->out_size - desc->file_size; - DBG(1,"padding desc, length=%zu", padlen); - res = write_out_padding(outfile, padlen, desc->padc, &css); - - desc->csum = csum_get(&css); - - return res; -} - - -int -write_out_header(FILE *outfile) -{ - union file_hdr tmp; - int res; - - errno = 0; - if (fseek(outfile, 0, SEEK_SET) != 0) { - ERRS("fseek failed on output file"); - return ERR_FATAL; - } - - switch (board->header_type) { - case HEADER_TYPE_CAS: - tmp.cas.type = HOST_TO_LE32(header.cas.type); - tmp.cas.id = HOST_TO_LE32(header.cas.id); - tmp.cas.kernel_offs = HOST_TO_LE32(sizeof(tmp.cas)); - tmp.cas.kernel_size = HOST_TO_LE32(kernel_image.out_size); - tmp.cas.kernel_csum = HOST_TO_LE32(kernel_image.csum); - tmp.cas.magic1 = HOST_TO_LE32(CAS_MAGIC1); - tmp.cas.magic2 = HOST_TO_LE32(CAS_MAGIC2); - tmp.cas.magic3 = HOST_TO_LE32(CAS_MAGIC3); - res = write_out_data(outfile, (uint8_t *)&tmp.cas, - sizeof(tmp.cas), NULL); - break; - case HEADER_TYPE_NFS: - tmp.nfs.type = HOST_TO_LE32(header.nfs.type); - tmp.nfs.id = HOST_TO_LE32(header.nfs.id); - tmp.nfs.kernel_offs = HOST_TO_LE32(sizeof(tmp.nfs)); - tmp.nfs.kernel_size = HOST_TO_LE32(kernel_image.out_size); - tmp.nfs.kernel_csum = HOST_TO_LE32(kernel_image.csum); - tmp.nfs.fs_offs = HOST_TO_LE32(sizeof(tmp.nfs) - + kernel_image.out_size); - tmp.nfs.fs_size = HOST_TO_LE32(fs_image.out_size); - tmp.nfs.fs_csum = HOST_TO_LE32(fs_image.csum); - res = write_out_data(outfile, (uint8_t *)&tmp.nfs, - sizeof(tmp.nfs), NULL); - break; - default: - ERR("invalid header type\n"); - return -EINVAL; - } - - return res; -} - -int -write_out_images(FILE *outfile) -{ - int res; - - res = image_writeout(outfile, &kernel_image); - if (res) - return res; - - res = image_writeout(outfile, &fs_image); - if (res) - return res; - - return 0; -} - - -struct board_info * -find_board(char *model) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->model != NULL; board++){ - if (strcasecmp(model, board->model) == 0) { - ret = board; - break; - } - }; - - return ret; -} - - -int -parse_opt_board(char ch, char *arg) -{ - - DBG(1,"parsing board option: -%c %s", ch, arg); - - if (board != NULL) { - ERR("only one board option allowed"); - return ERR_FATAL; - } - - if (required_arg(ch, arg)) - return ERR_FATAL; - - board = find_board(arg); - if (board == NULL){ - ERR("invalid/unknown board specified: %s", arg); - return ERR_FATAL; - } - - switch (board->header_type) { - case HEADER_TYPE_CAS: - header.cas.type = HEADER_TYPE_CAS; - header.cas.id = board->id; - break; - case HEADER_TYPE_NFS: - header.nfs.type = HEADER_TYPE_NFS; - header.nfs.id = board->id; - break; - default: - ERR("internal error, unknown header type\n"); - return ERR_FATAL; - } - - return 0; -} - - -int -parse_opt_image(char ch, char *arg) -{ - char buf[MAX_ARG_LEN]; - char *argv[MAX_ARG_COUNT]; - char *p; - struct image_desc *desc = NULL; - int i; - - switch (ch) { - case 'K': - if (kernel_image.file_name) { - WARN("only one kernel option allowed"); - break; - } - desc = &kernel_image; - break; - case 'F': - if (fs_image.file_name) { - WARN("only one fs option allowed"); - break; - } - desc = &fs_image; - break; - } - - if (!desc) - return ERR_FATAL; - - parse_arg(arg, buf, argv); - - i = 0; - p = argv[i++]; - if (!is_empty_arg(p)) { - desc->file_name = strdup(p); - if (desc->file_name == NULL) { - ERR("not enough memory"); - return ERR_FATAL; - } - } else { - ERR("no file specified for option %c", ch); - return ERR_FATAL; - } - - return 0; -} - - -int -process_images(void) -{ - int res; - - kernel_image.out_size = board->max_kernel_size; - kernel_image.padc = DEFAULT_PADC; - res = image_stat_file(&kernel_image); - if (res) - return res; - - if (!fs_image.file_name) - return 0; - - fs_image.out_size = board->max_fs_size; - fs_image.padc = DEFAULT_PADC; - res = image_stat_file(&fs_image); - if (res) - return res; - - return 0; -} - - -int -main(int argc, char *argv[]) -{ - int optinvalid = 0; /* flag for invalid option */ - int c; - int res = ERR_FATAL; - - FILE *outfile; - - progname=basename(argv[0]); - - opterr = 0; /* could not print standard getopt error messages */ - while ( 1 ) { - optinvalid = 0; - - c = getopt(argc, argv, "B:C:dhK:r:vw:x:"); - if (c == -1) - break; - - switch (c) { - case 'B': - optinvalid = parse_opt_board(c,optarg); - break; - case 'd': - invalid_causes_error = 0; - break; - case 'C': - case 'K': - optinvalid = parse_opt_image(c,optarg); - break; - case 'k': - keep_invalid_images = 1; - break; - case 'v': - verblevel++; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - optinvalid = 1; - break; - } - if (optinvalid != 0 ){ - ERR("invalid option: -%c", optopt); - goto out; - } - } - - if (board == NULL) { - ERR("no board specified"); - goto out; - } - - if (optind == argc) { - ERR("no output file specified"); - goto out; - } - - ofname = argv[optind++]; - - if (optind < argc) { - ERR("invalid option: %s", argv[optind]); - goto out; - } - - res = process_images(); - if (res == ERR_FATAL) - goto out; - - if (res == ERR_INVALID_IMAGE) { - if (invalid_causes_error) - res = ERR_FATAL; - - if (keep_invalid_images == 0) { - WARN("generation of invalid images \"%s\" disabled", ofname); - goto out; - } - - WARN("generating invalid image: \"%s\"", ofname); - } - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - res = ERR_FATAL; - goto out; - } - - if (write_out_header(outfile) != 0) { - res = ERR_FATAL; - goto out_flush; - } - - if (write_out_images(outfile) != 0) { - res = ERR_FATAL; - goto out_flush; - } - - if (write_out_header(outfile) != 0) { - res = ERR_FATAL; - goto out_flush; - } - - DBG(1,"Image file %s completed.", ofname); - -out_flush: - fflush(outfile); - fclose(outfile); - if (res == ERR_FATAL) { - unlink(ofname); - } -out: - if (res == ERR_FATAL) - return EXIT_FAILURE; - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/mkchkimg.c b/tools/firmware-utils/src/mkchkimg.c deleted file mode 100644 index b51eca9369..0000000000 --- a/tools/firmware-utils/src/mkchkimg.c +++ /dev/null @@ -1,331 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Make CHK Image - * - * This utility creates Netgear .chk files. - * - * Copyright (C) 2008 Dave C. Reeve <Dave.Reeve@dreeve.org> - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <errno.h> -#include <arpa/inet.h> -#include <unistd.h> - -#define BUF_LEN (2048) - -#define MAX_BOARD_ID_LEN (64) - -/* - * Note on the reserved field of the chk_header: - * OFW naming scheme is typically: DEVICENAME-VA.B.C.D_E.F.G.chk, with A-G - * between 0 and 255. For instance: EX3700_EX3800-V1.0.0.58_1.0.38.chk - * The reserved field works like this: - * reserved[0]: region code. 1 for WW (WorldWide) and 2 for NA (North America) - * reserved[1]: A - * reserved[2]: B - * reserved[3]: C - * reserved[4]: D - * reserved[5]: E - * reserved[6]: F - * reserved[7]: G - */ -struct chk_header { - uint32_t magic; - uint32_t header_len; - uint8_t reserved[8]; - uint32_t kernel_chksum; - uint32_t rootfs_chksum; - uint32_t kernel_len; - uint32_t rootfs_len; - uint32_t image_chksum; - uint32_t header_chksum; - /* char board_id[] - upto MAX_BOARD_ID_LEN */ -}; - -static void __attribute__ ((format (printf, 2, 3))) -fatal_error (int maybe_errno, const char * format, ...) -{ - va_list ap; - - fprintf (stderr, "mkchkimg: "); - va_start (ap, format); - vfprintf (stderr, format, ap); - va_end (ap); - - if (maybe_errno) { - fprintf (stderr, ": %s\n", strerror (maybe_errno)); - } else { - fprintf (stderr, "\n"); - } - - exit (EXIT_FAILURE); -} - -static void __attribute__ ((format (printf, 1, 2))) -message (const char * format, ...) -{ - va_list ap; - - fprintf (stderr, "mkchkimg: "); - va_start (ap, format); - vfprintf (stderr, format, ap); - va_end (ap); - fprintf (stderr, "\n"); -} - -struct ngr_checksum { - uint32_t c0; - uint32_t c1; -}; - -static inline void -netgear_checksum_init (struct ngr_checksum * c) -{ - c->c0 = c->c1 = 0; -} - -static inline void -netgear_checksum_add (struct ngr_checksum * c, unsigned char * buf, size_t len) -{ - size_t i; - - for (i=0; i<len; i++) { - c->c0 += buf[i] & 0xff; - c->c1 += c->c0; - } -} - -static inline unsigned long -netgear_checksum_fini (struct ngr_checksum * c) -{ - uint32_t b, checksum; - - b = (c->c0 & 65535) + ((c->c0 >> 16) & 65535); - c->c0 = ((b >> 16) + b) & 65535; - b = (c->c1 & 65535) + ((c->c1 >> 16) & 65535); - c->c1 = ((b >> 16) + b) & 65535; - checksum = ((c->c1 << 16) | c->c0); - return checksum; -} - -static void -print_help (void) -{ - fprintf (stderr, "Usage: mkchkimg -o output -k kernel [-f filesys] [-b board_id] [-r region]\n"); -} - -int -main (int argc, char * argv[]) -{ - int opt; - char * ptr; - size_t len; - size_t header_len; - struct chk_header * hdr; - struct ngr_checksum chk_part, chk_whole; - char buf[BUF_LEN]; - char * output_file, * kern_file, * fs_file; - FILE * out_fp, * kern_fp, * fs_fp; - char * board_id; - unsigned long region; - - /* Default values */ - board_id = "U12H072T00_NETGEAR"; - region = 1; /* 1=WW, 2=NA */ - output_file = NULL; - kern_file = NULL; - fs_file = NULL; - fs_fp = NULL; - - while ((opt = getopt (argc, argv, ":b:r:k:f:o:h")) != -1) { - switch (opt) { - case 'b': - /* Board Identity */ - if (strlen (optarg) > MAX_BOARD_ID_LEN) { - fatal_error (0, "Board lenght exceeds %d", - MAX_BOARD_ID_LEN); - } - board_id = optarg; - break; - - case 'r': - /* Region */ - errno = 0; - region = strtoul (optarg, &ptr, 0); - if (errno || ptr==optarg || *ptr!='\0') { - fatal_error (0, "Cannot parse region %s", optarg); - } - if (region > 0xff) { - fatal_error (0, "Region cannot exceed 0xff"); - } - break; - - case 'k': - /* Kernel */ - kern_file = optarg; - break; - - case 'f': - /* Filing System */ - fs_file = optarg; - break; - - case 'o': - /* Output file */ - output_file = optarg; - break; - - case 'h': - print_help (); - return EXIT_SUCCESS; - - case ':': - print_help (); - fatal_error (0, "Option -%c missing argument", optopt); - break; - - case '?': - print_help (); - fatal_error (0, "Unknown argument -%c", optopt); - break; - - default: - break; - } - } - - /* Check we have all the options expected */ - if (!kern_file) { - print_help (); - fatal_error (0, "Kernel file expected"); - } - if (!output_file) { - print_help (); - fatal_error (0, "Output file required"); - } - message ("Netgear CHK writer - v0.1"); - - /* Open the input file */ - kern_fp = fopen (kern_file, "r"); - if (!kern_fp) { - fatal_error (errno, "Cannot open %s", kern_file); - } - - /* Open the fs file, if specified */ - if (fs_file) { - fs_fp = fopen (fs_file, "r"); - if (!fs_fp) { - fclose(kern_fp); - fatal_error (errno, "Cannot open %s", fs_file); - } - } - - /* Open the output file */ - out_fp = fopen (output_file, "w+"); - if (!out_fp) { - fclose(kern_fp); - if (fs_fp) { - fclose(fs_fp); - } - fatal_error (errno, "Cannot open %s", output_file); - } - - /* Write zeros when the chk header will be */ - buf[0] = '\0'; - header_len = sizeof (struct chk_header) + strlen (board_id); - if (fwrite (buf, 1, header_len, out_fp) != header_len) { - fatal_error (errno, "Cannot write header"); - } - - /* Allocate storage for header, we fill in as we go */ - hdr = malloc (sizeof (struct chk_header)); - if (!hdr) { - fatal_error (0, "malloc failed"); - } - bzero (hdr, sizeof (struct chk_header)); - - /* Fill in known values */ - hdr->magic = htonl (0x2a23245e); - hdr->header_len = htonl(header_len); - hdr->reserved[0] = (unsigned char)(region & 0xff); - memset(&hdr->reserved[1], 99, sizeof(hdr->reserved) - 1); - - message (" Board Id: %s", board_id); - message (" Region: %s", region == 1 ? "World Wide (WW)" - : (region == 2 ? "North America (NA)" : "Unknown")); - - /* Copy the trx file, calculating the checksum as we go */ - netgear_checksum_init (&chk_part); - netgear_checksum_init (&chk_whole); - while (!feof (kern_fp)) { - len = fread (buf, 1, BUF_LEN, kern_fp); - if (len < 1) { - break; - } - if (fwrite (buf, len, 1, out_fp) != 1) { - fatal_error (errno, "Write error"); - } - hdr->kernel_len += len; - netgear_checksum_add (&chk_part, (unsigned char *)buf, len); - netgear_checksum_add (&chk_whole, (unsigned char *)buf, len); - } - fclose(kern_fp); - hdr->kernel_chksum = netgear_checksum_fini (&chk_part); - message (" Kernel Len: %u", hdr->kernel_len); - message ("Kernel Checksum: 0x%08x", hdr->kernel_chksum); - hdr->kernel_len = htonl (hdr->kernel_len); - hdr->kernel_chksum = htonl (hdr->kernel_chksum); - - /* Now copy the root fs, calculating the checksum as we go */ - if (fs_fp) { - netgear_checksum_init (&chk_part); - while (!feof (fs_fp)) { - len = fread (buf, 1, BUF_LEN, fs_fp); - if (len < 1) { - break; - } - if (fwrite (buf, len, 1, out_fp) != 1) { - fatal_error (errno, "Write error"); - } - hdr->rootfs_len += len; - netgear_checksum_add (&chk_part, (unsigned char *)buf, len); - netgear_checksum_add (&chk_whole, (unsigned char *)buf, len); - } - fclose(fs_fp); - hdr->rootfs_chksum = (netgear_checksum_fini (&chk_part)); - message (" Rootfs Len: %u", hdr->rootfs_len); - message ("Rootfs Checksum: 0x%08x", hdr->rootfs_chksum); - hdr->rootfs_len = htonl (hdr->rootfs_len); - hdr->rootfs_chksum = htonl (hdr->rootfs_chksum); - } - - /* Calcautate the image checksum */ - hdr->image_chksum = netgear_checksum_fini (&chk_whole); - message (" Image Checksum: 0x%08x", hdr->image_chksum); - hdr->image_chksum = htonl (hdr->image_chksum); - - /* Calculate the header checksum */ - netgear_checksum_init (&chk_part); - netgear_checksum_add (&chk_part, (unsigned char *)hdr, - sizeof (struct chk_header)); - netgear_checksum_add (&chk_part, (unsigned char *)board_id, - strlen (board_id)); - hdr->header_chksum = htonl (netgear_checksum_fini (&chk_part)); - - /* Finally rewind the output and write headers */ - rewind (out_fp); - if (fwrite (hdr, sizeof (struct chk_header), 1, out_fp) != 1) { - fatal_error (errno, "Cannot write header"); - } - if (fwrite (board_id, strlen (board_id), 1, out_fp) != 1) { - fatal_error (errno, "Cannot write board id"); - } - - /* Success */ - fclose(out_fp); - return EXIT_SUCCESS; -} - diff --git a/tools/firmware-utils/src/mkcsysimg.c b/tools/firmware-utils/src/mkcsysimg.c deleted file mode 100644 index 2347e63da1..0000000000 --- a/tools/firmware-utils/src/mkcsysimg.c +++ /dev/null @@ -1,1150 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org> - * - * This program was based on the code found in various Linux - * source tarballs released by Edimax for it's devices. - * Original author: David Hsu <davidhsu@realtek.com.tw> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> -#include <endian.h> /* for __BYTE_ORDER */ -#if defined(__CYGWIN__) -# include <byteswap.h> -#endif - -#include "csysimg.h" - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define HOST_TO_LE16(x) (x) -# define HOST_TO_LE32(x) (x) -# define LE16_TO_HOST(x) (x) -# define LE32_TO_HOST(x) (x) -#else -# define HOST_TO_LE16(x) bswap_16(x) -# define HOST_TO_LE32(x) bswap_32(x) -# define LE16_TO_HOST(x) bswap_16(x) -# define LE32_TO_HOST(x) bswap_32(x) -#endif - -#define MAX_NUM_BLOCKS 8 -#define MAX_ARG_COUNT 32 -#define MAX_ARG_LEN 1024 -#define FILE_BUF_LEN (16*1024) -#define CSYS_PADC 0xFF - -#define BLOCK_TYPE_BOOT 0 -#define BLOCK_TYPE_CONF 1 -#define BLOCK_TYPE_WEBP 2 -#define BLOCK_TYPE_CODE 3 -#define BLOCK_TYPE_XTRA 4 - -#define DEFAULT_BLOCK_ALIGN 0x10000U - -#define CSUM_SIZE_NONE 0 -#define CSUM_SIZE_8 1 -#define CSUM_SIZE_16 2 - - -struct csum_state{ - int size; - uint16_t val; - uint16_t tmp; - int odd; -}; - - -struct csys_block { - int type; /* type of the block */ - - int need_file; - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ - - unsigned char sig[SIG_LEN]; - uint32_t addr; - int addr_set; - uint32_t align; - int align_set; - uint8_t padc; - - uint32_t size; - uint32_t size_hdr; - uint32_t size_csum; - uint32_t size_avail; - - struct csum_state *css; -}; - - -struct board_info { - char *model; - char *name; - uint32_t flash_size; - - char sig_boot[SIG_LEN]; - char sig_conf[SIG_LEN]; - char sig_webp[SIG_LEN]; - - uint32_t boot_size; - uint32_t conf_size; - uint32_t webp_size; - uint32_t webp_size_max; - uint32_t code_size; - - uint32_t addr_code; - uint32_t addr_webp; -}; - -#define BOARD(m, n, f, sigb, sigw, bs, cs, ws, ac, aw) {\ - .model = m, .name = n, .flash_size = f<<20, \ - .sig_boot = sigb, .sig_conf = SIG_CONF, .sig_webp = sigw, \ - .boot_size = bs, .conf_size = cs, \ - .webp_size = ws, .webp_size_max = 3*0x10000, \ - .addr_code = ac, .addr_webp = aw \ - } - -#define BOARD_ADM(m,n,f, sigw) BOARD(m,n,f, ADM_BOOT_SIG, sigw, \ - ADM_BOOT_SIZE, ADM_CONF_SIZE, ADM_WEBP_SIZE, \ - ADM_CODE_ADDR, ADM_WEBP_ADDR) - - -/* - * Globals - */ -char *progname; -char *ofname = NULL; -int verblevel = 0; -int invalid_causes_error = 1; -int keep_invalid_images = 0; - -struct board_info *board = NULL; - -struct csys_block *boot_block = NULL; -struct csys_block *conf_block = NULL; -struct csys_block *webp_block = NULL; -struct csys_block *code_block = NULL; - -struct csys_block blocks[MAX_NUM_BLOCKS]; -int num_blocks = 0; - -static struct board_info boards[] = { - /* The original Edimax products */ - BOARD_ADM("BR-6104K", "Edimax BR-6104K", 2, SIG_BR6104K), - BOARD_ADM("BR-6104KP", "Edimax BR-6104KP", 2, SIG_BR6104KP), - BOARD_ADM("BR-6104Wg", "Edimax BR-6104Wg", 2, SIG_BR6104Wg), - BOARD_ADM("BR-6114WG", "Edimax BR-6114WG", 2, SIG_BR6114WG), - BOARD_ADM("BR-6524K", "Edimax BR-6524K", 2, SIG_BR6524K), - BOARD_ADM("BR-6524KP", "Edimax BR-6524KP", 2, SIG_BR6524KP), - BOARD_ADM("BR-6524N", "Edimax BR-6524N", 2, SIG_BR6524N), - BOARD_ADM("BR-6524WG", "Edimax BR-6524WG", 4, SIG_BR6524WG), - BOARD_ADM("BR-6524WP", "Edimax BR-6524WP", 4, SIG_BR6524WP), - BOARD_ADM("BR-6541K", "Edimax BR-6541K", 2, SIG_BR6541K), - BOARD_ADM("BR-6541KP", "Edimax BR-6541K", 2, SIG_BR6541KP), - BOARD_ADM("BR-6541WP", "Edimax BR-6541WP", 4, SIG_BR6541WP), - BOARD_ADM("EW-7207APg", "Edimax EW-7207APg", 2, SIG_EW7207APg), - BOARD_ADM("PS-1205UWg", "Edimax PS-1205UWg", 2, SIG_PS1205UWg), - BOARD_ADM("PS-3205U", "Edimax PS-3205U", 2, SIG_PS3205U), - BOARD_ADM("PS-3205UWg", "Edimax PS-3205UWg", 2, SIG_PS3205UWg), - - /* Hawking products */ - BOARD_ADM("H2BR4", "Hawking H2BR4", 2, SIG_H2BR4), - BOARD_ADM("H2WR54G", "Hawking H2WR54G", 4, SIG_H2WR54G), - - /* Planet products */ - BOARD_ADM("XRT-401D", "Planet XRT-401D", 2, SIG_XRT401D), - BOARD_ADM("XRT-402D", "Planet XRT-402D", 2, SIG_XRT402D), - - /* Conceptronic products */ - BOARD_ADM("C54BSR4", "Conceptronic C54BSR4", 2, SIG_C54BSR4), - - /* OSBRiDGE products */ - BOARD_ADM("5GXi", "OSBDRiDGE 5GXi", 2, SIG_5GXI), - - {.model = NULL} -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", progname, ## __VA_ARGS__ \ - , strerror(save)); \ -} while (0) - -#define WARN(fmt, ...) do { \ - fprintf(stderr, "[%s] *** warning: " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -#define DBG(lev, fmt, ...) do { \ - if (verblevel < lev) \ - break;\ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERR_FATAL -1 -#define ERR_INVALID_IMAGE -2 - -void -usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - struct board_info *board; - - fprintf(stream, "Usage: %s [OPTIONS...] <file>\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>.\n" -" valid <board> values:\n" - ); - for (board = boards; board->model != NULL; board++){ - fprintf(stream, -" %-12s: %s\n", - board->model, board->name); - }; - fprintf(stream, -" -d don't throw error on invalid images\n" -" -k keep invalid images\n" -" -b <file>[:<align>[:<padc>]]\n" -" add boot code to the image\n" -" -c <file>[:<align>[:<padc>]]\n" -" add configuration settings to the image\n" -" -r <file>:[<addr>][:<align>[:<padc>]]\n" -" add runtime code to the image\n" -" -w [<file>:[<addr>][:<align>[:<padc>]]]\n" -" add webpages to the image\n" -" -x <file>[:<align>[:<padc>]]\n" -" add extra data at the end of the image\n" -" -h show this screen\n" -"Parameters:\n" -" <file> write output to the file <file>\n" - ); - - exit(status); -} - -static inline uint32_t align(uint32_t base, uint32_t alignment) -{ - uint32_t ret; - - if (alignment) { - ret = (base + alignment - 1); - ret &= ~(alignment-1); - } else { - ret = base; - } - - return ret; -} - -/* - * argument parsing - */ -int -str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - - -int -str2u16(char *arg, uint16_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x10000)) { - return -1; - } - - *val = t & 0xFFFF; - return 0; -} - -int -str2u8(char *arg, uint8_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) { - return -1; - } - - *val = t & 0xFF; - return 0; -} - -int -str2sig(char *arg, uint32_t *sig) -{ - if (strlen(arg) != 4) - return -1; - - *sig = arg[0] | (arg[1] << 8) | (arg[2] << 16) | (arg[3] << 24); - - return 0; -} - - -int -parse_arg(char *arg, char *buf, char *argv[]) -{ - int res = 0; - size_t argl; - char *tok; - char **ap = &buf; - int i; - - memset(argv, 0, MAX_ARG_COUNT * sizeof(void *)); - - if ((arg == NULL)) { - /* no arguments */ - return 0; - } - - argl = strlen(arg); - if (argl == 0) { - /* no arguments */ - return 0; - } - - if (argl >= MAX_ARG_LEN) { - /* argument is too long */ - argl = MAX_ARG_LEN-1; - } - - memcpy(buf, arg, argl); - buf[argl] = '\0'; - - for (i = 0; i < MAX_ARG_COUNT; i++) { - tok = strsep(ap, ":"); - if (tok == NULL) { - break; - } -#if 0 - else if (tok[0] == '\0') { - break; - } -#endif - argv[i] = tok; - res++; - } - - return res; -} - - -int -required_arg(char c, char *arg) -{ - if (arg == NULL || *arg != '-') - return 0; - - ERR("option -%c requires an argument\n", c); - return ERR_FATAL; -} - - -int -is_empty_arg(char *arg) -{ - int ret = 1; - if (arg != NULL) { - if (*arg) ret = 0; - }; - return ret; -} - - -void -csum8_update(uint8_t *p, uint32_t len, struct csum_state *css) -{ - for ( ; len > 0; len --) { - css->val += *p++; - } -} - - -uint16_t -csum8_get(struct csum_state *css) -{ - uint8_t t; - - t = css->val; - return ~t + 1; -} - - -void -csum16_update(void *data, uint32_t len, struct csum_state *css) -{ - uint8_t *p = data; - uint16_t t; - - if (css->odd) { - t = css->tmp + (p[0]<<8); - css->val += LE16_TO_HOST(t); - css->odd = 0; - len--; - p++; - } - - for ( ; len > 1; len -= 2, p +=2 ) { - t = p[0] + (p[1] << 8); - css->val += LE16_TO_HOST(t); - } - - if (len == 1) { - css->tmp = p[0]; - css->odd = 1; - } -} - - -uint16_t -csum16_get(struct csum_state *css) -{ - char pad = 0; - - csum16_update(&pad, 1, css); - return ~css->val + 1; -} - - -void -csum_init(struct csum_state *css, int size) -{ - css->val = 0; - css->tmp = 0; - css->odd = 0; - css->size = size; -} - - -void -csum_update(void *data, uint32_t len, struct csum_state *css) -{ - uint8_t *p = data; - - switch (css->size) { - case CSUM_SIZE_8: - csum8_update(p,len,css); - break; - case CSUM_SIZE_16: - csum16_update(p,len,css); - break; - } -} - - -uint16_t -csum_get(struct csum_state *css) -{ - uint16_t ret; - - switch (css->size) { - case CSUM_SIZE_8: - ret = csum8_get(css); - break; - case CSUM_SIZE_16: - ret = csum16_get(css); - break; - default: - ERR("invalid checksum size\n"); - return 0; - } - - return ret; -} - - -/* - * routines to write data to the output file - */ -int -write_out_data(FILE *outfile, void *data, size_t len, - struct csum_state *css) -{ - uint8_t *ptr = data; - - errno = 0; - - fwrite(ptr, len, 1, outfile); - if (errno) { - ERRS("unable to write output file"); - return ERR_FATAL; - } - - if (css) { - csum_update(ptr, len, css); - } - - return 0; -} - - -int -write_out_padding(FILE *outfile, size_t len, uint8_t padc, - struct csum_state *css) -{ - uint8_t buf[512]; - size_t buflen = sizeof(buf); - int err; - - memset(buf, padc, buflen); - while (len > 0) { - if (len < buflen) - buflen = len; - - err = write_out_data(outfile, buf, buflen, css); - if (err) - return err; - - len -= buflen; - } - - return 0; -} - - -int -block_stat_file(struct csys_block *block) -{ - struct stat st; - int err; - - if (block->file_name == NULL) - return 0; - - err = stat(block->file_name, &st); - if (err){ - ERRS("stat failed on %s", block->file_name); - return ERR_FATAL; - } - - block->file_size = st.st_size; - return 0; -} - - -int -block_writeout_hdr(FILE *outfile, struct csys_block *block) -{ - struct csys_header hdr; - int res; - - if (block->size_hdr == 0) - return 0; - - /* setup header fields */ - memcpy(hdr.sig, block->sig, 4); - hdr.addr = HOST_TO_LE32(block->addr); - hdr.size = HOST_TO_LE32(block->size - block->size_hdr - block->size_csum); - - DBG(1,"writing header for block"); - res = write_out_data(outfile, (uint8_t *)&hdr, sizeof(hdr),NULL); - return res; - -} - - -int -block_writeout_file(FILE *outfile, struct csys_block *block) -{ - char buf[FILE_BUF_LEN]; - size_t buflen = sizeof(buf); - FILE *f; - size_t len; - int res; - - if (block->file_name == NULL) - return 0; - - if (block->file_size == 0) - return 0; - - errno = 0; - f = fopen(block->file_name,"r"); - if (errno) { - ERRS("unable to open file: %s", block->file_name); - return ERR_FATAL; - } - - len = block->file_size; - while (len > 0) { - if (len < buflen) - buflen = len; - - /* read data from source file */ - errno = 0; - fread(buf, buflen, 1, f); - if (errno != 0) { - ERRS("unable to read from file: %s", block->file_name); - res = ERR_FATAL; - break; - } - - res = write_out_data(outfile, buf, buflen, block->css); - if (res) - break; - - len -= buflen; - } - - fclose(f); - return res; -} - - -int -block_writeout_data(FILE *outfile, struct csys_block *block) -{ - int res; - size_t padlen; - - res = block_writeout_file(outfile, block); - if (res) - return res; - - /* write padding data if neccesary */ - padlen = block->size_avail - block->file_size; - DBG(1,"padding block, length=%zu", padlen); - res = write_out_padding(outfile, padlen, block->padc, block->css); - - return res; -} - - -int -block_writeout_csum(FILE *outfile, struct csys_block *block) -{ - uint16_t csum; - int res; - - if (block->size_csum == 0) - return 0; - - DBG(1,"writing checksum for block"); - csum = HOST_TO_LE16(csum_get(block->css)); - res = write_out_data(outfile, (uint8_t *)&csum, block->size_csum, NULL); - - return res; -} - - -int -block_writeout(FILE *outfile, struct csys_block *block) -{ - int res; - struct csum_state css; - - res = 0; - - if (block == NULL) - return res; - - block->css = NULL; - - DBG(2, "writing block, file=%s, file_size=%d, space=%d", - block->file_name, block->file_size, block->size_avail); - res = block_writeout_hdr(outfile, block); - if (res) - return res; - - if (block->size_csum != 0) { - block->css = &css; - csum_init(&css, block->size_csum); - } - - res = block_writeout_data(outfile, block); - if (res) - return res; - - res = block_writeout_csum(outfile, block); - if (res) - return res; - - return res; -} - - -int -write_out_blocks(FILE *outfile) -{ - struct csys_block *block; - int i, res; - - res = block_writeout(outfile, boot_block); - if (res) - return res; - - res = block_writeout(outfile, conf_block); - if (res) - return res; - - res = block_writeout(outfile, webp_block); - if (res) - return res; - - res = block_writeout(outfile, code_block); - if (res) - return res; - - res = 0; - for (i=0; i < num_blocks; i++) { - block = &blocks[i]; - - if (block->type != BLOCK_TYPE_XTRA) - continue; - - res = block_writeout(outfile, block); - if (res) - break; - } - - return res; -} - - -struct board_info * -find_board(char *model) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->model != NULL; board++){ - if (strcasecmp(model, board->model) == 0) { - ret = board; - break; - } - }; - - return ret; -} - - -int -parse_opt_board(char ch, char *arg) -{ - - DBG(1,"parsing board option: -%c %s", ch, arg); - - if (board != NULL) { - ERR("only one board option allowed"); - return ERR_FATAL; - } - - if (required_arg(ch, arg)) - return ERR_FATAL; - - board = find_board(arg); - if (board == NULL){ - ERR("invalid/unknown board specified: %s", arg); - return ERR_FATAL; - } - - return 0; -} - - -int -parse_opt_block(char ch, char *arg) -{ - char buf[MAX_ARG_LEN]; - char *argv[MAX_ARG_COUNT]; - char *p; - struct csys_block *block; - int i; - - if ( num_blocks > MAX_NUM_BLOCKS ) { - ERR("too many blocks specified"); - return ERR_FATAL; - } - - block = &blocks[num_blocks]; - - /* setup default field values */ - block->need_file = 1; - block->padc = 0xFF; - - switch (ch) { - case 'b': - if (boot_block) { - WARN("only one boot block allowed"); - break; - } - block->type = BLOCK_TYPE_BOOT; - boot_block = block; - break; - case 'c': - if (conf_block) { - WARN("only one config block allowed"); - break; - } - block->type = BLOCK_TYPE_CONF; - conf_block = block; - break; - case 'w': - if (webp_block) { - WARN("only one web block allowed"); - break; - } - block->type = BLOCK_TYPE_WEBP; - block->size_hdr = sizeof(struct csys_header); - block->size_csum = CSUM_SIZE_8; - block->need_file = 0; - webp_block = block; - break; - case 'r': - if (code_block) { - WARN("only one runtime block allowed"); - break; - } - block->type = BLOCK_TYPE_CODE; - block->size_hdr = sizeof(struct csys_header); - block->size_csum = CSUM_SIZE_16; - code_block = block; - break; - case 'x': - block->type = BLOCK_TYPE_XTRA; - break; - default: - ERR("unknown block type \"%c\"", ch); - return ERR_FATAL; - } - - parse_arg(arg, buf, argv); - - i = 0; - p = argv[i++]; - if (!is_empty_arg(p)) { - block->file_name = strdup(p); - if (block->file_name == NULL) { - ERR("not enough memory"); - return ERR_FATAL; - } - } else if (block->need_file){ - ERR("no file specified in %s", arg); - return ERR_FATAL; - } - - if (block->size_hdr) { - p = argv[i++]; - if (!is_empty_arg(p)) { - if (str2u32(p, &block->addr) != 0) { - ERR("invalid start address in %s", arg); - return ERR_FATAL; - } - block->addr_set = 1; - } - } - - p = argv[i++]; - if (!is_empty_arg(p)) { - if (str2u32(p, &block->align) != 0) { - ERR("invalid alignment value in %s", arg); - return ERR_FATAL; - } - block->align_set = 1; - } - - p = argv[i++]; - if (!is_empty_arg(p) && (str2u8(p, &block->padc) != 0)) { - ERR("invalid paddig character in %s", arg); - return ERR_FATAL; - } - - num_blocks++; - - return 0; -} - - -int -process_blocks(void) -{ - struct csys_block *block; - uint32_t offs = 0; - int i; - int res; - - res = 0; - /* collecting stats */ - for (i = 0; i < num_blocks; i++) { - block = &blocks[i]; - res = block_stat_file(block); - if (res) - return res; - } - - /* bootloader */ - block = boot_block; - if (block) { - block->size = board->boot_size; - if (block->file_size > board->boot_size) { - WARN("boot block is too big"); - res = ERR_INVALID_IMAGE; - } - } - offs += board->boot_size; - - /* configuration data */ - block = conf_block; - if (block) { - block->size = board->conf_size; - if (block->file_size > board->conf_size) { - WARN("config block is too big"); - res = ERR_INVALID_IMAGE; - } - } - offs += board->conf_size; - - /* webpages */ - block = webp_block; - if (block) { - - memcpy(block->sig, board->sig_webp, 4); - - if (block->addr_set == 0) - block->addr = board->addr_webp; - - if (block->align_set == 0) - block->align = DEFAULT_BLOCK_ALIGN; - - block->size = align(offs + block->file_size + block->size_hdr + - block->size_csum, block->align) - offs; - - if (block->size > board->webp_size_max) { - WARN("webpages block is too big"); - res = ERR_INVALID_IMAGE; - } - - DBG(2,"webpages start at %08x, size=%08x", offs, - block->size); - - offs += block->size; - if (offs > board->flash_size) { - WARN("webp block is too big"); - res = ERR_INVALID_IMAGE; - } - } - - /* runtime code */ - block = code_block; - if (block) { - memcpy(code_block->sig, SIG_CSYS, 4); - - if (block->addr_set == 0) - block->addr = board->addr_code; - - if (block->align_set == 0) - block->align = DEFAULT_BLOCK_ALIGN; - - block->size = align(offs + block->file_size + - block->size_hdr + block->size_csum, - block->align) - offs; - - DBG(2,"code block start at %08x, size=%08x", offs, - block->size); - - offs += block->size; - if (offs > board->flash_size) { - WARN("code block is too big"); - res = ERR_INVALID_IMAGE; - } - } - - for (i = 0; i < num_blocks; i++) { - block = &blocks[i]; - - if (block->type != BLOCK_TYPE_XTRA) - continue; - - if (block->align_set == 0) - block->align = DEFAULT_BLOCK_ALIGN; - - block->size = align(offs + block->file_size, - block->align) - offs; - - DBG(2,"file %s start at %08x, size=%08x, align=%08x", - block->file_name, offs, block->size, block->align); - - offs += block->size; - if (offs > board->flash_size) { - WARN("file %s is too big, size=%d, avail=%d", - block->file_name, block->file_size, - board->flash_size - offs); - res = ERR_INVALID_IMAGE; - } - } - - for (i = 0; i < num_blocks; i++) { - block = &blocks[i]; - - block->size_avail = block->size - block->size_hdr - - block->size_csum; - - if (block->size_avail < block->file_size) { - WARN("file %s is too big, size=%d, avail=%d", - block->file_name, block->file_size, - block->size_avail); - res = ERR_INVALID_IMAGE; - } - } - - return res; -} - - -int -main(int argc, char *argv[]) -{ - int optinvalid = 0; /* flag for invalid option */ - int c; - int res = ERR_FATAL; - - FILE *outfile; - - progname=basename(argv[0]); - - opterr = 0; /* could not print standard getopt error messages */ - while ( 1 ) { - optinvalid = 0; - - c = getopt(argc, argv, "b:B:c:dhkr:vw:x:"); - if (c == -1) - break; - - switch (c) { - case 'b': - case 'c': - case 'r': - case 'x': - optinvalid = parse_opt_block(c,optarg); - break; - case 'w': - if (optarg != NULL && *optarg == '-') { - /* rollback */ - optind--; - optarg = NULL; - } - optinvalid = parse_opt_block(c,optarg); - break; - case 'd': - invalid_causes_error = 0; - break; - case 'k': - keep_invalid_images = 1; - break; - case 'B': - optinvalid = parse_opt_board(c,optarg); - break; - case 'v': - verblevel++; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - optinvalid = 1; - break; - } - if (optinvalid != 0 ){ - ERR("invalid option: -%c", optopt); - goto out; - } - } - - if (board == NULL) { - ERR("no board specified"); - goto out; - } - - if (optind == argc) { - ERR("no output file specified"); - goto out; - } - - ofname = argv[optind++]; - - if (optind < argc) { - ERR("invalid option: %s", argv[optind]); - goto out; - } - - res = process_blocks(); - if (res == ERR_FATAL) - goto out; - - if (res == ERR_INVALID_IMAGE) { - if (invalid_causes_error) - res = ERR_FATAL; - - if (keep_invalid_images == 0) { - WARN("generation of invalid images \"%s\" disabled", ofname); - goto out; - } - - WARN("generating invalid image: \"%s\"", ofname); - } - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - res = ERR_FATAL; - goto out; - } - - if (write_out_blocks(outfile) != 0) { - res = ERR_FATAL; - goto out_flush; - } - - DBG(1,"Image file %s completed.", ofname); - -out_flush: - fflush(outfile); - fclose(outfile); - if (res == ERR_FATAL) { - unlink(ofname); - } -out: - if (res == ERR_FATAL) - return EXIT_FAILURE; - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/mkdapimg.c b/tools/firmware-utils/src/mkdapimg.c deleted file mode 100644 index e8b12599d8..0000000000 --- a/tools/firmware-utils/src/mkdapimg.c +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#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: mkdapimg [-p] [-m <model>] -s <sig> -i <input> -o <output> -// -// e.g.: mkdapimg -s RT3052-AP-DAP1350-3 -i sysupgrade.bin -o factory.bin -// -// If the model string <model> is not given, we will assume that -// the leading characters upto the first "-" is the model. -// -// The "-p" (patch) option is used to patch the exisiting image with the -// specified model and signature. -// The "-x" (fix) option will recalculate the payload size and checksum -// during the patch mode operation. - -// The img_hdr_struct was taken from the D-Link SDK: -// DAP-1350_A1_FW1.11NA_GPL/GPL_Source_Code/Uboot/DAP-1350/httpd/header.h - -#define MAX_MODEL_NAME_LEN 20 -#define MAX_SIG_LEN 30 -#define MAX_REGION_LEN 4 -#define MAX_VERSION_LEN 12 - -struct img_hdr_struct { - uint32_t checksum; - char model[MAX_MODEL_NAME_LEN]; - char sig[MAX_SIG_LEN]; - uint8_t partition; - uint8_t hdr_len; - uint8_t rsv1; - uint8_t rsv2; - uint32_t flash_byte_cnt; -} 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 [-p] [-m model] [-r region] [-v version] -s signature -i input -o output\n", progname); - exit(1); -} - -int -main(int ac, char *av[]) -{ - char model[MAX_MODEL_NAME_LEN+1]; - char signature[MAX_SIG_LEN+1]; - char region[MAX_REGION_LEN+1]; - char version[MAX_VERSION_LEN+1]; - int patchmode = 0; - int fixmode = 0; - int have_regionversion = 0; - - FILE *ifile = NULL; - FILE *ofile = NULL; - int c; - uint32_t cksum; - uint32_t bcnt; - - progname = basename(av[0]); - memset(model, 0, sizeof(model)); - memset(signature, 0, sizeof(signature)); - memset(region, 0, sizeof(region)); - memset(version, 0, sizeof(version)); - - while ( 1 ) { - int c; - - c = getopt(ac, av, "pxm:r:v:s:i:o:"); - if (c == -1) - break; - - switch (c) { - case 'p': - patchmode = 1; - break; - case 'x': - fixmode = 1; - break; - case 'm': - if (strlen(optarg) > MAX_MODEL_NAME_LEN) { - fprintf(stderr, "%s: model name exceeds %d chars\n", - progname, MAX_MODEL_NAME_LEN); - exit(1); - } - strcpy(model, optarg); - break; - case 'r': - if (strlen(optarg) > MAX_REGION_LEN) { - fprintf(stderr, "%s: region exceeds %d chars\n", - progname, MAX_REGION_LEN); - exit(1); - } - have_regionversion = 1; - strcpy(region, optarg); - break; - case 'v': - if (strlen(optarg) > MAX_VERSION_LEN) { - fprintf(stderr, "%s: version exceeds %d chars\n", - progname, MAX_VERSION_LEN); - exit(1); - } - have_regionversion = 1; - strcpy(version, optarg); - break; - case 's': - if (strlen(optarg) > MAX_SIG_LEN) { - fprintf(stderr, "%s: signature exceeds %d chars\n", - progname, MAX_SIG_LEN); - exit(1); - } - strcpy(signature, optarg); - 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(); - } - - if (model[0] == 0) { - char *p = strchr(signature, '-'); - if (p == NULL) { - fprintf(stderr, "%s: model name unknown\n", progname); - exit(1); - } - if (p - signature > MAX_MODEL_NAME_LEN) { - *p = 0; - fprintf(stderr, "%s: auto model name failed, string %s too long\n", progname, signature); - exit(1); - } - strncpy(model, signature, p - signature); - } - - if (patchmode) { - if (fread(&imghdr, sizeof(imghdr), 1, ifile) < 0) - perrexit(2, "fread on input"); - } - - for (bcnt = 0, cksum = 0 ; (c = fgetc(ifile)) != EOF ; bcnt++) - cksum += c & 0xff; - - if (fseek(ifile, patchmode ? sizeof(imghdr) : 0, SEEK_SET) < 0) - perrexit(2, "fseek on input"); - - if (patchmode == 0) { - // Fill in the header - memset(&imghdr, 0, sizeof(imghdr)); - imghdr.checksum = htonl(cksum); - imghdr.partition = 0 ; // don't care? - imghdr.hdr_len = sizeof(imghdr); - if (have_regionversion) { - imghdr.hdr_len += MAX_REGION_LEN; - imghdr.hdr_len += MAX_VERSION_LEN; - } - imghdr.flash_byte_cnt = htonl(bcnt); - } else { - if (ntohl(imghdr.checksum) != cksum) { - fprintf(stderr, "%s: patch mode, checksum mismatch\n", - progname); - if (fixmode) { - fprintf(stderr, "%s: fixing\n", progname); - imghdr.checksum = htonl(cksum); - } else - exit(3); - } else if (ntohl(imghdr.flash_byte_cnt) != bcnt) { - fprintf(stderr, "%s: patch mode, size mismatch\n", - progname); - if (fixmode) { - fprintf(stderr, "%s: fixing\n", progname); - imghdr.flash_byte_cnt = htonl(bcnt); - } else - exit(3); - } - } - - strncpy(imghdr.model, model, MAX_MODEL_NAME_LEN); - strncpy(imghdr.sig, signature, MAX_SIG_LEN); - - if (fwrite(&imghdr, sizeof(imghdr), 1, ofile) < 0) - perrexit(2, "fwrite header on output"); - if (have_regionversion) { - if (fwrite(®ion, MAX_REGION_LEN, 1, ofile) < 0) - perrexit(2, "fwrite header on output"); - if (fwrite(&version, MAX_VERSION_LEN, 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); -} diff --git a/tools/firmware-utils/src/mkdapimg2.c b/tools/firmware-utils/src/mkdapimg2.c deleted file mode 100644 index 21d90125d1..0000000000 --- a/tools/firmware-utils/src/mkdapimg2.c +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * (C) Nicolò Veronese <nicveronese@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 sysupgrade.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 = NULL; - FILE *ofile = NULL; - 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; -} diff --git a/tools/firmware-utils/src/mkdhpimg.c b/tools/firmware-utils/src/mkdhpimg.c deleted file mode 100644 index 9b77b44e05..0000000000 --- a/tools/firmware-utils/src/mkdhpimg.c +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016 FUKAUMI Naoki <naobsd@gmail.com> - */ - -#include <sys/stat.h> -#include <err.h> -#include <fcntl.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "buffalo-lib.h" - -#define DHP_HEADER_SIZE 20 - -static char *progname; - -static void -usage(void) -{ - - fprintf(stderr, "usage: %s <in> <out>\n", progname); - exit(EXIT_FAILURE); -} - -int -main(int argc, char *argv[]) -{ - struct stat in_st; - size_t size; - uint32_t crc; - int in, out; - uint8_t *buf; - - progname = argv[0]; - - if (argc != 3) - usage(); - - if ((in = open(argv[1], O_RDONLY)) == -1) - err(EXIT_FAILURE, "%s", argv[1]); - - if (fstat(in, &in_st) == -1) - err(EXIT_FAILURE, "%s", argv[1]); - - size = DHP_HEADER_SIZE + in_st.st_size; - - if ((buf = malloc(size)) == NULL) - err(EXIT_FAILURE, "malloc"); - - memset(buf, 0, DHP_HEADER_SIZE); - buf[0x0] = 0x62; - buf[0x1] = 0x67; - buf[0x2] = 0x6e; - buf[0xb] = 0xb1; - buf[0xc] = (size >> 24) & 0xff; - buf[0xd] = (size >> 16) & 0xff; - buf[0xe] = (size >> 8) & 0xff; - buf[0xf] = size & 0xff; - - read(in, &buf[DHP_HEADER_SIZE], in_st.st_size); - close(in); - - crc = buffalo_crc(buf, size); - buf[0x10] = (crc >> 24) & 0xff; - buf[0x11] = (crc >> 16) & 0xff; - buf[0x12] = (crc >> 8) & 0xff; - buf[0x13] = crc & 0xff; - - if ((out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) - err(EXIT_FAILURE, "%s", argv[2]); - write(out, buf, size); - close(out); - - free(buf); - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/mkdlinkfw-lib.c b/tools/firmware-utils/src/mkdlinkfw-lib.c deleted file mode 100644 index dbe178c6dd..0000000000 --- a/tools/firmware-utils/src/mkdlinkfw-lib.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * mkdlinkfw - * - * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com> - * - * This tool is based on mktplinkfw. - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <stdbool.h> -#include <endian.h> -#include <errno.h> -#include <time.h> -#include <sys/stat.h> -#include <zlib.h> /*for crc32 */ - -#include "mkdlinkfw-lib.h" - -extern char *progname; - -uint32_t jboot_timestamp(void) -{ - char *env = getenv("SOURCE_DATE_EPOCH"); - char *endptr = env; - time_t fixed_timestamp = -1; - errno = 0; - - if (env && *env) { - fixed_timestamp = strtoull(env, &endptr, 10); - - if (errno || (endptr && *endptr != '\0')) { - fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); - fixed_timestamp = -1; - } - } - - if (fixed_timestamp == -1) - time(&fixed_timestamp); - - return (((uint32_t) fixed_timestamp) - TIMESTAMP_MAGIC) >> 2; -} - -uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size) -{ - uint32_t counter = start_val; - uint16_t *ptr = data; - - while (size > 1) { - counter += *ptr; - ++ptr; - while (counter >> 16) - counter = (uint16_t) counter + (counter >> 16); - size -= 2; - } - if (size > 0) { - counter += *(uint8_t *) ptr; - counter -= 0xFF; - } - while (counter >> 16) - counter = (uint16_t) counter + (counter >> 16); - return counter; -} - -int get_file_stat(struct file_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) - return 0; - - res = stat(fdata->file_name, &st); - if (res) { - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - return 0; -} - -int read_to_buf(const struct file_info *fdata, char *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - size_t read; - - f = fopen(fdata->file_name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - read = fread(buf, fdata->file_size, 1, f); - if (ferror(f) || read != 1) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - - out_close: - fclose(f); - out: - return ret; -} - -int write_fw(const char *ofname, const char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - - out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) - unlink(ofname); - out: - return ret; -} diff --git a/tools/firmware-utils/src/mkdlinkfw-lib.h b/tools/firmware-utils/src/mkdlinkfw-lib.h deleted file mode 100644 index a459599665..0000000000 --- a/tools/firmware-utils/src/mkdlinkfw-lib.h +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * mkdlinkfw - * - * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com> - * - * This tool is based on mktplinkfw. - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#ifndef mkdlinkfw_lib_h -#define mkdlinkfw_lib_h - -#define AUH_MAGIC "DLK" -#define AUH_SIZE 80 -#define AUH_LVPS 0x01 -#define AUH_HDR_ID 0x4842 -#define AUH_HDR_VER 0x02 -#define AUH_SEC_ID 0x04 -#define AUH_INFO_TYPE 0x04 - -#define STAG_SIZE 16 -#define STAG_ID 0x04 -#define STAG_MAGIC 0x2B24 -#define STAG_CMARK_FACTORY 0xFF - -#define SCH2_SIZE 40 -#define SCH2_MAGIC 0x2124 -#define SCH2_VER 0x02 - -/* - * compression type values in the header - * so far onlysupport for LZMA is added - */ -#define FLAT 0 -#define JZ 1 -#define GZIP 2 -#define LZMA 3 - -#define RAM_ENTRY_ADDR 0x80000000 -#define RAM_LOAD_ADDR 0x80000000 -#define JBOOT_SIZE 0x10000 - -#define ALL_HEADERS_SIZE (AUH_SIZE + STAG_SIZE + SCH2_SIZE) -#define MAX_HEADER_COUNTER 10 -#define TIMESTAMP_MAGIC 0x35016f00L - -#define FACTORY 0 -#define SYSUPGRADE 1 - -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__); \ -} while (0) - -struct file_info { - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ -}; - -uint32_t jboot_timestamp(void); -uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size); -int get_file_stat(struct file_info *fdata); -int read_to_buf(const struct file_info *fdata, char *buf); -int write_fw(const char *ofname, const char *data, int len); - -#endif /* mkdlinkfw_lib_h */ diff --git a/tools/firmware-utils/src/mkdlinkfw.c b/tools/firmware-utils/src/mkdlinkfw.c deleted file mode 100644 index 6dbaf4ae27..0000000000 --- a/tools/firmware-utils/src/mkdlinkfw.c +++ /dev/null @@ -1,664 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * mkdlinkfw - * - * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com> - * - * This tool is based on mktplinkfw. - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <stdbool.h> -#include <endian.h> -#include <errno.h> -#include <sys/stat.h> -#include <zlib.h> /*for crc32 */ - -#include "mkdlinkfw-lib.h" - -/* ARM update header 2.0 - * used only in factory images to erase and flash selected area - */ -struct auh_header { - uint8_t rom_id[12]; /* 12-bit rom-id unique per router type */ - uint16_t derange; /* used for scramble header */ - uint16_t image_checksum; /* jboot_checksum of flashed data */ - - uint32_t space1; /* zeros */ - uint32_t space2; /* zeros */ - uint16_t space3; /* zerosu */ - uint8_t lpvs; /* must be 0x01 */ - uint8_t mbz; /* bust be 0 */ - uint32_t time_stamp; /* timestamp calculated in jboot way */ - - uint32_t erase_start; /* erase start address */ - uint32_t erase_length; /* erase length address */ - uint32_t data_offset; /* data start address */ - uint32_t data_length; /* data length address */ - - uint32_t space4; /* zeros */ - uint32_t space5; /* zeros */ - uint32_t space6; /* zeros */ - uint32_t space7; /* zeros */ - - uint16_t header_id; /* magic 0x4842 */ - uint16_t header_version; /* 0x02 for 2.0 */ - uint16_t space8; /* zeros */ - uint8_t section_id; /* section id */ - uint8_t image_info_type; /* (?) 0x04 in factory images */ - uint32_t image_info_offset; /* (?) zeros in factory images */ - uint16_t family_member; /* unique per router type */ - uint16_t header_checksum; /* negated jboot_checksum of header data */ -}; - -struct stag_header { /* used only of sch2 wrapped kernel data */ - uint8_t cmark; /* in factory 0xFF ,in sysuograde must be the same as id */ - uint8_t id; /* 0x04 */ - uint16_t magic; /* magic 0x2B24 */ - uint32_t time_stamp; /* timestamp calculated in jboot way */ - uint32_t image_length; /* lentgh of kernel + sch2 header */ - uint16_t image_checksum; /* negated jboot_checksum of sch2 + kernel */ - uint16_t tag_checksum; /* negated jboot_checksum of stag header data */ -}; - -struct sch2_header { /* used only in kernel partitions */ - uint16_t magic; /* magic 0x2124 */ - uint8_t cp_type; /* 0x00 for flat, 0x01 for jz, 0x02 for gzip, 0x03 for lzma */ - uint8_t version; /* 0x02 for sch2 */ - uint32_t ram_addr; /* ram entry address */ - uint32_t image_len; /* kernel image length */ - uint32_t image_crc32; /* kernel image crc */ - uint32_t start_addr; /* ram start address */ - uint32_t rootfs_addr; /* rootfs flash address */ - uint32_t rootfs_len; /* rootfls length */ - uint32_t rootfs_crc32; /* rootfs crc32 */ - uint32_t header_crc32; /* sch2 header crc32, durring calculation this area is replaced by zero */ - uint16_t header_length; /* sch2 header length: 0x28 */ - uint16_t cmd_line_length; /* cmd line length, known zeros */ -}; - -/* globals */ -static struct file_info inspect_info; -struct file_info kernel_info; -struct file_info rootfs_info; -struct file_info image_info; - -char *ofname; -char *progname; -uint32_t firmware_size; -uint32_t image_offset; -uint16_t family_member; -char *rom_id[12] = { 0 }; -char image_type; - -static void usage(int status) -{ - fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stderr, - "\n" - "Options:\n" - " -i <file> inspect given firmware file <file>\n" - " -f set family member id (hexval prefixed with 0x)\n" - " -F <file> read image and convert it to FACTORY\n" - " -k <file> read kernel image from the file <file>\n" - " -r <file> read rootfs image from the file <file>\n" - " -o <file> write output to the file <file>\n" - " -s <size> set firmware partition size\n" - " -m <version> set rom id to <version> (12-bit string val: \"DLK*********\")\n" - " -h show this screen\n"); - - exit(status); -} - -void print_auh_header(struct auh_header *printed_header) -{ - printf("\trom_id: %s\n" - "\tderange: 0x%04X\n" - "\timage_checksum: 0x%04X\n" - "\tspace1: 0x%08X\n" - "\tspace2: 0x%08X\n" - "\tspace3: 0x%04X\n" - "\tlpvs: 0x%02X\n" - "\tmbz: 0x%02X\n" - "\ttime_stamp: 0x%08X\n" - "\terase_start: 0x%08X\n" - "\terase_length: 0x%08X\n" - "\tdata_offset: 0x%08X\n" - "\tdata_length: 0x%08X\n" - "\tspace4: 0x%08X\n" - "\tspace5: 0x%08X\n" - "\tspace6: 0x%08X\n" - "\tspace7: 0x%08X\n" - "\theader_id: 0x%04X\n" - "\theader_version: 0x%02X\n" - "\tspace8: 0x%04X\n" - "\tsection_id: 0x%02X\n" - "\timage_info_type: 0x%02X\n" - "\timage_info_offset 0x%08X\n" - "\tfamily_member: 0x%04X\n" - "\theader_checksum: 0x%04X\n", - printed_header->rom_id, - printed_header->derange, - printed_header->image_checksum, - printed_header->space1, - printed_header->space2, - printed_header->space3, - printed_header->lpvs, - printed_header->mbz, - printed_header->time_stamp, - printed_header->erase_start, - printed_header->erase_length, - printed_header->data_offset, - printed_header->data_length, - printed_header->space4, - printed_header->space5, - printed_header->space6, - printed_header->space7, - printed_header->header_id, - printed_header->header_version, - printed_header->space8, - printed_header->section_id, - printed_header->image_info_type, - printed_header->image_info_offset, - printed_header->family_member, printed_header->header_checksum); -} - -void print_stag_header(struct stag_header *printed_header) -{ - printf("\tcmark: 0x%02X\n" - "\tid: 0x%02X\n" - "\tmagic: 0x%04X\n" - "\ttime_stamp: 0x%08X\n" - "\timage_length: 0x%04X\n" - "\timage_checksum: 0x%04X\n" - "\ttag_checksum: 0x%04X\n", - printed_header->cmark, - printed_header->id, - printed_header->magic, - printed_header->time_stamp, - printed_header->image_length, - printed_header->image_checksum, printed_header->tag_checksum); -} - -void print_sch2_header(struct sch2_header *printed_header) -{ - printf("\tmagic: 0x%04X\n" - "\tcp_type: 0x%02X\n" - "\tversion: 0x%02X\n" - "\tram_addr: 0x%08X\n" - "\timage_len: 0x%08X\n" - "\timage_crc32: 0x%08X\n" - "\tstart_addr: 0x%08X\n" - "\trootfs_addr: 0x%08X\n" - "\trootfs_len: 0x%08X\n" - "\trootfs_crc32: 0x%08X\n" - "\theader_crc32: 0x%08X\n" - "\theader_length: 0x%04X\n" - "\tcmd_line_length: 0x%04X\n", - printed_header->magic, - printed_header->cp_type, - printed_header->version, - printed_header->ram_addr, - printed_header->image_len, - printed_header->image_crc32, - printed_header->start_addr, - printed_header->rootfs_addr, - printed_header->rootfs_len, - printed_header->rootfs_crc32, - printed_header->header_crc32, - printed_header->header_length, printed_header->cmd_line_length); -} - -static int find_auh_headers(char *buf) -{ - char *tmp_buf = buf; - struct auh_header *tmp_header[MAX_HEADER_COUNTER]; - int header_counter = 0; - - int ret = EXIT_FAILURE; - - while (tmp_buf - buf <= inspect_info.file_size - AUH_SIZE) { - if (!memcmp(tmp_buf, AUH_MAGIC, 3)) { - if (((struct auh_header *)tmp_buf)->header_checksum == - (uint16_t) ~jboot_checksum(0, (uint16_t *) tmp_buf, - AUH_SIZE - 2)) { - uint16_t checksum = 0; - printf("Find proper AUH header at: 0x%lX!\n", - tmp_buf - buf); - tmp_header[header_counter] = - (struct auh_header *)tmp_buf; - checksum = - jboot_checksum(0, (uint16_t *) ((char *) - tmp_header - [header_counter] - + AUH_SIZE), - tmp_header - [header_counter]->data_length); - if (tmp_header[header_counter]->image_checksum - == checksum) - printf("Image checksum ok.\n"); - else - ERR("Image checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", tmp_header[header_counter]->image_checksum, checksum); - header_counter++; - if (header_counter > MAX_HEADER_COUNTER) - break; - } - } - tmp_buf++; - } - - if (header_counter == 0) - ERR("Can't find proper AUH header!\n"); - else if (header_counter > MAX_HEADER_COUNTER) - ERR("To many AUH headers!\n"); - else { - for (int i = 0; i < header_counter; i++) { - printf("AUH %d:\n", i); - print_auh_header(tmp_header[i]); - } - - ret = EXIT_SUCCESS; - } - - return ret; -} - -static int check_stag_header(char *buf, struct stag_header *header) -{ - - int ret = EXIT_FAILURE; - - uint8_t cmark_tmp = header->cmark; - header->cmark = header->id; - - if (header->tag_checksum == - (uint16_t) ~jboot_checksum(0, (uint16_t *) header, - STAG_SIZE - 2)) { - uint16_t checksum = 0; - printf("Find proper STAG header at: 0x%lX!\n", - (char *)header - buf); - checksum = - jboot_checksum(0, (uint16_t *) ((char *)header + STAG_SIZE), - header->image_length); - if (header->image_checksum == checksum) { - printf("Image checksum ok.\n"); - header->cmark = cmark_tmp; - print_stag_header(header); - ret = EXIT_SUCCESS; - } else - ERR("Image checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", header->image_checksum, checksum); - } else - ERR("STAG header checksum incorrect!"); - - header->cmark = cmark_tmp; - return ret; -} - -static int check_sch2_header(char *buf, struct sch2_header *header) -{ - - int ret = EXIT_FAILURE; - - uint32_t crc32_tmp = header->header_crc32; - header->header_crc32 = 0; - - if (crc32_tmp == crc32(0, (uint8_t *) header, header->header_length)) { - uint32_t crc32_val; - printf("Find proper SCH2 header at: 0x%lX!\n", - (char *)header - buf); - - crc32_val = - crc32(0, (uint8_t *) header + header->header_length, - header->image_len); - if (header->image_crc32 == crc32_val) { - printf("Kernel checksum ok.\n"); - - header->header_crc32 = crc32_tmp; - print_sch2_header(header); - ret = EXIT_SUCCESS; - } else - ERR("Kernel checksum incorrect! Stored: 0x%X Calculated: 0x%X\n", header->image_crc32, crc32_val); - - } else - ERR("SCH2 header checksum incorrect!"); - - header->header_crc32 = crc32_tmp; - return ret; -} - -static int inspect_fw(void) -{ - char *buf; - struct stag_header *stag_header_kernel; - struct sch2_header *sch2_header_kernel; - int ret = EXIT_FAILURE; - - buf = malloc(inspect_info.file_size); - if (!buf) { - ERR("no memory for buffer!\n"); - goto out; - } - - ret = read_to_buf(&inspect_info, buf); - if (ret) - goto out_free_buf; - - ret = find_auh_headers(buf); - if (ret) - goto out_free_buf; - - stag_header_kernel = (struct stag_header *)(buf + AUH_SIZE); - - ret = check_stag_header(buf, stag_header_kernel); - if (ret) - goto out_free_buf; - - sch2_header_kernel = (struct sch2_header *)(buf + AUH_SIZE + STAG_SIZE); - - ret = check_sch2_header(buf, sch2_header_kernel); - if (ret) - goto out_free_buf; - - out_free_buf: - free(buf); - out: - return ret; -} - -static int check_options(void) -{ - int ret; - - if (inspect_info.file_name) { - ret = get_file_stat(&inspect_info); - if (ret) - return ret; - - return 0; - } - - return 0; -} - -int fill_sch2(struct sch2_header *header, char *kernel_ptr, char *rootfs_ptr) -{ - - header->magic = SCH2_MAGIC; - header->cp_type = LZMA; - header->version = SCH2_VER; - header->ram_addr = RAM_LOAD_ADDR; - header->image_len = kernel_info.file_size; - header->image_crc32 = crc32(0, (uint8_t *) kernel_ptr, kernel_info.file_size); - header->start_addr = RAM_ENTRY_ADDR; - header->rootfs_addr = - image_offset + STAG_SIZE + SCH2_SIZE + kernel_info.file_size; - header->rootfs_len = rootfs_info.file_size; - header->rootfs_crc32 = crc32(0, (uint8_t *) rootfs_ptr, rootfs_info.file_size); - header->header_crc32 = 0; - header->header_length = SCH2_SIZE; - header->cmd_line_length = 0; - - header->header_crc32 = crc32(0, (uint8_t *) header, header->header_length); - - return EXIT_SUCCESS; -} - -int fill_stag(struct stag_header *header, uint32_t length) -{ - header->cmark = STAG_ID; - header->id = STAG_ID; - header->magic = STAG_MAGIC; - header->time_stamp = jboot_timestamp(); - header->image_length = length + SCH2_SIZE; - header->image_checksum = - jboot_checksum(0, (uint16_t *) ((char *)header + STAG_SIZE), - header->image_length); - header->tag_checksum = - ~jboot_checksum(0, (uint16_t *) header, STAG_SIZE - 2); - - if (image_type == FACTORY) - header->cmark = STAG_CMARK_FACTORY; - - return EXIT_SUCCESS; -}; - -int fill_auh(struct auh_header *header, uint32_t length) -{ - memcpy(header->rom_id, rom_id, 12); - header->derange = 0; - header->image_checksum = - jboot_checksum(0, (uint16_t *) ((char *)header + AUH_SIZE), length); - header->space1 = 0; - header->space2 = 0; - header->space3 = 0; - header->lpvs = AUH_LVPS; - header->mbz = 0; - header->time_stamp = jboot_timestamp(); - header->erase_start = image_offset; - header->erase_length = firmware_size; - header->data_offset = image_offset; - header->data_length = length; - header->space4 = 0; - header->space5 = 0; - header->space6 = 0; - header->space7 = 0; - header->header_id = AUH_HDR_ID; - header->header_version = AUH_HDR_VER; - header->space8 = 0; - header->section_id = AUH_SEC_ID; - header->image_info_type = AUH_INFO_TYPE; - header->image_info_offset = 0; - header->family_member = family_member; - header->header_checksum = - ~jboot_checksum(0, (uint16_t *) header, AUH_SIZE - 2); - - return EXIT_SUCCESS; -} - -int build_fw(void) -{ - char *buf; - char *kernel_ptr; - char *rootfs_ptr; - int ret = EXIT_FAILURE; - int writelen; - - struct stag_header *stag_header_kernel; - struct sch2_header *sch2_header_kernel; - - if (!kernel_info.file_name | !rootfs_info.file_name) - goto out; - - ret = get_file_stat(&kernel_info); - if (ret) - goto out; - ret = get_file_stat(&rootfs_info); - if (ret) - goto out; - - buf = malloc(firmware_size); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - if (rootfs_info.file_size + kernel_info.file_size + ALL_HEADERS_SIZE > - firmware_size) { - ERR("data is bigger than firmware_size!\n"); - goto out; - } - - memset(buf, 0xff, firmware_size); - - stag_header_kernel = (struct stag_header *)buf; - - sch2_header_kernel = - (struct sch2_header *)((char *)stag_header_kernel + STAG_SIZE); - kernel_ptr = (char *)sch2_header_kernel + SCH2_SIZE; - - ret = read_to_buf(&kernel_info, kernel_ptr); - if (ret) - goto out_free_buf; - - rootfs_ptr = kernel_ptr + kernel_info.file_size; - - ret = read_to_buf(&rootfs_info, rootfs_ptr); - if (ret) - goto out_free_buf; - - writelen = rootfs_ptr + rootfs_info.file_size - buf; - - fill_sch2(sch2_header_kernel, kernel_ptr, rootfs_ptr); - fill_stag(stag_header_kernel, kernel_info.file_size); - - ret = write_fw(ofname, buf, writelen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - - out_free_buf: - free(buf); - out: - return ret; -} - -int wrap_fw(void) -{ - char *buf; - char *image_ptr; - int ret = EXIT_FAILURE; - int writelen; - - struct auh_header *auh_header_kernel; - - if (!image_info.file_name) - goto out; - - ret = get_file_stat(&image_info); - if (ret) - goto out; - - buf = malloc(firmware_size); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - if (image_info.file_size + AUH_SIZE > - firmware_size) { - ERR("data is bigger than firmware_size!\n"); - goto out; - } - if (!family_member) { - ERR("No family_member!\n"); - goto out; - } - if (!(rom_id[0])) { - ERR("No rom_id!\n"); - goto out; - } - memset(buf, 0xff, firmware_size); - - image_ptr = (char *)(buf + AUH_SIZE); - - ret = read_to_buf(&image_info, image_ptr); - if (ret) - goto out_free_buf; - - writelen = image_ptr + image_info.file_size - buf; - - auh_header_kernel = (struct auh_header *)buf; - fill_auh(auh_header_kernel, writelen - AUH_SIZE); - - ret = write_fw(ofname, buf, writelen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - - out_free_buf: - free(buf); - out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - image_type = SYSUPGRADE; - family_member = 0; - firmware_size = 0; - image_offset = JBOOT_SIZE; - - while (1) { - int c; - - c = getopt(argc, argv, "f:F:i:hk:m:o:O:r:s:"); - if (c == -1) - break; - - switch (c) { - case 'f': - sscanf(optarg, "0x%hx", &family_member); - break; - case 'F': - image_info.file_name = optarg; - image_type = FACTORY; - break; - case 'i': - inspect_info.file_name = optarg; - break; - case 'k': - kernel_info.file_name = optarg; - break; - case 'm': - if (strlen(optarg) == 12) - memcpy(rom_id, optarg, 12); - break; - case 'r': - rootfs_info.file_name = optarg; - break; - case 'O': - sscanf(optarg, "0x%x", &image_offset); - break; - case 'o': - ofname = optarg; - break; - case 's': - sscanf(optarg, "0x%x", &firmware_size); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - if (!inspect_info.file_name) { - if (image_type == FACTORY) - ret = wrap_fw(); - else - ret = build_fw(); - } - else - ret = inspect_fw(); - - out: - return ret; - -} diff --git a/tools/firmware-utils/src/mkdniimg.c b/tools/firmware-utils/src/mkdniimg.c deleted file mode 100644 index 8798b7babf..0000000000 --- a/tools/firmware-utils/src/mkdniimg.c +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#define DNI_HDR_LEN 128 - -/* - * Globals - */ -static char *ifname; -static char *progname; -static char *ofname; -static char *version = "1.00.00"; -static char *region = ""; -static char *hd_id; - -static char *board_id; -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -v <version> set image version to <version>\n" -" -r <region> set image region to <region>\n" -" -H <hd_id> set image hardware id to <hd_id>\n" -" -h show this screen\n" - ); - - exit(status); -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int buflen; - int err; - struct stat st; - char *buf; - int pos, rem, i; - uint8_t csum; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "B:i:o:v:r:H:h"); - if (c == -1) - break; - - switch (c) { - case 'B': - board_id = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'v': - version = optarg; - break; - case 'r': - region = optarg; - break; - case 'H': - hd_id = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (board_id == NULL) { - ERR("no board specified"); - goto err; - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - buflen = st.st_size + DNI_HDR_LEN + 1; - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - memset(buf, 0, DNI_HDR_LEN); - pos = snprintf(buf, DNI_HDR_LEN, "device:%s\nversion:V%s\nregion:%s\n", - board_id, version, region); - rem = DNI_HDR_LEN - pos; - if (pos >= 0 && rem > 1 && hd_id) { - snprintf(buf + pos, rem, "hd_id:%s\n", hd_id); - } - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - errno = 0; - fread(buf + DNI_HDR_LEN, st.st_size, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto err_close_in; - } - - csum = 0; - for (i = 0; i < (st.st_size + DNI_HDR_LEN); i++) - csum += buf[i]; - - csum = 0xff - csum; - buf[st.st_size + DNI_HDR_LEN] = csum; - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto err_close_in; - } - - errno = 0; - fwrite(buf, buflen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto err_close_out; - } - - res = EXIT_SUCCESS; - - fflush(outfile); - - err_close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } - - err_close_in: - fclose(infile); - - err_free: - free(buf); - - err: - return res; -} diff --git a/tools/firmware-utils/src/mkedimaximg.c b/tools/firmware-utils/src/mkedimaximg.c deleted file mode 100644 index 899f9f6146..0000000000 --- a/tools/firmware-utils/src/mkedimaximg.c +++ /dev/null @@ -1,281 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2011 Vasilis Tsiligiannis <b_tsiligiannis@silverton.gr> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <libgen.h> -#include <getopt.h> -#include <errno.h> -#include <sys/stat.h> -#include <endian.h> /* for __BYTE_ORDER */ - -#define FALSE 0 -#define TRUE 1 - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define HOST_TO_LE16(x) (x) -# define HOST_TO_LE32(x) (x) -# define HOST_TO_BE16(x) bswap_16(x) -# define HOST_TO_BE32(x) bswap_32(x) -#else -# define HOST_TO_LE16(x) bswap_16(x) -# define HOST_TO_LE32(x) bswap_32(x) -# define HOST_TO_BE16(x) (x) -# define HOST_TO_BE32(x) (x) -#endif - -struct header -{ - unsigned char sign[4]; - unsigned int start; - unsigned int flash; - unsigned char model[4]; - unsigned int size; -} __attribute__ ((packed)); - -struct finfo -{ - char *name; - off_t size; -}; - -struct buf -{ - char *start; - size_t size; -}; - -static char *progname; -static int force_be = FALSE; - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, - "\n" - "Options:\n" - " -s <sig> set image signature to <sig>\n" - " -m <model> set model to <model>\n" - " -i <file> read input from file <file>\n" - " -o <file> write output to file <file>\n" - " -f <flash> set flash address to <flash>\n" - " -S <start> set start address to <start>\n" - " -b big-endianness mode\n"); - - exit(status); -} - -static int strtou32(char *arg, unsigned int *val) -{ - char *endptr = NULL; - - errno = 0; - *val = strtoul(arg, &endptr, 0); - if (errno || (endptr == arg) || (*endptr && (endptr != NULL))) { - return EXIT_SUCCESS; - } - - return EXIT_FAILURE; -} - -static unsigned short fwcsum (struct buf *buf) { - int i; - unsigned short ret = 0; - - for (i = 0; i < buf->size / 2; i++) { - if (force_be == FALSE) - ret -= ((unsigned short *) buf->start)[i]; - else - ret -= HOST_TO_BE16(((unsigned short *) buf->start)[i]); - } - - return ret; -} - -static int fwread(struct finfo *finfo, struct buf *buf) -{ - FILE *f; - - f = fopen(finfo->name, "r"); - if (!f) { - fprintf(stderr, "could not open \"%s\" for reading\n", finfo->name); - usage(EXIT_FAILURE); - } - - buf->size = fread(buf->start, 1, finfo->size, f); - if (buf->size != finfo->size) { - fprintf(stderr, "unable to read from file \"%s\"\n", finfo->name); - usage(EXIT_FAILURE); - } - - fclose(f); - - return EXIT_SUCCESS; -} - -static int fwwrite(struct finfo *finfo, struct buf *buf) -{ - FILE *f; - - f = fopen(finfo->name, "w"); - if (!f) { - fprintf(stderr, "could not open \"%s\" for writing\n", finfo->name); - usage(EXIT_FAILURE); - } - - buf->size = fwrite(buf->start, 1, finfo->size, f); - if (buf->size != finfo->size) { - fprintf(stderr, "unable to write to file \"%s\"\n", finfo->name); - usage(EXIT_FAILURE); - } - - fclose(f); - - return EXIT_SUCCESS; -} - -int main(int argc, char **argv) -{ - struct stat st; - struct header header; - struct buf ibuf, obuf; - struct finfo ifinfo, ofinfo; - unsigned short csum; - int c; - - ifinfo.name = ofinfo.name = NULL; - header.flash = header.size = header.start = 0; - progname = basename(argv[0]); - - while((c = getopt(argc, argv, "i:o:m:s:f:S:h:b")) != -1) { - switch (c) { - case 'i': - ifinfo.name = optarg; - break; - case 'o': - ofinfo.name = optarg; - break; - case 'm': - if (strlen(optarg) != 4) { - fprintf(stderr, "model must be 4 characters long\n"); - usage(EXIT_FAILURE); - } - memcpy(header.model, optarg, 4); - break; - case 's': - if (strlen(optarg) != 4) { - fprintf(stderr, "signature must be 4 characters long\n"); - usage(EXIT_FAILURE); - } - memcpy(header.sign, optarg, 4); - break; - case 'h': - usage(EXIT_SUCCESS); - break; - case 'f': - if (!strtou32(optarg, &header.flash)) { - fprintf(stderr, "invalid flash address specified\n"); - usage(EXIT_FAILURE); - } - break; - case 'S': - if (!strtou32(optarg, &header.start)) { - fprintf(stderr, "invalid start address specified\n"); - usage(EXIT_FAILURE); - } - break; - case 'b': - force_be = TRUE; - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (ifinfo.name == NULL) { - fprintf(stderr, "no input file specified\n"); - usage(EXIT_FAILURE); - } - - if (ofinfo.name == NULL) { - fprintf(stderr, "no output file specified\n"); - usage(EXIT_FAILURE); - } - - if (stat(ifinfo.name, &st)) { - fprintf(stderr, "stat failed on %s\n", ifinfo.name); - usage(EXIT_FAILURE); - } - - if (header.sign == NULL) { - fprintf(stderr, "no signature specified\n"); - usage(EXIT_FAILURE); - } - - if (header.model == NULL) { - fprintf(stderr, "no model specified\n"); - usage(EXIT_FAILURE); - } - - if (!header.flash) { - fprintf(stderr, "no flash address specified\n"); - usage(EXIT_FAILURE); - } - - if (!header.start) { - fprintf(stderr, "no start address specified\n"); - usage(EXIT_FAILURE); - } - - ifinfo.size = st.st_size; - - obuf.size = ifinfo.size + sizeof(struct header) + sizeof(unsigned short); - if (obuf.size % sizeof(unsigned short)) - obuf.size++; - - obuf.start = malloc(obuf.size); - if (!obuf.start) { - fprintf(stderr, "no memory for buffer\n"); - usage(EXIT_FAILURE); - } - memset(obuf.start, 0, obuf.size); - - ibuf.size = ifinfo.size; - ibuf.start = obuf.start + sizeof(struct header); - - if (fwread(&ifinfo, &ibuf)) - usage(EXIT_FAILURE); - - if (force_be == FALSE) { - header.flash = HOST_TO_LE32(header.flash); - header.size = HOST_TO_LE32(obuf.size - sizeof(struct header)); - header.start = HOST_TO_LE32(header.start); - } else { - header.flash = HOST_TO_BE32(header.flash); - header.size = HOST_TO_BE32(obuf.size - sizeof(struct header)); - header.start = HOST_TO_BE32(header.start); - } - - memcpy (obuf.start, &header, sizeof(struct header)); - - if (force_be == FALSE) - csum = HOST_TO_LE16(fwcsum(&ibuf)); - else - csum = HOST_TO_BE16(fwcsum(&ibuf)); - - memcpy(obuf.start + obuf.size - sizeof(unsigned short), - &csum, sizeof(unsigned short)); - - ofinfo.size = obuf.size; - - if (fwwrite(&ofinfo, &obuf)) - usage(EXIT_FAILURE); - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/mkfwimage.c b/tools/firmware-utils/src/mkfwimage.c deleted file mode 100644 index 7f15d1f196..0000000000 --- a/tools/firmware-utils/src/mkfwimage.c +++ /dev/null @@ -1,569 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2007 Ubiquiti Networks, Inc. - * Copyright (C) 2008 Lukas Kuna <ValXdater@seznam.cz> - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <inttypes.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <zlib.h> -#include <sys/mman.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <stdbool.h> -#include "fw.h" -#include "utils.h" - -typedef struct fw_layout_data { - u_int32_t kern_start; - u_int32_t kern_entry; - u_int32_t firmware_max_length; -} fw_layout_t; - -struct fw_info { - char name[PATH_MAX]; - struct fw_layout_data fw_layout; - bool sign; -}; - -struct fw_info fw_info[] = { - { - .name = "XS2", - .fw_layout = { - .kern_start = 0xbfc30000, - .kern_entry = 0x80041000, - .firmware_max_length= 0x00390000, - }, - .sign = false, - }, - { - .name = "XS5", - .fw_layout = { - .kern_start = 0xbe030000, - .kern_entry = 0x80041000, - .firmware_max_length= 0x00390000, - }, - .sign = false, - }, - { - .name = "RS", - .fw_layout = { - .kern_start = 0xbf030000, - .kern_entry = 0x80060000, - .firmware_max_length= 0x00B00000, - }, - .sign = false, - }, - { - .name = "RSPRO", - .fw_layout = { - .kern_start = 0xbf030000, - .kern_entry = 0x80060000, - .firmware_max_length= 0x00F00000, - }, - .sign = false, - }, - { - .name = "LS-SR71", - .fw_layout = { - .kern_start = 0xbf030000, - .kern_entry = 0x80060000, - .firmware_max_length= 0x00640000, - }, - .sign = false, - }, - { - .name = "XS2-8", - .fw_layout = { - .kern_start = 0xa8030000, - .kern_entry = 0x80041000, - .firmware_max_length= 0x006C0000, - }, - .sign = false, - - }, - { - .name = "XM", - .fw_layout = { - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x00760000, - }, - .sign = false, - }, - { - .name = "SW", - .fw_layout = { - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x00760000, - }, - .sign = false, - }, - { - .name = "UBDEV01", - .fw_layout = { - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x006A0000, - }, - .sign = false, - }, - { - .name = "WA", - .fw_layout = { - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x00F60000, - }, - .sign = true, - }, - { - .name = "XC", - .fw_layout = { - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x00F60000, - }, - .sign = true, - }, - { - .name = "ACB", - .fw_layout = { - .kern_start = 0x9f050000, - .kern_entry = 0x80002000, - .firmware_max_length= 0x00F60000, - }, - .sign = true, - }, - { - .name = "", - }, -}; - -typedef struct part_data { - char partition_name[64]; - int partition_index; - u_int32_t partition_baseaddr; - u_int32_t partition_startaddr; - u_int32_t partition_memaddr; - u_int32_t partition_entryaddr; - u_int32_t partition_length; - - char filename[PATH_MAX]; - struct stat stats; -} part_data_t; - -#define MAX_SECTIONS 8 -#define DEFAULT_OUTPUT_FILE "firmware-image.bin" -#define DEFAULT_VERSION "UNKNOWN" - -#define OPTIONS "B:hv:m:o:r:k:" - -typedef struct image_info { - char magic[16]; - char version[256]; - char outputfile[PATH_MAX]; - u_int32_t part_count; - part_data_t parts[MAX_SECTIONS]; - struct fw_info* fwinfo; -} image_info_t; - -static struct fw_info* get_fwinfo(char* board_name) { - struct fw_info *fwinfo = fw_info; - while(strlen(fwinfo->name)) { - if(strcmp(fwinfo->name, board_name) == 0) { - return fwinfo; - } - fwinfo++; - } - return NULL; -} - -static void write_header(void* mem, const char *magic, const char* version) -{ - header_t* header = mem; - memset(header, 0, sizeof(header_t)); - - FW_MEMCPY_STR(header->magic, magic); - FW_MEMCPY_STR(header->version, version); - header->crc = htonl(crc32(0L, (uint8_t*) header, - sizeof(header_t) - 2 * sizeof(u_int32_t))); - header->pad = 0L; -} - -static void write_signature(void* mem, u_int32_t sig_offset) -{ - /* write signature */ - signature_t* sign = (signature_t*)(mem + sig_offset); - memset(sign, 0, sizeof(signature_t)); - - FW_MEMCPY_STR(sign->magic, MAGIC_END); - sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); - sign->pad = 0L; -} - -static void write_signature_rsa(void* mem, u_int32_t sig_offset) -{ - /* write signature */ - signature_rsa_t* sign = (signature_rsa_t*)(mem + sig_offset); - memset(sign, 0, sizeof(signature_rsa_t)); - - FW_MEMCPY_STR(sign->magic, MAGIC_ENDS); -// sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); - sign->pad = 0L; -} - -static int write_part(void* mem, part_data_t* d) -{ - char* addr; - int fd; - part_t* p = mem; - part_crc_t* crc = mem + sizeof(part_t) + d->stats.st_size; - - fd = open(d->filename, O_RDONLY); - if (fd < 0) - { - ERROR("Failed opening file '%s'\n", d->filename); - return -1; - } - - if ((addr=(char*)mmap(0, d->stats.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) - { - ERROR("Failed mmaping memory for file '%s'\n", d->filename); - close(fd); - return -2; - } - - memcpy(mem + sizeof(part_t), addr, d->stats.st_size); - munmap(addr, d->stats.st_size); - - memset(p->name, 0, PART_NAME_LENGTH); - FW_MEMCPY_STR(p->magic, MAGIC_PART); - FW_MEMCPY_STR(p->name, d->partition_name); - - p->index = htonl(d->partition_index); - p->data_size = htonl(d->stats.st_size); - p->part_size = htonl(d->partition_length); - p->baseaddr = htonl(d->partition_baseaddr); - p->memaddr = htonl(d->partition_memaddr); - p->entryaddr = htonl(d->partition_entryaddr); - - crc->crc = htonl(crc32(0L, mem, d->stats.st_size + sizeof(part_t))); - crc->pad = 0L; - - return 0; -} - -static void usage(const char* progname) -{ - INFO("Version %s\n" - "Usage: %s [options]\n" - "\t-v <version string>\t - firmware version information, default: %s\n" - "\t-o <output file>\t - firmware output file, default: %s\n" - "\t-m <magic>\t - firmware magic, default: %s\n" - "\t-k <kernel file>\t\t - kernel file\n" - "\t-r <rootfs file>\t\t - rootfs file\n" - "\t-B <board name>\t\t - choose firmware layout for specified board (XS2, XS5, RS, XM)\n" - "\t-h\t\t\t - this help\n", VERSION, - progname, DEFAULT_VERSION, DEFAULT_OUTPUT_FILE, MAGIC_HEADER); -} - -static void print_image_info(const image_info_t* im) -{ - unsigned int i = 0; - - INFO("Firmware version: '%s'\n" - "Output file: '%s'\n" - "Part count: %u\n", - im->version, im->outputfile, - im->part_count); - - for (i = 0; i < im->part_count; ++i) - { - const part_data_t* d = &im->parts[i]; - INFO(" %10s: %8" PRId64 " bytes (free: %8" PRId64 ")\n", - d->partition_name, - d->stats.st_size, - d->partition_length - d->stats.st_size); - } -} - -static u_int32_t filelength(const char* file) -{ - FILE *p; - int ret = -1; - - if ( (p = fopen(file, "rb") ) == NULL) return (-1); - - fseek(p, 0, SEEK_END); - ret = ftell(p); - - fclose (p); - - return (ret); -} - -static int create_image_layout(const char* kernelfile, const char* rootfsfile, image_info_t* im) -{ - uint32_t rootfs_len = 0; - part_data_t* kernel = &im->parts[0]; - part_data_t* rootfs = &im->parts[1]; - - fw_layout_t* p = &im->fwinfo->fw_layout; - - printf("board = %s\n", im->fwinfo->name); - strcpy(kernel->partition_name, "kernel"); - kernel->partition_index = 1; - kernel->partition_baseaddr = p->kern_start; - if ( (kernel->partition_length = filelength(kernelfile)) == (u_int32_t)-1) return (-1); - kernel->partition_memaddr = p->kern_entry; - kernel->partition_entryaddr = p->kern_entry; - strncpy(kernel->filename, kernelfile, sizeof(kernel->filename)); - - rootfs_len = filelength(rootfsfile); - if (rootfs_len + kernel->partition_length > p->firmware_max_length) { - ERROR("File '%s' too big (0x%08X) - max size: 0x%08X (exceeds %u bytes)\n", - rootfsfile, rootfs_len, p->firmware_max_length, - (rootfs_len + kernel->partition_length) - p->firmware_max_length); - return (-2); - } - - strcpy(rootfs->partition_name, "rootfs"); - rootfs->partition_index = 2; - rootfs->partition_baseaddr = kernel->partition_baseaddr + kernel->partition_length; - rootfs->partition_length = p->firmware_max_length - kernel->partition_length; - rootfs->partition_memaddr = 0x00000000; - rootfs->partition_entryaddr = 0x00000000; - strncpy(rootfs->filename, rootfsfile, sizeof(rootfs->filename)); - - printf("kernel: %d 0x%08x\n", kernel->partition_length, kernel->partition_baseaddr); - printf("root: %d 0x%08x\n", rootfs->partition_length, rootfs->partition_baseaddr); - im->part_count = 2; - - return 0; -} - -/** - * Checks the availability and validity of all image components. - * Fills in stats member of the part_data structure. - */ -static int validate_image_layout(image_info_t* im) -{ - unsigned int i; - - if (im->part_count == 0 || im->part_count > MAX_SECTIONS) - { - ERROR("Invalid part count '%d'\n", im->part_count); - return -1; - } - - for (i = 0; i < im->part_count; ++i) - { - part_data_t* d = &im->parts[i]; - int len = strlen(d->partition_name); - if (len == 0 || len > 16) - { - ERROR("Invalid partition name '%s' of the part %d\n", - d->partition_name, i); - return -1; - } - if (stat(d->filename, &d->stats) < 0) - { - ERROR("Couldn't stat file '%s' from part '%s'\n", - d->filename, d->partition_name); - return -2; - } - if (d->stats.st_size == 0) - { - ERROR("File '%s' from part '%s' is empty!\n", - d->filename, d->partition_name); - return -3; - } - if (d->stats.st_size > d->partition_length) { - ERROR("File '%s' too big (%d) - max size: 0x%08X (exceeds %" PRId64 " bytes)\n", - d->filename, i, d->partition_length, - d->stats.st_size - d->partition_length); - return -4; - } - } - - return 0; -} - -static int build_image(image_info_t* im) -{ - char* mem; - char* ptr; - u_int32_t mem_size; - FILE* f; - unsigned int i; - - // build in-memory buffer - mem_size = sizeof(header_t); - if(im->fwinfo->sign) { - mem_size += sizeof(signature_rsa_t); - } else { - mem_size += sizeof(signature_t); - } - for (i = 0; i < im->part_count; ++i) - { - part_data_t* d = &im->parts[i]; - mem_size += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); - } - - mem = (char*)calloc(mem_size, 1); - if (mem == NULL) - { - ERROR("Cannot allocate memory chunk of size '%u'\n", mem_size); - return -1; - } - - // write header - write_header(mem, im->magic, im->version); - ptr = mem + sizeof(header_t); - // write all parts - for (i = 0; i < im->part_count; ++i) - { - part_data_t* d = &im->parts[i]; - int rc; - if ((rc = write_part(ptr, d)) != 0) - { - ERROR("ERROR: failed writing part %u '%s'\n", i, d->partition_name); - } - ptr += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); - } - // write signature - if(im->fwinfo->sign) { - write_signature_rsa(mem, mem_size - sizeof(signature_rsa_t)); - } else { - write_signature(mem, mem_size - sizeof(signature_t)); - } - - // write in-memory buffer into file - if ((f = fopen(im->outputfile, "w")) == NULL) - { - ERROR("Can not create output file: '%s'\n", im->outputfile); - free(mem); - return -10; - } - - if (fwrite(mem, mem_size, 1, f) != 1) - { - ERROR("Could not write %d bytes into file: '%s'\n", - mem_size, im->outputfile); - free(mem); - fclose(f); - return -11; - } - - free(mem); - fclose(f); - return 0; -} - - -int main(int argc, char* argv[]) -{ - char kernelfile[PATH_MAX]; - char rootfsfile[PATH_MAX]; - char board_name[PATH_MAX]; - int o, rc; - image_info_t im; - struct fw_info *fwinfo; - - memset(&im, 0, sizeof(im)); - memset(kernelfile, 0, sizeof(kernelfile)); - memset(rootfsfile, 0, sizeof(rootfsfile)); - memset(board_name, 0, sizeof(board_name)); - - strcpy(im.outputfile, DEFAULT_OUTPUT_FILE); - strcpy(im.version, DEFAULT_VERSION); - strncpy(im.magic, MAGIC_HEADER, sizeof(im.magic)); - - while ((o = getopt(argc, argv, OPTIONS)) != -1) - { - switch (o) { - case 'v': - if (optarg) - strncpy(im.version, optarg, sizeof(im.version) - 1); - break; - case 'o': - if (optarg) - strncpy(im.outputfile, optarg, sizeof(im.outputfile) - 1); - break; - case 'm': - if (optarg) - strncpy(im.magic, optarg, sizeof(im.magic) - 1); - break; - case 'h': - usage(argv[0]); - return -1; - case 'k': - if (optarg) - strncpy(kernelfile, optarg, sizeof(kernelfile) - 1); - break; - case 'r': - if (optarg) - strncpy(rootfsfile, optarg, sizeof(rootfsfile) - 1); - break; - case 'B': - if (optarg) - strncpy(board_name, optarg, sizeof(board_name) - 1); - break; - } - } - if (strlen(board_name) == 0) - strcpy(board_name, "XS2"); /* default to XS2 */ - - if (strlen(kernelfile) == 0) - { - ERROR("Kernel file is not specified, cannot continue\n"); - usage(argv[0]); - return -2; - } - - if (strlen(rootfsfile) == 0) - { - ERROR("Root FS file is not specified, cannot continue\n"); - usage(argv[0]); - return -2; - } - - if ((fwinfo = get_fwinfo(board_name)) == NULL) { - ERROR("Invalid baord name '%s'\n", board_name); - usage(argv[0]); - return -2; - } - - im.fwinfo = fwinfo; - - if ((rc = create_image_layout(kernelfile, rootfsfile, &im)) != 0) - { - ERROR("Failed creating firmware layout description - error code: %d\n", rc); - return -3; - } - - if ((rc = validate_image_layout(&im)) != 0) - { - ERROR("Failed validating firmware layout - error code: %d\n", rc); - return -4; - } - - print_image_info(&im); - - if ((rc = build_image(&im)) != 0) - { - ERROR("Failed building image file '%s' - error code: %d\n", im.outputfile, rc); - return -5; - } - - return 0; -} diff --git a/tools/firmware-utils/src/mkfwimage2.c b/tools/firmware-utils/src/mkfwimage2.c deleted file mode 100644 index a0db930df2..0000000000 --- a/tools/firmware-utils/src/mkfwimage2.c +++ /dev/null @@ -1,440 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2007 Ubiquiti Networks, Inc. - * Copyright (C) 2008 Lukas Kuna <ValXdater@seznam.cz> - * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <zlib.h> -#include <sys/mman.h> -#include <netinet/in.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include "fw.h" - -#undef VERSION -#define VERSION "1.2-OpenWrt.1" - -#define MAX_SECTIONS 8 -#define DEFAULT_OUTPUT_FILE "firmware-image.bin" -#define DEFAULT_VERSION "UNKNOWN" -#define DEFAULT_FLASH_BASE (0xbfc00000) - -#define FIRMWARE_MAX_LENGTH (0x390000) - -typedef struct part_data { - char partition_name[64]; - int partition_index; - u_int32_t partition_baseaddr; - u_int32_t partition_offset; - u_int32_t partition_memaddr; - u_int32_t partition_entryaddr; - u_int32_t partition_length; - - char filename[PATH_MAX]; - struct stat stats; -} part_data_t; - -typedef struct image_info { - char version[256]; - char outputfile[PATH_MAX]; - char magic[MAGIC_LENGTH]; - u_int32_t flash_baseaddr; - u_int32_t part_count; - part_data_t parts[MAX_SECTIONS]; -} image_info_t; - -static image_info_t im; -static int zero_part_baseaddr = 0; - -static void write_header(void* mem, const char* version) -{ - header_t* header = mem; - memset(header, 0, sizeof(header_t)); - - memcpy(header->magic, im.magic, MAGIC_LENGTH); - strncpy(header->version, version, sizeof(header->version)); - header->crc = htonl(crc32(0L, (unsigned char *)header, - sizeof(header_t) - 2 * sizeof(u_int32_t))); - header->pad = 0L; -} - -static void write_signature(void* mem, u_int32_t sig_offset) -{ - /* write signature */ - signature_t* sign = (signature_t*)(mem + sig_offset); - memset(sign, 0, sizeof(signature_t)); - - memcpy(sign->magic, MAGIC_END, MAGIC_LENGTH); - sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); - sign->pad = 0L; -} - -static int write_part(void* mem, part_data_t* d) -{ - char* addr; - int fd; - part_t* p = mem; - part_crc_t* crc = mem + sizeof(part_t) + d->stats.st_size; - - fd = open(d->filename, O_RDONLY); - if (fd < 0) { - ERROR("Failed opening file '%s'\n", d->filename); - return -1; - } - - if ((addr=(char*)mmap(0, d->stats.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { - ERROR("Failed mmaping memory for file '%s'\n", d->filename); - close(fd); - return -2; - } - - memcpy(mem + sizeof(part_t), addr, d->stats.st_size); - munmap(addr, d->stats.st_size); - - memset(p->name, 0, sizeof(p->name)); - strncpy(p->magic, MAGIC_PART, MAGIC_LENGTH); - strncpy(p->name, d->partition_name, sizeof(p->name)); - p->index = htonl(d->partition_index); - p->data_size = htonl(d->stats.st_size); - p->part_size = htonl(d->partition_length); - p->baseaddr = htonl(d->partition_baseaddr); - p->memaddr = htonl(d->partition_memaddr); - p->entryaddr = htonl(d->partition_entryaddr); - - crc->crc = htonl(crc32(0L, mem, d->stats.st_size + sizeof(part_t))); - crc->pad = 0L; - - return 0; -} - -static void usage(const char* progname) -{ - INFO("Version %s\n" - "Usage: %s [options]\n" - "\t-v <version string>\t - firmware version information, default: %s\n" - "\t-m <magic>\t\t - firmware magic, default: %s\n" - "\t-f <flash base>\t\t - flash base address, default: 0x%08x\n" - "\t-o <output file>\t - firmware output file, default: %s\n" - "\t-p <name>:<offset>:<len>:<memaddr>:<entry>:<file>\n " - "\t\t\t\t - create a partition from <file>\n" - "\t-z\t\t\t - set partition offsets to zero\n" - "\t-h\t\t\t - this help\n", - VERSION, progname, DEFAULT_VERSION, MAGIC_HEADER, - DEFAULT_FLASH_BASE, DEFAULT_OUTPUT_FILE); -} - -static void print_image_info(void) -{ - int i; - - INFO("Firmware version : '%s'\n" - "Output file : '%s'\n" - "Part count : %u\n", - im.version, im.outputfile, im.part_count); - - for (i = 0; i < im.part_count; ++i) { - const part_data_t* d = &im.parts[i]; - INFO(" %10s: %08x %08x %08x %08x %8ld bytes (free: %8ld)\n", - d->partition_name, - d->partition_baseaddr, - d->partition_length, - d->partition_entryaddr, - d->partition_memaddr, - d->stats.st_size, - d->partition_length - d->stats.st_size); - } -} - -static int filelength(const char* file) -{ - FILE *p; - int ret = -1; - - if ( (p = fopen(file, "rb") ) == NULL) return (-1); - - fseek(p, 0, SEEK_END); - ret = ftell(p); - - fclose (p); - - return (ret); -} - -int str2u32(char *arg, u_int32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno = 0; - t = strtoul(arg, &err, 0); - if (errno || (err == arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - -#ifndef STRINGIFY -#define STRINGIFY2(X) #X -#define STRINGIFY(X) STRINGIFY2(X) -#endif -static int image_layout_add_partition(const char *part_desc) -{ - part_data_t *d; - char memaddr[16]; - char entryaddr[16]; - char offset[16]; - char length[16]; - int t; - - if (im.part_count >= MAX_SECTIONS) { - ERROR("Too many partitions specified\n"); - return (-1); - } - - d = &im.parts[im.part_count]; - t = sscanf(part_desc, "%15[-0-9a-zA-Z]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%15[0-9a-fA-Fx]:%"STRINGIFY(PATH_MAX)"s", - d->partition_name, - offset, - length, - memaddr, - entryaddr, - d->filename); - - if (t != 6) { - ERROR("Bad partition parameter %d, '%s'\n", t, part_desc); - return (-1); - } - - if (strlen(d->partition_name) == 0) { - ERROR("No partition name specified in '%s'\n", part_desc); - return (-1); - } - - if (str2u32(offset, &d->partition_offset)) { - ERROR("Bad offset value '%s'\n", offset); - return (-1); - } - - if (str2u32(length, &d->partition_length)) { - ERROR("Bad length value '%s'\n", length); - return (-1); - } - - if (d->partition_length == 0) { - int flen; - flen = filelength(d->filename); - if (flen < 0) { - ERROR("Unable to determine size of '%s'\n", - d->filename); - return (-1); - } - d->partition_length = flen; - } - - if (str2u32(memaddr, &d->partition_memaddr)) { - ERROR("Bad memaddr vaule '%s'\n", memaddr); - return (-1); - } - - if (str2u32(entryaddr, &d->partition_entryaddr)) { - ERROR("Bad entry address value '%s'\n", entryaddr); - return (-1); - } - - im.part_count++; - d->partition_index = im.part_count; - - return 0; -} - -static int image_layout_verify(void) -{ - u_int32_t offset; - int i; - - if (im.part_count == 0) { - ERROR("No partitions specified\n"); - return -1; - } - - offset = im.parts[0].partition_offset; - for (i = 0; i < im.part_count; i++) - { - part_data_t* d = &im.parts[i]; - - if (stat(d->filename, &d->stats) < 0) { - ERROR("Couldn't stat file '%s' from part '%s'\n", - d->filename, d->partition_name); - return -2; - } - - if (d->stats.st_size == 0) { - ERROR("File '%s' from part '%s' is empty!\n", - d->filename, d->partition_name); - return -3; - } - - if (d->stats.st_size > d->partition_length) { - ERROR("File '%s' too big (%d) - max size: 0x%08X (exceeds %lu bytes)\n", - d->filename, i, d->partition_length, - d->stats.st_size - d->partition_length); - return -4; - } - - if (d->partition_offset < offset) - d->partition_offset = offset; - - if (zero_part_baseaddr) { - d->partition_baseaddr = 0; - } else { - d->partition_baseaddr = - im.flash_baseaddr + d->partition_offset; - } - offset += d->partition_length; - } - - return 0; -} - -static int build_image(void) -{ - char* mem; - char* ptr; - u_int32_t mem_size; - FILE* f; - int i; - - /* build in-memory buffer */ - mem_size = sizeof(header_t) + sizeof(signature_t); - for (i = 0; i < im.part_count; ++i) { - part_data_t* d = &im.parts[i]; - mem_size += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); - } - - mem = (char*)calloc(mem_size, 1); - if (mem == NULL) { - ERROR("Cannot allocate memory chunk of size '%u'\n", mem_size); - return -1; - } - - /* write header */ - write_header(mem, im.version); - ptr = mem + sizeof(header_t); - - /* write all parts */ - for (i = 0; i < im.part_count; ++i) { - part_data_t* d = &im.parts[i]; - int rc; - if ((rc = write_part(ptr, d)) != 0) { - ERROR("ERROR: failed writing part %u '%s'\n", i, d->partition_name); - return -1; - } - ptr += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); - } - - - /* write signature */ - write_signature(mem, mem_size - sizeof(signature_t)); - - /* write in-memory buffer into file */ - if ((f = fopen(im.outputfile, "w")) == NULL) { - ERROR("Can not create output file: '%s'\n", im.outputfile); - free(mem); - return -10; - } - - if (fwrite(mem, mem_size, 1, f) != 1) { - ERROR("Could not write %d bytes into file: '%s'\n", - mem_size, im.outputfile); - free(mem); - fclose(f); - return -11; - } - - free(mem); - fclose(f); - return 0; -} - -int main(int argc, char* argv[]) -{ - int o, rc; - - memset(&im, 0, sizeof(im)); - - strcpy(im.outputfile, DEFAULT_OUTPUT_FILE); - strcpy(im.version, DEFAULT_VERSION); - memcpy(im.magic, MAGIC_HEADER, MAGIC_LENGTH); - im.flash_baseaddr = DEFAULT_FLASH_BASE; - - while ((o = getopt(argc, argv, "f:hm:o:p:v:z")) != -1) - { - switch (o) { - case 'f': - if (optarg) - if (str2u32(optarg, &im.flash_baseaddr)) { - ERROR("Invalid flash start address %s\n", optarg); - return -1; - } - break; - case 'h': - usage(argv[0]); - return -1; - case 'm': - if (optarg) { - if (strlen(optarg) != MAGIC_LENGTH) { - ERROR("Invalid magic %s\n", optarg); - return -1; - } - - memcpy(im.magic, optarg, MAGIC_LENGTH); - } - break; - case 'o': - if (optarg) - strncpy(im.outputfile, optarg, sizeof(im.outputfile)); - break; - case 'p': - if (optarg) { - if (image_layout_add_partition(optarg)) - return -1; - } - break; - case 'v': - if (optarg) - strncpy(im.version, optarg, sizeof(im.version)); - break; - case 'z': - zero_part_baseaddr = 1; - break; - } - } - - rc = image_layout_verify(); - if (rc) { - ERROR("Failed validating firmware layout - error code: %d\n", - rc); - return -4; - } - - print_image_info(); - - rc = build_image(); - if (rc) { - ERROR("Failed building image file '%s' - error code: %d\n", - im.outputfile, rc); - return -5; - } - - return 0; -} diff --git a/tools/firmware-utils/src/mkheader_gemtek.c b/tools/firmware-utils/src/mkheader_gemtek.c deleted file mode 100644 index ab72a644ef..0000000000 --- a/tools/firmware-utils/src/mkheader_gemtek.c +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2014 Claudio Leite <leitec@staticky.com> - */ - -/* - * Builds a proper flash image for routers using some Gemtek - * OEM boards. These include the Airlink101 AR725W, the - * Asante SmartHub 600 (AWRT-600N), and Linksys WRT100/110. - * - * The resulting image is compatible with the factory firmware - * web upgrade and TFTP interface. - * - * To build: - * gcc -O2 -o mkheader_gemtek mkheader_gemtek.c -lz - * - * Claudio Leite <leitec@staticky.com> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> - -#include <zlib.h> /* for crc32() */ - -/* - * The header is in little-endian format. In case - * we are on a BE host, we need to swap binary - * values. - */ -#ifdef __APPLE__ -# include <libkern/OSByteOrder.h> -# define le32 OSSwapHostToLittleInt32 -#else -# if defined(__linux__) -# include <endian.h> -# if __BYTE_ORDER == __BIG_ENDIAN -# define CPU_BIG_ENDIAN -# endif -# else -# include <sys/endian.h> /* BSD's should have this */ -# if _BYTE_ORDER == _BIG_ENDIAN -# define CPU_BIG_ENDIAN -# endif -# endif -# ifdef CPU_BIG_ENDIAN -# define le32(x) (((x & 0xff000000) >> 24) | \ - ((x & 0x00ff0000) >> 8) | \ - ((x & 0x0000ff00) << 8) | \ - ((x & 0x000000ff) << 24)) -# else -# define le32(x) (x) -# endif -#endif - -struct gemtek_header { - uint8_t magic[4]; - uint8_t version[4]; - uint32_t product_id; - uint32_t imagesz; - uint32_t checksum; - uint32_t fast_checksum; - uint8_t build[4]; - uint8_t lang[4]; -}; - -#define HDRLEN sizeof(struct gemtek_header) - -struct machines { - char *desc; - char *id; - uint32_t maxsize; - struct gemtek_header header; -}; - -struct machines mach_def[] = { - {"Airlink101 AR725W", "ar725w", 0x340000, - {"GMTK", "1003", le32(0x03000001), 0, 0, - 0, "01\0\0", "EN\0\0"}}, - {"Asante AWRT-600N", "awrt600n", 0x340000, - {"A600", "1005", le32(0x03000001), 0, 0, - 0, "01\0\0", "EN\0\0"}}, - {"Linksys WRT100", "wrt100", 0x320000, - {"GMTK", "1007", le32(0x03040001), 0, 0, - 0, "2\0\0\0", "EN\0\0"}}, - {"Linksys WRT110", "wrt110", 0x320000, - {"GMTK", "1007", le32(0x03040001), 0, 0, - 0, "2\0\0\0", "EN\0\0"}}, - {0} -}; - -int -main(int argc, char *argv[]) -{ - unsigned long res, flen; - struct gemtek_header my_hdr; - FILE *f, *f_out; - int image_type = -1, index; - uint8_t *buf; - uint32_t crc; - - if (argc < 3) { - fprintf(stderr, "mkheader_gemtek <uImage> <webflash image> [machine ID]\n"); - fprintf(stderr, " where [machine ID] is one of:\n"); - for (index = 0; mach_def[index].desc != 0; index++) { - fprintf(stderr, " %-10s %s", mach_def[index].id, mach_def[index].desc); - if (index == 0) - fprintf(stderr, " (default)\n"); - else - fprintf(stderr, "\n"); - } - - exit(-1); - } - - if (argc == 4) { - for(index = 0; mach_def[index].id != 0; index++) { - if(strcmp(mach_def[index].id, argv[3]) == 0) { - image_type = index; - break; - } - } - - if(image_type == -1) { - fprintf(stderr, "\nERROR: invalid machine type\n"); - exit(-1); - } - } else - image_type = 0; - - printf("Opening %s...\n", argv[1]); - - f = fopen(argv[1], "r"); - if(!f) { - fprintf(stderr, "\nERROR: couldn't open input image\n"); - exit(-1); - } - - fseek(f, 0, SEEK_END); - flen = (unsigned long) ftell(f); - - printf(" %lu (0x%lX) bytes long\n", flen, flen); - - if (flen > mach_def[image_type].maxsize) { - fprintf(stderr, "\nERROR: image exceeds maximum compatible size\n"); - goto f_error; - } - - buf = malloc(flen + HDRLEN); - if (!buf) { - fprintf(stderr, "\nERROR: couldn't allocate buffer\n"); - goto f_error; - } - rewind(f); - res = fread(buf + HDRLEN, 1, flen, f); - if (res != flen) { - perror("Couldn't read entire file: fread()"); - goto f_error; - } - fclose(f); - - printf("\nCreating %s...\n", argv[2]); - - memcpy(&my_hdr, &mach_def[image_type].header, HDRLEN); - - printf(" Using %s magic\n", mach_def[image_type].desc); - - my_hdr.imagesz = le32(flen + HDRLEN); - memcpy(my_hdr.lang, "EN", 2); - - memcpy(buf, &my_hdr, HDRLEN); - - crc = crc32(0, buf, flen + HDRLEN); - printf(" CRC32: %08X\n", crc); - - my_hdr.checksum = le32(crc); - memcpy(buf, &my_hdr, HDRLEN); - - printf(" Writing...\n"); - - f_out = fopen(argv[2], "w"); - if(!f_out) { - fprintf(stderr, "\nERROR: couldn't open output image\n"); - exit(-1); - } - - fwrite(buf, 1, flen + HDRLEN, f_out); - - fclose(f_out); - - free(buf); - return 0; - -f_error: - fclose(f); - exit(-1); -} diff --git a/tools/firmware-utils/src/mkhilinkfw.c b/tools/firmware-utils/src/mkhilinkfw.c deleted file mode 100644 index 059692beee..0000000000 --- a/tools/firmware-utils/src/mkhilinkfw.c +++ /dev/null @@ -1,311 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2013 Jeff Kent <jeff@jkent.net> - * - * This tool encrypts and decrypts uImage formatted firmware for Hilink - * HLK-RM04 wireless modules. It will also truncate a dump of mtd6 and make - * it an image suitable for flashing via the stock firmware upgrade page. - * - * Build instructions: - * gcc -lcrypto hlkcrypt.c -o hlkcrypt - */ - -#include <arpa/inet.h> -#include <errno.h> -#include <fcntl.h> -#include <getopt.h> -#include <openssl/des.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#define DES_KEY "H@L9K*(3" - -#ifndef min -#define min(a,b) \ - ({ __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; }) -#endif - -#define IH_MAGIC 0x27051956 -#define IH_NMLEN 32 -typedef 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 */ -} image_header_t; - -static int temp_fd = -1; -static DES_key_schedule schedule; - -static void show_usage(const char *arg0); -static void exit_cleanup(void); -static void copy_file(int src, int dst); -static void do_encrypt(void *p, off_t len); -static void do_decrypt(void *p, off_t len); - - -int main(int argc, char **argv) -{ - int encrypt_opt = 0; - int decrypt_opt = 0; - int input_opt = 0; - int output_opt = 0; - char *input_filename = NULL; - char *output_filename = NULL; - - int input_fd; - int output_fd; - off_t file_len; - char *p; - char buf[sizeof(image_header_t) + 3]; - image_header_t *header; - - while (1) { - static struct option long_options[] = { - {"encrypt", no_argument, 0, 'e'}, - {"decrypt", no_argument, 0, 'd'}, - {"input", required_argument, 0, 'i'}, - {"output", required_argument, 0, 'o'}, - {0, 0, 0, 0 } - }; - int option_index = 0; - int c = getopt_long(argc, argv, "dei:o:", - long_options, &option_index); - if (c == -1) - break; - - switch (c) { - case 'd': - decrypt_opt++; - if (decrypt_opt > 1) { - fprintf(stderr, "%s: decrypt may only be specified once\n", - argv[0]); - show_usage(argv[0]); - } - break; - - case 'e': - encrypt_opt++; - if (encrypt_opt > 1) { - fprintf(stderr, "%s: encrypt may only be specified once\n", - argv[0]); - show_usage(argv[0]); - } - break; - - case 'i': - input_opt++; - if (input_opt > 1) { - fprintf(stderr, "%s: only one input file may be specified\n", - argv[0]); - show_usage(argv[0]); - } - if (strcmp("-", optarg) != 0) { - input_filename = optarg; - } - break; - - case 'o': - output_opt++; - if (output_opt > 1) { - fprintf(stderr, "%s: only one output file may be specified\n", - argv[0]); - show_usage(argv[0]); - } - if (strcmp("-", optarg) != 0) { - output_filename = optarg; - } - break; - - case '?': - exit(-1); - - default: - abort(); - } - } - - if (decrypt_opt && encrypt_opt) { - fprintf(stderr, "%s: decrypt and encrypt may not be used together\n", - argv[0]); - show_usage(argv[0]); - } - - if (!decrypt_opt && !encrypt_opt) { - fprintf(stderr, "%s: neither decrypt or encrypt were specified\n", - argv[0]); - show_usage(argv[0]); - } - - temp_fd = fileno(tmpfile()); - if (temp_fd < 0) { - fprintf(stderr, "Can't create temporary file\n"); - exit(EXIT_FAILURE); - } - - atexit(exit_cleanup); - DES_set_key_unchecked((const_DES_cblock *)DES_KEY, &schedule); - - if (input_filename) { - input_fd = open(input_filename, O_RDONLY); - if (input_fd < 0) { - fprintf(stderr, "Can't open %s for reading: %s\n", input_filename, - strerror(errno)); - exit(EXIT_FAILURE); - } - copy_file(input_fd, temp_fd); - close(input_fd); - } - else { - copy_file(STDIN_FILENO, temp_fd); - } - - file_len = lseek(temp_fd, 0, SEEK_CUR); - if (file_len < 64) { - fprintf(stderr, "Not enough data\n"); - exit(EXIT_FAILURE); - } - - p = mmap(0, file_len, PROT_READ|PROT_WRITE, MAP_SHARED, temp_fd, 0); - if (p == MAP_FAILED) { - fprintf(stderr, "mmap failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - if (encrypt_opt) { - header = (image_header_t *)p; - off_t len = min(file_len, - ntohl(header->ih_size) + sizeof(image_header_t)); - if (ntohl(header->ih_magic) != IH_MAGIC) { - fprintf(stderr, "Header magic incorrect: " - "expected 0x%08X, got 0x%08X\n", - IH_MAGIC, ntohl(header->ih_magic)); - munmap(p, file_len); - exit(EXIT_FAILURE); - } - do_encrypt(p, len); - munmap(p, file_len); - if (len != file_len) { - if (ftruncate(temp_fd, len) < 0) { - fprintf(stderr, "ftruncate failed: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - } - } - - if (decrypt_opt) { - off_t header_len = min(file_len, sizeof(image_header_t) + 3); - memcpy(buf, p, header_len); - do_decrypt(buf, header_len); - header = (image_header_t *)buf; - if (ntohl(header->ih_magic) != IH_MAGIC) { - fprintf(stderr, "Header magic incorrect: " - "expected 0x%08X, got 0x%08X\n", - IH_MAGIC, ntohl(header->ih_magic)); - exit(EXIT_FAILURE); - } - do_decrypt(p, file_len); - munmap(p, file_len); - } - - lseek(temp_fd, 0, SEEK_SET); - if (output_filename) { - output_fd = creat(output_filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - if (output_fd < 0) { - fprintf(stderr, "Can't open %s for writing: %s\n", - output_filename, strerror(errno)); - exit(EXIT_FAILURE); - } - copy_file(temp_fd, output_fd); - close(output_fd); - } - else { - copy_file(temp_fd, STDOUT_FILENO); - } - - exit(EXIT_SUCCESS); - return 0; -} - -static void show_usage(const char *arg0) -{ - fprintf(stderr, "usage: %s -d|-e [-i FILE] [-o FILE]\n\n", arg0); - fprintf(stderr, "%-15s %s\n", "-d, --decrypt", "decrypt data"); - fprintf(stderr, "%-15s %s\n", "-e, --encrypt", "encrypt data"); - fprintf(stderr, "%-15s %s\n", "-i, --input", "intput file (defaults to stdin)"); - fprintf(stderr, "%-15s %s\n", "-o, --output", "output file (defaults to stdout)"); - exit(-1); -} - -static void exit_cleanup(void) -{ - if (temp_fd >= 0) { - close(temp_fd); - } -} - -static void copy_file(int src, int dst) -{ - char buf[4096]; - ssize_t size; - - while ((size = read(src, buf, 4096)) > 0) { - write(dst, buf, size); - } -} - -static void do_encrypt(void *p, off_t len) -{ - DES_cblock *pblock; - int num_blocks; - - num_blocks = len / 8; - pblock = (DES_cblock *) p; - while (num_blocks--) { - DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT); - pblock++; - } - - num_blocks = (len - 3) / 8; - pblock = (DES_cblock *) (p + 3); - while (num_blocks--) { - DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT); - pblock++; - } -} - -static void do_decrypt(void *p, off_t len) -{ - DES_cblock *pblock; - int num_blocks; - - num_blocks = (len - 3) / 8; - pblock = (DES_cblock *) (p + 3); - while (num_blocks--) { - DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT); - pblock++; - } - - num_blocks = len / 8; - pblock = (DES_cblock *) p; - while (num_blocks--) { - DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT); - pblock++; - } -} diff --git a/tools/firmware-utils/src/mkmerakifw-old.c b/tools/firmware-utils/src/mkmerakifw-old.c deleted file mode 100644 index a3e7a726b8..0000000000 --- a/tools/firmware-utils/src/mkmerakifw-old.c +++ /dev/null @@ -1,384 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com> - * Copyright (C) 2016 Christian Lamparter <chunkeey@googlemail.com> - * - * The format of the header this tool generates was first documented by - * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the - * same purpose. I have created this reimplementation at his request. The - * original script can be found at: - * <https://github.com/riptidewave93/meraki-partbuilder> - * - * Support for the old header format, which is used by the Cisco Z1 AP - * has been reverse engineered from the nandloader's nand_load_bk function. - * The original code is part of Cisco's GPL code and can be found at: - * <https://github.com/riptidewave93/meraki-linux> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <libgen.h> -#include <endian.h> -#include <getopt.h> -#include <errno.h> -#include <arpa/inet.h> - -#define PADDING_BYTE 0xff - -#define HDR_LENGTH 0x00000020 -#define HDR_OFF_MAGIC1 0 -#define HDR_OFF_LOAD_ADDR 4 -#define HDR_OFF_IMAGELEN 8 -#define HDR_OFF_ENTRY 12 -#define HDR_OFF_CHECKSUM 16 -#define HDR_OFF_FILLER0 20 -#define HDR_OFF_FILLER1 24 -#define HDR_OFF_FILLER2 28 - -struct board_info { - char *id; - char *description; - uint32_t magic; - uint32_t imagelen; - uint32_t load_addr; - uint32_t entry; - bool le32; -}; - -/* - * Globals - */ -static char *progname; -static bool strip_padding; - -static char *board_id; -static const struct board_info *board; - -static const struct board_info boards[] = { - { - .id = "z1", - .description = "Meraki Z1 Access Point", - .magic = 0x4d495053, - .imagelen = 0x007e0000, - .load_addr = 0x80060000, - .entry = 0x80060000, - .le32 = 0, - }, { - .id = "mx64", - .description = "Meraki MX64/MX65", - .magic = 0x4d495053, - .imagelen = 0x00000000, - .load_addr = 0x60008000, - .entry = 0x60008000, - .le32 = 1, - }, { - /* terminating entry */ - } -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -static const struct board_info *find_board(const char *id) -{ - const struct board_info *ret; - const struct board_info *board; - - ret = NULL; - for (board = boards; board->id != NULL; board++) { - if (strcasecmp(id, board->id) == 0) { - ret = board; - break; - } - } - - return ret; -} - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - const struct board_info *board; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -i <file> read kernel image from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -s strip padding from the end of the image\n" -" -h show this screen\n" - ); - - fprintf(stream, "\nBoards:\n"); - for (board = boards; board->id != NULL; board++) - fprintf(stream, " %-16s%s\n", board->id, board->description); - - exit(status); -} - -static void writel(unsigned char *buf, size_t offset, uint32_t value, bool le32) -{ - if (!le32) - value = htonl(value); - - memcpy(buf + offset, &value, sizeof(uint32_t)); -} - -static const uint32_t crc32_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - -static inline uint32_t crc32_accumulate_8(const uint32_t crc, const uint8_t ch) -{ - return crc32_table[(crc ^ ch) & 0xff] ^ (crc >> 8); -} - -static void crc32_csum(uint8_t *buf, const size_t len, bool le32) -{ - int j, k, l, m; - uint32_t crc; - size_t i; - - crc = ~0; - k = le32 * 3; - l = le32 * -2 + 1; - - for (i = 0; i < len; i += 4) { - for (j = 3; j >= 0; j -= 1) { - m = (j - k) * l; - crc = crc32_accumulate_8(crc, buf[i + m]); - } - } - crc = ~crc; - - writel(buf, HDR_OFF_CHECKSUM, crc, le32); -} - - -static int meraki_build_hdr(const struct board_info *board, const size_t klen, - FILE *out, FILE *in) -{ - unsigned char *kernel; - unsigned char *buf; - size_t buflen; - size_t kspace; - - size_t rc; - buflen = board->imagelen; - - if (buflen > 0) { - kspace = buflen - HDR_LENGTH; - - if (klen > kspace) { - ERR("kernel file is too big - max size: 0x%08lX\n", kspace); - return EXIT_FAILURE; - } - } - - /* If requested, resize buffer to remove padding */ - if (strip_padding) - buflen = klen + HDR_LENGTH; - - /* Allocate and initialize buffer for final image */ - buf = malloc(buflen); - if (buf == NULL) { - ERRS("no memory for buffer: %s\n"); - return EXIT_FAILURE; - } - memset(buf, PADDING_BYTE, buflen); - - /* Load kernel */ - kernel = buf + HDR_LENGTH; - fread(kernel, klen, 1, in); - - /* Write magic values and filler */ - writel(buf, HDR_OFF_MAGIC1, board->magic, board->le32); - writel(buf, HDR_OFF_FILLER0, 0, board->le32); - writel(buf, HDR_OFF_FILLER1, 0, board->le32); - writel(buf, HDR_OFF_FILLER2, 0, board->le32); - - /* Write load and kernel entry point address */ - writel(buf, HDR_OFF_LOAD_ADDR, board->load_addr, board->le32); - writel(buf, HDR_OFF_ENTRY, board->entry, board->le32); - - /* Write header and image length */ - writel(buf, HDR_OFF_IMAGELEN, klen, board->le32); - - /* this gets replaced later, after the checksum has been calculated */ - writel(buf, HDR_OFF_CHECKSUM, 0, board->le32); - - /* Write checksum */ - crc32_csum(buf, klen + HDR_LENGTH, board->le32); - - rc = fwrite(buf, buflen, 1, out); - - free(buf); - - return rc == 1 ? EXIT_SUCCESS : EXIT_FAILURE; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - char *ofname = NULL, *ifname = NULL; - FILE *out, *in; - size_t klen; - - progname = basename(argv[0]); - - while (1) { - int c; - - c = getopt(argc, argv, "B:i:o:sh"); - if (c == -1) - break; - - switch (c) { - case 'B': - board_id = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 's': - strip_padding = true; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (board_id == NULL) { - ERR("no board specified"); - goto err; - } - - board = find_board(board_id); - if (board == NULL) { - ERR("unknown board \"%s\"", board_id); - goto err; - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - in = fopen(ifname, "r"); - if (in == NULL) { - ERRS("could not open \"%s\" for reading: %s", ifname); - goto err; - } - - /* Get kernel length */ - fseek(in, 0, SEEK_END); - klen = ftell(in); - rewind(in); - - out = fopen(ofname, "w"); - if (out == NULL) { - ERRS("could not open \"%s\" for writing: %s", ofname); - goto err_close_in; - } - - ret = meraki_build_hdr(board, klen, out, in); - fclose(out); - -err_close_in: - fclose(in); - -err: - return ret; -} diff --git a/tools/firmware-utils/src/mkmerakifw.c b/tools/firmware-utils/src/mkmerakifw.c deleted file mode 100644 index b84d42d148..0000000000 --- a/tools/firmware-utils/src/mkmerakifw.c +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2015 Thomas Hebb <tommyhebb@gmail.com> - * - * The format of the header this tool generates was first documented by - * Chris Blake <chrisrblake93 (at) gmail.com> in a shell script of the - * same purpose. I have created this reimplementation at his request. The - * original script can be found at: - * <https://github.com/riptidewave93/meraki-partbuilder> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <libgen.h> -#include <getopt.h> -#include <errno.h> -#include <arpa/inet.h> - -#include "sha1.h" - -#define PADDING_BYTE 0xff - -#define HDR_LENGTH 0x00000400 -#define HDR_OFF_MAGIC1 0 -#define HDR_OFF_HDRLEN 4 -#define HDR_OFF_IMAGELEN 8 -#define HDR_OFF_CHECKSUM 12 -#define HDR_OFF_MAGIC2 32 -#define HDR_OFF_MAGIC3 36 -#define HDR_OFF_STATICHASH 40 -#define HDR_OFF_KERNEL_OFFSET 40 -#define HDR_OFF_RAMDISK_OFFSET 44 -#define HDR_OFF_FDT_OFFSET 48 -#define HDR_OFF_UNKNOWN_OFFSET 52 - -struct board_info { - uint32_t magic1; - uint32_t magic2; - uint32_t magic3; - uint32_t imagelen; - union { - unsigned char statichash[20]; - struct { - uint32_t kernel_offset; - uint32_t ramdisk_offset; - uint32_t fdt_offset; - uint32_t unknown_offset; - } mx60; - } u; - char *id; - char *description; -}; - -/* - * Globals - */ -static char *progname; - -static char *board_id; -static const struct board_info *board; - -static const struct board_info boards[] = { - { - .id = "mr18", - .description = "Meraki MR18 Access Point", - .magic1 = 0x8e73ed8a, - .magic2 = 0x8e73ed8a, - .imagelen = 0x00800000, - .u.statichash = {0xda, 0x39, 0xa3, 0xee, 0x5e, - 0x6b, 0x4b, 0x0d, 0x32, 0x55, - 0xbf, 0xef, 0x95, 0x60, 0x18, - 0x90, 0xaf, 0xd8, 0x07, 0x09}, - }, { - .id = "mr24", - .description = "Meraki MR24 Access Point", - .magic1 = 0x8e73ed8a, - .magic2 = 0x8e73ed8a, - .imagelen = 0x00800000, - .u.statichash = {0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff}, - }, { - .id = "mx60", - .description = "Meraki MX60/MX60W Security Appliance", - .magic1 = 0x8e73ed8a, - .magic2 = 0xa1f0beef, /* Enables use of load addr in statichash */ - .magic3 = 0x00060001, /* This goes along with magic2 */ - .imagelen = 0x3fd00000, - /* The static hash below does the following: - * 1st Row: Kernel Offset - * 2nd Row: Ramdisk Offset - * 3rd Row: FDT Offset - * 4th Row: ? Unused/Unknown ? - * 5th Row: ? Unused/Unknown ? - */ - .u.mx60 = { - .kernel_offset = 0x10000, - .ramdisk_offset = 0x3FFC00, - .fdt_offset = 0x0400, - .unknown_offset = 0x0400, - }, - }, { - /* terminating entry */ - } -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -static const struct board_info *find_board(const char *id) -{ - const struct board_info *ret; - const struct board_info *board; - - ret = NULL; - for (board = boards; board->id != NULL; board++) { - if (strcasecmp(id, board->id) == 0) { - ret = board; - break; - } - } - - return ret; -} - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - const struct board_info *board; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -i <file> read kernel image from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -s strip padding from the end of the image\n" -" -h show this screen\n" - ); - - fprintf(stream, "\nBoards:\n"); - for (board = boards; board->id != NULL; board++) - fprintf(stream, " %-16s%s\n", board->id, board->description); - - exit(status); -} - -void writel(unsigned char *buf, size_t offset, uint32_t value) -{ - value = htonl(value); - memcpy(buf + offset, &value, sizeof(uint32_t)); -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - long klen; - size_t kspace; - unsigned char *kernel; - size_t buflen; - unsigned char *buf; - bool strip_padding = false; - char *ofname = NULL, *ifname = NULL; - FILE *out, *in; - - progname = basename(argv[0]); - - while (1) { - int c; - - c = getopt(argc, argv, "B:i:o:sh"); - if (c == -1) - break; - - switch (c) { - case 'B': - board_id = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 's': - strip_padding = true; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (board_id == NULL) { - ERR("no board specified"); - goto err; - } - - board = find_board(board_id); - if (board == NULL) { - ERR("unknown board \"%s\"", board_id); - goto err; - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - in = fopen(ifname, "r"); - if (in == NULL) { - ERRS("could not open \"%s\" for reading: %s", ifname); - goto err; - } - - buflen = board->imagelen; - kspace = buflen - HDR_LENGTH; - - /* Get kernel length */ - fseek(in, 0, SEEK_END); - klen = ftell(in); - rewind(in); - - if (klen > kspace) { - ERR("file \"%s\" is too big - max size: 0x%08lX\n", - ifname, kspace); - goto err_close_in; - } - - /* If requested, resize buffer to remove padding */ - if (strip_padding) - buflen = klen + HDR_LENGTH; - - /* Allocate and initialize buffer for final image */ - buf = malloc(buflen); - if (buf == NULL) { - ERRS("no memory for buffer: %s\n"); - goto err_close_in; - } - memset(buf, PADDING_BYTE, buflen); - - /* Load kernel */ - kernel = buf + HDR_LENGTH; - fread(kernel, klen, 1, in); - - /* Write magic values */ - writel(buf, HDR_OFF_MAGIC1, board->magic1); - writel(buf, HDR_OFF_MAGIC2, board->magic2); - writel(buf, HDR_OFF_MAGIC3, board->magic3); - - /* Write header and image length */ - writel(buf, HDR_OFF_HDRLEN, HDR_LENGTH); - writel(buf, HDR_OFF_IMAGELEN, klen); - - /* Write checksum and static hash */ - sha1_csum(kernel, klen, buf + HDR_OFF_CHECKSUM); - - switch (board->magic2) { - case 0xa1f0beef: - writel(buf, HDR_OFF_KERNEL_OFFSET, board->u.mx60.kernel_offset); - writel(buf, HDR_OFF_RAMDISK_OFFSET, board->u.mx60.ramdisk_offset); - writel(buf, HDR_OFF_FDT_OFFSET, board->u.mx60.fdt_offset), - writel(buf, HDR_OFF_UNKNOWN_OFFSET, board->u.mx60.unknown_offset); - break; - - case 0x8e73ed8a: - memcpy(buf + HDR_OFF_STATICHASH, board->u.statichash, 20); - break; - } - - /* Save finished image */ - out = fopen(ofname, "w"); - if (out == NULL) { - ERRS("could not open \"%s\" for writing: %s", ofname); - goto err_free; - } - fwrite(buf, buflen, 1, out); - - ret = EXIT_SUCCESS; - - fclose(out); - -err_free: - free(buf); - -err_close_in: - fclose(in); - -err: - return ret; -} diff --git a/tools/firmware-utils/src/mkmylofw.c b/tools/firmware-utils/src/mkmylofw.c deleted file mode 100644 index 9999b3c235..0000000000 --- a/tools/firmware-utils/src/mkmylofw.c +++ /dev/null @@ -1,1282 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2006-2008 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> -#include <endian.h> /* for __BYTE_ORDER */ - -#if defined(__CYGWIN__) -# include <byteswap.h> -#endif - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define HOST_TO_LE16(x) (x) -# define HOST_TO_LE32(x) (x) -#else -# define HOST_TO_LE16(x) bswap_16(x) -# define HOST_TO_LE32(x) bswap_32(x) -#endif - -#include "myloader.h" - -#define MAX_FW_BLOCKS 32 -#define MAX_ARG_COUNT 32 -#define MAX_ARG_LEN 1024 -#define FILE_BUF_LEN (16*1024) -#define PART_NAME_LEN 32 - -struct fw_block { - uint32_t addr; - uint32_t blocklen; /* length of the block */ - uint32_t flags; - - char *name; /* name of the file */ - uint32_t size; /* length of the file */ - uint32_t crc; /* crc value of the file */ -}; - -struct fw_part { - struct mylo_partition mylo; - char name[PART_NAME_LEN]; -}; - -#define BLOCK_FLAG_HAVEHDR 0x0001 - -struct cpx_board { - char *model; /* model number*/ - char *name; /* model name*/ - char *desc; /* description */ - uint16_t vid; /* vendor id */ - uint16_t did; /* device id */ - uint16_t svid; /* sub vendor id */ - uint16_t sdid; /* sub device id */ - uint32_t flash_size; /* size of flash */ - uint32_t part_offset; /* offset of the partition_table */ - uint32_t part_size; /* size of the partition_table */ -}; - -#define BOARD(_vid, _did, _svid, _sdid, _flash, _mod, _name, _desc, _po, _ps) { \ - .model = _mod, .name = _name, .desc = _desc, \ - .vid = _vid, .did = _did, .svid = _svid, .sdid = _sdid, \ - .flash_size = (_flash << 20), \ - .part_offset = _po, .part_size = _ps } - -#define CPX_BOARD(_did, _flash, _mod, _name, _desc, _po, _ps) \ - BOARD(VENID_COMPEX, _did, VENID_COMPEX, _did, _flash, _mod, _name, _desc, _po, _ps) - -#define CPX_BOARD_ADM(_did, _flash, _mod, _name, _desc) \ - CPX_BOARD(_did, _flash, _mod, _name, _desc, 0x10000, 0x10000) - -#define CPX_BOARD_AR71XX(_did, _flash, _mod, _name, _desc) \ - CPX_BOARD(_did, _flash, _mod, _name, _desc, 0x20000, 0x8000) - -#define CPX_BOARD_AR23XX(_did, _flash, _mod, _name, _desc) \ - CPX_BOARD(_did, _flash, _mod, _name, _desc, 0x10000, 0x10000) - -#define ALIGN(x,y) (((x)+((y)-1)) & ~((y)-1)) - -char *progname; -char *ofname = NULL; - -uint32_t flash_size = 0; -int fw_num_partitions = 0; -int fw_num_blocks = 0; -int verblevel = 0; - -struct mylo_fw_header fw_header; -struct fw_part fw_parts[MYLO_MAX_PARTITIONS]; -struct fw_block fw_blocks[MAX_FW_BLOCKS]; -struct cpx_board *board; - -struct cpx_board boards[] = { - CPX_BOARD_ADM(DEVID_COMPEX_NP18A, 4, - "NP18A", "Compex NetPassage 18A", - "Dualband Wireless A+G Internet Gateway"), - CPX_BOARD_ADM(DEVID_COMPEX_NP26G8M, 2, - "NP26G8M", "Compex NetPassage 26G (8M)", - "Wireless-G Broadband Multimedia Gateway"), - CPX_BOARD_ADM(DEVID_COMPEX_NP26G16M, 4, - "NP26G16M", "Compex NetPassage 26G (16M)", - "Wireless-G Broadband Multimedia Gateway"), - CPX_BOARD_ADM(DEVID_COMPEX_NP27G, 4, - "NP27G", "Compex NetPassage 27G", - "Wireless-G 54Mbps eXtended Range Router"), - CPX_BOARD_ADM(DEVID_COMPEX_NP28G, 4, - "NP28G", "Compex NetPassage 28G", - "Wireless 108Mbps Super-G XR Multimedia Router with 4 USB Ports"), - CPX_BOARD_ADM(DEVID_COMPEX_NP28GHS, 4, - "NP28GHS", "Compex NetPassage 28G (HotSpot)", - "HotSpot Solution"), - CPX_BOARD_ADM(DEVID_COMPEX_WP18, 4, - "WP18", "Compex NetPassage WP18", - "Wireless-G 54Mbps A+G Dualband Access Point"), - CPX_BOARD_ADM(DEVID_COMPEX_WP54G, 4, - "WP54G", "Compex WP54G", - "Wireless-G 54Mbps XR Access Point"), - CPX_BOARD_ADM(DEVID_COMPEX_WP54Gv1C, 2, - "WP54Gv1C", "Compex WP54G rev.1C", - "Wireless-G 54Mbps XR Access Point"), - CPX_BOARD_ADM(DEVID_COMPEX_WP54AG, 4, - "WP54AG", "Compex WP54AG", - "Wireless-AG 54Mbps XR Access Point"), - CPX_BOARD_ADM(DEVID_COMPEX_WPP54G, 4, - "WPP54G", "Compex WPP54G", - "Outdoor Access Point"), - CPX_BOARD_ADM(DEVID_COMPEX_WPP54AG, 4, - "WPP54AG", "Compex WPP54AG", - "Outdoor Access Point"), - - CPX_BOARD_AR71XX(DEVID_COMPEX_WP543, 2, - "WP543", "Compex WP543", - "BareBoard"), - CPX_BOARD_AR71XX(DEVID_COMPEX_WPE72, 8, - "WPE72", "Compex WPE72", - "BareBoard"), - - CPX_BOARD_AR23XX(DEVID_COMPEX_NP25G, 4, - "NP25G", "Compex NetPassage 25G", - "Wireless 54Mbps XR Router"), - CPX_BOARD_AR23XX(DEVID_COMPEX_WPE53G, 4, - "WPE53G", "Compex NetPassage 25G", - "Wireless 54Mbps XR Access Point"), - {.model = NULL} -}; - -void -errmsgv(int syserr, const char *fmt, va_list arg_ptr) -{ - int save = errno; - - fflush(0); - fprintf(stderr, "[%s] Error: ", progname); - vfprintf(stderr, fmt, arg_ptr); - if (syserr != 0) { - fprintf(stderr, ": %s", strerror(save)); - } - fprintf(stderr, "\n"); -} - -void -errmsg(int syserr, const char *fmt, ...) -{ - va_list arg_ptr; - va_start(arg_ptr, fmt); - errmsgv(syserr, fmt, arg_ptr); - va_end(arg_ptr); -} - -void -dbgmsg(int level, const char *fmt, ...) -{ - va_list arg_ptr; - if (verblevel >= level) { - fflush(0); - va_start(arg_ptr, fmt); - vfprintf(stderr, fmt, arg_ptr); - fprintf(stderr, "\n"); - va_end(arg_ptr); - } -} - - -void -usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - struct cpx_board *board; - - fprintf(stream, "Usage: %s [OPTION...] <file>\n", progname); - fprintf(stream, -"\n" -" <file> write output to the <file>\n" -"\n" -"Options:\n" -" -B <board> create firmware for the board specified with <board>.\n" -" This option set vendor id, device id, subvendor id,\n" -" subdevice id, and flash size options to the right value.\n" -" valid <board> values:\n"); - for (board = boards; board->model != NULL; board++){ - fprintf(stream, -" %-12s: %s\n", - board->model, board->name); - }; - fprintf(stream, -" -i <vid>:<did>[:<svid>[:<sdid>]]\n" -" create firmware for board with vendor id <vid>, device\n" -" id <did>, subvendor id <svid> and subdevice id <sdid>.\n" -" -r <rev> set board revision to <rev>.\n" -" -s <size> set flash size to <size>\n" -" -b <addr>:<len>[:[<flags>]:<file>]\n" -" define block at <addr> with length of <len>.\n" -" valid <flag> values:\n" -" h : add crc header before the file data.\n" -" -p <addr>:<len>[:<flags>[:<param>[:<name>[:<file>]]]]\n" -" add partition at <addr>, with size of <len> to the\n" -" partition table, set partition name to <name>, partition \n" -" flags to <flags> and partition parameter to <param>.\n" -" If the <file> is specified content of the file will be \n" -" added to the firmware image.\n" -" valid <flag> values:\n" -" a: this is the active partition. The bootloader loads\n" -" the firmware from this partition.\n" -" h: the partition data have a header.\n" -" l: the partition data uses LZMA compression.\n" -" p: the bootloader loads data from this partition to\n" -" the RAM before decompress it.\n" -" -h show this screen\n" - ); - - exit(status); -} - -/* - * Code to compute the CRC-32 table. Borrowed from - * gzip-1.0.3/makecrc.c. - */ - -static uint32_t crc_32_tab[256]; - -void -init_crc_table(void) -{ - /* Not copyrighted 1990 Mark Adler */ - - uint32_t c; /* crc shift register */ - uint32_t e; /* polynomial exclusive-or pattern */ - int i; /* counter for all possible eight bit values */ - int k; /* byte being shifted into crc apparatus */ - - /* terms of polynomial defining this crc (except x^32): */ - static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* Make exclusive-or pattern from polynomial */ - e = 0; - for (i = 0; i < sizeof(p)/sizeof(int); i++) - e |= 1L << (31 - p[i]); - - crc_32_tab[0] = 0; - - for (i = 1; i < 256; i++) { - c = 0; - for (k = i | 256; k != 1; k >>= 1) { - c = c & 1 ? (c >> 1) ^ e : c >> 1; - if (k & 1) - c ^= e; - } - crc_32_tab[i] = c; - } -} - - -void -update_crc(uint8_t *p, uint32_t len, uint32_t *crc) -{ - uint32_t t; - - t = *crc ^ 0xFFFFFFFFUL; - while (len--) { - t = crc_32_tab[(t ^ *p++) & 0xff] ^ (t >> 8); - } - *crc = t ^ 0xFFFFFFFFUL; -} - - -uint32_t -get_crc(uint8_t *p, uint32_t len) -{ - uint32_t crc; - - crc = 0; - update_crc(p ,len , &crc); - return crc; -} - - -int -str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - - -int -str2u16(char *arg, uint16_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x10000)) { - return -1; - } - - *val = t & 0xFFFF; - return 0; -} - - -struct cpx_board * -find_board(char *model){ - struct cpx_board *board; - struct cpx_board *tmp; - - board = NULL; - for (tmp = boards; tmp->model != NULL; tmp++){ - if (strcasecmp(model, tmp->model) == 0) { - board = tmp; - break; - } - }; - - return board; -} - - -int -get_file_crc(struct fw_block *ff) -{ - FILE *f; - uint8_t buf[FILE_BUF_LEN]; - uint32_t readlen = sizeof(buf); - int res = -1; - size_t len; - - if ((ff->flags & BLOCK_FLAG_HAVEHDR) == 0) { - res = 0; - goto out; - } - - errno = 0; - f = fopen(ff->name,"r"); - if (errno) { - errmsg(1,"unable to open file %s", ff->name); - goto out; - } - - ff->crc = 0; - len = ff->size; - while (len > 0) { - if (len < readlen) - readlen = len; - - errno = 0; - fread(buf, readlen, 1, f); - if (errno) { - errmsg(1,"unable to read from file %s", ff->name); - goto out_close; - } - - update_crc(buf, readlen, &ff->crc); - len -= readlen; - } - - res = 0; - -out_close: - fclose(f); -out: - return res; -} - - -int -process_files(void) -{ - struct fw_block *b; - struct stat st; - int i; - - for (i = 0; i < fw_num_blocks; i++) { - b = &fw_blocks[i]; - if ((b->addr + b->blocklen) > flash_size) { - errmsg(0, "block at 0x%08X is too big", b->addr); - return -1; - } - if (b->name == NULL) - continue; - - if (stat(b->name, &st) < 0) { - errmsg(0, "stat failed on %s",b->name); - return -1; - } - if (b->blocklen == 0) { - b->blocklen = flash_size - b->addr; - } - if (st.st_size > b->blocklen) { - errmsg(0,"file %s is too big",b->name); - return -1; - } - - b->size = st.st_size; - } - - return 0; -} - - -int -process_partitions(void) -{ - struct mylo_partition *part; - int i; - - for (i = 0; i < fw_num_partitions; i++) { - part = &fw_parts[i].mylo; - - if (part->addr > flash_size) { - errmsg(0, "invalid partition at 0x%08X", part->addr); - return -1; - } - - if ((part->addr + part->size) > flash_size) { - errmsg(0, "partition at 0x%08X is too big", part->addr); - return -1; - } - } - - return 0; -} - - -/* - * routines to write data to the output file - */ -int -write_out_data(FILE *outfile, void *data, size_t len, uint32_t *crc) -{ - uint8_t *ptr = data; - - errno = 0; - - fwrite(ptr, len, 1, outfile); - if (errno) { - errmsg(1,"unable to write output file"); - return -1; - } - - if (crc) { - update_crc(ptr, len, crc); - } - - return 0; -} - - -int -write_out_desc(FILE *outfile, struct mylo_fw_blockdesc *desc, uint32_t *crc) -{ - return write_out_data(outfile, (uint8_t *)desc, - sizeof(*desc), crc); -} - - -int -write_out_padding(FILE *outfile, size_t len, uint8_t padc, uint32_t *crc) -{ - uint8_t buff[512]; - size_t buflen = sizeof(buff); - - memset(buff, padc, buflen); - - while (len > 0) { - if (len < buflen) - buflen = len; - - if (write_out_data(outfile, buff, buflen, crc)) - return -1; - - len -= buflen; - } - - return 0; -} - - -int -write_out_file(FILE *outfile, struct fw_block *block, uint32_t *crc) -{ - char buff[FILE_BUF_LEN]; - size_t buflen = sizeof(buff); - FILE *f; - size_t len; - - errno = 0; - - if (block->name == NULL) { - return 0; - } - - if ((block->flags & BLOCK_FLAG_HAVEHDR) != 0) { - struct mylo_partition_header ph; - - if (get_file_crc(block) != 0) - return -1; - - ph.crc = HOST_TO_LE32(block->crc); - ph.len = HOST_TO_LE32(block->size); - - if (write_out_data(outfile, (uint8_t *)&ph, sizeof(ph), crc) != 0) - return -1; - } - - f = fopen(block->name,"r"); - if (errno) { - errmsg(1,"unable to open file: %s", block->name); - return -1; - } - - len = block->size; - while (len > 0) { - if (len < buflen) - buflen = len; - - /* read data from source file */ - errno = 0; - fread(buff, buflen, 1, f); - if (errno != 0) { - errmsg(1,"unable to read from file: %s",block->name); - return -1; - } - - if (write_out_data(outfile, buff, buflen, crc) != 0) - return -1; - - len -= buflen; - } - - fclose(f); - - /* align next block on a 4 byte boundary */ - len = block->size % 4; - if (write_out_padding(outfile, len, 0xFF, crc)) - return -1; - - dbgmsg(1,"file %s written out", block->name); - return 0; -} - - -int -write_out_header(FILE *outfile, uint32_t *crc) -{ - struct mylo_fw_header hdr; - - memset(&hdr, 0, sizeof(hdr)); - - hdr.magic = HOST_TO_LE32(MYLO_MAGIC_FIRMWARE); - hdr.crc = HOST_TO_LE32(fw_header.crc); - hdr.vid = HOST_TO_LE16(fw_header.vid); - hdr.did = HOST_TO_LE16(fw_header.did); - hdr.svid = HOST_TO_LE16(fw_header.svid); - hdr.sdid = HOST_TO_LE16(fw_header.sdid); - hdr.rev = HOST_TO_LE32(fw_header.rev); - hdr.fwhi = HOST_TO_LE32(fw_header.fwhi); - hdr.fwlo = HOST_TO_LE32(fw_header.fwlo); - hdr.flags = HOST_TO_LE32(fw_header.flags); - - if (fseek(outfile, 0, SEEK_SET) != 0) { - errmsg(1,"fseek failed on output file"); - return -1; - } - - return write_out_data(outfile, (uint8_t *)&hdr, sizeof(hdr), crc); -} - - -int -write_out_partitions(FILE *outfile, uint32_t *crc) -{ - struct mylo_partition_table p; - char part_names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; - int ret; - int i; - - if (fw_num_partitions == 0) - return 0; - - memset(&p, 0, sizeof(p)); - memset(part_names, 0, sizeof(part_names)); - - p.magic = HOST_TO_LE32(MYLO_MAGIC_PARTITIONS); - for (i = 0; i < fw_num_partitions; i++) { - struct mylo_partition *mp; - struct fw_part *fp; - - mp = &p.partitions[i]; - fp = &fw_parts[i]; - mp->flags = HOST_TO_LE16(fp->mylo.flags); - mp->type = HOST_TO_LE16(PARTITION_TYPE_USED); - mp->addr = HOST_TO_LE32(fp->mylo.addr); - mp->size = HOST_TO_LE32(fp->mylo.size); - mp->param = HOST_TO_LE32(fp->mylo.param); - - memcpy(part_names[i], fp->name, PART_NAME_LEN); - } - - ret = write_out_data(outfile, (uint8_t *)&p, sizeof(p), crc); - if (ret) - return ret; - - ret = write_out_data(outfile, (uint8_t *)part_names, sizeof(part_names), - crc); - return ret; -} - - -int -write_out_blocks(FILE *outfile, uint32_t *crc) -{ - struct mylo_fw_blockdesc desc; - struct fw_block *b; - uint32_t dlen; - int i; - - /* - * if at least one partition specified, write out block descriptor - * for the partition table - */ - if (fw_num_partitions > 0) { - desc.type = HOST_TO_LE32(FW_DESC_TYPE_USED); - desc.addr = HOST_TO_LE32(board->part_offset); - desc.dlen = HOST_TO_LE32(sizeof(struct mylo_partition_table) + - (MYLO_MAX_PARTITIONS * PART_NAME_LEN)); - desc.blen = HOST_TO_LE32(board->part_size); - - if (write_out_desc(outfile, &desc, crc) != 0) - return -1; - } - - /* - * write out block descriptors for each files - */ - for (i = 0; i < fw_num_blocks; i++) { - b = &fw_blocks[i]; - - /* detect block size */ - dlen = b->size; - if ((b->flags & BLOCK_FLAG_HAVEHDR) != 0) { - dlen += sizeof(struct mylo_partition_header); - } - - /* round up to 4 bytes */ - dlen = ALIGN(dlen, 4); - - /* setup the descriptor */ - desc.type = HOST_TO_LE32(FW_DESC_TYPE_USED); - desc.addr = HOST_TO_LE32(b->addr); - desc.dlen = HOST_TO_LE32(dlen); - desc.blen = HOST_TO_LE32(b->blocklen); - - if (write_out_desc(outfile, &desc, crc) != 0) - return -1; - } - - /* - * write out the null block descriptor - */ - memset(&desc, 0, sizeof(desc)); - if (write_out_desc(outfile, &desc, crc) != 0) - return -1; - - if (write_out_partitions(outfile, crc) != 0) - return -1; - - /* - * write out data for each blocks - */ - for (i = 0; i < fw_num_blocks; i++) { - b = &fw_blocks[i]; - if (write_out_file(outfile, b, crc) != 0) - return -1; - } - - return 0; -} - - -/* - * argument parsing - */ -int -parse_arg(char *arg, char *buf, char *argv[]) -{ - int res = 0; - size_t argl; - char *tok; - char **ap = &buf; - int i; - - if ((arg == NULL)) { - /* invalid argument string */ - return -1; - } - - argl = strlen(arg); - if (argl == 0) { - /* no arguments */ - return res; - } - - if (argl >= MAX_ARG_LEN) { - /* argument is too long */ - argl = MAX_ARG_LEN-1; - } - - memset(argv, 0, MAX_ARG_COUNT * sizeof(void *)); - memcpy(buf, arg, argl); - buf[argl] = '\0'; - - for (i = 0; i < MAX_ARG_COUNT; i++) { - tok = strsep(ap, ":"); - if (tok == NULL) { - break; - } -#if 0 - else if (tok[0] == '\0') { - break; - } -#endif - argv[i] = tok; - res++; - } - - return res; -} - - -int -required_arg(char c, char *arg) -{ - if ((optarg != NULL) && (*arg == '-')){ - errmsg(0,"option %c requires an argument\n", c); - return -1; - } - - return 0; -} - - -int -is_empty_arg(char *arg) -{ - int ret = 1; - if (arg != NULL) { - if (*arg) ret = 0; - }; - return ret; -} - - -int -parse_opt_flags(char ch, char *arg) -{ - if (required_arg(ch, arg)) { - goto err_out; - } - - if (str2u32(arg, &fw_header.flags) != 0) { - errmsg(0,"invalid firmware flags: %s", arg); - goto err_out; - } - - dbgmsg(1, "firmware flags set to %X bytes", fw_header.flags); - - return 0; - -err_out: - return -1; -} - - -int -parse_opt_size(char ch, char *arg) -{ - if (required_arg(ch, arg)) { - goto err_out; - } - - if (str2u32(arg, &flash_size) != 0) { - errmsg(0,"invalid flash size: %s", arg); - goto err_out; - } - - dbgmsg(1, "flash size set to %d bytes", flash_size); - - return 0; - -err_out: - return -1; -} - - -int -parse_opt_id(char ch, char *arg) -{ - char buf[MAX_ARG_LEN]; - char *argv[MAX_ARG_COUNT]; - char *p; - - if (required_arg(ch, arg)) { - goto err_out; - } - - parse_arg(arg, buf, argv); - - /* processing vendor ID*/ - p = argv[0]; - if (is_empty_arg(p)) { - errmsg(0,"vendor id is missing from -%c %s",ch, arg); - goto err_out; - } else if (str2u16(p, &fw_header.vid) != 0) { - errmsg(0,"invalid vendor id: %s", p); - goto err_out; - } - - dbgmsg(1, "vendor id is set to 0x%04X", fw_header.vid); - - /* processing device ID*/ - p = argv[1]; - if (is_empty_arg(p)) { - errmsg(0,"device id is missing from -%c %s",ch, arg); - goto err_out; - } else if (str2u16(p, &fw_header.did) != 0) { - errmsg(0,"invalid device id: %s", p); - goto err_out; - } - - dbgmsg(1, "device id is set to 0x%04X", fw_header.did); - - /* processing sub vendor ID*/ - p = argv[2]; - if (is_empty_arg(p)) { - fw_header.svid = fw_header.vid; - } else if (str2u16(p, &fw_header.svid) != 0) { - errmsg(0,"invalid sub vendor id: %s", p); - goto err_out; - } - - dbgmsg(1, "sub vendor id is set to 0x%04X", fw_header.svid); - - /* processing device ID*/ - p = argv[3]; - if (is_empty_arg(p)) { - fw_header.sdid = fw_header.did; - } else if (str2u16(p, &fw_header.sdid) != 0) { - errmsg(0,"invalid sub device id: %s", p); - goto err_out; - } - - dbgmsg(1, "sub device id is set to 0x%04X", fw_header.sdid); - - /* processing revision */ - p = argv[4]; - if (is_empty_arg(p)) { - fw_header.rev = 0; - } else if (str2u32(arg, &fw_header.rev) != 0) { - errmsg(0,"invalid revision number: %s", p); - goto err_out; - } - - dbgmsg(1, "board revision is set to 0x%08X", fw_header.rev); - - return 0; - -err_out: - return -1; -} - - -int -parse_opt_block(char ch, char *arg) -{ - char buf[MAX_ARG_LEN]; - char *argv[MAX_ARG_COUNT]; - int argc; - struct fw_block *b; - char *p; - - if (required_arg(ch, arg)) { - goto err_out; - } - - if (fw_num_blocks >= MAX_FW_BLOCKS) { - errmsg(0,"too many blocks specified"); - goto err_out; - } - - argc = parse_arg(arg, buf, argv); - dbgmsg(1,"processing block option %s, count %d", arg, argc); - - b = &fw_blocks[fw_num_blocks++]; - - /* processing block address */ - p = argv[0]; - if (is_empty_arg(p)) { - errmsg(0,"no block address specified in %s", arg); - goto err_out; - } else if (str2u32(p, &b->addr) != 0) { - errmsg(0,"invalid block address: %s", p); - goto err_out; - } - - /* processing block length */ - p = argv[1]; - if (is_empty_arg(p)) { - errmsg(0,"no block length specified in %s", arg); - goto err_out; - } else if (str2u32(p, &b->blocklen) != 0) { - errmsg(0,"invalid block length: %s", p); - goto err_out; - } - - if (argc < 3) { - dbgmsg(1,"empty block %s", arg); - goto success; - } - - /* processing flags */ - p = argv[2]; - if (is_empty_arg(p) == 0) { - for ( ; *p != '\0'; p++) { - switch (*p) { - case 'h': - b->flags |= BLOCK_FLAG_HAVEHDR; - break; - default: - errmsg(0, "invalid block flag \"%c\"", *p); - goto err_out; - } - } - } - - /* processing file name */ - p = argv[3]; - if (is_empty_arg(p)) { - errmsg(0,"file name missing in %s", arg); - goto err_out; - } - - b->name = strdup(p); - if (b->name == NULL) { - errmsg(0,"not enough memory"); - goto err_out; - } - -success: - - return 0; - -err_out: - return -1; -} - - -int -parse_opt_partition(char ch, char *arg) -{ - char buf[MAX_ARG_LEN]; - char *argv[MAX_ARG_COUNT]; - char *p; - struct mylo_partition *part; - struct fw_part *fp; - - if (required_arg(ch, arg)) { - goto err_out; - } - - if (fw_num_partitions >= MYLO_MAX_PARTITIONS) { - errmsg(0, "too many partitions specified"); - goto err_out; - } - - fp = &fw_parts[fw_num_partitions++]; - part = &fp->mylo; - - parse_arg(arg, buf, argv); - - /* processing partition address */ - p = argv[0]; - if (is_empty_arg(p)) { - errmsg(0,"partition address missing in -%c %s",ch, arg); - goto err_out; - } else if (str2u32(p, &part->addr) != 0) { - errmsg(0,"invalid partition address: %s", p); - goto err_out; - } - - /* processing partition size */ - p = argv[1]; - if (is_empty_arg(p)) { - errmsg(0,"partition size missing in -%c %s",ch, arg); - goto err_out; - } else if (str2u32(p, &part->size) != 0) { - errmsg(0,"invalid partition size: %s", p); - goto err_out; - } - - /* processing partition flags */ - p = argv[2]; - if (is_empty_arg(p) == 0) { - for ( ; *p != '\0'; p++) { - switch (*p) { - case 'a': - part->flags |= PARTITION_FLAG_ACTIVE; - break; - case 'p': - part->flags |= PARTITION_FLAG_PRELOAD; - break; - case 'l': - part->flags |= PARTITION_FLAG_LZMA; - break; - case 'h': - part->flags |= PARTITION_FLAG_HAVEHDR; - break; - default: - errmsg(0, "invalid partition flag \"%c\"", *p); - goto err_out; - } - } - } - - /* processing partition parameter */ - p = argv[3]; - if (is_empty_arg(p)) { - /* set default partition parameter */ - part->param = 0; - } else if (str2u32(p, &part->param) != 0) { - errmsg(0,"invalid partition parameter: %s", p); - goto err_out; - } - - p = argv[4]; - if (is_empty_arg(p)) { - /* set default partition parameter */ - fp->name[0] = '\0'; - } else { - strncpy(fp->name, p, PART_NAME_LEN); - } - -#if 1 - if (part->size == 0) { - part->size = flash_size - part->addr; - } - - /* processing file parameter */ - p = argv[5]; - if (is_empty_arg(p) == 0) { - struct fw_block *b; - - if (fw_num_blocks == MAX_FW_BLOCKS) { - errmsg(0,"too many blocks specified", p); - goto err_out; - } - b = &fw_blocks[fw_num_blocks++]; - b->name = strdup(p); - b->addr = part->addr; - b->blocklen = part->size; - if (part->flags & PARTITION_FLAG_HAVEHDR) { - b->flags |= BLOCK_FLAG_HAVEHDR; - } - } -#endif - - return 0; - -err_out: - return -1; -} - - -int -parse_opt_board(char ch, char *arg) -{ - if (required_arg(ch, arg)) { - goto err_out; - } - - board = find_board(arg); - if (board == NULL){ - errmsg(0,"invalid/unknown board specified: %s", arg); - goto err_out; - } - - fw_header.vid = board->vid; - fw_header.did = board->did; - fw_header.svid = board->svid; - fw_header.sdid = board->sdid; - - flash_size = board->flash_size; - - return 0; - -err_out: - return -1; -} - - -int -parse_opt_rev(char ch, char *arg) -{ - if (required_arg(ch, arg)) { - return -1; - } - - if (str2u32(arg, &fw_header.rev) != 0) { - errmsg(0,"invalid revision number: %s", arg); - return -1; - } - - return 0; -} - - -/* - * main - */ -int -main(int argc, char *argv[]) -{ - int optinvalid = 0; /* flag for invalid option */ - int c; - int res = EXIT_FAILURE; - - FILE *outfile; - uint32_t crc; - - progname=basename(argv[0]); - - memset(&fw_header, 0, sizeof(fw_header)); - - /* init header defaults */ - fw_header.vid = VENID_COMPEX; - fw_header.did = DEVID_COMPEX_WP54G; - fw_header.svid = VENID_COMPEX; - fw_header.sdid = DEVID_COMPEX_WP54G; - fw_header.fwhi = 0x20000; - fw_header.fwlo = 0x20000; - fw_header.flags = 0; - - opterr = 0; /* could not print standard getopt error messages */ - while ((c = getopt(argc, argv, "b:B:f:hi:p:r:s:v")) != -1) { - optinvalid = 0; - switch (c) { - case 'b': - optinvalid = parse_opt_block(c,optarg); - break; - case 'B': - optinvalid = parse_opt_board(c,optarg); - break; - case 'f': - optinvalid = parse_opt_flags(c,optarg); - break; - case 'h': - usage(EXIT_SUCCESS); - break; - case 'i': - optinvalid = parse_opt_id(c,optarg); - break; - case 'p': - optinvalid = parse_opt_partition(c,optarg); - break; - case 'r': - optinvalid = parse_opt_rev(c,optarg); - break; - case 's': - optinvalid = parse_opt_size(c,optarg); - break; - case 'v': - verblevel++; - break; - default: - optinvalid = 1; - break; - } - if (optinvalid != 0 ){ - errmsg(0, "invalid option: -%c", optopt); - goto out; - } - } - - if (optind == argc) { - errmsg(0, "no output file specified"); - goto out; - } - - ofname = argv[optind++]; - - if (optind < argc) { - errmsg(0, "invalid option: %s", argv[optind]); - goto out; - } - - if (!board) { - errmsg(0, "no board specified"); - goto out; - } - - if (flash_size == 0) { - errmsg(0, "no flash size specified"); - goto out; - } - - if (process_files() != 0) { - goto out; - } - - if (process_partitions() != 0) { - goto out; - } - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - errmsg(1, "could not open \"%s\" for writing", ofname); - goto out; - } - - crc = 0; - init_crc_table(); - - if (write_out_header(outfile, &crc) != 0) - goto out_flush; - - if (write_out_blocks(outfile, &crc) != 0) - goto out_flush; - - fw_header.crc = crc; - if (write_out_header(outfile, NULL) != 0) - goto out_flush; - - dbgmsg(1,"Firmware file %s completed.", ofname); - - res = EXIT_SUCCESS; - -out_flush: - fflush(outfile); - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } -out: - return res; -} diff --git a/tools/firmware-utils/src/mkplanexfw.c b/tools/firmware-utils/src/mkplanexfw.c deleted file mode 100644 index c86b6b5b88..0000000000 --- a/tools/firmware-utils/src/mkplanexfw.c +++ /dev/null @@ -1,263 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include "sha1.h" - -#if (__BYTE_ORDER == __BIG_ENDIAN) -# define HOST_TO_BE32(x) (x) -# define BE32_TO_HOST(x) (x) -#else -# define HOST_TO_BE32(x) bswap_32(x) -# define BE32_TO_HOST(x) bswap_32(x) -#endif - - -struct planex_hdr { - uint8_t sha1sum[20]; - char version[8]; - uint8_t unk1[2]; - uint32_t datalen; -} __attribute__ ((packed)); - -struct board_info { - char *id; - uint32_t seed; - uint8_t unk[2]; - uint32_t datalen; -}; - -/* - * Globals - */ -static char *ifname; -static char *progname; -static char *ofname; -static char *version = "1.00.00"; - -static char *board_id; -static struct board_info *board; - -static struct board_info boards[] = { - { - .id = "MZK-W04NU", - .seed = 2, - .unk = {0x04, 0x08}, - .datalen = 0x770000, - }, { - .id = "MZK-W300NH", - .seed = 4, - .unk = {0x00, 0x00}, - .datalen = 0x770000, - }, { - /* terminating entry */ - } -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -static struct board_info *find_board(char *id) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->id != NULL; board++){ - if (strcasecmp(id, board->id) == 0) { - ret = board; - break; - } - }; - - return ret; -} - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -v <version> set image version to <version>\n" -" -h show this screen\n" - ); - - exit(status); -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int buflen; - int err; - struct stat st; - char *buf; - struct planex_hdr *hdr; - sha1_context ctx; - uint32_t seed; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "B:i:o:v:h"); - if (c == -1) - break; - - switch (c) { - case 'B': - board_id = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'v': - version = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (board_id == NULL) { - ERR("no board specified"); - goto err; - } - - board = find_board(board_id); - if (board == NULL) { - ERR("unknown board '%s'", board_id); - goto err; - }; - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - if (st.st_size > board->datalen) { - ERR("file '%s' is too big - max size: 0x%08X (exceeds %lu bytes)\n", - ifname, board->datalen, st.st_size - board->datalen); - goto err; - } - - buflen = board->datalen + 0x10000; - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - memset(buf, 0xff, buflen); - hdr = (struct planex_hdr *)buf; - - hdr->datalen = HOST_TO_BE32(board->datalen); - hdr->unk1[0] = board->unk[0]; - hdr->unk1[1] = board->unk[1]; - - snprintf(hdr->version, sizeof(hdr->version), "%s", version); - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - errno = 0; - fread(buf + sizeof(*hdr), st.st_size, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto err_close_in; - } - - seed = HOST_TO_BE32(board->seed); - sha1_starts(&ctx); - sha1_update(&ctx, (uchar *) &seed, sizeof(seed)); - sha1_update(&ctx, buf + sizeof(*hdr), board->datalen); - sha1_finish(&ctx, hdr->sha1sum); - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto err_close_in; - } - - errno = 0; - fwrite(buf, buflen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto err_close_out; - } - - res = EXIT_SUCCESS; - - fflush(outfile); - - err_close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } - - err_close_in: - fclose(infile); - - err_free: - free(buf); - - err: - return res; -} - diff --git a/tools/firmware-utils/src/mkporayfw.c b/tools/firmware-utils/src/mkporayfw.c deleted file mode 100644 index 9efa310629..0000000000 --- a/tools/firmware-utils/src/mkporayfw.c +++ /dev/null @@ -1,787 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Builder/viewer/extractor utility for Poray firmware image files - * - * Copyright (C) 2013 Michel Stempin <michel.stempin@wanadoo.fr> - * Copyright (C) 2013 Felix Kaechele <felix@fetzig.org> - * Copyright (C) 2013 <admin@openschemes.com> - * - * This tool is based on: - * TP-Link firmware upgrade tool. - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * Itself based on: - * TP-Link WR941 V2 firmware checksum fixing tool. - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> -#include <libgen.h> -#include <getopt.h> -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> -#include <arpa/inet.h> -#include <netinet/in.h> - -#if (__BYTE_ORDER == __BIG_ENDIAN) -# define HOST_TO_BE32(x) (x) -# define BE32_TO_HOST(x) (x) -# define HOST_TO_LE32(x) bswap_32(x) -# define LE32_TO_HOST(x) bswap_32(x) -#else -# define HOST_TO_BE32(x) bswap_32(x) -# define BE32_TO_HOST(x) bswap_32(x) -# define HOST_TO_LE32(x) (x) -# define LE32_TO_HOST(x) (x) -#endif - -/* Fixed header flags */ -#define HEADER_FLAGS 0x020e0000 - -/* Recognized Hardware ID magic */ -#define HWID_HAME_MPR_A1_L8 0x32473352 -#define HWID_PORAY_R50B 0x31353033 -#define HWID_PORAY_R50D 0x33353033 -#define HWID_PORAY_R50E 0x34353033 -#define HWID_PORAY_M3 0x31353335 -#define HWID_PORAY_M4 0x32353335 -#define HWID_PORAY_Q3 0x33353335 -#define HWID_PORAY_X5_X6 0x35353335 -#define HWID_PORAY_X8 0x36353335 -#define HWID_PORAY_X1 0x38353335 -#define HWID_NEXX_WT1520 0x30353332 -#define HWID_NEXX_WT3020 0x30323033 -#define HWID_A5_V11 0x32473352 - -/* Recognized XOR obfuscation keys */ -#define KEY_HAME 0 -#define KEY_PORAY_1 1 -#define KEY_PORAY_2 2 -#define KEY_PORAY_3 3 -#define KEY_PORAY_4 4 -#define KEY_NEXX_1 5 -#define KEY_NEXX_2 6 -#define KEY_A5_V11 7 - -/* XOR key length */ -#define KEY_LEN 15 - -struct file_info { - char *file_name; /* Name of the file */ - uint32_t file_size; /* Length of the file */ -}; - -struct fw_header { - uint32_t hw_id; /* Hardware id */ - uint32_t firmware_len; /* Firmware data length */ - uint32_t flags; /* Header flags */ - uint8_t pad[16]; -} __attribute__ ((packed)); - -struct flash_layout { - char *id; - uint32_t fw_max_len; -}; - -struct board_info { - char *id; - uint32_t hw_id; - char *layout_id; - uint32_t key; -}; - -/* - * Globals - */ -static char *ofname; -static char *progname; - -static char *board_id; -static struct board_info *board; -static char *layout_id; -static struct flash_layout *layout; -static char *opt_hw_id; -static uint32_t hw_id; -static struct file_info firmware_info; -static uint32_t firmware_len = 0; - -static int inspect = 0; -static int extract = 0; - -static uint8_t key[][KEY_LEN] = { - {0xC8, 0x3C, 0x3A, 0x93, 0xA2, 0x95, 0xC3, 0x63, 0x48, 0x45, 0x58, 0x09, 0x12, 0x03, 0x08}, - {0x89, 0x6B, 0x5A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, - {0xC9, 0x1C, 0x3A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, - {0x19, 0x1B, 0x3A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, - {0x79, 0x7B, 0x7A, 0x93, 0x92, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0xE6, 0xC7}, - {0x19, 0x1C, 0x4A, 0x93, 0x96, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0x16, 0xC6}, - {0x39, 0x1C, 0x4A, 0x93, 0x96, 0x95, 0xC3, 0x63, 0xD0, 0xA3, 0x9C, 0x92, 0x2E, 0x16, 0xC6}, - {0xC8, 0x3C, 0x3A, 0x93, 0xA2, 0x95, 0xC3, 0x63, 0x48, 0x45, 0x58, 0x09, 0x20, 0x11, 0x08}, -}; - -static struct flash_layout layouts[] = { - { - .id = "4M", - .fw_max_len = 0x3c0000, - }, { - .id = "8M", - .fw_max_len = 0x7c0000, - }, { - /* terminating entry */ - } -}; - -static struct board_info boards[] = { - { - .id = "A5-V11", - .hw_id = HWID_A5_V11, - .layout_id = "4M", - .key = KEY_A5_V11, - }, { - .id = "MPR-A1", - .hw_id = HWID_HAME_MPR_A1_L8, - .layout_id = "4M", - .key = KEY_HAME, - }, { - .id = "MPR-L8", - .hw_id = HWID_HAME_MPR_A1_L8, - .layout_id = "4M", - .key = KEY_HAME, - }, { - .id = "R50B", - .hw_id = HWID_PORAY_R50B, - .layout_id = "4M", - .key = KEY_PORAY_2, - }, { - .id = "R50D", - .hw_id = HWID_PORAY_R50D, - .layout_id = "4M", - .key = KEY_PORAY_3, - }, { - .id = "R50E", - .hw_id = HWID_PORAY_R50E, - .layout_id = "4M", - .key = KEY_PORAY_4, - }, { - .id = "M3", - .hw_id = HWID_PORAY_M3, - .layout_id = "4M", - .key = KEY_PORAY_1, - }, { - .id = "M4", - .hw_id = HWID_PORAY_M4, - .layout_id = "4M", - .key = KEY_PORAY_1, - }, { - .id = "Q3", - .hw_id = HWID_PORAY_Q3, - .layout_id = "4M", - .key = KEY_PORAY_1, - }, { - .id = "X5 or X6", - .hw_id = HWID_PORAY_X5_X6, - .layout_id = "8M", - .key = KEY_PORAY_1, - }, { - .id = "X5", - .hw_id = HWID_PORAY_X5_X6, - .layout_id = "8M", - .key = KEY_PORAY_1, - }, { - .id = "X6", - .hw_id = HWID_PORAY_X5_X6, - .layout_id = "8M", - .key = KEY_PORAY_1, - }, { - .id = "X8", - .hw_id = HWID_PORAY_X8, - .layout_id = "8M", - .key = KEY_PORAY_1, - }, { - .id = "X1", - .hw_id = HWID_PORAY_X1, - .layout_id = "8M", - .key = KEY_PORAY_1, - }, { - .id = "WT1520", - .hw_id = HWID_NEXX_WT1520, - .layout_id = "4M", - .key = KEY_NEXX_1, - }, { - .id = "WT1520", - .hw_id = HWID_NEXX_WT1520, - .layout_id = "8M", - .key = KEY_NEXX_1, - }, { - .id = "WT3020", - .hw_id = HWID_NEXX_WT3020, - .layout_id = "4M", - .key = KEY_NEXX_2, - }, { - .id = "WT3020", - .hw_id = HWID_NEXX_WT3020, - .layout_id = "8M", - .key = KEY_NEXX_2, - }, { - - - - - /* terminating entry */ - } -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ":%s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -/* - * Find a board by its name - */ -static struct board_info *find_board(char *id) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->id != NULL; board++){ - if (strcasecmp(id, board->id) == 0) { - ret = board; - break; - } - }; - - return ret; -} - -/* - * Find a board by its hardware ID - */ -static struct board_info *find_board_by_hwid(uint32_t hw_id) -{ - struct board_info *board; - - for (board = boards; board->id != NULL; board++) { - if (hw_id == board->hw_id) - return board; - }; - - return NULL; -} - -/* - * Find a Flash memory layout by its name - */ -static struct flash_layout *find_layout(char *id) -{ - struct flash_layout *ret; - struct flash_layout *l; - - ret = NULL; - for (l = layouts; l->id != NULL; l++){ - if (strcasecmp(id, l->id) == 0) { - ret = l; - break; - } - }; - - return ret; -} - -/* - * Display usage - */ -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -H <hwid> use hardware id specified with <hwid>\n" -" -F <id> use flash layout specified with <id>\n" -" -f <file> read firmware image from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -i inspect given firmware file (requires -f)\n" -" -x extract combined kernel and rootfs while inspecting (implies -i)\n" -" -h show this screen\n" - ); - - exit(status); -} - -/* - * Get file statistics - */ -static int get_file_stat(struct file_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) { - return 0; - } - res = stat(fdata->file_name, &st); - if (res){ - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - return 0; -} - -/* - * Read file into buffer - */ -static int read_to_buf(struct file_info *fdata, uint8_t *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(fdata->file_name, "rb"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - errno = 0; - fread(buf, fdata->file_size, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - - out_close: - fclose(f); - out: - return ret; -} - -/* - * Check command line options - */ -static int check_options(void) -{ - int ret; - - if (firmware_info.file_name == NULL) { - ERR("no firmware image specified"); - return -1; - } - - ret = get_file_stat(&firmware_info); - if (ret) - return ret; - - if (inspect) - return 0; - - if (board_id == NULL && opt_hw_id == NULL) { - ERR("either board or hardware id must be specified"); - return -1; - } - - if (board_id) { - board = find_board(board_id); - if (board == NULL) { - ERR("unknown/unsupported board id \"%s\"", board_id); - return -1; - } - if (layout_id == NULL) { - layout_id = board->layout_id; - } - hw_id = board->hw_id; - } else { - hw_id = strtoul(opt_hw_id, NULL, 0); - board = find_board_by_hwid(hw_id); - if (layout_id == NULL) { - layout_id = board->layout_id; - } - } - - layout = find_layout(layout_id); - if (layout == NULL) { - ERR("unknown flash layout \"%s\"", layout_id); - return -1; - } - - firmware_len = firmware_info.file_size; - - if (firmware_info.file_size > - layout->fw_max_len - sizeof (struct fw_header)) { - ERR("firmware image is too big"); - return -1; - } - - if (ofname == NULL) { - ERR("no output file specified"); - return -1; - } - return 0; -} - -/* - * Fill in firmware header - */ -static void fill_header(uint8_t *buf) -{ - struct fw_header *hdr = (struct fw_header *) buf; - - memset(hdr, 0, sizeof (struct fw_header)); - hdr->hw_id = HOST_TO_LE32(hw_id); - hdr->firmware_len = HOST_TO_LE32(firmware_len); - hdr->flags = HOST_TO_LE32(HEADER_FLAGS); -} - -/* - * Compute firmware checksum - */ -static uint16_t checksum_fw(uint8_t *data, int len) -{ - int i; - int32_t checksum = 0; - - for (i = 0; i < len - 1; i += 2) { - checksum += (data[i + 1] << 8) | data[i]; - } - if (i < len) { - checksum += data[i]; - } - checksum = checksum + (checksum >> 16) + 0xffff; - checksum = ~(checksum + (checksum >> 16)) & 0xffff; - return (uint16_t) checksum; -} - -/* - * (De)obfuscate firmware using an XOR operation with a fixed length key - */ -static void xor_fw(uint8_t *data, int len) -{ - int i; - - for (i = 0; i <= len; i++) { - data[i] ^= key[board->key][i % KEY_LEN]; - } -} - -/* - * Write firmware to file - */ -static int write_fw(uint8_t *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "wb"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - - out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); - } - out: - return ret; -} - -/* - * Build firmware file - */ -static int build_fw(void) -{ - int buflen; - uint8_t *buf, *p; - int ret = EXIT_FAILURE; - int writelen = 0; - uint16_t checksum; - - buflen = layout->fw_max_len; - - buf = (uint8_t *) malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - memset(buf, 0xff, buflen); - p = buf + sizeof (struct fw_header); - ret = read_to_buf(&firmware_info, p); - if (ret) { - goto out_free_buf; - } - writelen = sizeof (struct fw_header) + firmware_len + 2; - - /* Fill in header */ - fill_header(buf); - - /* Compute firmware checksum */ - checksum = checksum_fw(buf + sizeof (struct fw_header), firmware_len); - - /* Cannot use network order function because checksum is not word-aligned */ - buf[writelen - 1] = checksum >> 8; - buf[writelen - 2] = checksum & 0xff; - - /* XOR obfuscate firmware */ - xor_fw(buf + sizeof (struct fw_header), firmware_len + 2); - - /* Write firmware file */ - ret = write_fw(buf, writelen); - if (ret) { - goto out_free_buf; - } - ret = EXIT_SUCCESS; - - out_free_buf: - free(buf); - out: - return ret; -} - -/* Helper functions to inspect_fw() representing different output formats */ -static inline void inspect_fw_pstr(char *label, char *str) -{ - printf("%-23s: %s\n", label, str); -} - -static inline void inspect_fw_phex(char *label, uint32_t val) -{ - printf("%-23s: 0x%08x\n", label, val); -} - -static inline void inspect_fw_phexpost(char *label, - uint32_t val, char *post) -{ - printf("%-23s: 0x%08x (%s)\n", label, val, post); -} - -static inline void inspect_fw_phexdef(char *label, - uint32_t val, uint32_t defval) -{ - printf("%-23s: 0x%08x ", label, val); - - if (val == defval) { - printf("(== OpenWrt default)\n"); - } else { - printf("(OpenWrt default: 0x%08x)\n", defval); - } -} - -static inline void inspect_fw_phexexp(char *label, - uint32_t val, uint32_t expval) -{ - printf("%-23s: 0x%08x ", label, val); - - if (val == expval) { - printf("(ok)\n"); - } else { - printf("(expected: 0x%08x)\n", expval); - } -} - -static inline void inspect_fw_phexdec(char *label, uint32_t val) -{ - printf("%-23s: 0x%08x / %8u bytes\n", label, val, val); -} - -static inline void inspect_fw_pchecksum(char *label, - uint16_t val, uint16_t expval) -{ - printf("%-23s: 0x%04x ", label, val); - if (val == expval) { - printf("(ok)\n"); - } else { - printf("(expected: 0x%04x)\n", expval); - } -} - -static int inspect_fw(void) -{ - uint8_t *buf; - struct fw_header *hdr; - int ret = EXIT_FAILURE; - uint16_t computed_checksum, file_checksum; - - buf = (uint8_t *) malloc(firmware_info.file_size); - if (!buf) { - ERR("no memory for buffer!\n"); - goto out; - } - - ret = read_to_buf(&firmware_info, buf); - if (ret) { - goto out_free_buf; - } - hdr = (struct fw_header *)buf; - - inspect_fw_pstr("File name", firmware_info.file_name); - inspect_fw_phexdec("File size", firmware_info.file_size); - - printf("\n"); - - inspect_fw_phexdec("Header size", sizeof (struct fw_header)); - board = find_board_by_hwid(LE32_TO_HOST(hdr->hw_id)); - if (board) { - layout = find_layout(board->layout_id); - inspect_fw_phexpost("Hardware ID", - LE32_TO_HOST( hdr->hw_id), board->id); - } else { - inspect_fw_phexpost("Hardware ID", - LE32_TO_HOST(hdr->hw_id), "unknown"); - } - inspect_fw_phexdec("Firmware data length", - LE32_TO_HOST(hdr->firmware_len)); - - inspect_fw_phexexp("Flags", - LE32_TO_HOST(hdr->flags), HEADER_FLAGS); - printf("\n"); - - /* XOR unobfuscate firmware */ - xor_fw(buf + sizeof (struct fw_header), LE32_TO_HOST(hdr->firmware_len) + 2); - - /* Compute firmware checksum */ - computed_checksum = checksum_fw(buf + sizeof (struct fw_header), LE32_TO_HOST(hdr->firmware_len)); - - /* Cannot use network order function because checksum is not word-aligned */ - file_checksum = (buf[firmware_info.file_size - 1] << 8) | buf[firmware_info.file_size - 2]; - inspect_fw_pchecksum("Firmware checksum", computed_checksum, file_checksum); - - /* Verify checksum */ - if (computed_checksum != file_checksum) { - ret = -1; - ERR("checksums do not match"); - goto out_free_buf; - } - - printf("\n"); - - if (extract) { - FILE *fp; - char *filename; - - if (ofname == NULL) { - filename = malloc(strlen(firmware_info.file_name) + 10); - sprintf(filename, "%s-firmware", firmware_info.file_name); - } else { - filename = ofname; - } - printf("Extracting firmware to \"%s\"...\n", filename); - fp = fopen(filename, "wb"); - if (fp) { - if (!fwrite(buf + sizeof (struct fw_header), - LE32_TO_HOST(hdr->firmware_len), 1, fp)) { - ERRS("error in fwrite(): %s", strerror(errno)); - } - fclose(fp); - } else { - ERRS("error in fopen(): %s", strerror(errno)); - } - if (ofname == NULL) { - free(filename); - } - printf("\n"); - } - - out_free_buf: - free(buf); - out: - return ret; -} - -/* - * Main entry point - */ -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - - int c; - - while ((c = getopt(argc, argv, "B:H:F:f:o:ixh")) != -1) { - switch (c) { - case 'B': - board_id = optarg; - break; - case 'H': - opt_hw_id = optarg; - break; - case 'F': - layout_id = optarg; - break; - case 'f': - firmware_info.file_name = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'i': - inspect = 1; - break; - case 'x': - inspect = 1; - extract = 1; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) { - goto out; - } - if (!inspect) { - ret = build_fw(); - } else { - ret = inspect_fw(); - } - - out: - return ret; -} diff --git a/tools/firmware-utils/src/mkrasimage.c b/tools/firmware-utils/src/mkrasimage.c deleted file mode 100644 index 636e90a1cd..0000000000 --- a/tools/firmware-utils/src/mkrasimage.c +++ /dev/null @@ -1,461 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * --- ZyXEL header format --- - * Original Version by Benjamin Berg <benjamin@sipsolutions.net> - * C implementation based on generation-script by Christian Lamparter <chunkeey@gmail.com> - * - * The firmware image prefixed with a header (which is written into the MTD device). - * The header is one erase block (~64KiB) in size, but the checksum only convers the - * first 2KiB. Padding is 0xff. All integers are in big-endian. - * - * The checksum is always a 16-Bit System V checksum (sum -s) stored in a 32-Bit integer. - * - * 4 bytes: checksum of the rootfs image - * 4 bytes: length of the contained rootfs image file (big endian) - * 32 bytes: Firmware Version string (NUL terminated, 0xff padded) - * 4 bytes: checksum over the header partition (big endian - see below) - * 64 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded) - * 4 bytes: checksum of the kernel partition - * 4 bytes: length of the contained kernel image file (big endian) - * rest: 0xff padding (To erase block size) - * - * The kernel partition checksum and length is not used for every device. - * If it's notused, pad those 8 bytes with 0xFF. - * - * The checksums are calculated by adding up all bytes and if a 16bit - * overflow occurs, one is added and the sum is masked to 16 bit: - * csum = csum + databyte; if (csum > 0xffff) { csum += 1; csum &= 0xffff }; - * Should the file have an odd number of bytes then the byte len-0x800 is - * used additionally. - * - * The checksum for the header is calculated over the first 2048 bytes with - * the rootfs image checksum as the placeholder during calculation. - */ -#include <fcntl.h> -#include <getopt.h> -#include <libgen.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> - -#include <sys/mman.h> -#include <sys/stat.h> - -#include <arpa/inet.h> - -#define VERSION_STRING_LEN 31 -#define ROOTFS_HEADER_LEN 40 - -#define KERNEL_HEADER_LEN 8 - -#define BOARD_NAME_LEN 64 -#define BOARD_HEADER_LEN 68 - -#define HEADER_PARTITION_CALC_LENGTH 2048 -#define HEADER_PARTITION_LENGTH 0x10000 - -struct file_info { - char *name; /* name of the file */ - char *data; /* file content */ - size_t size; /* length of the file */ -}; - -static char *progname; - -static char *board_name = 0; -static char *version_name = 0; -static unsigned int rootfs_size = 0; -static unsigned int header_length = HEADER_PARTITION_LENGTH; - -static struct file_info kernel = { NULL, NULL, 0 }; -static struct file_info rootfs = { NULL, NULL, 0 }; -static struct file_info rootfs_out = { NULL, NULL, 0 }; -static struct file_info out = { NULL, NULL, 0 }; - -#define ERR(fmt, ...) do { \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -void map_file(struct file_info *finfo) -{ - struct stat file_stat = {0}; - int fd; - - fd = open(finfo->name, O_RDONLY, (mode_t)0600); - if (fd == -1) { - ERR("Error while opening file %s.", finfo->name); - exit(EXIT_FAILURE); - } - - if (fstat(fd, &file_stat) == -1) { - ERR("Error getting file size for %s.", finfo->name); - exit(EXIT_FAILURE); - } - - finfo->size = file_stat.st_size; - finfo->data = mmap(0, finfo->size, PROT_READ, MAP_SHARED, fd, 0); - - if (finfo->data == MAP_FAILED) { - ERR("Error mapping file %s.", finfo->name); - exit(EXIT_FAILURE); - } - - close(fd); -} - -void unmap_file(struct file_info *finfo) -{ - if(munmap(finfo->data, finfo->size) == -1) { - ERR("Error unmapping file %s.", finfo->name); - exit(EXIT_FAILURE); - } -} - -void write_file(struct file_info *finfo) -{ - FILE *fout = fopen(finfo->name, "w"); - - fwrite(finfo->data, finfo->size, 1, fout); - - if (ferror(fout)) { - ERR("Wanted to write, but something went wrong."); - exit(EXIT_FAILURE); - } - - fclose(fout); -} - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, - "\n" - "Options:\n" - " -k <kernel> path for kernel image\n" - " -r <rootfs> path for rootfs image\n" - " -s <rfssize> size of output rootfs\n" - " -v <version> version string\n" - " -b <boardname> name of board to generate image for\n" - " -o <out_name> name of output image\n" - " -l <hdr_length> length of header, default 65536\n" - " -h show this screen\n" - ); - - exit(status); -} - -static int sysv_chksm(const unsigned char *data, int size) -{ - int r; - int checksum; - unsigned int s = 0; /* The sum of all the input bytes, modulo (UINT_MAX + 1). */ - - - for (int i = 0; i < size; i++) { - s += data[i]; - } - - r = (s & 0xffff) + ((s & 0xffffffff) >> 16); - checksum = (r & 0xffff) + (r >> 16); - - return checksum; -} - -static int zyxel_chksm(const unsigned char *data, int size) -{ - return htonl(sysv_chksm(data, size)); -} - -char *generate_rootfs_header(struct file_info filesystem, char *version) -{ - size_t version_string_length; - unsigned int chksm, size; - char *rootfs_header; - size_t ptr = 0; - - rootfs_header = malloc(ROOTFS_HEADER_LEN); - if (!rootfs_header) { - ERR("Couldn't allocate memory for rootfs header!"); - exit(EXIT_FAILURE); - } - - /* Prepare padding for firmware-version string here */ - memset(rootfs_header, 0xff, ROOTFS_HEADER_LEN); - - chksm = zyxel_chksm((const unsigned char *)filesystem.data, filesystem.size); - size = htonl(filesystem.size); - - /* 4 bytes: checksum of the rootfs image */ - memcpy(rootfs_header + ptr, &chksm, 4); - ptr += 4; - - /* 4 bytes: length of the contained rootfs image file (big endian) */ - memcpy(rootfs_header + ptr, &size, 4); - ptr += 4; - - /* 32 bytes: Firmware Version string (NUL terminated, 0xff padded) */ - version_string_length = strlen(version) <= VERSION_STRING_LEN ? strlen(version) : VERSION_STRING_LEN; - memcpy(rootfs_header + ptr, version, version_string_length); - ptr += version_string_length; - /* Add null-terminator */ - rootfs_header[ptr] = 0x0; - - return rootfs_header; -} - -char *generate_kernel_header(struct file_info kernel) -{ - unsigned int chksm, size; - char *kernel_header; - size_t ptr = 0; - - kernel_header = malloc(KERNEL_HEADER_LEN); - if (!kernel_header) { - ERR("Couldn't allocate memory for kernel header!"); - exit(EXIT_FAILURE); - } - - chksm = zyxel_chksm((const unsigned char *)kernel.data, kernel.size); - size = htonl(kernel.size); - - /* 4 bytes: checksum of the kernel image */ - memcpy(kernel_header + ptr, &chksm, 4); - ptr += 4; - - /* 4 bytes: length of the contained kernel image file (big endian) */ - memcpy(kernel_header + ptr, &size, 4); - - return kernel_header; -} - -unsigned int generate_board_header_checksum(char *kernel_hdr, char *rootfs_hdr, char *boardname) -{ - char *board_hdr_tmp; - unsigned int sum; - size_t ptr = 0; - - /* - * The checksum of the board header is calculated over the first 2048 bytes of - * the header partition with the rootfs checksum used as a placeholder for then - * board checksum we calculate in this step. The checksum gained from this step - * is then used for the final board header partition. - */ - - board_hdr_tmp = malloc(HEADER_PARTITION_CALC_LENGTH); - if (!board_hdr_tmp) { - ERR("Couldn't allocate memory for temporary board header!"); - exit(EXIT_FAILURE); - } - memset(board_hdr_tmp, 0xff, HEADER_PARTITION_CALC_LENGTH); - - /* 40 bytes: RootFS header */ - memcpy(board_hdr_tmp, rootfs_hdr, ROOTFS_HEADER_LEN); - ptr += ROOTFS_HEADER_LEN; - - /* 4 bytes: RootFS checksum (BE) as placeholder for board-header checksum */ - memcpy(board_hdr_tmp + ptr, rootfs_hdr, 4); - ptr += 4; - - /* 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded) */ - memcpy(board_hdr_tmp + ptr, boardname, strlen(boardname)); - ptr += strlen(boardname); - /* Add null-terminator */ - board_hdr_tmp[ptr] = 0x0; - ptr = ROOTFS_HEADER_LEN + 4 + BOARD_NAME_LEN; - - /* 8 bytes: Kernel header */ - if (kernel_hdr) - memcpy(board_hdr_tmp + ptr, kernel_hdr, 8); - - /* Calculate the checksum over the first 2048 bytes */ - sum = zyxel_chksm((const unsigned char *)board_hdr_tmp, HEADER_PARTITION_CALC_LENGTH); - free(board_hdr_tmp); - return sum; -} - -char *generate_board_header(char *kernel_hdr, char *rootfs_hdr, char *boardname) -{ - unsigned int board_checksum; - char *board_hdr; - - board_hdr = malloc(BOARD_HEADER_LEN); - if (!board_hdr) { - ERR("Couldn't allocate memory for board header!"); - exit(EXIT_FAILURE); - } - memset(board_hdr, 0xff, BOARD_HEADER_LEN); - - /* 4 bytes: checksum over the header partition (big endian) */ - board_checksum = generate_board_header_checksum(kernel_hdr, rootfs_hdr, boardname); - memcpy(board_hdr, &board_checksum, 4); - - /* 32 bytes: Model (e.g. "NBG6617", NUL termiated, 0xff padded) */ - memcpy(board_hdr + 4, boardname, strlen(boardname)); - board_hdr[4 + strlen(boardname)] = 0x0; - - return board_hdr; -} - -int build_image() -{ - char *rootfs_header = NULL; - char *kernel_header = NULL; - char *board_header = NULL; - - size_t ptr; - - /* Load files */ - if (kernel.name) - map_file(&kernel); - map_file(&rootfs); - - /* As ZyXEL Web-GUI only accept images with a rootfs equal or larger than the first firmware shipped - * for the device, we need to pad rootfs partition to this size. To perform further calculations, we - * decide the size of this part here. In case the rootfs we want to integrate in our image is larger, - * take it's size, otherwise the supplied size. - * - * Be careful! We rely on assertion of correct size to be performed beforehand. It is unknown if images - * with a to large rootfs are accepted or not. - */ - rootfs_out.size = rootfs_size < rootfs.size ? rootfs.size : rootfs_size; - - /* - * Allocate memory and copy input rootfs for temporary output rootfs. - * This is important as we have to generate the rootfs checksum over the - * entire rootfs partition. As we might have to pad the partition to allow - * for flashing via ZyXEL's Web-GUI, we prepare the rootfs partition for the - * output image here (and also use it for calculating the rootfs checksum). - * - * The roofs padding has to be done with 0x00. - */ - rootfs_out.data = calloc(rootfs_out.size, sizeof(char)); - memcpy(rootfs_out.data, rootfs.data, rootfs.size); - - /* Prepare headers */ - rootfs_header = generate_rootfs_header(rootfs_out, version_name); - if (kernel.name) - kernel_header = generate_kernel_header(kernel); - board_header = generate_board_header(kernel_header, rootfs_header, board_name); - - /* Prepare output file */ - out.size = header_length + rootfs_out.size; - if (kernel.name) - out.size += kernel.size; - out.data = malloc(out.size); - memset(out.data, 0xFF, out.size); - - /* Build output image */ - memcpy(out.data, rootfs_header, ROOTFS_HEADER_LEN); - memcpy(out.data + ROOTFS_HEADER_LEN, board_header, BOARD_HEADER_LEN); - if (kernel.name) - memcpy(out.data + ROOTFS_HEADER_LEN + BOARD_HEADER_LEN, kernel_header, KERNEL_HEADER_LEN); - ptr = header_length; - memcpy(out.data + ptr, rootfs_out.data, rootfs_out.size); - ptr += rootfs_out.size; - if (kernel.name) - memcpy(out.data + ptr, kernel.data, kernel.size); - - /* Write back output image */ - write_file(&out); - - /* Free allocated memory */ - if (kernel.name) - unmap_file(&kernel); - unmap_file(&rootfs); - free(out.data); - free(rootfs_out.data); - - free(rootfs_header); - if (kernel.name) - free(kernel_header); - free(board_header); - - return 0; -} - -int check_options() -{ - if (!rootfs.name) { - ERR("No rootfs filename supplied"); - return -2; - } - - if (!out.name) { - ERR("No output filename supplied"); - return -3; - } - - if (!board_name) { - ERR("No board-name supplied"); - return -4; - } - - if (!version_name) { - ERR("No version supplied"); - return -5; - } - - if (rootfs_size <= 0) { - ERR("Invalid rootfs size supplied"); - return -6; - } - - if (strlen(board_name) > 31) { - ERR("Board name is to long"); - return -7; - } - return 0; -} - -int main(int argc, char *argv[]) -{ - int ret; - progname = basename(argv[0]); - while (1) { - int c; - - c = getopt(argc, argv, "b:k:o:r:s:v:l:h"); - if (c == -1) - break; - - switch (c) { - case 'b': - board_name = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - case 'k': - kernel.name = optarg; - break; - case 'o': - out.name = optarg; - break; - case 'r': - rootfs.name = optarg; - break; - case 's': - sscanf(optarg, "%u", &rootfs_size); - break; - case 'v': - version_name = optarg; - break; - case 'l': - sscanf(optarg, "%u", &header_length); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - usage(EXIT_FAILURE); - - return build_image(); -} diff --git a/tools/firmware-utils/src/mkrtn56uimg.c b/tools/firmware-utils/src/mkrtn56uimg.c deleted file mode 100644 index a43746dc1c..0000000000 --- a/tools/firmware-utils/src/mkrtn56uimg.c +++ /dev/null @@ -1,289 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * Copyright (C) 2014 OpenWrt.org - * Copyright (C) 2014 Mikko Hissa <mikko.hissa@werzek.com> - */ - -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netinet/in.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <unistd.h> -#include <zlib.h> - -#define IH_MAGIC 0x27051956 -#define IH_NMLEN 32 -#define IH_PRODLEN 23 - -#define IH_TYPE_INVALID 0 -#define IH_TYPE_STANDALONE 1 -#define IH_TYPE_KERNEL 2 -#define IH_TYPE_RAMDISK 3 -#define IH_TYPE_MULTI 4 -#define IH_TYPE_FIRMWARE 5 -#define IH_TYPE_SCRIPT 6 -#define IH_TYPE_FILESYSTEM 7 - -/* - * Compression Types - */ -#define IH_COMP_NONE 0 -#define IH_COMP_GZIP 1 -#define IH_COMP_BZIP2 2 -#define IH_COMP_LZMA 3 - -typedef struct { - uint8_t major; - uint8_t minor; -} version_t; - -typedef struct { - version_t kernel; - version_t fs; - uint8_t productid[IH_PRODLEN]; - uint8_t sub_fs; - uint32_t ih_ksz; -} asus_t; - -typedef struct image_header { - uint32_t ih_magic; - uint32_t ih_hcrc; - uint32_t ih_time; - uint32_t ih_size; - uint32_t ih_load; - uint32_t ih_ep; - uint32_t ih_dcrc; - uint8_t ih_os; - uint8_t ih_arch; - uint8_t ih_type; - uint8_t ih_comp; - union { - char ih_name[IH_NMLEN]; - asus_t asus; - } tail; -} image_header_t; - -typedef struct squashfs_sb { - uint32_t s_magic; - uint32_t pad0[9]; - uint64_t bytes_used; -} squashfs_sb_t; - -typedef enum { - NONE, FACTORY, SYSUPGRADE, -} op_mode_t; - -void -calc_crc(image_header_t *hdr, void *data, uint32_t len) -{ - /* - * Calculate payload checksum - */ - hdr->ih_dcrc = htonl(crc32(0, (Bytef *)data, len)); - hdr->ih_size = htonl(len); - /* - * Calculate header checksum - */ - hdr->ih_hcrc = 0; - hdr->ih_hcrc = htonl(crc32(0, (Bytef *)hdr, sizeof(image_header_t))); -} - - -static void -usage(const char *progname, int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, "\n" - "Options:\n" - " -f <file> generate a factory flash image <file>\n" - " -s <file> generate a sysupgrade flash image <file>\n" - " -h show this screen\n"); - exit(status); -} - -int -process_image(char *progname, char *filename, op_mode_t opmode) -{ - int fd; - void *ptr; - char namebuf[IH_NMLEN]; - struct stat sbuf; - uint32_t offset_kernel, offset_sqfs, offset_end, - offset_sec_header, offset_eb, offset_image_end; - squashfs_sb_t *sqs; - image_header_t *hdr; - - if ((fd = open(filename, O_RDWR, 0666)) < 0) { - fprintf (stderr, "%s: Can't open %s: %s\n", - progname, filename, strerror(errno)); - return (EXIT_FAILURE); - } - - if (fstat(fd, &sbuf) < 0) { - fprintf (stderr, "%s: Can't stat %s: %s\n", - progname, filename, strerror(errno)); - return (EXIT_FAILURE); - } - - if ((unsigned)sbuf.st_size < sizeof(image_header_t)) { - fprintf (stderr, - "%s: Bad size: \"%s\" is no valid image\n", - progname, filename); - return (EXIT_FAILURE); - } - - ptr = (void *)mmap(0, sbuf.st_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - fd, 0); - - if ((caddr_t)ptr == (caddr_t)-1) { - fprintf (stderr, "%s: Can't read %s: %s\n", - progname, filename, strerror(errno)); - return (EXIT_FAILURE); - } - - hdr = ptr; - - if (ntohl(hdr->ih_magic) != IH_MAGIC) { - fprintf (stderr, - "%s: Bad Magic Number: \"%s\" is no valid image\n", - progname, filename); - return (EXIT_FAILURE); - } - - if (opmode == FACTORY) { - strncpy(namebuf, hdr->tail.ih_name, IH_NMLEN); - hdr->tail.asus.kernel.major = 0; - hdr->tail.asus.kernel.minor = 0; - hdr->tail.asus.fs.major = 0; - hdr->tail.asus.fs.minor = 0; - strncpy((char *)&hdr->tail.asus.productid, "RT-N56U", IH_PRODLEN); - } - - if (hdr->tail.asus.ih_ksz == 0) - hdr->tail.asus.ih_ksz = htonl(ntohl(hdr->ih_size) + sizeof(image_header_t)); - - offset_kernel = sizeof(image_header_t); - offset_sqfs = ntohl(hdr->tail.asus.ih_ksz); - sqs = ptr + offset_sqfs; - offset_sec_header = offset_sqfs + sqs->bytes_used; - - /* - * Reserve space for the second header. - */ - offset_end = offset_sec_header + sizeof(image_header_t); - offset_eb = ((offset_end>>16)+1)<<16; - - if (opmode == FACTORY) - offset_image_end = offset_eb + 4; - else - offset_image_end = sbuf.st_size; - /* - * Move the second header at the end of the image. - */ - offset_end = offset_sec_header; - offset_sec_header = offset_eb - sizeof(image_header_t); - - /* - * Remove jffs2 markers between squashfs and eb boundary. - */ - if (opmode == FACTORY) - memset(ptr+offset_end, 0xff ,offset_eb - offset_end); - - /* - * Grow the image if needed. - */ - if (offset_image_end > sbuf.st_size) { - (void) munmap((void *)ptr, sbuf.st_size); - ftruncate(fd, offset_image_end); - ptr = (void *)mmap(0, offset_image_end, - PROT_READ | PROT_WRITE, - MAP_SHARED, - fd, 0); - /* - * jffs2 marker - */ - if (opmode == FACTORY) { - *(uint8_t *)(ptr+offset_image_end-4) = 0xde; - *(uint8_t *)(ptr+offset_image_end-3) = 0xad; - *(uint8_t *)(ptr+offset_image_end-2) = 0xc0; - *(uint8_t *)(ptr+offset_image_end-1) = 0xde; - } - } - - /* - * Calculate checksums for the second header to be used after flashing. - */ - if (opmode == FACTORY) { - hdr = ptr+offset_sec_header; - memcpy(hdr, ptr, sizeof(image_header_t)); - strncpy(hdr->tail.ih_name, namebuf, IH_NMLEN); - calc_crc(hdr, ptr+offset_kernel, offset_sqfs - offset_kernel); - calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_image_end - offset_kernel); - } else { - calc_crc((image_header_t *)ptr, ptr+offset_kernel, offset_sqfs - offset_kernel); - } - - if (sbuf.st_size > offset_image_end) - (void) munmap((void *)ptr, sbuf.st_size); - else - (void) munmap((void *)ptr, offset_image_end); - - ftruncate(fd, offset_image_end); - (void) close (fd); - - return EXIT_SUCCESS; -} - -int -main(int argc, char **argv) -{ - int opt; - char *filename = NULL; - char *progname; - op_mode_t opmode = NONE; - - progname = argv[0]; - - while ((opt = getopt(argc, argv,":s:f:h?")) != -1) { - switch (opt) { - case 's': - opmode = SYSUPGRADE; - filename = optarg; - break; - case 'f': - opmode = FACTORY; - filename = optarg; - break; - case 'h': - opmode = NONE; - default: - usage(progname, EXIT_FAILURE); - opmode = NONE; - } - } - - if(filename == NULL) - opmode = NONE; - - switch (opmode) { - case NONE: - usage(progname, EXIT_FAILURE); - break; - case FACTORY: - case SYSUPGRADE: - return process_image(progname, filename, opmode); - break; - } - - return EXIT_SUCCESS; -} - diff --git a/tools/firmware-utils/src/mksenaofw.c b/tools/firmware-utils/src/mksenaofw.c deleted file mode 100644 index 172d5f3b4d..0000000000 --- a/tools/firmware-utils/src/mksenaofw.c +++ /dev/null @@ -1,568 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * Copyright (C) 2012 OpenWrt.org - * Copyright (C) 2012 Mikko Hissa <mikko.hissa@uta.fi> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <libgen.h> -#include <errno.h> -#include <arpa/inet.h> -#include <unistd.h> -#include "md5.h" - -#define HDR_LEN 0x60 -#define BUF_SIZE 0x200 -#define VERSION_SIZE 0x10 -#define MD5_SIZE 0x10 -#define PAD_SIZE 0x20 - -#define DEFAULT_BLOCK_SIZE 65535 - -#define DEFAULT_HEAD_VALUE 0x0 -#define DEFAULT_VERSION "123" -#define DEFAULT_MAGIC 0x12345678 - -typedef struct { - uint32_t head; - uint32_t vendor_id; - uint32_t product_id; - uint8_t version[VERSION_SIZE]; - uint32_t firmware_type; - uint32_t filesize; - uint32_t zero; - uint8_t md5sum[MD5_SIZE]; - uint8_t pad[PAD_SIZE]; - uint32_t chksum; - uint32_t magic; -} img_header; - -typedef struct { - uint8_t id; - char * name; -} firmware_type; - -typedef enum { - NONE, ENCODE, DECODE -} op_mode; - -static firmware_type FIRMWARE_TYPES[] = { - { 0x00, "combo" }, /* Used for new capwap-included style header */ - { 0x01, "bootloader" }, - { 0x02, "kernel" }, - { 0x03, "kernelapp" }, - { 0x04, "apps" }, - /* The types below this line vary by manufacturer */ - { 0x05, "littleapps (D-Link)/factoryapps (EnGenius)" }, - { 0x06, "sounds (D-Link)/littleapps (EnGenius)" }, - { 0x07, "userconfig (D-Link)/appdata (EnGenius)" }, - { 0x08, "userconfig (EnGenius)"}, - { 0x09, "odmapps (EnGenius)"}, - { 0x0a, "factoryapps (D-Link)" }, - { 0x0b, "odmapps (D-Link)" }, - { 0x0c, "langpack (D-Link)" } -}; - -#define MOD_DEFAULT 0x616C6C00 -#define SKU_DEFAULT 0x0 -#define DATECODE_NONE 0xFFFFFFFF -#define FIRMWARE_TYPE_NONE 0xFF - -struct capwap_header { - uint32_t mod; - uint32_t sku; - uint32_t firmware_ver[3]; - uint32_t datecode; - uint32_t capwap_ver[3]; - uint32_t model_size; - uint8_t model[]; -}; - -static long get_file_size(const char *filename) -{ - FILE *fp_file; - long result; - - fp_file = fopen(filename, "r"); - if (!fp_file) - return -1; - fseek(fp_file, 0, SEEK_END); - result = ftell(fp_file); - fclose(fp_file); - return result; -} - -static int header_checksum(void *data, size_t len) -{ - int sum = 0; /* shouldn't this be unsigned ? */ - size_t i; - - if (data != NULL && len > 0) { - for (i = 0; i < len; ++i) - sum += ((unsigned char *)data)[i]; - return sum; - } - - return -1; -} - -static int md5_file(const char *filename, uint8_t *dst) -{ - FILE *fp_src; - MD5_CTX ctx; - char buf[BUF_SIZE]; - size_t bytes_read; - - MD5_Init(&ctx); - - fp_src = fopen(filename, "r+b"); - if (!fp_src) { - return -1; - } - while (!feof(fp_src)) { - bytes_read = fread(&buf, 1, BUF_SIZE, fp_src); - MD5_Update(&ctx, &buf, bytes_read); - } - fclose(fp_src); - - MD5_Final(dst, &ctx); - - return 0; -} - -static int encode_image(const char *input_file_name, - const char *output_file_name, img_header *header, - struct capwap_header *cw_header, int block_size) -{ - char buf[BUF_SIZE]; - size_t pad_len = 0; - size_t bytes_avail; - size_t bytes_read; - - FILE *fp_output; - FILE *fp_input; - - int model_size; - long magic; - size_t i; - - fp_input = fopen(input_file_name, "r+b"); - if (!fp_input) { - fprintf(stderr, "Cannot open %s !!\n", input_file_name); - return -1; - } - - fp_output = fopen(output_file_name, "w+b"); - if (!fp_output) { - fprintf(stderr, "Cannot open %s !!\n", output_file_name); - fclose(fp_input); - return -1; - } - - header->filesize = get_file_size(input_file_name); - if (!header->filesize) { - fprintf(stderr, "File %s open/size error!\n", input_file_name); - fclose(fp_input); - fclose(fp_output); - return -1; - } - /* - * Zero padding - */ - if (block_size > 0) { - pad_len = block_size - (header->filesize % block_size); - } - - if (md5_file(input_file_name, (uint8_t *) &header->md5sum) < 0) { - fprintf(stderr, "MD5 failed on file %s\n", input_file_name); - fclose(fp_input); - fclose(fp_output); - return -1; - } - header->zero = 0; - header->chksum = header_checksum(header, HDR_LEN); - if (cw_header) { - header->chksum += header_checksum(cw_header, - sizeof(struct capwap_header) + cw_header->model_size); - } - - header->head = htonl(header->head); - header->vendor_id = htonl(header->vendor_id); - header->product_id = htonl(header->product_id); - header->firmware_type = htonl(header->firmware_type); - header->filesize = htonl(header->filesize); - header->chksum = htonl(header->chksum); - magic = header->magic; - header->magic = htonl(header->magic); - - fwrite(header, HDR_LEN, 1, fp_output); - - if (cw_header) { - model_size = cw_header->model_size; - cw_header->mod = htonl(cw_header->mod); - cw_header->sku = htonl(cw_header->sku); - cw_header->firmware_ver[0] = htonl(cw_header->firmware_ver[0]); - cw_header->firmware_ver[1] = htonl(cw_header->firmware_ver[1]); - cw_header->firmware_ver[2] = htonl(cw_header->firmware_ver[2]); - cw_header->datecode = htonl(cw_header->datecode); - cw_header->capwap_ver[0] = htonl(cw_header->capwap_ver[0]); - cw_header->capwap_ver[1] = htonl(cw_header->capwap_ver[1]); - cw_header->capwap_ver[2] = htonl(cw_header->capwap_ver[2]); - cw_header->model_size = htonl(cw_header->model_size); - fwrite(cw_header, sizeof(struct capwap_header) + model_size, 1, - fp_output); - } - - while (!feof(fp_input) || pad_len > 0) { - - if (!feof(fp_input)) - bytes_read = fread(&buf, 1, BUF_SIZE, fp_input); - else - bytes_read = 0; - - /* - * No more bytes read, start padding - */ - if (bytes_read < BUF_SIZE && pad_len > 0) { - bytes_avail = BUF_SIZE - bytes_read; - memset( &buf[bytes_read], 0, bytes_avail); - bytes_read += bytes_avail < pad_len ? bytes_avail : pad_len; - pad_len -= bytes_avail < pad_len ? bytes_avail : pad_len; - } - - for (i = 0; i < bytes_read; i++) - buf[i] ^= magic >> (i % 8) & 0xff; - fwrite(&buf, bytes_read, 1, fp_output); - } - - fclose(fp_input); - fclose(fp_output); - return 1; -} - -int decode_image(const char *input_file_name, const char *output_file_name) -{ - struct capwap_header cw_header; - char buf[BUF_SIZE]; - img_header header; - - char *pmodel = NULL; - FILE *fp_input; - FILE *fp_output; - - size_t bytes_read; - size_t bytes_written; - unsigned int i; - - fp_input = fopen(input_file_name, "r+b"); - if (!fp_input) { - fprintf(stderr, "Cannot open %s !!\n", input_file_name); - return -1; - } - - fp_output = fopen(output_file_name, "w+b"); - if (!fp_output) { - fprintf(stderr, "Cannot open %s !!\n", output_file_name); - fclose(fp_input); - return -1; - } - - if (fread(&header, 1, HDR_LEN, fp_input) != HDR_LEN) { - fprintf(stderr, "Incorrect header size reading base header!!"); - fclose(fp_input); - fclose(fp_output); - return -1; - } - - header.head = ntohl(header.head); - header.vendor_id = ntohl(header.vendor_id); - header.product_id = ntohl(header.product_id); - header.firmware_type = ntohl(header.firmware_type); - header.filesize = ntohl(header.filesize); - header.chksum = ntohl(header.chksum); - header.magic = ntohl(header.magic); - - /* read capwap header if firmware_type is zero */ - if (header.firmware_type == 0) { - if (fread(&cw_header, 1, sizeof(struct capwap_header), - fp_input) != sizeof(struct capwap_header)) { - fprintf(stderr, "Incorrect header size reading capwap_header!!"); - fclose(fp_input); - fclose(fp_output); - return -1; - } - cw_header.mod = ntohl(cw_header.mod); - cw_header.sku = ntohl(cw_header.sku); - cw_header.firmware_ver[0] = ntohl(cw_header.firmware_ver[0]); - cw_header.firmware_ver[1] = ntohl(cw_header.firmware_ver[1]); - cw_header.firmware_ver[2] = ntohl(cw_header.firmware_ver[2]); - cw_header.datecode = ntohl(cw_header.datecode); - cw_header.capwap_ver[0] = ntohl(cw_header.capwap_ver[0]); - cw_header.capwap_ver[1] = ntohl(cw_header.capwap_ver[1]); - cw_header.capwap_ver[2] = ntohl(cw_header.capwap_ver[2]); - cw_header.model_size = ntohl(cw_header.model_size); - - pmodel = malloc(cw_header.model_size + 1); - if (pmodel) { - pmodel[cw_header.model_size] = '\0'; - if (fread(pmodel, 1, cw_header.model_size, fp_input) != - cw_header.model_size) { - fprintf(stderr, "Incorrect header size reading model name!!"); - free(pmodel); - fclose(fp_input); - fclose(fp_output); - return -1; - } - free(pmodel); - } else { - fprintf(stderr, "Incorrect header size reading model name!!"); - fclose(fp_input); - fclose(fp_output); - return -1; - } - } - - bytes_written = 0; - while (!feof(fp_input)) { - - bytes_read = fread(&buf, 1, BUF_SIZE, fp_input); - for (i = 0; i < bytes_read; i++) - buf[i] ^= header.magic >> (i % 8) & 0xff; - - /* - * Handle padded source file - */ - if (bytes_written + bytes_read > header.filesize) { - bytes_read = header.filesize - bytes_written; - if (bytes_read > 0) - fwrite(&buf, bytes_read, 1, fp_output); - break; - } - - fwrite(&buf, bytes_read, 1, fp_output); - bytes_written += bytes_read; - } - - fclose(fp_input); - fclose(fp_output); - - return 1; -} - -static void usage(const char *progname, int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - size_t i; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, "\n" - "Options:\n" - " -e <file> encode image file <file>\n" - " -d <file> decode image file <file>\n" - " -o <file> write output to the file <file>\n" - " -t <type> set image type to <type>\n" - " valid image <type> values:\n"); - for (i = 0; i < sizeof(FIRMWARE_TYPES) / sizeof(firmware_type); i++) { - fprintf(stream, " %-5i= %s\n", FIRMWARE_TYPES[i].id, - FIRMWARE_TYPES[i].name); - } - fprintf(stream, " -v <version> set image version to <version>\n" - " -r <vendor> set image vendor id to <vendor>\n" - " -p <product> set image product id to <product>\n" - " -m <magic> set encoding magic <magic>\n" - " -z enable image padding to <blocksize>\n" - " -b <blocksize> set image <blocksize>, defaults to %u\n" - " -c <datecode> add capwap header with <datecode> (e.g. 171101)\n" - " -w <fw_ver> firmware version for capwap header (e.g. 3.0.1)\n" - " -x <cw_ver> capwap firmware version for capwap header (e.g. 1.8.53)\n" - " -n <name> model name for capwap header (e.g. ENS620EXT)\n" - " -h show this screen\n", DEFAULT_BLOCK_SIZE); - exit(status); -} - -int main(int argc, char *argv[]) -{ - static const char period[2] = "."; - struct capwap_header cw_header; - img_header header; - - struct capwap_header *pcw_header = NULL; - char *output_file = NULL; - char *input_file = NULL; - char *progname = NULL; - char *mod_name = NULL; - char *token; - - op_mode mode = NONE; - int tmp, pad = 0; - int block_size; - size_t i; - int opt; - - block_size = DEFAULT_BLOCK_SIZE; - progname = basename(argv[0]); - - memset(&header, 0, sizeof(img_header)); - header.magic = DEFAULT_MAGIC; - header.head = DEFAULT_HEAD_VALUE; - header.firmware_type = FIRMWARE_TYPE_NONE; - memset(&cw_header, 0, sizeof(struct capwap_header)); - cw_header.mod = MOD_DEFAULT; - cw_header.sku = SKU_DEFAULT; - cw_header.datecode = DATECODE_NONE; - strncpy( (char*)&header.version, DEFAULT_VERSION, VERSION_SIZE - 1); - - while ((opt = getopt(argc, argv, ":o:e:d:t:v:r:p:m:b:c:w:x:n:h?z")) != -1) { - switch (opt) { - case 'e': - input_file = optarg; - mode = ENCODE; - break; - case 'd': - input_file = optarg; - mode = DECODE; - break; - case 'o': - output_file = optarg; - break; - case 't': - tmp = strtol(optarg, 0, 10); - for (i = 0; i < sizeof(FIRMWARE_TYPES) / sizeof(firmware_type); - i++) { - if (FIRMWARE_TYPES[i].id == tmp) { - header.firmware_type = FIRMWARE_TYPES[i].id; - break; - } - } - if (header.firmware_type == FIRMWARE_TYPE_NONE) { - fprintf(stderr, "Invalid firmware type \"0\"!\n"); - usage(progname, EXIT_FAILURE); - } - break; - case 'v': - strncpy( (char*)&header.version, optarg, - VERSION_SIZE - 1); - break; - case 'r': - header.vendor_id = strtol(optarg, 0, 0); - break; - case 'p': - header.product_id = strtol(optarg, 0, 0); - break; - case 'm': - header.magic = strtoul(optarg, 0, 16); - break; - case 'z': - pad = 1; - break; - case 'b': - block_size = strtol(optarg, 0, 10); - break; - case 'c': - cw_header.datecode = strtoul(optarg, 0, 10); - break; - case 'w': - token = strtok(optarg, period); - i = 0; - while (token && (i < 3)) { - cw_header.firmware_ver[i++] = - strtoul(token, 0, 10); - token = strtok(NULL, period); - } - break; - case 'x': - token = strtok(optarg, period); - i = 0; - while (token && (i < 3)) { - cw_header.capwap_ver[i++] = - strtoul(token, 0, 10); - token = strtok(NULL, period); - } - break; - case 'n': - mod_name = optarg; - cw_header.model_size = strlen(mod_name); - break; - case 'h': - usage(progname, EXIT_SUCCESS); - break; - case ':': - fprintf(stderr, "Option -%c requires an operand\n", optopt); - usage(progname, EXIT_FAILURE); - break; - case '?': - fprintf(stderr, "Unrecognized option: -%c\n", optopt); - usage(progname, EXIT_FAILURE); - break; - default: - usage(progname, EXIT_FAILURE); - break; - } - } - - /* Check required arguments */ - if (mode == NONE) { - fprintf(stderr, "A mode must be defined\n"); - usage(progname, EXIT_FAILURE); - } - - if (input_file == NULL || output_file == NULL) { - fprintf(stderr, "Input and output files must be defined\n"); - usage(progname, EXIT_FAILURE); - } - - if (mode == DECODE) { - if (decode_image(input_file, output_file) < 0) - return EXIT_FAILURE; - - return EXIT_SUCCESS; - } - - if ((header.firmware_type == 0) && - (cw_header.datecode == DATECODE_NONE)) { - fprintf(stderr, "Firmware type must be non-zero for non-capwap images\n"); - usage(progname, EXIT_FAILURE); - } - - if (header.vendor_id == 0 || header.product_id == 0) { - fprintf(stderr, "Vendor ID and Product ID must be defined and non-zero\n"); - usage(progname, EXIT_FAILURE); - } - - /* Check capwap header specific arguments */ - if (cw_header.datecode != DATECODE_NONE) { - if (!mod_name) { - fprintf(stderr, "Capwap header specified: model name must be specified\n"); - usage(progname, EXIT_FAILURE); - } - if (!cw_header.firmware_ver[0] && !cw_header.firmware_ver[1] && - !cw_header.firmware_ver[2]) { - fprintf(stderr, "Capwap header specified, fw_ver must be non-zero\n"); - } - if (!cw_header.capwap_ver[0] && !cw_header.capwap_ver[1] && - !cw_header.capwap_ver[2]) { - fprintf(stderr, "Capwap header specified, cw_ver must be non-zero\n"); - } - pcw_header = malloc(sizeof(struct capwap_header) + - cw_header.model_size); - if (pcw_header) { - memcpy(pcw_header, &cw_header, - sizeof(struct capwap_header)); - memcpy(&(pcw_header->model), mod_name, - cw_header.model_size); - } else { - fprintf(stderr, "Failed to allocate memory\n"); - return EXIT_FAILURE; - } - } - - if (encode_image(input_file, output_file, &header, pcw_header, - pad ? block_size : 0) < 0) - return EXIT_FAILURE; - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/mksercommfw.c b/tools/firmware-utils/src/mksercommfw.c deleted file mode 100644 index 5fa323f2d5..0000000000 --- a/tools/firmware-utils/src/mksercommfw.c +++ /dev/null @@ -1,262 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <unistd.h> -#include <byteswap.h> -#include <endian.h> -#include <getopt.h> - -#if !defined(__BYTE_ORDER) -#error "Unknown byte order" -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_be32(x) (x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_be32(x) bswap_32(x) -#else -#error "Unsupported endianness" -#endif - -/* #define DEBUG 1 */ - -#ifdef DEBUG -#define DBG(...) {printf(__VA_ARGS__); } -#else -#define DBG(...) {} -#endif - -#define ERR(...) {printf(__VA_ARGS__); } - -/* - * Fw Header Layout for Netgear / Sercomm devices (bytes) - * - * Size : 512 bytes + zipped image size - * - * Locations: - * magic : 0-6 ASCII - * version: 7-11 fixed - * hwID : 11-44 ASCII - * hwVer : 45-54 ASCII - * swVer : 55-62 uint32_t in BE - * magic : 63-69 ASCII - * ChkSum : 511 Inverse value of the full image checksum while this location is 0x00 - */ -static const char* magic = "sErCoMm"; /* 7 */ -static const unsigned char version[4] = { 0x00, 0x01, 0x00, 0x00 }; -static const int header_sz = 512; -static const int footer_sz = 71; - -static int is_header = 1; - -struct file_info { - char* file_name; /* name of the file */ - char* file_data; /* data of the file in memory */ - u_int32_t file_size; /* length of the file */ -}; - -static u_int8_t getCheckSum(char* data, int len) { - u_int8_t new = 0; - int i; - - if (!data) { - ERR("Invalid pointer provided!\n"); - return 0; - } - - for (i = 0; i < len; i++) { - new += data[i]; - } - - return new; -} - -/* - * read file into buffer - * add space for header/footer - */ -static int copyToOutputBuf(struct file_info* finfo) { - FILE* fp = NULL; - - int file_sz = 0; - int extra_sz; - int hdr_pos; - int img_pos; - - if (!finfo || !finfo->file_name) { - ERR("Invalid pointer provided!\n"); - return -1; - } - - DBG("Opening file: %s\n", finfo->file_name); - - if (!(fp = fopen(finfo->file_name, "rb"))) { - ERR("Error opening file: %s\n", finfo->file_name); - return -1; - } - - /* Get filesize */ - rewind(fp); - fseek(fp, 0L, SEEK_END); - file_sz = ftell(fp); - rewind(fp); - - if (file_sz < 1) { - ERR("Error getting filesize: %s\n", finfo->file_name); - fclose(fp); - return -1; - } - - if (is_header) { - extra_sz = header_sz; - hdr_pos = 0; - img_pos = header_sz; - } else { - extra_sz = footer_sz; - hdr_pos = file_sz; - img_pos = 0; - } - - DBG("Filesize: %i\n", file_sz); - finfo->file_size = file_sz + extra_sz; - - if (!(finfo->file_data = malloc(finfo->file_size))) { - ERR("Out of memory!\n"); - fclose(fp); - return -1; - } - - /* init header/footer bytes */ - memset(finfo->file_data + hdr_pos, 0, extra_sz); - - /* read file and take care of leading header if exists */ - if (fread(finfo->file_data + img_pos, 1, file_sz, fp) != file_sz) { - ERR("Error reading file %s\n", finfo->file_name); - fclose(fp); - return -1; - } - - DBG("File: read successful\n"); - fclose(fp); - - return hdr_pos; -} - -static int writeFile(struct file_info* finfo) { - FILE* fp; - - if (!finfo || !finfo->file_name) { - ERR("Invalid pointer provided!\n"); - return -1; - } - - DBG("Opening file: %s\n", finfo->file_name); - - if (!(fp = fopen(finfo->file_name, "w"))) { - ERR("Error opening file: %s\n", finfo->file_name); - return -1; - } - - DBG("Writing file: %s\n", finfo->file_name); - - if (fwrite(finfo->file_data, 1, finfo->file_size, fp) != finfo->file_size) { - ERR("Wanted to write, but something went wrong!\n"); - fclose(fp); - return -1; - } - - fclose(fp); - return 0; -} - -static void usage(char* argv[]) { - printf("Usage: %s [OPTIONS...]\n" - "\n" - "Options:\n" - " -f add sercom footer (if absent, header)\n" - " -b <hwid> use hardware id specified with <hwid> (ASCII)\n" - " -r <hwrev> use hardware revision specified with <hwrev> (ASCII)\n" - " -v <version> set image version to <version> (decimal, hex or octal notation)\n" - " -i <file> input file\n" - , argv[0]); -} - -int main(int argc, char* argv[]) { - struct file_info image = { 0 }; - - char* hwID = NULL; - char* hwVer = NULL; - u_int32_t swVer = 0; - u_int8_t chkSum; - int hdr_offset; - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "b:i:r:v:f"); - if (c == -1) - break; - - switch (c) { - case 'b': - hwID = optarg; - break; - case 'f': - is_header = 0; - break; - case 'i': - image.file_name = optarg; - break; - case 'r': - hwVer = optarg; - break; - case 'v': - swVer = (u_int32_t) strtol(optarg, NULL, 0); - swVer = cpu_to_be32(swVer); - break; - default: - usage(argv); - return EXIT_FAILURE; - } - } - - if (!hwID || !hwVer || !image.file_name) { - usage(argv); - return EXIT_FAILURE; - } - - /* - * copy input to buffer, add extra space for header/footer and return - * header position - */ - hdr_offset = copyToOutputBuf(&image); - if (hdr_offset < 0) - return EXIT_FAILURE; - - DBG("Filling header: %s %s %2X %s\n", hwID, hwVer, swVer, magic); - - strncpy(image.file_data + hdr_offset + 0, magic, 7); - memcpy(image.file_data + hdr_offset + 7, version, sizeof(version)); - strncpy(image.file_data + hdr_offset + 11, hwID, 34); - strncpy(image.file_data + hdr_offset + 45, hwVer, 10); - memcpy(image.file_data + hdr_offset + 55, &swVer, sizeof(swVer)); - strncpy(image.file_data + hdr_offset + 63, magic, 7); - - /* calculate checksum and invert checksum */ - if (is_header) { - chkSum = getCheckSum(image.file_data, image.file_size); - chkSum = (chkSum ^ 0xFF) + 1; - DBG("Checksum for Image: %hhX\n", chkSum); - - /* write checksum to header */ - image.file_data[511] = (char) chkSum; - } - - /* overwrite input file */ - if (writeFile(&image)) - return EXIT_FAILURE; - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/mktitanimg.c b/tools/firmware-utils/src/mktitanimg.c deleted file mode 100644 index 654a6bd09b..0000000000 --- a/tools/firmware-utils/src/mktitanimg.c +++ /dev/null @@ -1,1036 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <libgen.h> -#include "mktitanimg.h" - - -struct checksumrecord -{ - unsigned int magic; - unsigned int chksum; /* The checksum for the complete header. - Excepting the - checksum block */ -}; -/*************************************************************************** - * void print_help(void) - ***************************************************************************/ -void print_help(void) -{ - static char* help_page[]= - { - "mknspimg version 1.0, Texas Instruments, 2004", - "Syntax:", - " mknspimg -o outfile -i image1 image2 -a align1 align2 [-v] [-b] [-p prod_id] [-r rel_id] [-s rel_name] [-f flags]", - "Example:", - " mknspimg -o nsp_image.bin -i kernel.bin files.img -a 0 4096", - "This generates 'nsp_image.bin' from two input files aligning first to 0 and second to 4096 bytes." - }; - - int num_lines = sizeof(help_page)/sizeof(char*); - int i; - for(i=0; i < num_lines; i++) { - printf("%s\n", help_page[i]); - } -} - -/*************************************************************************** - * void mknspimg_print_hdr(NSP_IMG_HDR* p_img_hdr) - ***************************************************************************/ -void mknspimg_print_hdr(struct nsp_img_hdr *hdr) -{ - struct nsp_img_hdr_chksum *chksum; - struct nsp_img_hdr_sections *section; - int i; - - printf("****************** NSP Image Summary ******************\n"); - printf("Magic: 0x%x\n", hdr->head.magic); - printf("Image Header Size: 0x%x bytes\n", hdr->head.hdr_size); - printf("Total Image Size: %d bytes\n", hdr->head.image_size); - printf("Product ID: 0x%x\n", hdr->head.prod_id); - printf("Release ID: 0x%x\n", hdr->head.rel_id); - printf("Version ID: 0x%x\n", hdr->head.version); - - printf("Offset Info: 0x%x\n", hdr->head.info_offset); - printf("Offset Sect info: 0x%x\n", hdr->head.sect_info_offset); - printf("Offset Sections: 0x%x\n", hdr->sect_info.sections_offset); - - chksum=(struct nsp_img_hdr_chksum *)(hdr+hdr->head.chksum_offset); - printf("Header Checksum: 0x%x\n", chksum->hdr_chksum); - - printf("+++ Section Information +++\n"); - printf("# of sections: %u\n", hdr->sect_info.num_sects); - section=&(hdr->sections); - for(i = 0; i < hdr->sect_info.num_sects; i++, section++) { - printf("+++++ Section %d +++++\n", i); - printf("Total size: %u bytes\n", section->total_size); - printf("Raw Size: %u bytes\n", section->raw_size); - printf("Offset: 0x%x\n", section->offset); - printf("Type: 0x%x\n", section->type); - printf("Name: %s\n", section->name); - } - printf("*******************************************************\n"); -} - -CMDLINE_CFG cmd_line_cfg = -{ - { - /* MIN MAX FLAGS OPTION */ - { 2, 2, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-a' align1 align2 */ - { 0, 0, CMDLINE_OPTFLAG_ALLOW }, /* '-b' bootstrap */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-c' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-d' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-e' */ - { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-f' flags */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-g' */ - { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-h' */ - { 2, 2, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-i arg1 arg2 ' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-j' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-k' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-l' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-m' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-n' */ - { 1, 1, (CMDLINE_OPTFLAG_ALLOW | CMDLINE_OPTFLAG_MANDAT) }, /* '-o arg' */ - { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-p' PROD_ID */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-q' */ - { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-r' REL_ID */ - { 1, 1, CMDLINE_OPTFLAG_ALLOW }, /* '-s' "Release XXX.XXX" */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-t' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-u' */ - { 0, 0, CMDLINE_OPTFLAG_ALLOW }, /* '-v' control VERBOSE/NON-VERBOSE mode */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-w' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-x' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* '-y' */ - { 0, 0, !CMDLINE_OPTFLAG_ALLOW } /* '-z' */ - }, - { 0, 0, !CMDLINE_OPTFLAG_ALLOW }, /* global arguments */ -}; - -/*************************************************************************** - * int nsp_img_write(void* image, char* file, int padding) - * Write out the image. - ***************************************************************************/ -int main(int argc, char* argv[], char* env[]) -{ - FILE* nsp_image = NULL; - int header_version=1; - int cmdline_err; - char* cmdline_error_msg; - - char* filen_out; - - int i,count; /* loop variables */ - int num_sects = 2; /* We require exactly two image with -i option - (see CMDLINE_CFG structure above) */ - int total = 0; - - int header_size=0; - struct nsp_img_hdr_head *img_hdr_head; /* Start of image header */ - struct nsp_img_hdr_info *img_hdr_info; - struct nsp_img_hdr_section_info *img_hdr_section_info ; - struct nsp_img_hdr_sections *img_hdr_sections, *section; /* Section pointers */ - - - /* Configure the command line. */ - cmdline_configure(&cmd_line_cfg); - - /* Read and parse the command line. */ - cmdline_err = cmdline_read(argc, argv); - - /* Check for parsing errors. */ - if(cmdline_err != 0) { - /* Get the parse error message */ - cmdline_error_msg = cmdline_error(cmdline_err); - - /* Print it out */ - printf("%s\n", cmdline_error_msg); - - /* Print our help too */ - print_help(); - return -1; - } - if(cmdline_getopt_count('h') > 0) - { - header_version=atoi(argv[cmdline_getarg(cmdline_getarg_list('h'),0)]); - } - /* Set up arguments */ - filen_out = argv[cmdline_getarg(cmdline_getarg_list('o'),0)]; - /* Command line arguments have been parsed. Start doing our work. */ - - /* Caculate the header size, and allocate the memory, and assign the sub pointers */ - header_size = sizeof(struct nsp_img_hdr_head) + /* This has a single section - desc block already */ - (header_version==1?0:4) + - sizeof(struct nsp_img_hdr_info) + - sizeof(struct nsp_img_hdr_section_info) + - sizeof(struct nsp_img_hdr_sections) * num_sects ; - - img_hdr_head = (struct nsp_img_hdr_head *)malloc(header_size); - memset(img_hdr_head, 0x0, header_size); - img_hdr_info = (struct nsp_img_hdr_info*)((char *)img_hdr_head + sizeof(struct nsp_img_hdr_head) + (header_version==1?0:4)); - img_hdr_section_info = (struct nsp_img_hdr_section_info*)((char *)img_hdr_info + sizeof(struct nsp_img_hdr_info)); - img_hdr_sections = (struct nsp_img_hdr_sections*)((char *)img_hdr_section_info + sizeof(struct nsp_img_hdr_section_info)); - section = img_hdr_sections; - memset(img_hdr_head, 0xff, (void*)img_hdr_info - (void*)img_hdr_head); - - img_hdr_head->hdr_version = header_version; - img_hdr_head->hdr_size = header_size; - img_hdr_head->info_offset = (void*)img_hdr_info - (void*)img_hdr_head; - img_hdr_head->sect_info_offset = (void*)img_hdr_section_info - (void*)img_hdr_head; - - img_hdr_section_info->num_sects = num_sects; - img_hdr_section_info->sect_size = sizeof(struct nsp_img_hdr_sections); - img_hdr_section_info->sections_offset = (void*)img_hdr_sections - (void*)img_hdr_head; - -/* chksum = (struct nsp_img_hdr_chksum *) - ((unsigned int)image_hdr + header_size - sizeof(struct nsp_img_hdr_chksum));*/ - - /* Open the out file */ - nsp_image = fopen(filen_out,"wb+"); - if(nsp_image==NULL) { - printf("ERROR: can't open %s for writing.\n", filen_out); - return -1; - } - - /* Skip image header. We'll come back to it after we've written out the images. */ - fseek(nsp_image,header_size,SEEK_SET); - total = ftell(nsp_image); - total = header_size; - printf("total=%x\n",total); - { - int align; - int padding; - char * buf; - align = (header_version==1?0x10000:0x4000); - if(align==0) { - /* The user indicated no padding */ - padding = 0; - } else { - /* Calculate number padding bytes */ - if((total %align) ==0) - padding=0; - else - padding = align - (total % align); - } - if(padding>0) - { - buf=malloc(padding); - memset(buf, 0xff, padding); - if(fwrite((void*)buf,1,padding,nsp_image)!=padding) { - printf("ERROR: can't write to %s.\n", filen_out); - free(buf); - fclose(nsp_image); - return -1; - } - free(buf); - - } - total+=padding; - - - } - /* Write out all specified images (with -i option) */ - for(i=0; i < num_sects; i++) { - char* file_name; /* input file name */ - FILE* filep; /* input file pointer */ - int padding; /* number of padding bytes to prepend */ - int align; /* align factor from command line */ - int result; /* intermediate result */ - char * buf; - - /* Open the specified image for reading */ - file_name = argv[cmdline_getarg(cmdline_getarg_list('i'),i)]; - filep = fopen(file_name, "rb"); - if(filep==NULL) { - printf("ERROR: can't open file %s for reading.\n", file_name); - return -1; - } - section->flags = ~0x00; - /* Determine file size */ - fseek(filep,0,SEEK_END); - section->raw_size=ftell(filep); - fseek(filep,0,SEEK_SET); - cs_calc_sum(filep,(unsigned long *)§ion->chksum,0); - fseek(filep,0,SEEK_SET); - - /* Retrieve the alignment constant */ - /* Set image offset from the beginning of the out file */ - section->offset=total;// + padding; - - //total += padding; - - /* Copy the image file into nsp_image */ - count = section->raw_size; - buf=malloc(count); - result=fread(buf, 1, count, filep); - fwrite(buf, 1, result, nsp_image); - free(buf); - - /* HACK: This is a hack to get the names and types to the files. - TODO: Fix this to be a real method */ - if(i==0){ - section->type=NSP_IMG_SECTION_TYPE_KERNEL; - strncpy(section->name, "kernel", 16); - } else if(i==1){ - section->type=NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT; - strncpy(section->name, "root", 16); - } - - /* Account for the total */ - align = strtoul(argv[cmdline_getarg(cmdline_getarg_list('a'),i)],NULL,0); - if(i==0){ - if(align==0 || (((section->raw_size+ section->offset)%align)==0)) - padding=0; - else - padding = align - ((section->raw_size+ section->offset) % align); - - section->total_size=section->raw_size + padding; - } - else{ - #define EXTRA_BLOCK 0x10000 - unsigned int squash_padding; - squash_padding = EXTRA_BLOCK - section->raw_size % EXTRA_BLOCK; - buf=malloc(EXTRA_BLOCK + 4); - memset(buf, 0, squash_padding); - fwrite(buf, 1, squash_padding, nsp_image); - memset(buf, 0, EXTRA_BLOCK + 4); - *((unsigned int *)buf)=0xdec0adde; - *((unsigned int *)(buf+EXTRA_BLOCK))=0xdec0adde; - fwrite(buf, 1, EXTRA_BLOCK+4, nsp_image); - free(buf); - - if(align==0 || (((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) %align)==0)) - padding=0; - else - padding = align - ((section->raw_size + (EXTRA_BLOCK + 4 + squash_padding)) % align); - section->total_size=section->raw_size + (EXTRA_BLOCK + 4 + squash_padding) + padding; - } - if(padding>0){ - buf=malloc(padding); - memset(buf, 0xff, padding); - fwrite(buf, 1, padding, nsp_image); - free(buf); - } - printf("*****padding is %d\ttotal_size=%d\traw_size=%d\n",padding, section->total_size, section->raw_size); - - //total += section->raw_size; - total = section->total_size + section->offset; - printf("total=0x%x\n",total); - /* Close the input file */ - fclose(filep); - - /* Move the section pointer to the next slot */ - section++; - } - - /* Take care of the NSP image header fields */ - - /* head fields */ - img_hdr_head->magic = NSP_IMG_MAGIC_NUMBER; - img_hdr_head->boot_offset = img_hdr_sections->offset; - img_hdr_head->flags = ~0x00; /* Set to all 1's */ - - if(cmdline_getopt_count('b')) - img_hdr_head->flags &= ~(NSP_IMG_FLAG_FAILBACK_5 | NSP_IMG_FLAG_FAILBACK_1); - - if(cmdline_getopt_count('f')) - img_hdr_head->flags = strtoul(argv[cmdline_getarg(cmdline_getarg_list('f'),0)], 0, 16); - -#if 0 - img_hdr_head->hdr_version = 2; - img_hdr_head->hdr_size = header_size; -#endif - - if(cmdline_getopt_count('p')) - img_hdr_head->prod_id = strtoul(argv[cmdline_getarg(cmdline_getarg_list('p'),0)], 0, 16); - else - img_hdr_head->prod_id = 0x4C575943; - - if(cmdline_getopt_count('r')) - img_hdr_head->rel_id = strtoul(argv[cmdline_getarg(cmdline_getarg_list('r'),0)], 0, 0); - else - img_hdr_head->rel_id = 0x10203040; - - if(cmdline_getopt_count('s')) - img_hdr_head->version = strtoul(argv[cmdline_getarg(cmdline_getarg_list('s'),0)], 0, 0); - else - img_hdr_head->version = 0x0b040000; - img_hdr_head->image_size = total; -#if 0 - img_hdr_head->info_offset = (unsigned int)(&(image_hdr->info)) - - (unsigned int)image_hdr; - img_hdr_head->sect_info_offset= (unsigned int)(&(image_hdr->sect_info)) - - (unsigned int)image_hdr; -#endif -// image_hdr->head.chksum_offset = (unsigned int)chksum - (unsigned int)image_hdr; - img_hdr_head->chksum_offset = 0xffffffff; -// image_hdr->head.pad1 = 0xffffffff; - /* info fields */ - /* TODO: Fix. Do nothing yet */ -// strncpy(nsp_img_hdr.id.prod_info,NSP_PRODINFO_STRING,sizeof(NSP_PRODINFO_STRING)); - strcpy(img_hdr_info->image_filename, (const char *)basename(filen_out)); - /* section fields */ -#if 0 - img_hdr_section_info->num_sects= num_sects; - img_hdr_section_info->sect_size= sizeof(struct nsp_img_hdr_sections); - img_hdr_section_info->sections_offset= (unsigned int)(&(image_hdr->sections)) - - (unsigned int)image_hdr; -#endif - - /* Calculate checksum(s) */ -#if 0 - chksum->hdr_chksum = cs_calc_buf_sum((char*)image_hdr, - header_size - sizeof(struct nsp_img_hdr_chksum)); -#endif - /* Write out the NSP header. */ - fseek(nsp_image,0,SEEK_SET); - count = fwrite((void*)img_hdr_head, header_size, 1, nsp_image); - if(count!=1) { - printf("ERROR: can't write to %s.\n", filen_out); - return -1; - } - - /* Check if -v option was specified (no arg needed) */ - if(cmdline_getopt_count('v') > 0) - { - struct nsp_img_hdr_head head; - struct nsp_img_hdr *hdr; - - /* Rewind the file back to the beginning */ - fseek(nsp_image,0,SEEK_SET); - - /* Read header from the file */ - fread((void*)&head, sizeof(struct nsp_img_hdr_head), - 1, nsp_image); - - /* Get memory to store the complete header */ - hdr = (struct nsp_img_hdr *)malloc(head.hdr_size); - - /* Read header from the file */ - fseek(nsp_image,0,SEEK_SET); - fread((void*)hdr, head.hdr_size, 1, nsp_image); - - /* Print it out */ - mknspimg_print_hdr(hdr); - printf("Generated total %d bytes\n",total); - free(hdr); - } - - free(img_hdr_head); - - { - struct checksumrecord cr; - cr.magic=CKSUM_MAGIC_NUMBER; - cs_calc_sum(nsp_image, (unsigned long *)&cr.chksum, 0); - fseek(nsp_image,0, SEEK_END); - fwrite(&cr, 1, sizeof(cr), nsp_image); - } - { - FILE * non_web; - char fname[256]; - char * img_buf; - unsigned int len; - strcpy(fname, filen_out); - strcat(fname, ".non_web"); - non_web = fopen(fname,"wb+"); - fseek(nsp_image, 0, SEEK_END); - len = ftell(nsp_image); - img_buf=malloc(len); - fseek(nsp_image, 0, SEEK_SET); - fread(img_buf, 1, len, nsp_image); - img_buf[0xb] = 0x17; - fwrite(img_buf, 1, len-sizeof(struct checksumrecord), non_web); - fclose(non_web); - free(img_buf); - } - /* Close NSP image file */ - fclose(nsp_image); - - /* return result */ - return(0); -} - -#ifdef DMALLOC -#include <dmalloc.h> -#endif /* DMALLOC */ - -#define BUFLEN (1 << 16) - -static unsigned long crctab[256] = -{ - 0x0, - 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, - 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, - 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, - 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, - 0x5BD4B01B, 0x569796C2, 0x52568B75, 0x6A1936C8, 0x6ED82B7F, - 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, - 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, - 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58, - 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, - 0xA4AD16EA, 0xA06C0B5D, 0xD4326D90, 0xD0F37027, 0xDDB056FE, - 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95, - 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4, - 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0, - 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, - 0x2AC12072, 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, - 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, 0x7897AB07, - 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C, - 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, - 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, - 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, - 0xBB60ADFC, 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698, - 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D, - 0x94EA7B2A, 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, - 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, 0xC6BCF05F, - 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34, - 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, - 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, - 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A, - 0x58C1663D, 0x558240E4, 0x51435D53, 0x251D3B9E, 0x21DC2629, - 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, - 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, - 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E, - 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, - 0xEBA91BBC, 0xEF68060B, 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, - 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3, - 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2, - 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71, - 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, - 0x857130C3, 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, - 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, 0x7B827D21, - 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A, - 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E, 0x18197087, - 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC, - 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, - 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE, - 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, - 0xDBEE767C, 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, - 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, 0x89B8FD09, - 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, - 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF, - 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4 -}; - -int cs_is_tagged(FILE *fp) -{ - char buf[8]; - - fseek(fp, -8, SEEK_END); - fread(buf, 8, 1, fp); - if(*(unsigned long*)buf == CKSUM_MAGIC_NUMBER) - return 1; - return 0; -} - -unsigned long cs_read_sum(FILE *fp) -{ - char buf[8]; - - fseek(fp, -8, SEEK_END); - fread(buf, 8, 1, fp); - return *((unsigned long*)&buf[4]); -} - -int cs_calc_sum(FILE *fp, unsigned long *res, int tagged) -{ - unsigned char buf[BUFLEN]; - unsigned long crc = 0; - uintmax_t length = 0; - size_t bytes_read; - - fseek(fp, 0, SEEK_SET); - - while((bytes_read = fread(buf, 1, BUFLEN, fp)) > 0) - { - unsigned char *cp = buf; - - if(length + bytes_read < length) - return 0; - - if(bytes_read != BUFLEN && tagged) - bytes_read -= 8; - - length += bytes_read; - while(bytes_read--) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF]; - } - - if(ferror(fp)) - return 0; - - for(; length; length >>= 8) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF]; - - crc = ~crc & 0xFFFFFFFF; - - *res = crc; - - return 1; -} - -unsigned long cs_calc_buf_sum(char *buf, int size) -{ - unsigned long crc = 0; - char *cp = buf; - unsigned long length = size; - - while(size--) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF]; - - for(; length; length >>= 8) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF]; - - crc = ~crc & 0xFFFFFFFF; - - return crc; -} - -unsigned long cs_calc_buf_sum_ds(char *buf, int buf_size, char *sign, int sign_len) -{ - unsigned long crc = 0; - char *cp = buf; - unsigned long length = buf_size+sign_len; - - while(buf_size--) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF]; - - cp = sign; - while(sign_len--) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ *cp++) & 0xFF]; - - - for(; length; length >>= 8) - crc =(crc << 8) ^ crctab[((crc >> 24) ^ length) & 0xFF]; - - crc = ~crc & 0xFFFFFFFF; - - return crc; -} - -int cs_set_sum(FILE *fp, unsigned long sum, int tagged) -{ - unsigned long magic = CKSUM_MAGIC_NUMBER; - - if(tagged) - fseek(fp, -8, SEEK_END); - else - fseek(fp, 0, SEEK_END); - - if(fwrite(&magic, 1, 4, fp) < 4) - return 0; - if(fwrite(&sum, 1, 4, fp) < 4) - return 0; - - return 1; -} - -void cs_get_sum(FILE *fp, unsigned long *sum) -{ - unsigned long magic = 0; - - fseek(fp, -8, SEEK_END); - - fread(&magic, 4, 1, fp); - fread(sum, 4, 1, fp); -} - -int cs_validate_file(char *filename) -{ - FILE *pFile = NULL; - unsigned long sum = 0, res = 0; - - if((pFile = fopen(filename, "r")) == NULL) - return 0; - - if(!cs_is_tagged(pFile)) - { - fclose(pFile); - return 0; - } - if(!cs_calc_sum(pFile, &sum, 1)) - { - fclose(pFile); - return 0; - } - cs_get_sum(pFile, &res); - fclose(pFile); - - if(sum != res) - return 0; - return 1; -} - -/* ********* Library internal data ********* */ -#define CMDLINE_TRUE 1 -#define CMDLINE_FALSE 0 - -typedef enum CMDLINE_ERR -{ - CMDLINE_ERR_OK = 0, /* No Error (OK) */ - CMDLINE_ERR_ERROR = -1, /* Unspecified error */ - CMDLINE_ERR_INVKEY = -3, /* Invalid option key */ - CMDLINE_ERR_MANYARG = -4, /* Too many arguments */ - CMDLINE_ERR_FEWARG = -5, /* Too few arguments */ - CMDLINE_ERR_ILLOPT = -6, /* Option not allowed (illegal option) */ - CMDLINE_ERR_NOMEM = -7, /* No memory */ - CMDLINE_ERR_OPTMIS = -8 /* A mandatory option is missing */ -} CMDLINE_ERR; - -/* Argument list */ -typedef struct CMDLINE_ARG -{ - int index; /* Index of the argument in the command line */ - struct CMDLINE_ARG* p_next; /* Next node in the linked list */ -} CMDLINE_ARG; - -/* Master control block for an option */ -typedef struct CMDLINE_ARGS -{ - int argc; /* Total count of arguments found */ - int optc; /* Total count of options found */ - CMDLINE_ARG* list; /* Argument list */ -} CMDLINE_ARGS; - -/* Master control block for all found arguments */ -typedef struct CMDLINE_DATA -{ - CMDLINE_ARGS opt_args[26]; /* Array of MCBs for each option ('a' through 'z') */ - CMDLINE_ARGS glb_args; /* Global arguments */ - int parsed; /* Internal flag to prevent client calls if library is not initialized */ -} CMDLINE_DATA; - -/* ********* Local Data ********* */ -static CMDLINE_CFG cmdline_cfg; -static CMDLINE_DATA cmdline_data; - -char* cmdline_errmsg = "CMDLINE ERROR"; - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -void* cmdline_getarg_list(char opt) -{ - int index = (opt - 'a'); - - /* Check the validity of the index */ - if((index < 0) || (index > 25)) - { - /* ERROR: Wrong option */ - return NULL; - } - - /* Return a pointer to the ARGS control structure */ - return((void*)(&cmdline_data.opt_args[index])); -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -int cmdline_getarg_count(void* list) -{ - CMDLINE_ARGS* p_args = (CMDLINE_ARGS*)list; - - /* Return number of arguments for this option */ - return(p_args->argc); -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -int cmdline_getopt_count(char opt) -{ - int index; - - /* Calculate index value */ - index = opt - 'a'; - if(index < 0 || index > 25) return -1; - - /* Return number of arguments for this option */ - return(cmdline_data.opt_args[index].optc); -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -int cmdline_getarg(void* list, int num) -{ - int i; - CMDLINE_ARGS* p_args = (CMDLINE_ARGS*)list; - CMDLINE_ARG* p_arg; - - /* Search the 'num' argument in the list for this option */ - for(i=0,p_arg=p_args->list; (p_arg!=NULL) && (i<p_args->argc); i++, p_arg=p_arg->p_next) - { - /* if num matches i, we found it */ - if(i==num) return(p_arg->index); - } - /* We did not find the specified argument or the list was empty */ - return -1; -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -int cmdline_configure(CMDLINE_CFG* p_cfg) -{ - /* reset global data */ - memset(&cmdline_cfg,0,sizeof(cmdline_cfg)); - memset(&cmdline_data,0,sizeof(cmdline_data)); - - /* Copy the user's config structure */ - cmdline_cfg = *p_cfg; - return 0; -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -char* cmdline_error(int err) -{ - /* TODO: implement a table of error messages */ - return(cmdline_errmsg); -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -static void cmdline_print_args(CMDLINE_ARGS* p_arglist, char* argv[]) -{ - CMDLINE_ARG* p_arg; - - printf(" Number of times option was specified: %d\n", p_arglist->optc); - printf(" Number of Arguments: %d\n", p_arglist->argc); - - if(p_arglist->argc > 0) - { - printf(" Argument List: "); - - for(p_arg=p_arglist->list; p_arg != NULL; p_arg=p_arg->p_next) - printf("%s ", argv[p_arg->index]); - } - - printf("\n"); -} - -/* *************************************************************** -* Print all found command line options and their arguments -****************************************************************** */ -void cmdline_print(char* argv[]) -{ - int i; - - /* Check if the command line was parsed */ - if(cmdline_data.parsed != CMDLINE_TRUE) - { - printf("The command line has not been parsed yet.\n"); - return; - } - - /* Print out option arguments */ - for( i = 0; i < 26; i++ ) - { - /* Check if the option was specified */ - if(cmdline_data.opt_args[i].optc !=0 ) - { - /* Print out option name and arguments */ - printf("Option: -%c\n", (char)('a'+i)); - cmdline_print_args(&(cmdline_data.opt_args[i]), argv); - } - } - - /* Print out global arguments */ - printf("Global arguments:\n"); - cmdline_print_args(&(cmdline_data.glb_args), argv); -} - -/* *************************************************************** -* Print configuration -****************************************************************** */ -void cmdline_print_cfg(void) -{ - -} - -static void cmdline_argadd(CMDLINE_ARGS* p_arglist, CMDLINE_ARG* p_arg) -{ - CMDLINE_ARG* p_list; - CMDLINE_ARG* p_prev=NULL; - - /* See if we had anything in the list */ - if(p_arglist->argc == 0) - { - /* Link the argument in */ - p_arglist->list = p_arg; - } - else - { - /* Find the tail of the list */ - for(p_list=p_arglist->list; p_list != NULL; p_list=p_list->p_next) - p_prev = p_list; - - /* Link the argument in */ - p_prev->p_next=p_arg; - } - - /* Keep track of arg number */ - p_arglist->argc++; -} - -/* *************************************************************** -* cmdline_read() -* Read and parse command line arguments -****************************************************************** */ -int cmdline_read(int argc, char* argv[]) -{ - int i, option=0; - - /* Process every command line argument in argv[] array */ - for( i = 1; i < argc; i++ ) - { - /* Does the argument start with a dash? */ - if( *argv[i] == '-' ) - { - /* The argument must be two characters: a dash, and a letter */ - if( strlen(argv[i]) != 2 ) - { - /* ERROR: option syntax (needs to be a dash and one letter) */ - return(CMDLINE_ERR_ERROR); - } - - /* Check validity of the option key ('a' through 'z') */ - if( ((*(argv[i] + 1)) < 'a') || ((*(argv[i] + 1)) > 'z') ) - { - /* ERROR: option sysntax (invalid option key) */ - return(CMDLINE_ERR_INVKEY); - } - - /* Calculate the option index */ - option = (*(argv[i] + 1)) - 'a'; - if((option < 0) || (option > 25)) return(CMDLINE_ERR_INVKEY); - - /* Check to see if the option is allowed */ - if( cmdline_cfg.opts[option].flags & CMDLINE_OPTFLAG_ALLOW ) - { - /* Option allowed. */ - cmdline_data.opt_args[option].optc++; - continue; - } - else - { - /* ERROR: Option is not allowed */ - return(CMDLINE_ERR_ILLOPT); - } - } - else - { - /* Read the arguments for the option */ - CMDLINE_ARG* p_arg; - - /* Allocate space for the argument node */ - p_arg = (CMDLINE_ARG*)calloc(1,sizeof(CMDLINE_ARG)); - if( p_arg== NULL ) - { - /* ERROR: Can't allocate memory for the argument index */ - return(CMDLINE_ERR_NOMEM); - } - - /* Initialize the argument */ - p_arg->index = i; - p_arg->p_next = NULL; - - /* Check if we can add to the list of arguments for this option */ - if( (option < 0) /* Do we have to add to the global list? */ - || (cmdline_data.opt_args[option].argc == cmdline_cfg.opts[option].max) /* Did we reach MAX arguments? */ - ) - { - /* This option does not require arguments. Keep the argument in the global list. */ - cmdline_argadd(&(cmdline_data.glb_args), p_arg); - continue; - } - else - { - /* See if the current count has reached max for this option */ - if( cmdline_data.opt_args[option].argc == cmdline_cfg.opts[option].max ) - { - /* ERROR: too many arguments for an option */ - return(CMDLINE_ERR_MANYARG); - } - else - { - /* Link the argument to the arg list of the option */ - cmdline_argadd(&(cmdline_data.opt_args[option]), p_arg); - continue; - } - } - } - } - - /* ****** We read the complete command line. See if what we collected matches the configuration ******* */ - - /* Check every collected option against its configuration */ - for( i=0; i < 26; i++ ) - { - /* Check if this option was allowed */ - if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_ALLOW) - { - /* See if it was mandatory */ - if(cmdline_cfg.opts[i].flags & CMDLINE_OPTFLAG_MANDAT) - { - /* Check if we really collected this option on the command line. */ - if(cmdline_data.opt_args[i].optc == 0) - { - /* ERROR: a missing mandatory option */ - return(CMDLINE_ERR_OPTMIS); - } - else - { - /* Option was there. Check how many args we got for it. */ - if(cmdline_data.opt_args[i].argc < cmdline_cfg.opts[i].min) - { - /* ERROR: too few arguments for an option */ - return(CMDLINE_ERR_FEWARG); - } - else - { - /* This mandatory option was proper. */ - continue; - } - } - } - else /* This is non-mandatory option: */ - { - /* Check if the option was specified on the command line */ - if(cmdline_data.opt_args[i].optc == 0) - { - /* option wasn't specified, go to the next */ - continue; - } - else - { - /* Option was there. Check how many args we collected for it. */ - if(cmdline_data.opt_args[i].argc < cmdline_cfg.opts[i].min) - { - /* ERROR: too few arguments for a non-mandatory option */ - return(CMDLINE_ERR_FEWARG); - } - else - { - /* This non-mandatory option was proper. */ - continue; - } - } - } - } - else /* Option was not allowed. */ - { - /* We should not get here as the non-allowed options should have been - trapped eariler. */ - } - } - - /* Command line was proper as far as the number of options and their arguments */ - cmdline_data.parsed = CMDLINE_TRUE; - return(CMDLINE_ERR_OK); -} diff --git a/tools/firmware-utils/src/mktitanimg.h b/tools/firmware-utils/src/mktitanimg.h deleted file mode 100644 index 27b37b3fda..0000000000 --- a/tools/firmware-utils/src/mktitanimg.h +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#ifndef __MKTITANIMG_H -#define __MKTITANIMG_H - -#ifndef CFGMGR_CKSUM_H -#define CFGMGR_CKSUM_H - -#define CKSUM_MAGIC_NUMBER 0xC453DE23 - -#include <inttypes.h> -#include <stdio.h> -#include <errno.h> - -int cs_is_tagged(FILE*); -unsigned long cs_read_sum(FILE*); -int cs_calc_sum(FILE*, unsigned long*, int); -int cs_set_sum(FILE*, unsigned long, int); -void cs_get_sum(FILE*, unsigned long*); -unsigned long cs_calc_buf_sum(char*, int); -int cs_validate_file(char*); - -#endif -#ifndef ___CMDLINE_H___ -#define ___CMDLINE_H___ - -/* ********* Library Configuration ********* */ -typedef struct CMDLINE_OPT -{ - int min; /* Minimum number of arguments this option takes */ - int max; /* Maximum number of arguments this option takes */ - int flags; /* Controlling flags (whether to accept or not, etc) */ -} CMDLINE_OPT; - -typedef struct CMDLINE_CFG -{ - CMDLINE_OPT opts[26]; /* Options 'a' through 'z' */ - CMDLINE_OPT global; /* Global option (outside 'a'..'z') */ -} CMDLINE_CFG; -/* ******************************************** */ - -#define CMDLINE_OPTFLAG_ALLOW 0x1 /* The option is allowed */ -#define CMDLINE_OPTFLAG_MANDAT 0x2 /* The option is mandatory */ - -extern void cmdline_print(char* argv[]); - -extern int cmdline_configure(CMDLINE_CFG* p_cfg); -extern int cmdline_read(int argc, char* argv[]); - -extern void* cmdline_getarg_list(char opt); -extern int cmdline_getarg_count(void* list); -extern int cmdline_getopt_count(char opt); -extern int cmdline_getarg(void* list, int num); - -extern char* cmdline_error(int err); -#endif - - -#ifndef _NSPIMGHDR_H_ -#define _NSPIMGHDR_H_ - -/* This file describes the header format for the single image. The image is broken - up into several pieces. The image contains this header plus 1 or more sections. - Each section contains a binary block that could be a kernel, filesystem, etc. The - only garentee for this is that the very first section MUST be executable. Meaning - that the bootloader will be able to take the address of the header start, add the - header size, and execute that binary block. The header has its own checksum. It - starts hdr_size-4 bytes from the start of the header. - */ - -struct nsp_img_hdr_head -{ - unsigned int magic; /* Magic number to identify this image header */ - unsigned int boot_offset; /* Offset from start of header to kernel code. */ - unsigned int flags; /* Image flags. */ - unsigned int hdr_version; /* Version of this header. */ - unsigned int hdr_size; /* The complete size of all portions of the header */ - unsigned int prod_id; /* This product id */ - unsigned int rel_id; /* Which release this is */ - unsigned int version; /* name-MMM.nnn.ooo-rxx => 0xMMnnooxx. See comment - below */ - unsigned int image_size; /* Image size (including header) */ - unsigned int info_offset; /* Offset from start of header to info block */ - unsigned int sect_info_offset; /* Offset from start of header to section desc */ - unsigned int chksum_offset; /* Offset from start of header to chksum block */ -// unsigned int pad1; -}; - -/* The patch id is a machine readable value that takes the normal patch level, and encodes - the correct numbers inside of it. The format of the patches are name-MM.NN.oo-rxx.bin. - Convert MM, NN, oo, and xx into hex, and encode them as 0xMMNNooxx. Thus: - att-1.2.18-r14.bin => 0x0102120e */ - -/* The following are the flag bits for the above flags variable */ -/* List of NSP status flags: */ -#define NSP_IMG_FLAG_FAILBACK_MASK 0xF8000000 - -/* NSP Image status flag: Flag indicates individual sections image */ -#define NSP_IMG_FLAG_INDIVIDUAL 0x00000001 - -/* NSP Image status flag 1: Image contains a bootable image when this bit is 0 */ -#define NSP_IMG_FLAG_FAILBACK_1 0x08000000 - -/* NSP Image status flag 2: Image contains a non-bootable image when this bit is 0 */ -#define NSP_IMG_FLAG_FAILBACK_2 0x10000000 - -/* NSP Image status flag 3: PSPBoot has tried the image when this bit is 0 */ -#define NSP_IMG_FLAG_FAILBACK_3 0x20000000 - -/* NSP Image status flag 4: Image is now secondary image when this bit is 0 */ -#define NSP_IMG_FLAG_FAILBACK_4 0x40000000 - -/* NSP Image status flag 5: Image contains a valid image when this bit is 0 */ -#define NSP_IMG_FLAG_FAILBACK_5 0x80000000 - -/* NSP Single image magic number */ -#define NSP_IMG_MAGIC_NUMBER 0x4D544443 - - -struct nsp_img_hdr_info -{ - char release_name[64]; /* Name of release */ - char image_filename[64]; /* name-mm.nn.oo-rxx.bin format */ -}; - -struct nsp_img_hdr_section_info -{ - unsigned int num_sects; /* Number of section (and section desc blocks) in this - image */ - unsigned int sect_size; /* Size of a SINGLE section_desc block */ - unsigned int sections_offset; /* Offset to from start of header to the start of - the section blocks */ -}; - -/* There will be one of more of the following stuctures in the image header. Each - section will have one of these blocks. */ -struct nsp_img_hdr_sections -{ - unsigned int offset; /* Offset of section from start of NSP_IMG_HDR_HEAD */ - unsigned int total_size; /* Size of section (including pad size.) */ - unsigned int raw_size; /* Size of section only */ - unsigned int flags; /* Section flags */ - unsigned int chksum; /* Section checksum */ - unsigned int type; /* Section type. What kind of info does this section - describe */ - char name[16]; /* Reference name for this section. */ -}; -#define NSP_IMG_SECTION_TYPE_KERNEL (0x01) -#define NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT (0x02) -#define NSP_IMG_SECTION_TYPE_FILESYSTEM (0x03) - -struct nsp_img_hdr -{ - struct nsp_img_hdr_head head; /* Head portion */ - struct nsp_img_hdr_info info; /* Info */ - struct nsp_img_hdr_section_info sect_info; /* Section block */ - struct nsp_img_hdr_sections sections; /* 1 or more section_description blocks. More - section_desc blocks will be appended here - for each additional section needed */ -}; - -struct nsp_img_hdr_chksum -{ - unsigned int hdr_chksum; /* The checksum for the complete header. Excepting the - checksum block */ -}; - -struct nsp_img_hdr_sections *nsp_img_hdr_get_section_ptr_by_name(struct nsp_img_hdr *hdr, char *name); -unsigned int nsp_img_hdr_get_section_offset_by_name(struct nsp_img_hdr *hdr, char *name); -unsigned int nsp_img_hdr_get_section_size_by_name(struct nsp_img_hdr *hdr, char *name); - -#endif -#endif /* __MKTITANIMG_H */ diff --git a/tools/firmware-utils/src/mktplinkfw-lib.c b/tools/firmware-utils/src/mktplinkfw-lib.c deleted file mode 100644 index 9ad2a5d216..0000000000 --- a/tools/firmware-utils/src/mktplinkfw-lib.c +++ /dev/null @@ -1,261 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * This tool was based on: - * TP-Link WR941 V2 firmware checksum fixing tool. - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <stdbool.h> -#include <endian.h> -#include <errno.h> -#include <sys/stat.h> - -#include <arpa/inet.h> -#include <netinet/in.h> - -#include "mktplinkfw-lib.h" -#include "md5.h" - -extern char *ofname; -extern char *progname; -extern uint32_t kernel_len; -extern struct file_info kernel_info; -extern struct file_info rootfs_info; -extern struct flash_layout *layout; -extern uint32_t rootfs_ofs; -extern uint32_t rootfs_align; -extern int combined; -extern int strip_padding; -extern int add_jffs2_eof; - -static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; - -void fill_header(char *buf, int len); - -struct flash_layout *find_layout(struct flash_layout *layouts, const char *id) -{ - struct flash_layout *ret; - struct flash_layout *l; - - ret = NULL; - for (l = layouts; l->id != NULL; l++){ - if (strcasecmp(id, l->id) == 0) { - ret = l; - break; - } - }; - - return ret; -} - -void get_md5(const char *data, int size, uint8_t *md5) -{ - MD5_CTX ctx; - - MD5_Init(&ctx); - MD5_Update(&ctx, data, size); - MD5_Final(md5, &ctx); -} - -int get_file_stat(struct file_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) - return 0; - - res = stat(fdata->file_name, &st); - if (res){ - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - return 0; -} - -int read_to_buf(const struct file_info *fdata, char *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(fdata->file_name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - errno = 0; - fread(buf, fdata->file_size, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - -out_close: - fclose(f); -out: - return ret; -} - -static int pad_jffs2(char *buf, int currlen, int maxlen) -{ - int len; - uint32_t pad_mask; - - len = currlen; - pad_mask = (4 * 1024) | (64 * 1024); /* EOF at 4KB and at 64KB */ - while ((len < maxlen) && (pad_mask != 0)) { - uint32_t mask; - int i; - - for (i = 10; i < 32; i++) { - mask = 1 << i; - if (pad_mask & mask) - break; - } - - len = ALIGN(len, mask); - - for (i = 10; i < 32; i++) { - mask = 1 << i; - if ((len & (mask - 1)) == 0) - pad_mask &= ~mask; - } - - for (i = 0; i < sizeof(jffs2_eof_mark); i++) - buf[len + i] = jffs2_eof_mark[i]; - - len += sizeof(jffs2_eof_mark); - } - - return len; -} - -int write_fw(const char *ofname, const char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - -out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); - } -out: - return ret; -} - -/* Helper functions to inspect_fw() representing different output formats */ -inline void inspect_fw_pstr(const char *label, const char *str) -{ - printf("%-23s: %s\n", label, str); -} - -inline void inspect_fw_phex(const char *label, uint32_t val) -{ - printf("%-23s: 0x%08x\n", label, val); -} - -inline void inspect_fw_phexdec(const char *label, uint32_t val) -{ - printf("%-23s: 0x%08x / %8u bytes\n", label, val, val); -} - -inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text) -{ - int i; - - printf("%-23s:", label); - for (i=0; i<MD5SUM_LEN; i++) - printf(" %02x", val[i]); - printf(" %s\n", text); -} - -// header_size = sizeof(struct fw_header) -int build_fw(size_t header_size) -{ - int buflen; - char *buf; - char *p; - int ret = EXIT_FAILURE; - int writelen = 0; - - writelen = header_size + kernel_len; - - if (combined) - buflen = writelen; - else - buflen = layout->fw_max_len; - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - memset(buf, 0xff, buflen); - p = buf + header_size; - ret = read_to_buf(&kernel_info, p); - if (ret) - goto out_free_buf; - - if (!combined) { - p = buf + rootfs_ofs; - - ret = read_to_buf(&rootfs_info, p); - if (ret) - goto out_free_buf; - - writelen = rootfs_ofs + rootfs_info.file_size; - - if (add_jffs2_eof) - writelen = pad_jffs2(buf, writelen, layout->fw_max_len); - } - - if (!strip_padding) - writelen = buflen; - - fill_header(buf, writelen); - ret = write_fw(ofname, buf, writelen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - -out_free_buf: - free(buf); -out: - return ret; -} diff --git a/tools/firmware-utils/src/mktplinkfw-lib.h b/tools/firmware-utils/src/mktplinkfw-lib.h deleted file mode 100644 index 2003908cf9..0000000000 --- a/tools/firmware-utils/src/mktplinkfw-lib.h +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * This tool was based on: - * TP-Link WR941 V2 firmware checksum fixing tool. - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - - -#ifndef mktplinkfw_lib_h -#define mktplinkfw_lib_h - -#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) -#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0])) - -#define MD5SUM_LEN 16 - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - - -struct file_info { - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ -}; - -struct flash_layout { - char *id; - uint32_t fw_max_len; - uint32_t kernel_la; - uint32_t kernel_ep; - uint32_t rootfs_ofs; -}; - -struct flash_layout *find_layout(struct flash_layout *layouts, const char *id); -void get_md5(const char *data, int size, uint8_t *md5); -int get_file_stat(struct file_info *fdata); -int read_to_buf(const struct file_info *fdata, char *buf); -int write_fw(const char *ofname, const char *data, int len); -inline void inspect_fw_pstr(const char *label, const char *str); -inline void inspect_fw_phex(const char *label, uint32_t val); -inline void inspect_fw_phexdec(const char *label, uint32_t val); -inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text); -int build_fw(size_t header_size); - -#endif /* mktplinkfw_lib_h */ diff --git a/tools/firmware-utils/src/mktplinkfw.c b/tools/firmware-utils/src/mktplinkfw.c deleted file mode 100644 index e6d76a1942..0000000000 --- a/tools/firmware-utils/src/mktplinkfw.c +++ /dev/null @@ -1,644 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * This tool was based on: - * TP-Link WR941 V2 firmware checksum fixing tool. - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <stdbool.h> -#include <endian.h> -#include <errno.h> -#include <sys/stat.h> - -#include <arpa/inet.h> -#include <netinet/in.h> - -#include "md5.h" -#include "mktplinkfw-lib.h" - -#define HEADER_VERSION_V1 0x01000000 -#define HEADER_VERSION_V2 0x02000000 - -struct fw_header { - uint32_t version; /* header version */ - char vendor_name[24]; - char fw_version[36]; - uint32_t hw_id; /* hardware id */ - uint32_t hw_rev; /* hardware revision */ - uint32_t region_code; /* region code */ - uint8_t md5sum1[MD5SUM_LEN]; - uint32_t unk2; - uint8_t md5sum2[MD5SUM_LEN]; - uint32_t unk3; - uint32_t kernel_la; /* kernel load address */ - uint32_t kernel_ep; /* kernel entry point */ - uint32_t fw_length; /* total length of the firmware */ - uint32_t kernel_ofs; /* kernel data offset */ - uint32_t kernel_len; /* kernel data length */ - uint32_t rootfs_ofs; /* rootfs data offset */ - uint32_t rootfs_len; /* rootfs data length */ - uint32_t boot_ofs; /* bootloader data offset */ - uint32_t boot_len; /* bootloader data length */ - uint16_t ver_hi; - uint16_t ver_mid; - uint16_t ver_lo; - uint8_t pad[130]; - char region_str1[32]; - char region_str2[32]; - uint8_t pad2[160]; -} __attribute__ ((packed)); - -struct fw_region { - char name[4]; - uint32_t code; -}; - - -/* - * Globals - */ -char *ofname; -char *progname; -static char *vendor = "TP-LINK Technologies"; -static char *version = "ver. 1.0"; -static char *fw_ver = "0.0.0"; -static uint32_t hdr_ver = HEADER_VERSION_V1; - -static char *layout_id; -struct flash_layout *layout; -static char *opt_hw_id; -static uint32_t hw_id; -static char *opt_hw_rev; -static uint32_t hw_rev; -static uint32_t opt_hdr_ver = 1; -static char *country; -static const struct fw_region *region; -static int fw_ver_lo; -static int fw_ver_mid; -static int fw_ver_hi; -struct file_info kernel_info; -static uint32_t kernel_la = 0; -static uint32_t kernel_ep = 0; -uint32_t kernel_len = 0; -struct file_info rootfs_info; -uint32_t rootfs_ofs = 0; -uint32_t rootfs_align; -static struct file_info boot_info; -int combined; -int strip_padding; -int add_jffs2_eof; -static uint32_t fw_max_len; -static uint32_t reserved_space; - -static struct file_info inspect_info; -static int extract = 0; -static bool endian_swap = false; -static bool rootfs_ofs_calc = false; - -static const char md5salt_normal[MD5SUM_LEN] = { - 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb, - 0xdd, 0xf9, 0xe7, 0xf4, 0x0e, 0xae, 0x47, 0x38, -}; - -static const char md5salt_boot[MD5SUM_LEN] = { - 0x8c, 0xef, 0x33, 0x5b, 0xd5, 0xc5, 0xce, 0xfa, - 0xa7, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42, -}; - -static struct flash_layout layouts[] = { - { - .id = "4M", - .fw_max_len = 0x3c0000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x140000, - }, { - .id = "4Mlzma", - .fw_max_len = 0x3c0000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x100000, - }, { - .id = "8M", - .fw_max_len = 0x7c0000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x140000, - }, { - .id = "8Mlzma", - .fw_max_len = 0x7c0000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x100000, - }, { - .id = "8Mmtk", - .fw_max_len = 0x7c0000, - .kernel_la = 0x80000000, - .kernel_ep = 0x8000c310, - .rootfs_ofs = 0x100000, - }, { - .id = "16M", - .fw_max_len = 0xf80000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x140000, - }, { - .id = "16Mlzma", - .fw_max_len = 0xf80000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x100000, - }, { - .id = "16Mppc", - .fw_max_len = 0xf80000, - .kernel_la = 0x00000000 , - .kernel_ep = 0xc0000000, - .rootfs_ofs = 0x2a0000, - }, { - /* terminating entry */ - } -}; - -static const struct fw_region regions[] = { - /* Default region (universal) uses code 0 as well */ - {"US", 1}, - {"EU", 0}, - {"BR", 0}, -}; - -static const struct fw_region * find_region(const char *country) { - size_t i; - - for (i = 0; i < ARRAY_SIZE(regions); i++) { - if (strcasecmp(regions[i].name, country) == 0) - return ®ions[i]; - } - - return NULL; -} - -static void usage(int status) -{ - fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stderr, -"\n" -"Options:\n" -" -c use combined kernel image\n" -" -e swap endianness in kernel load address and entry point\n" -" -E <ep> overwrite kernel entry point with <ep> (hexval prefixed with 0x)\n" -" -L <la> overwrite kernel load address with <la> (hexval prefixed with 0x)\n" -" -H <hwid> use hardware id specified with <hwid>\n" -" -W <hwrev> use hardware revision specified with <hwrev>\n" -" -C <country> set region code to <country>\n" -" -F <id> use flash layout specified with <id>\n" -" -k <file> read kernel image from the file <file>\n" -" -r <file> read rootfs image from the file <file>\n" -" -a <align> align the rootfs start on an <align> bytes boundary\n" -" -R <offset> overwrite rootfs offset with <offset> (hexval prefixed with 0x)\n" -" -O calculate rootfs offset for combined images\n" -" -o <file> write output to the file <file>\n" -" -s strip padding from the end of the image\n" -" -j add jffs2 end-of-filesystem markers\n" -" -N <vendor> set image vendor to <vendor>\n" -" -V <version> set image version to <version>\n" -" -v <version> set firmware version to <version>\n" -" -m <version> set header version to <version>\n" -" -i <file> inspect given firmware file <file>\n" -" -x extract kernel and rootfs while inspecting (requires -i)\n" -" -X <size> reserve <size> bytes in the firmware image (hexval prefixed with 0x)\n" -" -h show this screen\n" - ); - - exit(status); -} - -static int check_options(void) -{ - int ret; - int exceed_bytes; - - if (inspect_info.file_name) { - ret = get_file_stat(&inspect_info); - if (ret) - return ret; - - return 0; - } else if (extract) { - ERR("no firmware for inspection specified"); - return -1; - } - - if (opt_hw_id == NULL) { - ERR("hardware id not specified"); - return -1; - } - hw_id = strtoul(opt_hw_id, NULL, 0); - - if (!combined && layout_id == NULL) { - ERR("flash layout is not specified"); - return -1; - } - - if (opt_hw_rev) - hw_rev = strtoul(opt_hw_rev, NULL, 0); - else - hw_rev = 1; - - if (country) { - region = find_region(country); - if (!region) { - ERR("unknown region code \"%s\"", country); - return -1; - } - } - - if (combined) { - if (!kernel_la || !kernel_ep) { - ERR("kernel loading address and entry point must be specified for combined image"); - return -1; - } - } else { - layout = find_layout(layouts, layout_id); - if (layout == NULL) { - ERR("unknown flash layout \"%s\"", layout_id); - return -1; - } - - if (!kernel_la) - kernel_la = layout->kernel_la; - if (!kernel_ep) - kernel_ep = layout->kernel_ep; - if (!rootfs_ofs) - rootfs_ofs = layout->rootfs_ofs; - - if (reserved_space > layout->fw_max_len) { - ERR("reserved space is not valid"); - return -1; - } - } - - if (kernel_info.file_name == NULL) { - ERR("no kernel image specified"); - return -1; - } - - ret = get_file_stat(&kernel_info); - if (ret) - return ret; - - kernel_len = kernel_info.file_size; - - if (!combined) { - fw_max_len = layout->fw_max_len - reserved_space; - - if (rootfs_info.file_name == NULL) { - ERR("no rootfs image specified"); - return -1; - } - - ret = get_file_stat(&rootfs_info); - if (ret) - return ret; - - if (rootfs_align) { - kernel_len += sizeof(struct fw_header); - rootfs_ofs = ALIGN(kernel_len, rootfs_align); - kernel_len -= sizeof(struct fw_header); - - DBG("rootfs offset aligned to 0x%u", rootfs_ofs); - - exceed_bytes = kernel_len + rootfs_info.file_size - (fw_max_len - sizeof(struct fw_header)); - if (exceed_bytes > 0) { - ERR("images are too big by %i bytes", exceed_bytes); - return -1; - } - } else { - exceed_bytes = kernel_info.file_size - (rootfs_ofs - sizeof(struct fw_header)); - if (exceed_bytes > 0) { - ERR("kernel image is too big by %i bytes", exceed_bytes); - return -1; - } - - exceed_bytes = rootfs_info.file_size - (fw_max_len - rootfs_ofs); - if (exceed_bytes > 0) { - ERR("rootfs image is too big by %i bytes", exceed_bytes); - return -1; - } - } - } - - if (ofname == NULL) { - ERR("no output file specified"); - return -1; - } - - ret = sscanf(fw_ver, "%d.%d.%d", &fw_ver_hi, &fw_ver_mid, &fw_ver_lo); - if (ret != 3) { - ERR("invalid firmware version '%s'", fw_ver); - return -1; - } - - if (opt_hdr_ver == 1) { - hdr_ver = HEADER_VERSION_V1; - } else if (opt_hdr_ver == 2) { - hdr_ver = HEADER_VERSION_V2; - } else { - ERR("invalid header version '%u'", opt_hdr_ver); - return -1; - } - - return 0; -} - -void fill_header(char *buf, int len) -{ - struct fw_header *hdr = (struct fw_header *)buf; - - memset(hdr, 0, sizeof(struct fw_header)); - - hdr->version = htonl(hdr_ver); - strncpy(hdr->vendor_name, vendor, sizeof(hdr->vendor_name)); - strncpy(hdr->fw_version, version, sizeof(hdr->fw_version)); - hdr->hw_id = htonl(hw_id); - hdr->hw_rev = htonl(hw_rev); - - hdr->kernel_la = htonl(kernel_la); - hdr->kernel_ep = htonl(kernel_ep); - hdr->kernel_ofs = htonl(sizeof(struct fw_header)); - hdr->kernel_len = htonl(kernel_len); - - if (!combined) { - if (boot_info.file_size == 0) - memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1)); - else - memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1)); - - hdr->fw_length = htonl(layout->fw_max_len); - hdr->rootfs_ofs = htonl(rootfs_ofs); - hdr->rootfs_len = htonl(rootfs_info.file_size); - } - - if (combined && rootfs_ofs_calc) { - hdr->rootfs_ofs = htonl(sizeof(struct fw_header) + kernel_len); - } - - hdr->ver_hi = htons(fw_ver_hi); - hdr->ver_mid = htons(fw_ver_mid); - hdr->ver_lo = htons(fw_ver_lo); - - if (region) { - hdr->region_code = htonl(region->code); - snprintf( - hdr->region_str1, sizeof(hdr->region_str1), "00000000;%02X%02X%02X%02X;", - region->name[0], region->name[1], region->name[2], region->name[3] - ); - snprintf( - hdr->region_str2, sizeof(hdr->region_str2), "%02X%02X%02X%02X", - region->name[0], region->name[1], region->name[2], region->name[3] - ); - } - - if (endian_swap) { - hdr->kernel_la = bswap_32(hdr->kernel_la); - hdr->kernel_ep = bswap_32(hdr->kernel_ep); - } - - if (!combined) - get_md5(buf, len, hdr->md5sum1); -} - -static int inspect_fw(void) -{ - char *buf; - struct fw_header *hdr; - uint8_t md5sum[MD5SUM_LEN]; - int ret = EXIT_FAILURE; - - buf = malloc(inspect_info.file_size); - if (!buf) { - ERR("no memory for buffer!\n"); - goto out; - } - - ret = read_to_buf(&inspect_info, buf); - if (ret) - goto out_free_buf; - hdr = (struct fw_header *)buf; - - inspect_fw_pstr("File name", inspect_info.file_name); - inspect_fw_phexdec("File size", inspect_info.file_size); - - if ((ntohl(hdr->version) != HEADER_VERSION_V1) && - (ntohl(hdr->version) != HEADER_VERSION_V2)) { - ERR("file does not seem to have V1/V2 header!\n"); - goto out_free_buf; - } - - inspect_fw_phexdec("Version 1 Header size", sizeof(struct fw_header)); - - memcpy(md5sum, hdr->md5sum1, sizeof(md5sum)); - if (ntohl(hdr->boot_len) == 0) - memcpy(hdr->md5sum1, md5salt_normal, sizeof(md5sum)); - else - memcpy(hdr->md5sum1, md5salt_boot, sizeof(md5sum)); - get_md5(buf, inspect_info.file_size, hdr->md5sum1); - - if (memcmp(md5sum, hdr->md5sum1, sizeof(md5sum))) { - inspect_fw_pmd5sum("Header MD5Sum1", md5sum, "(*ERROR*)"); - inspect_fw_pmd5sum(" --> expected", hdr->md5sum1, ""); - } else { - inspect_fw_pmd5sum("Header MD5Sum1", md5sum, "(ok)"); - } - if (ntohl(hdr->unk2) != 0) - inspect_fw_phexdec("Unknown value 2", hdr->unk2); - inspect_fw_pmd5sum("Header MD5Sum2", hdr->md5sum2, - "(purpose yet unknown, unchecked here)"); - if (ntohl(hdr->unk3) != 0) - inspect_fw_phexdec("Unknown value 3", hdr->unk3); - - printf("\n"); - - inspect_fw_pstr("Vendor name", hdr->vendor_name); - inspect_fw_pstr("Firmware version", hdr->fw_version); - inspect_fw_phex("Hardware ID", ntohl(hdr->hw_id)); - inspect_fw_phex("Hardware Revision", ntohl(hdr->hw_rev)); - inspect_fw_phex("Region code", ntohl(hdr->region_code)); - - printf("\n"); - - inspect_fw_phexdec("Kernel data offset", - ntohl(hdr->kernel_ofs)); - inspect_fw_phexdec("Kernel data length", - ntohl(hdr->kernel_len)); - inspect_fw_phex("Kernel load address", - ntohl(hdr->kernel_la)); - inspect_fw_phex("Kernel entry point", - ntohl(hdr->kernel_ep)); - inspect_fw_phexdec("Rootfs data offset", - ntohl(hdr->rootfs_ofs)); - inspect_fw_phexdec("Rootfs data length", - ntohl(hdr->rootfs_len)); - inspect_fw_phexdec("Boot loader data offset", - ntohl(hdr->boot_ofs)); - inspect_fw_phexdec("Boot loader data length", - ntohl(hdr->boot_len)); - inspect_fw_phexdec("Total firmware length", - ntohl(hdr->fw_length)); - - if (extract) { - FILE *fp; - char *filename; - - printf("\n"); - - filename = malloc(strlen(inspect_info.file_name) + 8); - sprintf(filename, "%s-kernel", inspect_info.file_name); - printf("Extracting kernel to \"%s\"...\n", filename); - fp = fopen(filename, "w"); - if (fp) { - if (!fwrite(buf + ntohl(hdr->kernel_ofs), - ntohl(hdr->kernel_len), 1, fp)) { - ERR("error in fwrite(): %s", strerror(errno)); - } - fclose(fp); - } else { - ERR("error in fopen(): %s", strerror(errno)); - } - free(filename); - - filename = malloc(strlen(inspect_info.file_name) + 8); - sprintf(filename, "%s-rootfs", inspect_info.file_name); - printf("Extracting rootfs to \"%s\"...\n", filename); - fp = fopen(filename, "w"); - if (fp) { - if (!fwrite(buf + ntohl(hdr->rootfs_ofs), - ntohl(hdr->rootfs_len), 1, fp)) { - ERR("error in fwrite(): %s", strerror(errno)); - } - fclose(fp); - } else { - ERR("error in fopen(): %s", strerror(errno)); - } - free(filename); - } - - out_free_buf: - free(buf); - out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "a:H:E:F:L:m:V:N:W:C:ci:k:r:R:o:OxX:ehsjv:"); - if (c == -1) - break; - - switch (c) { - case 'a': - sscanf(optarg, "0x%x", &rootfs_align); - break; - case 'H': - opt_hw_id = optarg; - break; - case 'E': - sscanf(optarg, "0x%x", &kernel_ep); - break; - case 'F': - layout_id = optarg; - break; - case 'W': - opt_hw_rev = optarg; - break; - case 'C': - country = optarg; - break; - case 'L': - sscanf(optarg, "0x%x", &kernel_la); - break; - case 'm': - sscanf(optarg, "%u", &opt_hdr_ver); - break; - case 'V': - version = optarg; - break; - case 'v': - fw_ver = optarg; - break; - case 'N': - vendor = optarg; - break; - case 'c': - combined++; - break; - case 'k': - kernel_info.file_name = optarg; - break; - case 'r': - rootfs_info.file_name = optarg; - break; - case 'R': - sscanf(optarg, "0x%x", &rootfs_ofs); - break; - case 'o': - ofname = optarg; - break; - case 'O': - rootfs_ofs_calc = 1; - break; - case 's': - strip_padding = 1; - break; - case 'i': - inspect_info.file_name = optarg; - break; - case 'j': - add_jffs2_eof = 1; - break; - case 'x': - extract = 1; - break; - case 'e': - endian_swap = true; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - case 'X': - sscanf(optarg, "0x%x", &reserved_space); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - if (!inspect_info.file_name) - ret = build_fw(sizeof(struct fw_header)); - else - ret = inspect_fw(); - - out: - return ret; -} diff --git a/tools/firmware-utils/src/mktplinkfw2.c b/tools/firmware-utils/src/mktplinkfw2.c deleted file mode 100644 index 47fe710dff..0000000000 --- a/tools/firmware-utils/src/mktplinkfw2.c +++ /dev/null @@ -1,647 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * This tool was based on: - * TP-Link WR941 V2 firmware checksum fixing tool. - * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <stdbool.h> -#include <endian.h> -#include <sys/stat.h> - -#include <arpa/inet.h> -#include <netinet/in.h> - -#include "md5.h" -#include "mktplinkfw-lib.h" - -struct fw_header { - uint32_t version; /* 0x00: header version */ - char fw_version[48]; /* 0x04: fw version string */ - uint32_t hw_id; /* 0x34: hardware id */ - uint32_t hw_rev; /* 0x38: FIXME: hardware revision? */ - uint32_t hw_ver_add; /* 0x3c: additional hardware version */ - uint8_t md5sum1[MD5SUM_LEN]; /* 0x40 */ - uint32_t unk2; /* 0x50: 0x00000000 */ - uint8_t md5sum2[MD5SUM_LEN]; /* 0x54 */ - uint32_t unk3; /* 0x64: 0xffffffff */ - - uint32_t kernel_la; /* 0x68: kernel load address */ - uint32_t kernel_ep; /* 0x6c: kernel entry point */ - uint32_t fw_length; /* 0x70: total length of the image */ - uint32_t kernel_ofs; /* 0x74: kernel data offset */ - uint32_t kernel_len; /* 0x78: kernel data length */ - uint32_t rootfs_ofs; /* 0x7c: rootfs data offset */ - uint32_t rootfs_len; /* 0x80: rootfs data length */ - uint32_t boot_ofs; /* 0x84: bootloader offset */ - uint32_t boot_len; /* 0x88: bootloader length */ - uint16_t unk4; /* 0x8c: 0x55aa */ - uint8_t sver_hi; /* 0x8e */ - uint8_t sver_lo; /* 0x8f */ - uint8_t unk5; /* 0x90: magic: 0xa5 */ - uint8_t ver_hi; /* 0x91 */ - uint8_t ver_mid; /* 0x92 */ - uint8_t ver_lo; /* 0x93 */ - uint8_t pad[364]; -} __attribute__ ((packed)); - -#define FLAG_LE_KERNEL_LA_EP 0x00000001 /* Little-endian used for kernel load address & entry point */ - -struct board_info { - char *id; - uint32_t hw_id; - uint32_t hw_rev; - uint32_t hw_ver_add; - char *layout_id; - uint32_t hdr_ver; - uint32_t flags; -}; - -/* - * Globals - */ -char *ofname; -char *progname; -static char *vendor = "TP-LINK Technologies"; -static char *version = "ver. 1.0"; -static char *fw_ver = "0.0.0"; -static char *sver = "1.0"; -static uint32_t hdr_ver = 2; - -static struct board_info custom_board; - -static struct board_info *board; -static char *layout_id; -struct flash_layout *layout; -static char *opt_hw_id; -static char *opt_hw_rev; -static char *opt_hw_ver_add; -static int fw_ver_lo; -static int fw_ver_mid; -static int fw_ver_hi; -static int sver_lo; -static int sver_hi; -struct file_info kernel_info; -static uint32_t kernel_la = 0; -static uint32_t kernel_ep = 0; -uint32_t kernel_len = 0; -struct file_info rootfs_info; -uint32_t rootfs_ofs = 0; -uint32_t rootfs_align; -static struct file_info boot_info; -int combined; -int strip_padding; -int add_jffs2_eof; - -static struct file_info inspect_info; -static int extract = 0; - -char md5salt_normal[MD5SUM_LEN] = { - 0xdc, 0xd7, 0x3a, 0xa5, 0xc3, 0x95, 0x98, 0xfb, - 0xdc, 0xf9, 0xe7, 0xf4, 0x0e, 0xae, 0x47, 0x37, -}; - -char md5salt_boot[MD5SUM_LEN] = { - 0x8c, 0xef, 0x33, 0x5f, 0xd5, 0xc5, 0xce, 0xfa, - 0xac, 0x9c, 0x28, 0xda, 0xb2, 0xe9, 0x0f, 0x42, -}; - -static struct flash_layout layouts[] = { - { - .id = "4Mmtk", - .fw_max_len = 0x3c0000, - .kernel_la = 0x80000000, - .kernel_ep = 0x80000000, - .rootfs_ofs = 0x140000, - }, { - .id = "4MLmtk", - .fw_max_len = 0x3d0000, - .kernel_la = 0x80000000, - .kernel_ep = 0x80000000, - .rootfs_ofs = 0x140000, - }, { - .id = "8Mltq", - .fw_max_len = 0x7a0000, - .kernel_la = 0x80002000, - .kernel_ep = 0x80002000, - .rootfs_ofs = 0x140000, - }, { - .id = "16Mltq", - .fw_max_len = 0xf90000, - .kernel_la = 0x80002000, - .kernel_ep = 0x800061b0, - .rootfs_ofs = 0x140000, - }, { - .id = "8Mmtk", - .fw_max_len = 0x7a0000, - .kernel_la = 0x80000000, - .kernel_ep = 0x80000000, - .rootfs_ofs = 0x140000, - }, { - .id = "8MSUmtk", /* Split U-Boot OS */ - .fw_max_len = 0x770000, - .kernel_la = 0x80000000, - .kernel_ep = 0x80000000, - .rootfs_ofs = 0x140000, - }, { - .id = "8MLmtk", - .fw_max_len = 0x7b0000, - .kernel_la = 0x80000000, - .kernel_ep = 0x80000000, - .rootfs_ofs = 0x140000, - }, { - .id = "8Mqca", - .fw_max_len = 0x7a0000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x140000, - }, { - .id = "16Mqca", - .fw_max_len = 0xf90000, - .kernel_la = 0x80060000, - .kernel_ep = 0x80060000, - .rootfs_ofs = 0x140000, - }, { - /* terminating entry */ - } -}; - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -c use combined kernel image\n" -" -e swap endianness in kernel load address and entry point\n" -" -E <ep> overwrite kernel entry point with <ep> (hexval prefixed with 0x)\n" -" -L <la> overwrite kernel load address with <la> (hexval prefixed with 0x)\n" -" -H <hwid> use hardware id specified with <hwid>\n" -" -W <hwrev> use hardware revision specified with <hwrev>\n" -" -w <hwveradd> use additional hardware version specified with <hwveradd>\n" -" -F <id> use flash layout specified with <id>\n" -" -k <file> read kernel image from the file <file>\n" -" -r <file> read rootfs image from the file <file>\n" -" -a <align> align the rootfs start on an <align> bytes boundary\n" -" -R <offset> overwrite rootfs offset with <offset> (hexval prefixed with 0x)\n" -" -o <file> write output to the file <file>\n" -" -s strip padding from the end of the image\n" -" -j add jffs2 end-of-filesystem markers\n" -" -N <vendor> set image vendor to <vendor>\n" -" -T <version> set header version to <version>\n" -" -V <version> set image version to <version>\n" -" -v <version> set firmware version to <version>\n" -" -y <version> set secondary version to <version>\n" -" -i <file> inspect given firmware file <file>\n" -" -x extract kernel and rootfs while inspecting (requires -i)\n" -" -h show this screen\n" - ); - - exit(status); -} - -static int check_options(void) -{ - int ret; - - if (inspect_info.file_name) { - ret = get_file_stat(&inspect_info); - if (ret) - return ret; - - return 0; - } else if (extract) { - ERR("no firmware for inspection specified"); - return -1; - } - - if (opt_hw_id == NULL) { - ERR("hardware id must be specified"); - return -1; - } - - board = &custom_board; - - if (layout_id == NULL) { - ERR("flash layout is not specified"); - return -1; - } - - board->hw_id = strtoul(opt_hw_id, NULL, 0); - - board->hw_rev = 1; - board->hw_ver_add = 0; - - if (opt_hw_rev) - board->hw_rev = strtoul(opt_hw_rev, NULL, 0); - if (opt_hw_ver_add) - board->hw_ver_add = strtoul(opt_hw_ver_add, NULL, 0); - - layout = find_layout(layouts, layout_id); - if (layout == NULL) { - ERR("unknown flash layout \"%s\"", layout_id); - return -1; - } - - if (!kernel_la) - kernel_la = layout->kernel_la; - if (!kernel_ep) - kernel_ep = layout->kernel_ep; - if (!rootfs_ofs) - rootfs_ofs = layout->rootfs_ofs; - - if (kernel_info.file_name == NULL) { - ERR("no kernel image specified"); - return -1; - } - - ret = get_file_stat(&kernel_info); - if (ret) - return ret; - - kernel_len = kernel_info.file_size; - - if (combined) { - if (kernel_info.file_size > - layout->fw_max_len - sizeof(struct fw_header)) { - ERR("kernel image is too big"); - return -1; - } - } else { - if (rootfs_info.file_name == NULL) { - ERR("no rootfs image specified"); - return -1; - } - - ret = get_file_stat(&rootfs_info); - if (ret) - return ret; - - if (rootfs_align) { - kernel_len += sizeof(struct fw_header); - rootfs_ofs = ALIGN(kernel_len, rootfs_align); - kernel_len -= sizeof(struct fw_header); - - DBG("rootfs offset aligned to 0x%u", rootfs_ofs); - - if (kernel_len + rootfs_info.file_size > - layout->fw_max_len - sizeof(struct fw_header)) { - ERR("images are too big"); - return -1; - } - } else { - if (kernel_info.file_size > - rootfs_ofs - sizeof(struct fw_header)) { - ERR("kernel image is too big"); - return -1; - } - - if (rootfs_info.file_size > - (layout->fw_max_len - rootfs_ofs)) { - ERR("rootfs image is too big"); - return -1; - } - } - } - - if (ofname == NULL) { - ERR("no output file specified"); - return -1; - } - - ret = sscanf(fw_ver, "%d.%d.%d", &fw_ver_hi, &fw_ver_mid, &fw_ver_lo); - if (ret != 3) { - ERR("invalid firmware version '%s'", fw_ver); - return -1; - } - - ret = sscanf(sver, "%d.%d", &sver_hi, &sver_lo); - if (ret != 2) { - ERR("invalid secondary version '%s'", sver); - return -1; - } - - return 0; -} - -void fill_header(char *buf, int len) -{ - struct fw_header *hdr = (struct fw_header *)buf; - unsigned ver_len; - - memset(hdr, '\xff', sizeof(struct fw_header)); - - hdr->version = htonl(bswap_32(hdr_ver)); - ver_len = strlen(version); - if (ver_len > (sizeof(hdr->fw_version) - 1)) - ver_len = sizeof(hdr->fw_version) - 1; - - memcpy(hdr->fw_version, version, ver_len); - hdr->fw_version[ver_len] = 0; - - hdr->hw_id = htonl(board->hw_id); - hdr->hw_rev = htonl(board->hw_rev); - hdr->hw_ver_add = htonl(board->hw_ver_add); - - if (boot_info.file_size == 0) { - memcpy(hdr->md5sum1, md5salt_normal, sizeof(hdr->md5sum1)); - hdr->boot_ofs = htonl(0); - hdr->boot_len = htonl(0); - } else { - memcpy(hdr->md5sum1, md5salt_boot, sizeof(hdr->md5sum1)); - hdr->boot_ofs = htonl(rootfs_ofs + rootfs_info.file_size); - hdr->boot_len = htonl(rootfs_info.file_size); - } - - hdr->kernel_la = htonl(kernel_la); - hdr->kernel_ep = htonl(kernel_ep); - hdr->fw_length = htonl(layout->fw_max_len); - hdr->kernel_ofs = htonl(sizeof(struct fw_header)); - hdr->kernel_len = htonl(kernel_len); - if (!combined) { - hdr->rootfs_ofs = htonl(rootfs_ofs); - hdr->rootfs_len = htonl(rootfs_info.file_size); - } - - hdr->boot_ofs = htonl(0); - hdr->boot_len = htonl(boot_info.file_size); - - hdr->unk2 = htonl(0); - hdr->unk3 = htonl(0xffffffff); - hdr->unk4 = htons(0x55aa); - hdr->unk5 = 0xa5; - - hdr->sver_hi = sver_hi; - hdr->sver_lo = sver_lo; - - hdr->ver_hi = fw_ver_hi; - hdr->ver_mid = fw_ver_mid; - hdr->ver_lo = fw_ver_lo; - - if (board->flags & FLAG_LE_KERNEL_LA_EP) { - hdr->kernel_la = bswap_32(hdr->kernel_la); - hdr->kernel_ep = bswap_32(hdr->kernel_ep); - } - - get_md5(buf, len, hdr->md5sum1); -} - -static int inspect_fw(void) -{ - char *buf; - struct fw_header *hdr; - uint8_t md5sum[MD5SUM_LEN]; - struct board_info *board; - int ret = EXIT_FAILURE; - - buf = malloc(inspect_info.file_size); - if (!buf) { - ERR("no memory for buffer!\n"); - goto out; - } - - ret = read_to_buf(&inspect_info, buf); - if (ret) - goto out_free_buf; - hdr = (struct fw_header *)buf; - - board = &custom_board; - - if (board->flags & FLAG_LE_KERNEL_LA_EP) { - hdr->kernel_la = bswap_32(hdr->kernel_la); - hdr->kernel_ep = bswap_32(hdr->kernel_ep); - } - - inspect_fw_pstr("File name", inspect_info.file_name); - inspect_fw_phexdec("File size", inspect_info.file_size); - - switch(bswap_32(ntohl(hdr->version))) { - case 2: - case 3: - break; - default: - ERR("file does not seem to have V2/V3 header!\n"); - goto out_free_buf; - } - - inspect_fw_phexdec("Version 2 Header size", sizeof(struct fw_header)); - - memcpy(md5sum, hdr->md5sum1, sizeof(md5sum)); - if (ntohl(hdr->boot_len) == 0) - memcpy(hdr->md5sum1, md5salt_normal, sizeof(md5sum)); - else - memcpy(hdr->md5sum1, md5salt_boot, sizeof(md5sum)); - get_md5(buf, inspect_info.file_size, hdr->md5sum1); - - if (memcmp(md5sum, hdr->md5sum1, sizeof(md5sum))) { - inspect_fw_pmd5sum("Header MD5Sum1", md5sum, "(*ERROR*)"); - inspect_fw_pmd5sum(" --> expected", hdr->md5sum1, ""); - } else { - inspect_fw_pmd5sum("Header MD5Sum1", md5sum, "(ok)"); - } - if (ntohl(hdr->unk2) != 0) - inspect_fw_phexdec("Unknown value 2", hdr->unk2); - inspect_fw_pmd5sum("Header MD5Sum2", hdr->md5sum2, - "(purpose yet unknown, unchecked here)"); - - if (ntohl(hdr->unk3) != 0xffffffff) - inspect_fw_phexdec("Unknown value 3", hdr->unk3); - - if (ntohs(hdr->unk4) != 0x55aa) - inspect_fw_phexdec("Unknown value 4", hdr->unk4); - - if (hdr->unk5 != 0xa5) - inspect_fw_phexdec("Unknown value 5", hdr->unk5); - - printf("\n"); - - inspect_fw_pstr("Firmware version", hdr->fw_version); - inspect_fw_phex("Hardware ID", ntohl(hdr->hw_id)); - inspect_fw_phex("Hardware Revision", - ntohl(hdr->hw_rev)); - inspect_fw_phex("Additional HW Version", - ntohl(hdr->hw_ver_add)); - - printf("%-23s: %d.%d.%d-%d.%d\n", "Software version", - hdr->ver_hi, hdr->ver_mid, hdr->ver_lo, - hdr->sver_hi, hdr->sver_lo); - - printf("\n"); - - inspect_fw_phexdec("Kernel data offset", - ntohl(hdr->kernel_ofs)); - inspect_fw_phexdec("Kernel data length", - ntohl(hdr->kernel_len)); - inspect_fw_phex("Kernel load address", - ntohl(hdr->kernel_la)); - inspect_fw_phex("Kernel entry point", - ntohl(hdr->kernel_ep)); - inspect_fw_phexdec("Rootfs data offset", - ntohl(hdr->rootfs_ofs)); - inspect_fw_phexdec("Rootfs data length", - ntohl(hdr->rootfs_len)); - inspect_fw_phexdec("Boot loader data offset", - ntohl(hdr->boot_ofs)); - inspect_fw_phexdec("Boot loader data length", - ntohl(hdr->boot_len)); - inspect_fw_phexdec("Total firmware length", - ntohl(hdr->fw_length)); - - if (extract) { - FILE *fp; - char *filename; - - printf("\n"); - - filename = malloc(strlen(inspect_info.file_name) + 8); - sprintf(filename, "%s-kernel", inspect_info.file_name); - printf("Extracting kernel to \"%s\"...\n", filename); - fp = fopen(filename, "w"); - if (fp) { - if (!fwrite(buf + ntohl(hdr->kernel_ofs), - ntohl(hdr->kernel_len), 1, fp)) { - ERR("error in fwrite(): %s", strerror(errno)); - } - fclose(fp); - } else { - ERR("error in fopen(): %s", strerror(errno)); - } - free(filename); - - filename = malloc(strlen(inspect_info.file_name) + 8); - sprintf(filename, "%s-rootfs", inspect_info.file_name); - printf("Extracting rootfs to \"%s\"...\n", filename); - fp = fopen(filename, "w"); - if (fp) { - if (!fwrite(buf + ntohl(hdr->rootfs_ofs), - ntohl(hdr->rootfs_len), 1, fp)) { - ERR("error in fwrite(): %s", strerror(errno)); - } - fclose(fp); - } else { - ERR("error in fopen(): %s", strerror(errno)); - } - free(filename); - } - - out_free_buf: - free(buf); - out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "a:H:E:F:L:V:N:W:w:ci:k:r:R:o:xhsjv:y:T:e"); - if (c == -1) - break; - - switch (c) { - case 'a': - sscanf(optarg, "0x%x", &rootfs_align); - break; - case 'H': - opt_hw_id = optarg; - break; - case 'E': - sscanf(optarg, "0x%x", &kernel_ep); - break; - case 'F': - layout_id = optarg; - break; - case 'W': - opt_hw_rev = optarg; - break; - case 'w': - opt_hw_ver_add = optarg; - break; - case 'L': - sscanf(optarg, "0x%x", &kernel_la); - break; - case 'V': - version = optarg; - break; - case 'v': - fw_ver = optarg; - break; - case 'y': - sver = optarg; - break; - case 'N': - vendor = optarg; - break; - case 'c': - combined++; - break; - case 'k': - kernel_info.file_name = optarg; - break; - case 'r': - rootfs_info.file_name = optarg; - break; - case 'R': - sscanf(optarg, "0x%x", &rootfs_ofs); - break; - case 'o': - ofname = optarg; - break; - case 's': - strip_padding = 1; - break; - case 'i': - inspect_info.file_name = optarg; - break; - case 'j': - add_jffs2_eof = 1; - break; - case 'x': - extract = 1; - break; - case 'T': - hdr_ver = atoi(optarg); - break; - case 'e': - custom_board.flags = FLAG_LE_KERNEL_LA_EP; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - if (!inspect_info.file_name) - ret = build_fw(sizeof(struct fw_header)); - else - ret = inspect_fw(); - - out: - return ret; -} - diff --git a/tools/firmware-utils/src/mkwrggimg.c b/tools/firmware-utils/src/mkwrggimg.c deleted file mode 100644 index 65ad293caa..0000000000 --- a/tools/firmware-utils/src/mkwrggimg.c +++ /dev/null @@ -1,279 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2016 Stijn Tintel <stijn@linux-ipv6.be> - */ - -#define _ANSI_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> -#include <libgen.h> -#include <getopt.h> -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include "md5.h" - -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define WRGG03_MAGIC 0x20080321 - -struct wrgg03_header { - char signature[32]; - uint32_t magic1; - uint32_t magic2; - char version[16]; - char model[16]; - uint32_t flag[2]; - uint32_t reserve[2]; - char buildno[16]; - uint32_t size; - uint32_t offset; - char devname[32]; - char digest[16]; -} __attribute__ ((packed)); - -static char *progname; -static char *ifname; -static char *ofname; -static char *signature; -static char *version; -static char *model; -static uint32_t flag = 0; -static uint32_t reserve = 0; -static char *buildno; -static uint32_t offset; -static char *devname; -static int big_endian; - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -b create image in big endian format\n" -" -B <buildno> build number\n" -" -i <file> read input from the file <file>\n" -" -d <name> set device name to <name>\n" -" -m <model> model name\n" -" -o <file> write output to the file <file>\n" -" -O <offset> set offset to <offset>\n" -" -s <sig> set image signature to <sig>\n" -" -h show this screen\n" - ); - - exit(status); -} - -static void put_u32(void *data, uint32_t val, int swap) -{ - unsigned char *p = data; - - if (swap) { - p[0] = (val >> 24) & 0xff; - p[1] = (val >> 16) & 0xff; - p[2] = (val >> 8) & 0xff; - p[3] = val & 0xff; - } else { - p[3] = (val >> 24) & 0xff; - p[2] = (val >> 16) & 0xff; - p[1] = (val >> 8) & 0xff; - p[0] = val & 0xff; - } -} - -static void get_digest(struct wrgg03_header *header, char *data, int size) -{ - MD5_CTX ctx; - - MD5_Init(&ctx); - - MD5_Update(&ctx, (char *)&header->offset, sizeof(header->offset)); - MD5_Update(&ctx, (char *)&header->devname, sizeof(header->devname)); - MD5_Update(&ctx, data, size); - - MD5_Final((unsigned char *)header->digest, &ctx); -} - -int main(int argc, char *argv[]) -{ - struct wrgg03_header *header; - char *buf; - struct stat st; - int buflen; - int err; - int res = EXIT_FAILURE; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "bd:i:m:o:s:v:B:O:h"); - if (c == -1) - break; - - switch (c) { - case 'b': - big_endian = 1; - break; - case 'B': - buildno = optarg; - break; - case 'd': - devname = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'm': - model = optarg; - break; - case 'o': - ofname = optarg; - break; - case 's': - signature = optarg; - break; - case 'v': - version = optarg; - break; - case 'O': - offset = strtoul(optarg, NULL, 0); - break; - case 'h': - usage(EXIT_SUCCESS); - break; - - default: - usage(EXIT_FAILURE); - break; - } - } - - if (signature == NULL) { - ERR("no signature specified"); - goto err; - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - if (devname == NULL) { - ERR("no device name specified"); - goto err; - } - - if (model == NULL) { - ERR("no model name specified"); - goto err; - } - - if (buildno == NULL) { - ERR("no build number specified"); - goto err; - } - - if (version == NULL) { - ERR("no version specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - buflen = st.st_size + sizeof(struct wrgg03_header); - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - errno = 0; - fread(buf + sizeof(struct wrgg03_header), st.st_size, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto close_in; - } - - header = (struct wrgg03_header *) buf; - memset(header, '\0', sizeof(struct wrgg03_header)); - - strncpy(header->signature, signature, sizeof(header->signature)); - put_u32(&header->magic1, WRGG03_MAGIC, 0); - put_u32(&header->magic2, WRGG03_MAGIC, 0); - strncpy(header->version, version, sizeof(header->version)); - strncpy(header->model, model, sizeof(header->model)); - put_u32(&header->flag, flag, 0); - put_u32(&header->reserve, reserve, 0); - strncpy(header->buildno, buildno, sizeof(header->buildno)); - put_u32(&header->size, st.st_size, big_endian); - put_u32(&header->offset, offset, big_endian); - strncpy(header->devname, devname, sizeof(header->devname)); - - get_digest(header, buf + sizeof(struct wrgg03_header), st.st_size); - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto close_in; - } - - errno = 0; - fwrite(buf, buflen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto close_out; - } - - fflush(outfile); - - res = EXIT_SUCCESS; - -close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) - unlink(ofname); -close_in: - fclose(infile); -err_free: - free(buf); -err: - return res; -} diff --git a/tools/firmware-utils/src/mkwrgimg.c b/tools/firmware-utils/src/mkwrgimg.c deleted file mode 100644 index 9a5993c277..0000000000 --- a/tools/firmware-utils/src/mkwrgimg.c +++ /dev/null @@ -1,236 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> -#include <libgen.h> -#include <getopt.h> -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include "md5.h" - -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define WRG_MAGIC 0x20040220 - -struct wrg_header { - char signature[32]; - uint32_t magic1; - uint32_t magic2; - uint32_t size; - uint32_t offset; - char devname[32]; - char digest[16]; -} __attribute__ ((packed)); - -static char *progname; -static char *ifname; -static char *ofname; -static char *signature; -static char *dev_name; -static uint32_t offset; -static int big_endian; - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -b create image in big endian format\n" -" -i <file> read input from the file <file>\n" -" -d <name> set device name to <name>\n" -" -o <file> write output to the file <file>\n" -" -O <offset> set offset to <offset>\n" -" -s <sig> set image signature to <sig>\n" -" -h show this screen\n" - ); - - exit(status); -} - -static void put_u32(void *data, uint32_t val) -{ - unsigned char *p = data; - - if (big_endian) { - p[0] = (val >> 24) & 0xff; - p[1] = (val >> 16) & 0xff; - p[2] = (val >> 8) & 0xff; - p[3] = val & 0xff; - } else { - p[3] = (val >> 24) & 0xff; - p[2] = (val >> 16) & 0xff; - p[1] = (val >> 8) & 0xff; - p[0] = val & 0xff; - } -} - -static void get_digest(struct wrg_header *header, char *data, int size) -{ - MD5_CTX ctx; - - MD5_Init(&ctx); - - MD5_Update(&ctx, (char *)&header->offset, sizeof(header->offset)); - MD5_Update(&ctx, (char *)&header->devname, sizeof(header->devname)); - MD5_Update(&ctx, data, size); - - MD5_Final((unsigned char *)header->digest, &ctx); -} - -int main(int argc, char *argv[]) -{ - struct wrg_header *header; - char *buf; - struct stat st; - int buflen; - int err; - int res = EXIT_FAILURE; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "bd:i:o:s:O:h"); - if (c == -1) - break; - - switch (c) { - case 'b': - big_endian = 1; - break; - case 'd': - dev_name = optarg; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 's': - signature = optarg; - break; - case 'O': - offset = strtoul(optarg, NULL, 0); - break; - case 'h': - usage(EXIT_SUCCESS); - break; - - default: - usage(EXIT_FAILURE); - break; - } - } - - if (signature == NULL) { - ERR("no signature specified"); - goto err; - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - if (dev_name == NULL) { - ERR("no device name specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - buflen = st.st_size + sizeof(struct wrg_header); - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - errno = 0; - fread(buf + sizeof(struct wrg_header), st.st_size, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto close_in; - } - - header = (struct wrg_header *) buf; - memset(header, '\0', sizeof(struct wrg_header)); - - strncpy(header->signature, signature, sizeof(header->signature)); - strncpy(header->devname, dev_name, sizeof(header->signature)); - put_u32(&header->magic1, WRG_MAGIC); - put_u32(&header->magic2, WRG_MAGIC); - put_u32(&header->size, st.st_size); - put_u32(&header->offset, offset); - - get_digest(header, buf + sizeof(struct wrg_header), st.st_size); - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto close_in; - } - - errno = 0; - fwrite(buf, buflen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto close_out; - } - - fflush(outfile); - - res = EXIT_SUCCESS; - -close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) - unlink(ofname); -close_in: - fclose(infile); -err_free: - free(buf); -err: - return res; -} diff --git a/tools/firmware-utils/src/mkzcfw.c b/tools/firmware-utils/src/mkzcfw.c deleted file mode 100644 index 1318b4acdc..0000000000 --- a/tools/firmware-utils/src/mkzcfw.c +++ /dev/null @@ -1,396 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#include "cyg_crc.h" - -#if (__BYTE_ORDER == __BIG_ENDIAN) -# define HOST_TO_BE32(x) (x) -# define BE32_TO_HOST(x) (x) -# define HOST_TO_LE32(x) bswap_32(x) -# define LE32_TO_HOST(x) bswap_32(x) -#else -# define HOST_TO_BE32(x) bswap_32(x) -# define BE32_TO_HOST(x) bswap_32(x) -# define HOST_TO_LE32(x) (x) -# define LE32_TO_HOST(x) (x) -#endif - -#define MAGIC_FIRMWARE 0x6d726966 /* 'firm' */ -#define MAGIC_KERNEL 0x676d694b /* 'Kimg' */ -#define MAGIC_ROOTFS 0x676d6952 /* 'Rimg' */ - -struct file_info { - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ -}; - -struct fw_header { - uint32_t magic; - uint32_t length; - uint32_t unk1; - uint32_t unk2; -} __attribute__ ((packed)); - -struct fw_tail { - uint32_t hw_id; - uint32_t crc; -} __attribute__ ((packed)); - -struct board_info { - char *id; - uint32_t hw_id; - uint32_t kernel_len; - uint32_t rootfs_len; -}; - -/* - * Globals - */ -static char *ofname; -static char *progname; - -static char *board_id; -static struct board_info *board; -static struct file_info kernel_info; -static struct file_info rootfs_info; - - -static struct board_info boards[] = { - { - .id = "ZCN-1523H-2-8", - .hw_id = 0x66661523, - .kernel_len = 0x170000, - .rootfs_len = 0x610000, - }, { - .id = "ZCN-1523H-5-16", - .hw_id = 0x6615235A, - .kernel_len = 0x170000, - .rootfs_len = 0x610000, - }, { - /* terminating entry */ - } -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define DBG(fmt, ...) do { \ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -static struct board_info *find_board(char *id) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->id != NULL; board++){ - if (strcasecmp(id, board->id) == 0) { - ret = board; - break; - } - }; - - return ret; -} - -static void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>\n" -" -k <file> read kernel image from the file <file>\n" -" -r <file> read rootfs image from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -h show this screen\n" - ); - - exit(status); -} - -static int get_file_stat(struct file_info *fdata) -{ - struct stat st; - int res; - - if (fdata->file_name == NULL) - return 0; - - res = stat(fdata->file_name, &st); - if (res){ - ERRS("stat failed on %s", fdata->file_name); - return res; - } - - fdata->file_size = st.st_size; - return 0; -} - -static int read_to_buf(struct file_info *fdata, char *buf) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(fdata->file_name, "r"); - if (f == NULL) { - ERRS("could not open \"%s\" for reading", fdata->file_name); - goto out; - } - - errno = 0; - fread(buf, fdata->file_size, 1, f); - if (errno != 0) { - ERRS("unable to read from file \"%s\"", fdata->file_name); - goto out_close; - } - - ret = EXIT_SUCCESS; - - out_close: - fclose(f); - out: - return ret; -} - -static int check_options(void) -{ - int ret; - - if (board_id == NULL) { - ERR("no board specified"); - return -1; - } - - board = find_board(board_id); - if (board == NULL) { - ERR("unknown/unsupported board id \"%s\"", board_id); - return -1; - } - - if (kernel_info.file_name == NULL) { - ERR("no kernel image specified"); - return -1; - } - - ret = get_file_stat(&kernel_info); - if (ret) - return ret; - - if (kernel_info.file_size > board->kernel_len) { - ERR("kernel image is too big"); - return -1; - } - - if (rootfs_info.file_name == NULL) { - ERR("no rootfs image specified"); - return -1; - } - - ret = get_file_stat(&rootfs_info); - if (ret) - return ret; - - if (rootfs_info.file_size > board->rootfs_len) { - ERR("rootfs image is too big"); - return -1; - } - - if (ofname == NULL) { - ERR("no output file specified"); - return -1; - } - - return 0; -} - -static int write_fw(char *data, int len) -{ - FILE *f; - int ret = EXIT_FAILURE; - - f = fopen(ofname, "w"); - if (f == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - errno = 0; - fwrite(data, len, 1, f); - if (errno) { - ERRS("unable to write output file"); - goto out_flush; - } - - DBG("firmware file \"%s\" completed", ofname); - - ret = EXIT_SUCCESS; - - out_flush: - fflush(f); - fclose(f); - if (ret != EXIT_SUCCESS) { - unlink(ofname); - } - out: - return ret; -} - -static int build_fw(void) -{ - int buflen; - char *buf; - char *p; - int ret = EXIT_FAILURE; - struct fw_header *hdr; - struct fw_tail *tail; - - buflen = 3 * sizeof(struct fw_header) + - kernel_info.file_size + rootfs_info.file_size + - 3 * sizeof(struct fw_tail); - - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto out; - } - - p = buf; - memset(p, 0, buflen); - - /* fill firmware header */ - hdr = (struct fw_header *) p; - hdr->magic = HOST_TO_LE32(MAGIC_FIRMWARE); - hdr->length = HOST_TO_LE32(buflen - sizeof(struct fw_header)); - p += sizeof(struct fw_header); - - /* fill kernel block header */ - hdr = (struct fw_header *) p; - hdr->magic = HOST_TO_LE32(MAGIC_KERNEL); - hdr->length = HOST_TO_LE32(kernel_info.file_size + - sizeof(struct fw_tail)); - p += sizeof(struct fw_header); - - /* read kernel data */ - ret = read_to_buf(&kernel_info, p); - if (ret) - goto out_free_buf; - - /* fill firmware tail */ - tail = (struct fw_tail *) (p + kernel_info.file_size); - tail->hw_id = HOST_TO_BE32(board->hw_id); - tail->crc = HOST_TO_BE32(cyg_crc32(p, kernel_info.file_size + - sizeof(struct fw_tail) - 4)); - - p += kernel_info.file_size + sizeof(struct fw_tail); - - /* fill rootfs block header */ - hdr = (struct fw_header *) p; - hdr->magic = HOST_TO_LE32(MAGIC_ROOTFS); - hdr->length = HOST_TO_LE32(rootfs_info.file_size + - sizeof(struct fw_tail)); - p += sizeof(struct fw_header); - - /* read rootfs data */ - ret = read_to_buf(&rootfs_info, p); - if (ret) - goto out_free_buf; - - /* fill firmware tail */ - tail = (struct fw_tail *) (p + rootfs_info.file_size); - tail->hw_id = HOST_TO_BE32(board->hw_id); - tail->crc = HOST_TO_BE32(cyg_crc32(p, rootfs_info.file_size + - sizeof(struct fw_tail) - 4)); - - p += rootfs_info.file_size + sizeof(struct fw_tail); - - /* fill firmware tail */ - tail = (struct fw_tail *) p; - tail->hw_id = HOST_TO_BE32(board->hw_id); - tail->crc = HOST_TO_BE32(cyg_crc32(buf + sizeof(struct fw_header), - buflen - sizeof(struct fw_header) - 4)); - - ret = write_fw(buf, buflen); - if (ret) - goto out_free_buf; - - ret = EXIT_SUCCESS; - - out_free_buf: - free(buf); - out: - return ret; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "B:k:r:o:h"); - if (c == -1) - break; - - switch (c) { - case 'B': - board_id = optarg; - break; - case 'k': - kernel_info.file_name = optarg; - break; - case 'r': - rootfs_info.file_name = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - ret = check_options(); - if (ret) - goto out; - - ret = build_fw(); - - out: - return ret; -} - diff --git a/tools/firmware-utils/src/mkzynfw.c b/tools/firmware-utils/src/mkzynfw.c deleted file mode 100644 index e856112f16..0000000000 --- a/tools/firmware-utils/src/mkzynfw.c +++ /dev/null @@ -1,1126 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * Copyright (C) 2007-2008 OpenWrt.org - * Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> -#include <endian.h> /* for __BYTE_ORDER */ -#if defined(__CYGWIN__) -# include <byteswap.h> -#endif -#include <inttypes.h> - -#include "zynos.h" - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define HOST_TO_LE16(x) (x) -# define HOST_TO_LE32(x) (x) -# define LE16_TO_HOST(x) (x) -# define LE32_TO_HOST(x) (x) -# define HOST_TO_BE16(x) bswap_16(x) -# define HOST_TO_BE32(x) bswap_32(x) -# define BE16_TO_HOST(x) bswap_16(x) -# define BE32_TO_HOST(x) bswap_32(x) -#else -# define HOST_TO_BE16(x) (x) -# define HOST_TO_BE32(x) (x) -# define BE16_TO_HOST(x) (x) -# define BE32_TO_HOST(x) (x) -# define HOST_TO_LE16(x) bswap_16(x) -# define HOST_TO_LE32(x) bswap_32(x) -# define LE16_TO_HOST(x) bswap_16(x) -# define LE32_TO_HOST(x) bswap_32(x) -#endif - -#define ALIGN(x,y) (((x)+((y)-1)) & ~((y)-1)) - -#define MAX_NUM_BLOCKS 8 -#define MAX_ARG_COUNT 32 -#define MAX_ARG_LEN 1024 -#define FILE_BUF_LEN (16*1024) - - -struct csum_state{ - int odd; - uint32_t sum; - uint32_t tmp; -}; - -struct fw_block { - uint32_t align; /* alignment of this block */ - char *file_name; /* name of the file */ - uint32_t file_size; /* length of the file */ - char *mmap_name; /* name in the MMAP table */ - int type; /* block type */ - uint32_t padlen; - uint8_t padc; -}; - -#define BLOCK_TYPE_BOOTEXT 0 -#define BLOCK_TYPE_RAW 1 - -struct fw_mmap { - uint32_t addr; - uint32_t size; - uint32_t user_addr; - uint32_t user_size; -}; -#define MMAP_DATA_SIZE 1024 -#define MMAP_ALIGN 16 - -struct board_info { - char *name; /* model name */ - char *desc; /* description */ - uint16_t vendor; /* vendor id */ - uint16_t model; /* model id */ - uint32_t flash_base; /* flash base address */ - uint32_t flash_size; /* board flash size */ - uint32_t code_start; /* code start address */ - uint32_t romio_offs; /* offset of the firmware within the flash */ - uint32_t bootext_size; /* maximum size of bootext block */ -}; - -/* - * Globals - */ -char *progname; -char *ofname = NULL; -int verblevel = 0; - -struct board_info *board = NULL; - -struct fw_block blocks[MAX_NUM_BLOCKS]; -struct fw_block *bootext_block = NULL; -int num_blocks = 0; - -#define ADM5120_FLASH_BASE 0xBFC00000 -#define ADM5120_CODE_START 0x80008000 - -/* TODO: check values for AR7 */ -#define AR7_FLASH_BASE 0xB0000000 -#define AR7_CODE_START 0x94008000 - -#define ATHEROS_FLASH_BASE 0xBFC00000 -#define ATHEROS_CODE_START 0x80e00000 - -#define AR71XX_FLASH_BASE 0xBFC00000 -#define AR71XX_CODE_START 0x81E00000 - -#define BOARD(n, d, v, m, fb, fs, cs, fo) { \ - .name = (n), .desc=(d), \ - .vendor = (v), .model = (m), \ - .flash_base = (fb), .flash_size = (fs)<<20, \ - .code_start = (cs), .romio_offs = (fo), \ - .bootext_size = BOOTEXT_DEF_SIZE \ - } - -#define ADMBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \ - ADM5120_FLASH_BASE, fs, ADM5120_CODE_START, 0x8000) - -#define ADMBOARD2(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \ - ADM5120_FLASH_BASE, fs, ADM5120_CODE_START, 0x10000) - -#define AR7BOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \ - AR7_FLASH_BASE, fs, AR7_CODE_START, 0x8000) - -#define ATHEROSBOARD1(n, d, m, fs) BOARD(n, d, ZYNOS_VENDOR_ID_ZYXEL, m, \ - ATHEROS_FLASH_BASE, fs, ATHEROS_CODE_START, 0x30000) - -#define AR71XXBOARD1(n, d, m, fs) { \ - .name = (n), .desc=(d), \ - .vendor = (ZYNOS_VENDOR_ID_ZYXEL), .model = (m), \ - .flash_base = (AR71XX_FLASH_BASE), .flash_size = (fs)<<20, \ - .code_start = (AR71XX_CODE_START), .romio_offs = (0x40000), \ - .bootext_size = 0x30000 \ - } - - -static struct board_info boards[] = { - /* - * Infineon/ADMtek ADM5120 based boards - */ - ADMBOARD2("ES-2024A", "ZyXEL ES-2024A", ZYNOS_MODEL_ES_2024A, 4), - ADMBOARD2("ES-2024PWR", "ZyXEL ES-2024PWR", ZYNOS_MODEL_ES_2024PWR, 4), - ADMBOARD2("ES-2108", "ZyXEL ES-2108", ZYNOS_MODEL_ES_2108, 4), - ADMBOARD2("ES-2108-F", "ZyXEL ES-2108-F", ZYNOS_MODEL_ES_2108_F, 4), - ADMBOARD2("ES-2108-G", "ZyXEL ES-2108-G", ZYNOS_MODEL_ES_2108_G, 4), - ADMBOARD2("ES-2108-LC", "ZyXEL ES-2108-LC", ZYNOS_MODEL_ES_2108_LC, 4), - ADMBOARD2("ES-2108PWR", "ZyXEL ES-2108PWR", ZYNOS_MODEL_ES_2108PWR, 4), - ADMBOARD1("HS-100", "ZyXEL HomeSafe 100", ZYNOS_MODEL_HS_100, 2), - ADMBOARD1("HS-100W", "ZyXEL HomeSafe 100W", ZYNOS_MODEL_HS_100W, 2), - ADMBOARD1("P-334", "ZyXEL Prestige 334", ZYNOS_MODEL_P_334, 2), - ADMBOARD1("P-334U", "ZyXEL Prestige 334U", ZYNOS_MODEL_P_334U, 4), - ADMBOARD1("P-334W", "ZyXEL Prestige 334W", ZYNOS_MODEL_P_334W, 2), - ADMBOARD1("P-334WH", "ZyXEL Prestige 334WH", ZYNOS_MODEL_P_334WH, 4), - ADMBOARD1("P-334WHD", "ZyXEL Prestige 334WHD", ZYNOS_MODEL_P_334WHD, 4), - ADMBOARD1("P-334WT", "ZyXEL Prestige 334WT", ZYNOS_MODEL_P_334WT, 4), - ADMBOARD1("P-335", "ZyXEL Prestige 335", ZYNOS_MODEL_P_335, 4), - ADMBOARD1("P-335Plus", "ZyXEL Prestige 335Plus", ZYNOS_MODEL_P_335PLUS, 4), - ADMBOARD1("P-335U", "ZyXEL Prestige 335U", ZYNOS_MODEL_P_335U, 4), - ADMBOARD1("P-335WT", "ZyXEL Prestige 335WT", ZYNOS_MODEL_P_335WT, 4), - - { - .name = "P-2602HW-D1A", - .desc = "ZyXEL P-2602HW-D1A", - .vendor = ZYNOS_VENDOR_ID_ZYXEL, - .model = ZYNOS_MODEL_P_2602HW_D1A, - .flash_base = AR7_FLASH_BASE, - .flash_size = 4*1024*1024, - .code_start = 0x94008000, - .romio_offs = 0x20000, - .bootext_size = BOOTEXT_DEF_SIZE, - }, - -#if 0 - /* - * Texas Instruments AR7 based boards - */ - AR7BOARD1("P-660H-61", "ZyXEL P-660H-61", ZYNOS_MODEL_P_660H_61, 2), - AR7BOARD1("P-660H-63", "ZyXEL P-660H-63", ZYNOS_MODEL_P_660H_63, 2), - AR7BOARD1("P-660H-D1", "ZyXEL P-660H-D1", ZYNOS_MODEL_P_660H_D1, 2), - AR7BOARD1("P-660H-D3", "ZyXEL P-660H-D3", ZYNOS_MODEL_P_660H_D3, 2), - AR7BOARD1("P-660HW-61", "ZyXEL P-660HW-61", ZYNOS_MODEL_P_660HW_61, 2), - AR7BOARD1("P-660HW-63", "ZyXEL P-660HW-63", ZYNOS_MODEL_P_660HW_63, 2), - AR7BOARD1("P-660HW-67", "ZyXEL P-660HW-67", ZYNOS_MODEL_P_660HW_67, 2), - AR7BOARD1("P-660HW-D1", "ZyXEL P-660HW-D1", ZYNOS_MODEL_P_660HW_D1, 2), - AR7BOARD1("P-660HW-D3", "ZyXEL P-660HW-D3", ZYNOS_MODEL_P_660HW_D3, 2), - AR7BOARD1("P-660R-61", "ZyXEL P-660R-61", ZYNOS_MODEL_P_660R_61, 2), - AR7BOARD1("P-660R-61C", "ZyXEL P-660R-61C", ZYNOS_MODEL_P_660R_61C, 2), - AR7BOARD1("P-660R-63", "ZyXEL P-660R-63", ZYNOS_MODEL_P_660R_63, 2), - AR7BOARD1("P-660R-63C", "ZyXEL P-660R-63C", ZYNOS_MODEL_P_660R_63C, 2), - AR7BOARD1("P-660R-67", "ZyXEL P-660R-67", ZYNOS_MODEL_P_660R_67, 2), - AR7BOARD1("P-660R-D1", "ZyXEL P-660R-D1", ZYNOS_MODEL_P_660R_D1, 2), - AR7BOARD1("P-660R-D3", "ZyXEL P-660R-D3", ZYNOS_MODEL_P_660R_D3, 2), -#endif - { - .name = "O2SURF", - .desc = "O2 DSL Surf & Phone", - .vendor = ZYNOS_VENDOR_ID_O2, - .model = ZYNOS_MODEL_O2SURF, - .flash_base = AR7_FLASH_BASE, - .flash_size = 8*1024*1024, - .code_start = 0x94014000, - .romio_offs = 0x40000, - .bootext_size = BOOTEXT_DEF_SIZE, - }, - - /* -:x - */ - ATHEROSBOARD1("NBG-318S", "ZyXEL NBG-318S", ZYNOS_MODEL_NBG_318S, 4), - - /* - * Atheros ar71xx based boards - */ - AR71XXBOARD1("NBG-460N", "ZyXEL NBG-460N", ZYNOS_MODEL_NBG_460N, 4), - - {.name = NULL} -}; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -#define WARN(fmt, ...) do { \ - fprintf(stderr, "[%s] *** warning: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define DBG(lev, fmt, ...) do { \ - if (verblevel < lev) \ - break;\ - fprintf(stderr, "[%s] " fmt "\n", progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERR_FATAL -1 -#define ERR_INVALID_IMAGE -2 - -/* - * Helper routines - */ -void -usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - struct board_info *board; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -B <board> create image for the board specified with <board>.\n" -" valid <board> values:\n" - ); - for (board = boards; board->name != NULL; board++){ - fprintf(stream, -" %-12s= %s\n", - board->name, board->desc); - }; - fprintf(stream, -" -b <file>[:<align>]\n" -" add boot extension block to the image\n" -" -r <file>[:<align>]\n" -" add raw block to the image\n" -" -o <file> write output to the file <file>\n" -" -h show this screen\n" - ); - - exit(status); -} - - -/* - * argument parsing - */ -int -str2u32(char *arg, uint32_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err)) { - return -1; - } - - *val = t; - return 0; -} - - -int -str2u16(char *arg, uint16_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x10000)) { - return -1; - } - - *val = t & 0xFFFF; - return 0; -} - -int -str2u8(char *arg, uint8_t *val) -{ - char *err = NULL; - uint32_t t; - - errno=0; - t = strtoul(arg, &err, 0); - if (errno || (err==arg) || ((err != NULL) && *err) || (t >= 0x100)) { - return -1; - } - - *val = t & 0xFF; - return 0; -} - -int -str2sig(char *arg, uint32_t *sig) -{ - if (strlen(arg) != 4) - return -1; - - *sig = arg[0] | (arg[1] << 8) | (arg[2] << 16) | (arg[3] << 24); - - return 0; -} - - -int -parse_arg(char *arg, char *buf, char *argv[]) -{ - int res = 0; - size_t argl; - char *tok; - char **ap = &buf; - int i; - - memset(argv, 0, MAX_ARG_COUNT * sizeof(void *)); - - if ((arg == NULL)) { - /* no arguments */ - return 0; - } - - argl = strlen(arg); - if (argl == 0) { - /* no arguments */ - return 0; - } - - if (argl >= MAX_ARG_LEN) { - /* argument is too long */ - argl = MAX_ARG_LEN-1; - } - - memcpy(buf, arg, argl); - buf[argl] = '\0'; - - for (i = 0; i < MAX_ARG_COUNT; i++) { - tok = strsep(ap, ":"); - if (tok == NULL) { - break; - } -#if 0 - else if (tok[0] == '\0') { - break; - } -#endif - argv[i] = tok; - res++; - } - - return res; -} - - -int -required_arg(char c, char *arg) -{ - if (arg == NULL || *arg != '-') - return 0; - - ERR("option -%c requires an argument\n", c); - return -1; -} - - -int -is_empty_arg(char *arg) -{ - int ret = 1; - if (arg != NULL) { - if (*arg) ret = 0; - }; - return ret; -} - - -void -csum_init(struct csum_state *css) -{ - css->odd = 0; - css->sum = 0; - css->tmp = 0; -} - - -void -csum_update(void *data, uint32_t len, struct csum_state *css) -{ - uint8_t *p = data; - - if (len == 0) - return; - - if (css->odd) { - css->sum += (css->tmp << 8) + p[0]; - if (css->sum > 0xFFFF) { - css->sum += 1; - css->sum &= 0xFFFF; - } - css->odd = 0; - len--; - p++; - } - - for ( ; len > 1; len -= 2, p +=2 ) { - css->sum += (p[0] << 8) + p[1]; - if (css->sum > 0xFFFF) { - css->sum += 1; - css->sum &= 0xFFFF; - } - } - - if (len == 1){ - css->tmp = p[0]; - css->odd = 1; - } -} - - -uint16_t -csum_get(struct csum_state *css) -{ - char pad = 0; - - csum_update(&pad, 1, css); - return css->sum; -} - -uint16_t -csum_buf(uint8_t *p, uint32_t len) -{ - struct csum_state css; - - csum_init(&css); - csum_update(p, len, &css); - return csum_get(&css); - -} - -/* - * routines to write data to the output file - */ -int -write_out_data(FILE *outfile, void *data, size_t len, - struct csum_state *css) -{ - uint8_t *ptr = data; - - errno = 0; - - fwrite(ptr, len, 1, outfile); - if (errno) { - ERR("unable to write output file"); - return -1; - } - - if (css) { - csum_update(ptr, len, css); - } - - return 0; -} - - -int -write_out_padding(FILE *outfile, size_t len, uint8_t padc, - struct csum_state *css) -{ - uint8_t buf[512]; - size_t buflen = sizeof(buf); - - memset(buf, padc, buflen); - while (len > 0) { - if (len < buflen) - buflen = len; - - if (write_out_data(outfile, buf, buflen, css)) - return -1; - - len -= buflen; - } - - return 0; -} - - -int -write_out_data_align(FILE *outfile, void *data, size_t len, size_t align, - struct csum_state *css) -{ - size_t padlen; - int res; - - res = write_out_data(outfile, data, len, css); - if (res) - return res; - - padlen = ALIGN(len,align) - len; - res = write_out_padding(outfile, padlen, 0xFF, css); - - return res; -} - - -int -write_out_header(FILE *outfile, struct zyn_rombin_hdr *hdr) -{ - struct zyn_rombin_hdr t; - - errno = 0; - if (fseek(outfile, 0, SEEK_SET) != 0) { - ERRS("fseek failed on output file"); - return -1; - } - - /* setup temporary header fields */ - memset(&t, 0, sizeof(t)); - t.addr = HOST_TO_BE32(hdr->addr); - memcpy(&t.sig, ROMBIN_SIGNATURE, ROMBIN_SIG_LEN); - t.type = hdr->type; - t.flags = hdr->flags; - t.osize = HOST_TO_BE32(hdr->osize); - t.csize = HOST_TO_BE32(hdr->csize); - t.ocsum = HOST_TO_BE16(hdr->ocsum); - t.ccsum = HOST_TO_BE16(hdr->ccsum); - t.mmap_addr = HOST_TO_BE32(hdr->mmap_addr); - - DBG(2, "hdr.addr = 0x%08x", hdr->addr); - DBG(2, "hdr.type = 0x%02x", hdr->type); - DBG(2, "hdr.osize = 0x%08x", hdr->osize); - DBG(2, "hdr.csize = 0x%08x", hdr->csize); - DBG(2, "hdr.flags = 0x%02x", hdr->flags); - DBG(2, "hdr.ocsum = 0x%04x", hdr->ocsum); - DBG(2, "hdr.ccsum = 0x%04x", hdr->ccsum); - DBG(2, "hdr.mmap_addr = 0x%08x", hdr->mmap_addr); - - return write_out_data(outfile, (uint8_t *)&t, sizeof(t), NULL); -} - - -int -write_out_mmap(FILE *outfile, struct fw_mmap *mmap, struct csum_state *css) -{ - struct zyn_mmt_hdr *mh; - uint8_t buf[MMAP_DATA_SIZE]; - uint32_t user_size; - char *data; - int res; - - memset(buf, 0, sizeof(buf)); - - mh = (struct zyn_mmt_hdr *)buf; - - /* TODO: needs to recreate the memory map too? */ - mh->count=0; - - /* Build user data section */ - data = (char *)buf + sizeof(*mh); - data += sprintf(data, "Vendor 1 %d", board->vendor); - *data++ = '\0'; - data += sprintf(data, "Model 1 %d", BE16_TO_HOST(board->model)); - *data++ = '\0'; - /* TODO: make hardware version configurable? */ - data += sprintf(data, "HwVerRange 2 %d %d", 0, 0); - *data++ = '\0'; - - user_size = (uint8_t *)data - buf; - mh->user_start= HOST_TO_BE32(mmap->addr+sizeof(*mh)); - mh->user_end= HOST_TO_BE32(mmap->addr+user_size); - mh->csum = HOST_TO_BE16(csum_buf(buf+sizeof(*mh), user_size)); - - res = write_out_data(outfile, buf, sizeof(buf), css); - - return res; -} - - -int -block_stat_file(struct fw_block *block) -{ - struct stat st; - int res; - - if (block->file_name == NULL) - return 0; - - res = stat(block->file_name, &st); - if (res){ - ERRS("stat failed on %s", block->file_name); - return res; - } - - block->file_size = st.st_size; - return 0; -} - - -int -read_magic(uint16_t *magic) -{ - FILE *f; - int res; - - errno = 0; - f = fopen(bootext_block->file_name,"r"); - if (errno) { - ERRS("unable to open file: %s", bootext_block->file_name); - return -1; - } - - errno = 0; - fread(magic, 2, 1, f); - if (errno != 0) { - ERRS("unable to read from file: %s", bootext_block->file_name); - res = -1; - goto err; - } - - res = 0; - -err: - fclose(f); - return res; -} - - -int -write_out_file(FILE *outfile, char *name, size_t len, struct csum_state *css) -{ - char buf[FILE_BUF_LEN]; - size_t buflen = sizeof(buf); - FILE *f; - int res; - - DBG(2, "writing out file, name=%s, len=%zu", - name, len); - - errno = 0; - f = fopen(name,"r"); - if (errno) { - ERRS("unable to open file: %s", name); - return -1; - } - - while (len > 0) { - if (len < buflen) - buflen = len; - - /* read data from source file */ - errno = 0; - fread(buf, buflen, 1, f); - if (errno != 0) { - ERRS("unable to read from file: %s",name); - res = -1; - break; - } - - res = write_out_data(outfile, buf, buflen, css); - if (res) - break; - - len -= buflen; - } - - fclose(f); - return res; -} - - -int -write_out_block(FILE *outfile, struct fw_block *block, struct csum_state *css) -{ - int res; - - if (block == NULL) - return 0; - - if (block->file_name == NULL) - return 0; - - if (block->file_size == 0) - return 0; - - res = write_out_file(outfile, block->file_name, - block->file_size, css); - return res; -} - - -int -write_out_image(FILE *outfile) -{ - struct fw_block *block; - struct fw_mmap mmap; - struct zyn_rombin_hdr hdr; - struct csum_state css; - int i, res; - uint32_t offset; - uint32_t padlen; - uint16_t csum; - uint16_t t; - - /* setup header fields */ - memset(&hdr, 0, sizeof(hdr)); - hdr.addr = board->code_start; - hdr.type = OBJECT_TYPE_BOOTEXT; - hdr.flags = ROMBIN_FLAG_OCSUM; - - offset = board->romio_offs; - - res = write_out_header(outfile, &hdr); - if (res) - return res; - - offset += sizeof(hdr); - - csum_init(&css); - res = write_out_block(outfile, bootext_block, &css); - if (res) - return res; - - offset += bootext_block->file_size; - if (offset > (board->romio_offs + board->bootext_size)) { - ERR("bootext file '%s' is too big", bootext_block->file_name); - return -1; - } - - padlen = ALIGN(offset, MMAP_ALIGN) - offset; - res = write_out_padding(outfile, padlen, 0xFF, &css); - if (res) - return res; - - offset += padlen; - - mmap.addr = board->flash_base + offset; - res = write_out_mmap(outfile, &mmap, &css); - if (res) - return res; - - offset += MMAP_DATA_SIZE; - - if ((offset - board->romio_offs) < board->bootext_size) { - padlen = board->romio_offs + board->bootext_size - offset; - res = write_out_padding(outfile, padlen, 0xFF, &css); - if (res) - return res; - offset += padlen; - - DBG(2, "bootext end at %08x", offset); - } - - for (i = 0; i < num_blocks; i++) { - block = &blocks[i]; - - if (block->type == BLOCK_TYPE_BOOTEXT) - continue; - - padlen = ALIGN(offset, block->align) - offset; - res = write_out_padding(outfile, padlen, 0xFF, &css); - if (res) - return res; - offset += padlen; - - res = write_out_block(outfile, block, &css); - if (res) - return res; - offset += block->file_size; - } - - padlen = ALIGN(offset, 4) - offset; - res = write_out_padding(outfile, padlen, 0xFF, &css); - if (res) - return res; - offset += padlen; - - csum = csum_get(&css); - hdr.mmap_addr = mmap.addr; - hdr.osize = 2; - - res = read_magic(&hdr.ocsum); - if (res) - return res; - hdr.ocsum = BE16_TO_HOST(hdr.ocsum); - - if (csum <= hdr.ocsum) - t = hdr.ocsum - csum; - else - t = hdr.ocsum - csum - 1; - - DBG(2, "ocsum=%04x, csum=%04x, fix=%04x", hdr.ocsum, csum, t); - - t = HOST_TO_BE16(t); - res = write_out_data(outfile, (uint8_t *)&t, 2, NULL); - if (res) - return res; - - - res = write_out_header(outfile, &hdr); - - return res; -} - - -struct board_info * -find_board(char *name) -{ - struct board_info *ret; - struct board_info *board; - - ret = NULL; - for (board = boards; board->name != NULL; board++){ - if (strcasecmp(name, board->name) == 0) { - ret = board; - break; - } - }; - - return ret; -} - - -int -parse_opt_board(char ch, char *arg) -{ - - DBG(1,"parsing board option: -%c %s", ch, arg); - - if (board != NULL) { - ERR("only one board option allowed"); - return -1; - } - - if (required_arg(ch, arg)) - return -1; - - board = find_board(arg); - if (board == NULL){ - ERR("invalid/unknown board specified: %s", arg); - return -1; - } - - return 0; -} - - -int -parse_opt_ofname(char ch, char *arg) -{ - - if (ofname != NULL) { - ERR("only one output file allowed"); - return -1; - } - - if (required_arg(ch, arg)) - return -1; - - ofname = arg; - - return 0; -} - - -int -parse_opt_block(char ch, char *arg) -{ - char buf[MAX_ARG_LEN]; - char *argv[MAX_ARG_COUNT]; - char *p; - struct fw_block *block; - int i; - - if ( num_blocks >= MAX_NUM_BLOCKS ) { - ERR("too many blocks specified"); - return -1; - } - - block = &blocks[num_blocks++]; - - /* setup default field values */ - block->padc = 0xFF; - - switch(ch) { - case 'b': - if (bootext_block) { - ERR("only one boot extension block allowed"); - break; - } - block->type = BLOCK_TYPE_BOOTEXT; - bootext_block = block; - break; - case 'r': - block->type = BLOCK_TYPE_RAW; - break; - } - - parse_arg(arg, buf, argv); - - i = 0; - p = argv[i++]; - if (is_empty_arg(p)) { - ERR("no file specified in %s", arg); - return -1; - } else { - block->file_name = strdup(p); - if (block->file_name == NULL) { - ERR("not enough memory"); - return -1; - } - } - - if (block->type == BLOCK_TYPE_BOOTEXT) - return 0; - - p = argv[i++]; - if (!is_empty_arg(p)) { - if (str2u32(p, &block->align) != 0) { - ERR("invalid block align in %s", arg); - return -1; - } - } - - return 0; -} - - -int -calc_block_offsets(int type, uint32_t *offset) -{ - struct fw_block *block; - uint32_t next_offs; - uint32_t avail; - int i, res; - - DBG(1,"calculating block offsets, starting with %" PRIu32, - *offset); - - res = 0; - for (i = 0; i < num_blocks; i++) { - block = &blocks[i]; - - if (block->type != type) - continue; - - next_offs = ALIGN(*offset, block->align); - avail = board->flash_size - next_offs; - if (block->file_size > avail) { - ERR("file %s is too big, offset = %u, size=%u," - " avail = %u, align = %u", block->file_name, - (unsigned)next_offs, - (unsigned)block->file_size, - (unsigned)avail, - (unsigned)block->align); - res = -1; - break; - } - - block->padlen = next_offs - *offset; - *offset += block->file_size; - } - - return res; -} - -int -process_blocks(void) -{ - struct fw_block *block; - uint32_t offset; - int i; - int res; - - /* collecting file stats */ - for (i = 0; i < num_blocks; i++) { - block = &blocks[i]; - res = block_stat_file(block); - if (res) - return res; - } - - offset = board->romio_offs + bootext_block->file_size; - res = calc_block_offsets(BLOCK_TYPE_RAW, &offset); - - return res; -} - - -int -main(int argc, char *argv[]) -{ - int optinvalid = 0; /* flag for invalid option */ - int c; - int res = EXIT_FAILURE; - - FILE *outfile; - - progname=basename(argv[0]); - - opterr = 0; /* could not print standard getopt error messages */ - while ( 1 ) { - optinvalid = 0; - - c = getopt(argc, argv, "b:B:ho:r:v"); - if (c == -1) - break; - - switch (c) { - case 'b': - case 'r': - optinvalid = parse_opt_block(c,optarg); - break; - case 'B': - optinvalid = parse_opt_board(c,optarg); - break; - case 'o': - optinvalid = parse_opt_ofname(c,optarg); - break; - case 'v': - verblevel++; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - optinvalid = 1; - break; - } - if (optinvalid != 0 ) { - ERR("invalid option: -%c", optopt); - goto out; - } - } - - if (board == NULL) { - ERR("no board specified"); - goto out; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto out; - } - - if (optind < argc) { - ERR("invalid option: %s", argv[optind]); - goto out; - } - - if (process_blocks() != 0) { - goto out; - } - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto out; - } - - if (write_out_image(outfile) != 0) - goto out_flush; - - DBG(1,"Image file %s completed.", ofname); - - res = EXIT_SUCCESS; - -out_flush: - fflush(outfile); - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } -out: - return res; -} diff --git a/tools/firmware-utils/src/mkzyxelzldfw.c b/tools/firmware-utils/src/mkzyxelzldfw.c deleted file mode 100644 index b61d0c1485..0000000000 --- a/tools/firmware-utils/src/mkzyxelzldfw.c +++ /dev/null @@ -1,830 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2020 Vincent Wiemann <vw@derowe.com> - * - * This program is derived from ZyXEL's GPL U-Boot code. - * Copyright (C) 2011-2011 ZyXEL Communications, Corp. - */ - -#define _POSIX_SOURCE -#define _POSIX_C_SOURCE 199309L /* getopt */ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <time.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <string.h> -#include <unistd.h> -#include <netinet/in.h> -#include <limits.h> -#include "md5.h" - -#define ZYXEL_MAGIC 0xdeadbeaf -#define MAX_MODELS 5 -#define CHECKSUM_SIZE sizeof(uint32_t) -#define MAX_FILES 32 -#define MAX_FILENAME 64 - -#define DATE_SIZE 32 -#define REV_SIZE 32 - -#define error(fmt, ...) \ - do { \ - printf("Error: " fmt, ##__VA_ARGS__); \ - exit(1); \ - } while (0) - -enum { - FILE_TYPE_BM = 1, - FILE_TYPE_KERNEL, - FILE_TYPE_CORE, - FILE_TYPE_DB, - FILE_TYPE_CONF, - FILE_TYPE_WTP -}; - -struct file_type_tbl { - int type; - char *str; -}; - -struct file_type_tbl file_types[] = { - { FILE_TYPE_BM, "bm" }, { FILE_TYPE_KERNEL, "kernel" }, - { FILE_TYPE_CORE, "core" }, { FILE_TYPE_DB, "db" }, - { FILE_TYPE_CONF, "conf", }, { FILE_TYPE_WTP, "wtp" } -}; -static int FILE_TYPE_COUNT = sizeof(file_types) / sizeof(struct file_type_tbl); - -struct fw_header { - uint32_t checksum; /* MD5-based checksum */ - uint32_t magic; /* 0xdeadbeaf */ - uint16_t version; /* version of the firmware archive */ - uint16_t files_count; /* number of files contained */ - uint16_t models_count; /* number of supported models */ - uint16_t models[MAX_MODELS]; /* supported models' IDs */ - uint32_t total_length; /* total length of the firmware archive */ - uint16_t files_offset; /* offset of the first file */ - uint16_t header_length; /* length of this header */ - uint16_t info_length; /* length of the file information header */ - uint16_t __padding1[3]; /* reserved for future use */ - char capwap_version[32]; /* e.g. "undefined" */ - char model_name[32]; /* e.g. "NWA512X-FAT" */ -} __attribute__((packed)); - -struct fw_header_file { - uint16_t type; /* file type (e.g. FILE_TYPE_KERNEL) */ - uint16_t flags; /* unknown */ - uint32_t length; /* length of the file */ - uint32_t checksum; /* checksum of the file */ - uint32_t flash_offset; /* write offset from beginning of flash */ - char filename[MAX_FILENAME]; /* original file name */ - char target[128]; /* target "file" name (e.g. "kernel", "zldfs") */ - char revision[REV_SIZE]; /* revision string */ - char date[32]; /* creation date string */ -} __attribute__((packed)); - -struct fw_header_kernel { - char bm_version[64]; - char kernel_version[64]; - char core_version[64]; - char capwap_version[32]; - char model_name[32]; - uint32_t bm_checksum; - uint32_t kernel_checksum; - uint32_t zld_checksum; - uint32_t core_checksum; - uint16_t max_models; - uint16_t models[MAX_MODELS]; - char padding[512 - 64 * 4 - 4 * 4 - 2 - MAX_MODELS * 2 - 4]; - uint32_t baudrate; -} __attribute__((packed)); - -struct firmware_file { - struct fw_header_file header; - size_t offset; - char filepath[PATH_MAX]; -}; - -struct firmware { - struct fw_header header; - struct firmware_file *files; - size_t files_count; - struct fw_header_kernel kernel_header; - char lower_endian; -}; - -static size_t get_file_size(FILE *fp) -{ - size_t pos = (size_t)ftell(fp); - size_t file_size; - - fseek(fp, 0, SEEK_END); - file_size = (size_t)ftell(fp); - fseek(fp, (long int)pos, SEEK_SET); - - return file_size; -} - -static void copy_from_to_file(FILE *fp_src, size_t src_offset, FILE *fp_dst, - size_t dst_offset, size_t length) -{ - int buf[512]; - size_t len; - - if (src_offset) - fseek(fp_src, (long int)src_offset, SEEK_SET); - - if (dst_offset) - fseek(fp_src, (long int)dst_offset, SEEK_SET); - - while (length) { - if (length >= sizeof(buf)) { - len = sizeof(buf); - } else { - len = length; - } - - length -= len; - - if (fread(buf, len, 1, fp_src) != 1) - error("Failed to read"); - - if (fwrite(buf, len, 1, fp_dst) != 1) - error("Failed to write"); - } -} - -static void extract_to_file(FILE *fp_src, char *dst, size_t length, - size_t offset) -{ - FILE *fp_dst; - - if (!(fp_dst = fopen(dst, "wb"))) - error("Failed to open %s for writing", dst); - - copy_from_to_file(fp_src, offset, fp_dst, 0, length); - - fclose(fp_dst); -} - -static void dump_firmware_header(struct fw_header *header_p) -{ - int i; - - printf("FIRMWARE HEADER\n"); - printf("checksum = 0x%08x, magic = 0x%08x\n", - header_p->checksum, header_p->magic); - printf("version = 0x%04x, files_count = %12d\n", - header_p->version, header_p->files_count); - printf("models_count = %12d, total_length = %12d\n", - header_p->models_count, header_p->total_length); - printf("files_offset = 0x%04x, header_length = %12d\n", - header_p->files_offset, header_p->header_length); - printf("info_length = %12d, capwap_version = %12s\n", - header_p->info_length, header_p->capwap_version); - printf("model_name = %s\n", header_p->model_name); - printf("models ="); - for (i = 0; i < header_p->models_count && i < MAX_MODELS; i++) - printf(" 0x%04x", header_p->models[i]); - printf("\n\n"); -} - -static int get_file_type_id(char *type) -{ - struct file_type_tbl *ft = file_types; - int i; - - for (i = 0; i < FILE_TYPE_COUNT; i++, ft++) - if (!strcmp(type, ft->str)) - return ft->type; - - printf("Supported file types:\n"); - for (i = 0, ft = file_types; i < FILE_TYPE_COUNT; i++, ft++) - printf("%8s (ID 0x%x)\n", ft->str, ft->type); - - error("Unknown file type \"%s\"\n", type); - - return 0; -} - -static char *get_file_type_string(int type) -{ - struct file_type_tbl *ft = file_types; - int i; - - for (i = 0; i < FILE_TYPE_COUNT; i++, ft++) - if (ft->type == type) - return ft->str; - - return NULL; -} - -static void dump_file_header(struct fw_header_file *file_header) -{ - printf("\nfilename=%s, type=%s, flags=0x%x target=%s, revision=%s\n", - file_header->filename, get_file_type_string(file_header->type), - file_header->flags, file_header->target, file_header->revision); - printf("date=%s, length=%u, checksum=0x%08x, flash_offset=0x%08x\n", - file_header->date, file_header->length, file_header->checksum, - file_header->flash_offset); -} - -static void dump_kernel_header(struct fw_header_kernel *kernel_header) -{ - int i; - - printf("KERNEL HEADER (%lu bytes)\n", sizeof(struct fw_header_kernel)); - printf("bm_version = %s\n", kernel_header->bm_version); - printf("kernel_version = %s\n", kernel_header->kernel_version); - printf("core_version = %s\n", kernel_header->core_version); - printf("capwap_version = %s\n", kernel_header->capwap_version); - printf("model_name = %s\n", kernel_header->model_name); - printf("bm_checksum = 0x%08x\n", kernel_header->bm_checksum); - printf("kernel_checksum = 0x%08x\n", kernel_header->kernel_checksum); - printf("zld_checksum = 0x%08x\n", kernel_header->zld_checksum); - printf("core_checksum = 0x%08x\n", kernel_header->core_checksum); - printf("max_models = %u\n", kernel_header->max_models); - printf("models ="); - for (i = 0; i < 5; i++) - printf(" 0x%04x", kernel_header->models[i]); - printf("\n"); - printf("baudrate = %u\n", kernel_header->baudrate); - printf("\n"); -} - -static void translate_fw_header(struct fw_header *header_p) -{ - int i; - - header_p->magic = ntohl(header_p->magic); - header_p->version = ntohs(header_p->version); - header_p->files_count = ntohs(header_p->files_count); - header_p->models_count = ntohs(header_p->models_count); - for (i = 0; i < MAX_MODELS; i++) - header_p->models[i] = ntohs(header_p->models[i]); - header_p->total_length = ntohl(header_p->total_length); - header_p->files_offset = ntohs(header_p->files_offset); - header_p->header_length = ntohs(header_p->header_length); - header_p->info_length = ntohs(header_p->info_length); -} - -static void translate_file_header(struct fw_header_file *file_header) -{ - file_header->type = ntohs(file_header->type); - file_header->flags = ntohs(file_header->flags); - file_header->length = ntohl(file_header->length); - file_header->checksum = ntohl(file_header->checksum); - file_header->flash_offset = ntohl(file_header->flash_offset); -} - -static void translate_kernel_header(struct fw_header_kernel *kernel_header) -{ - int i; - - kernel_header->bm_checksum = ntohl(kernel_header->bm_checksum); - kernel_header->kernel_checksum = ntohl(kernel_header->kernel_checksum); - /*kernel_header->zld_checksum = ntohl(kernel_header->zld_checksum);*/ - kernel_header->core_checksum = ntohl(kernel_header->core_checksum); - - kernel_header->max_models = ntohs(kernel_header->max_models); - for (i = 0; i < MAX_MODELS; i++) - kernel_header->models[i] = ntohs(kernel_header->models[i]); - kernel_header->baudrate = ntohl(kernel_header->baudrate); -} - -static void checksum_add_from_buf(MD5_CTX *ctx, void *buf, - size_t length, size_t offset) -{ - char *begin = &((char *)buf)[offset]; - - MD5_Update(ctx, begin, length); -} - -static void checksum_add_from_file(MD5_CTX *ctx, FILE *fp_src, - size_t length, size_t offset) -{ - int buf[512]; - size_t len; - - fseek(fp_src, (long int)offset, SEEK_SET); - while (length) { - if (length >= sizeof(buf)) { - len = sizeof(buf); - } else { - len = length; - } - - length -= len; - - if (fread(buf, len, 1, fp_src) != 1) - error("Failed to read for checksum calculation"); - - checksum_add_from_buf(ctx, buf, len, 0); - } -} - -static uint32_t checksum_finish(MD5_CTX *ctx) -{ - unsigned char md5sum[16]; - uint32_t checksum = 0; - int i; - - MD5_Final(md5sum, ctx); - - for (i = 0; i < 16; i += 4) - checksum += ((uint32_t)md5sum[i] << 24 | - (uint32_t)md5sum[i + 1] << 16 | - (uint32_t)md5sum[i + 2] << 8 | - (uint32_t)md5sum[i + 3]); - - if (checksum == 0) - checksum = 1; - - return checksum; -} - -static uint32_t checksum_calculate(FILE *fp, size_t kernel_offset) -{ - struct fw_header_kernel dummy; - MD5_CTX ctx; - size_t file_size; - - fseek(fp, 0, SEEK_SET); - file_size = get_file_size(fp); - - MD5_Init(&ctx); - - checksum_add_from_file(&ctx, fp, kernel_offset - CHECKSUM_SIZE, - CHECKSUM_SIZE); - - /* use a zeroed out kernel version header */ - memset(&dummy, 0, sizeof(dummy)); - checksum_add_from_buf(&ctx, &dummy, sizeof(dummy), 0); - - checksum_add_from_file(&ctx, fp, - file_size - kernel_offset - sizeof(dummy), - kernel_offset + sizeof(dummy)); - - return checksum_finish(&ctx); -} - -static uint32_t checksum_calculate_file(char *filename) -{ - MD5_CTX ctx; - FILE *fp; - size_t file_size; - - if (!(fp = fopen(filename, "rb"))) - error("Failed to open %s for writing\n", filename); - - file_size = get_file_size(fp); - - MD5_Init(&ctx); - - checksum_add_from_file(&ctx, fp, file_size, 0); - - fclose(fp); - - return checksum_finish(&ctx); -} - -static void parse_firmware(struct firmware *fw, FILE *fp) -{ - struct firmware_file *file; - size_t file_size, file_offset, kernel_offset; - uint32_t checksum = 0; - int i; - - if (!fw) - error("Failed to allocate firmware struct\n"); - - file_size = get_file_size(fp); - - if (file_size < sizeof(fw->header)) - error("File too small\n"); - - if (1 != fread(&fw->header, sizeof(fw->header), 1, fp)) - error("Failed to read firmware header\n"); - - if (ntohl(fw->header.magic) == ZYXEL_MAGIC) { - fw->lower_endian = 1; - translate_fw_header(&fw->header); - } else if (fw->header.magic != ZYXEL_MAGIC) { - error("Unsupported magic. Expected 0x%x, but found 0x%x\n", - ZYXEL_MAGIC, fw->header.magic); - } - - if (fw->header.models_count != MAX_MODELS) - error("Wrong number of models. Expected %u, but found %u\n", - MAX_MODELS, fw->header.models_count); - - dump_firmware_header(&fw->header); - - if (fw->header.total_length != file_size) - error("File size does not match. Expected %lu, but found %u\n", - file_size, fw->header.total_length); - - file_offset = sizeof(fw->header) + - fw->header.files_count * sizeof(struct fw_header_file); - - if (file_offset != fw->header.files_offset) - error("File offset does not match definition in header\n"); - - if (file_size < file_offset) - error("File too small for %u file headers\n", - fw->header.files_count); - - if (NULL == (fw->files = malloc(fw->header.files_count * - sizeof(struct firmware_file)))) - error("Failed to allocate memory for %u file structs\n", - fw->header.files_count); - - for (i = 0, file = fw->files; i < fw->header.files_count; i++, file++) { - if (1 != fread(file, sizeof(struct fw_header_file), 1, fp)) - error("Failed to read file header #%u\n", i + 1); - - if (fw->lower_endian) - translate_file_header(&file->header); - - if (file_offset + file->header.length > fw->header.total_length) - error("File offset exceeds size of firmware archive\n"); - - if (file->header.type == FILE_TYPE_KERNEL) - kernel_offset = file_offset; - - file->offset = file_offset; - - file_offset += file->header.length; - } - - if (!kernel_offset) - error("Kernel image missing for checksum calculation\n"); - - /* as we know the kernel offset, we can calculate the checksum - * as it must be excluded from checksum calculation */ - checksum = checksum_calculate(fp, kernel_offset); - - if (fw->lower_endian) - checksum = ntohl(checksum); - - if (checksum != fw->header.checksum) - printf("WARN: Checksum mismatch. Calculated 0x%x\n", checksum); - - fseek(fp, (long int)kernel_offset, SEEK_SET); - if (1 != fread(&fw->kernel_header, sizeof(fw->kernel_header), 1, fp)) - error("Failed to read kernel header\n"); - - if (fw->lower_endian) - translate_kernel_header(&fw->kernel_header); - - dump_kernel_header(&fw->kernel_header); -} - -static void extract_firmware(struct firmware *fw, char *filename) -{ - struct firmware_file *file; - FILE *fp; - int i; - - if (!(fp = fopen(filename, "rb"))) - error("Failed to open firmware archive for extraction %s\n", - filename); - - parse_firmware(fw, fp); - - printf("Extracting files..."); - - for (i = 0, file = fw->files; i < fw->header.files_count; i++, file++) { - dump_file_header(&file->header); - if (file->header.type == FILE_TYPE_KERNEL) { - /* strip kernel header */ - extract_to_file( - fp, file->header.filename, - file->header.length - - sizeof(struct fw_header_kernel), - file->offset + sizeof(struct fw_header_kernel)); - } else { - extract_to_file(fp, file->header.filename, - file->header.length, file->offset); - } - - printf("Calculated file checksum is 0x%08x\n", - checksum_calculate_file(file->header.filename)); - } - - free(fw->files); - fclose(fp); -} - -static void init_fw_header(struct firmware *fw) -{ - int i; - - for (i = 0; i < MAX_MODELS; i++) - fw->header.models[i] = 0xffff; - - fw->kernel_header.baudrate = 115200; - fw->kernel_header.max_models = MAX_MODELS; - /* ZyXEL messed up their code and included a 32 bit pointer */ - fw->header.header_length = sizeof(fw->header) + 4; - fw->header.magic = ZYXEL_MAGIC; -} - -static void write_headers(FILE *fp, struct firmware *fw) -{ - struct firmware_file *file; - unsigned int i; - - fseek(fp, 0, SEEK_SET); - - if (1 != fwrite(&fw->header, sizeof(fw->header), 1, fp)) - error("Failed to write firmware header\n"); - - for (i = 0, file = fw->files; i < fw->files_count; i++, file++) - if (1 != - fwrite(&file->header, sizeof(struct fw_header_file), 1, fp)) - error("Failed to write file header #%u\n", i + 1); -} - -static void usage(char *progname) -{ - printf("Usage: %s\n" - " For extraction:\n" - " -e <file> extract firmware <file>\n\n" - " For creation:\n" - " -v <version> set hexadecimal firmware <version>\n" - " -b <checksum> set hexadecimal bootmanager <checksum>\n" - " -c <version> set capwap <version> string\n" - " -m <model> set <model> string\n" - " -d <model_id> set (up to %u) hexadecimal <model_id>\n" - " (multiple input files)\n" - " -i <file> add input <file>\n" - " -o <offset> set hexadecimal flash offset for file\n" - " -r <revision> set revision string for file\n" - " -t <type> choose file <type>\n" - " -x <target> set (partition) <target> of file\n" - " <output_filename>\n", - progname, MAX_MODELS); - exit(1); -} - -int main(int argc, char *argv[]) -{ - struct firmware fw; - struct firmware_file *file; - struct firmware_file *core_file = NULL; - struct stat attr; - static const char *optstr = "e:v:b:c:m:d:i:o:r:t:x:h"; - const char *capwap_version = "undefined"; - const char *separator = " | "; - char *filename; - FILE *fp_src, *fp_dst; - size_t kernel_offset = 0; - unsigned int i; - int opt; - - memset(&fw, 0, sizeof(fw)); - init_fw_header(&fw); - - if (argc < 1) - usage(argv[0]); - - opt = getopt(argc, argv, optstr); - if (opt == -1) - usage(argv[0]); - while (opt != -1) { - if (optarg == NULL) - usage(argv[0]); - - switch (opt) { - case 'e': - extract_firmware(&fw, optarg); - exit(0); - case 'v': - fw.header.version = (uint16_t)strtol(optarg, NULL, 16); - if (!fw.header.version) - error("Invalid version number\n"); - break; - case 'b': - fw.kernel_header.bm_checksum = - (uint32_t)strtol(optarg, NULL, 16); - break; - case 'c': - strncpy(fw.header.capwap_version, optarg, - sizeof(fw.header.capwap_version) - 1); - break; - case 'm': - strncpy(fw.header.model_name, optarg, - sizeof(fw.header.model_name) - 1); - break; - case 'd': - if (fw.header.models_count == MAX_MODELS) - error("Max. number of supported models is %u\n", - MAX_MODELS); - - fw.header.models[fw.header.models_count] = - (uint16_t)strtol(optarg, NULL, 16); - fw.header.models_count++; - break; - case 'i': - filename = optarg; - - if (!fw.files && - NULL == (fw.files = malloc( - MAX_FILES * - sizeof(struct firmware_file)))) - error("Failed to allocate %u file structs\n", - MAX_FILES); - - if (fw.files_count == MAX_FILES) - error("Maximum number of files reached (%u)\n", - MAX_FILES); - - if (stat(optarg, &attr)) - error("Stat failed on %s\n", optarg); - - strftime(fw.files[fw.files_count].header.date, - DATE_SIZE - 1, "%Y-%m-%d %H:%M:%S", - localtime(&attr.st_mtime)); - - strncpy(fw.files[fw.files_count].filepath, optarg, - PATH_MAX - 1); - - filename = strrchr(optarg, '/'); - if (!filename) - filename = optarg; - - strncpy(fw.files[fw.files_count].header.filename, - filename, MAX_FILENAME - 1); - - fw.files_count++; - break; - case 'o': - if (!fw.files_count) - error("Specify offset after filename\n"); - - fw.files[fw.files_count - 1].header.flash_offset = - (uint32_t)strtol(optarg, NULL, 16); - break; - case 'r': - if (!fw.files_count) - error("Specify file revision after filename\n"); - - strncpy(fw.files[fw.files_count - 1].header.revision, - optarg, REV_SIZE - 1); - break; - case 't': - if (!fw.files_count) - error("Specify file type after filename!\n"); - - fw.files[fw.files_count - 1].header.type = - get_file_type_id(optarg); - break; - case 'x': - if (!fw.files_count) - error("Specify file target after filename!\n"); - strncpy(fw.files[fw.files_count - 1].header.target, - optarg, sizeof(fw.files[0].header.target) - 1); - break; - case 'h': - default: - usage(argv[0]); - } - - opt = getopt(argc, argv, optstr); - } - - if (!fw.header.models_count) - error("Supported model IDs missing (option -d)\n"); - - if (!fw.header.version) - error("Version number missing (e.g. -v 0x100)\n"); - - if (!fw.kernel_header.bm_checksum) - error("Bootmanager checksum is missing (option -b)\n"); - - if (!strlen(fw.header.model_name)) - error("Model name missing (option -m)\n"); - - if (!strlen(fw.header.capwap_version)) - strncpy(fw.header.capwap_version, capwap_version, - sizeof(fw.header.capwap_version) - 1); - - fw.header.models_count = MAX_MODELS; - fw.header.files_count = fw.files_count; - memcpy(fw.kernel_header.models, fw.header.models, - sizeof(fw.header.models)); - - for (i = 0; i < fw.files_count; i++) { - if (!fw.files[i].header.type) - error("No file or type specified for file %s\n", - fw.files[i].filepath); - - if (!strlen(fw.files[i].header.target)) - error("Target missing for %s (e.g. -x zldfs)\n", - fw.files[i].filepath); - - if (!strlen(fw.files[i].header.revision)) - error("Revision missing for %s\n", - fw.files[i].filepath); - } - - filename = argv[optind]; - if (!(fp_dst = fopen(filename, "w+b"))) - error("Failed to open %s for writing\n", filename); - - write_headers(fp_dst, &fw); - - fw.header.info_length = sizeof(struct fw_header_file); - fw.header.files_offset = - sizeof(fw.header) + fw.files_count * fw.header.info_length; - if ((size_t)ftell(fp_dst) != fw.header.files_offset) - error("Oops. Something went wrong writing the file headers"); - - fw.header.total_length = fw.header.files_offset; - for (i = 0, file = fw.files; i < fw.files_count; i++, file++) { - file->header.checksum = checksum_calculate_file(file->filepath); - - if (!(fp_src = fopen(file->filepath, "rb"))) - error("Failed to open %s for writing\n", filename); - - file->offset = fw.header.total_length; - - file->header.length = get_file_size(fp_src); - - if (file->header.type == FILE_TYPE_KERNEL) - if (1 != fwrite(&fw.kernel_header, - sizeof(fw.kernel_header), 1, fp_dst)) - error("Failed to write kernel header\n"); - - copy_from_to_file(fp_src, 0, fp_dst, 0, file->header.length); - - if (file->header.type == FILE_TYPE_KERNEL) { - file->header.length += sizeof(fw.kernel_header); - kernel_offset = file->offset; - fw.kernel_header.kernel_checksum = - file->header.checksum; - if (strlen(file->header.revision) + strlen(separator) + - strlen(file->header.date) >= - sizeof(fw.kernel_header.kernel_version)) - error("Kernel file revision too long\n"); - - strcat(fw.kernel_header.kernel_version, - file->header.revision); - strcat(fw.kernel_header.kernel_version, separator); - strcat(fw.kernel_header.kernel_version, - file->header.date); - } else if (file->header.type == FILE_TYPE_CORE) { - core_file = file; - } - - fw.header.total_length += file->header.length; - - translate_file_header(&file->header); - - fclose(fp_src); - } - - /* update headers with correct lengths and endianness */ - translate_fw_header(&fw.header); - - write_headers(fp_dst, &fw); - - if (!kernel_offset) - error("Kernel image needed for checksum calculation\n"); - - /* update headers with correct checksum */ - fw.header.checksum = htonl(checksum_calculate(fp_dst, kernel_offset)); - fseek(fp_dst, 0, SEEK_SET); - fwrite(&fw.header.checksum, sizeof(fw.header.checksum), 1, fp_dst); - - fw.kernel_header.zld_checksum = fw.header.checksum; - strncpy(fw.kernel_header.model_name, fw.header.model_name, - sizeof(fw.kernel_header.model_name) - 1); - strncpy(fw.kernel_header.capwap_version, fw.header.capwap_version, - sizeof(fw.kernel_header.capwap_version) - 1); - - translate_kernel_header(&fw.kernel_header); - - if (core_file) { - fw.kernel_header.core_checksum = core_file->header.checksum; - - if (strlen(core_file->header.revision) + strlen(separator) + - strlen(core_file->header.date) >= - sizeof(fw.kernel_header.core_version)) - error("Core file revision string too long\n"); - - strcat(fw.kernel_header.core_version, - core_file->header.revision); - strcat(fw.kernel_header.core_version, separator); - strcat(fw.kernel_header.core_version, core_file->header.date); - } - - fseek(fp_dst, (long int)kernel_offset, SEEK_SET); - fwrite(&fw.kernel_header, sizeof(fw.kernel_header), 1, fp_dst); - - fclose(fp_dst); - - exit(0); -} diff --git a/tools/firmware-utils/src/motorola-bin.c b/tools/firmware-utils/src/motorola-bin.c deleted file mode 100644 index 6fda2a9e31..0000000000 --- a/tools/firmware-utils/src/motorola-bin.c +++ /dev/null @@ -1,212 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * motorola-bin.c - * - * Copyright (C) 2005-2006 Mike Baker, - * Imre Kaloz <kaloz@openwrt.org> - * D. Hugh Redelmeier - * OpenWrt.org - */ - -/* - * Motorola's firmware flashing code requires an extra header. - * The header is eight bytes (see struct motorola below). - * This program will take a firmware file and create a new one - * with this header: - * motorola-bin --wr850g WR850G_V403.stripped.trx WR850G_V403.trx - * - * Note: Motorola's firmware is distributed with this header. - * If you need to flash Motorola firmware on a router running OpenWRT, - * you will to remove this header. Use the --strip flag: - * motorola-bin --strip WR850G_V403.trx WR850G_V403.stripped.trx - */ - -/* - * February 1, 2006 - * - * Add support for for creating WA840G and WE800G images - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <string.h> -#include <netinet/in.h> -#include <inttypes.h> - -#define BPB 8 /* bits/byte */ - -static uint32_t crc32[1<<BPB]; - -static void init_crc32() -{ - const uint32_t poly = ntohl(0x2083b8ed); - int n; - - for (n = 0; n < 1<<BPB; n++) { - uint32_t crc = n; - int bit; - - for (bit = 0; bit < BPB; bit++) - crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); - crc32[n] = crc; - } -} - -static uint32_t crc32buf(unsigned char *buf, size_t len) -{ - uint32_t crc = 0xFFFFFFFF; - - for (; len; len--, buf++) - crc = crc32[(uint8_t)crc ^ *buf] ^ (crc >> BPB); - return crc; -} - -struct motorola { - uint32_t crc; // crc32 of the remainder - uint32_t flags; // unknown, 105770* -}; - -static const struct model { - char digit; /* a digit signifying model (historical) */ - const char *name; - uint32_t flags; -} models[] = { - { '1', "WR850G", 0x10577050LU }, - { '2', "WA840G", 0x10577040LU }, - { '3', "WE800G", 0x10577000LU }, - { '\0', NULL, 0 } -}; - -static void usage(const char *) __attribute__ (( __noreturn__ )); - -static void usage(const char *mess) -{ - const struct model *m; - - fprintf(stderr, "Error: %s\n", mess); - fprintf(stderr, "Usage: motorola-bin -device|--strip infile outfile\n"); - fprintf(stderr, "Known devices: "); - - for (m = models; m->digit != '\0'; m++) - fprintf(stderr, " %c - %s", m->digit, m->name); - - fprintf(stderr, "\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - off_t len; // of original firmware - int fd; - void *trx; // pointer to original firmware (mmmapped) - struct motorola *firmware; // pionter to prefix + copy of original firmware - uint32_t flags; - - // verify parameters - - if (argc != 4) - usage("wrong number of arguments"); - - // mmap trx file - if ((fd = open(argv[2], O_RDONLY)) < 0 - || (len = lseek(fd, 0, SEEK_END)) < 0 - || (trx = mmap(0, len, PROT_READ, MAP_SHARED, fd, 0)) == (void *) (-1) - || close(fd) < 0) - { - fprintf(stderr, "Error loading file %s: %s\n", argv[2], strerror(errno)); - exit(1); - } - - init_crc32(); - - if (strcmp(argv[1], "--strip") == 0) - { - const char *ugh = NULL; - - if (len < sizeof(struct motorola)) { - ugh = "input file too short"; - } else { - const struct model *m; - - firmware = trx; - if (htonl(crc32buf(trx + offsetof(struct motorola, flags), len - offsetof(struct motorola, flags))) != firmware->crc) - ugh = "Invalid CRC"; - for (m = models; ; m++) { - if (m->digit == '\0') { - if (ugh == NULL) - ugh = "unrecognized flags field"; - break; - } - if (firmware->flags == htonl(m->flags)) { - fprintf(stderr, "Firmware for Motorola %s\n", m->name); - break; - } - } - } - - if (ugh != NULL) { - fprintf(stderr, "%s\n", ugh); - exit(3); - } else { - // all is well, write the file without the prefix - if ((fd = open(argv[3], O_CREAT|O_WRONLY|O_TRUNC,0644)) < 0 - || write(fd, trx + sizeof(struct motorola), len - sizeof(struct motorola)) != len - sizeof(struct motorola) - || close(fd) < 0) - { - fprintf(stderr, "Error storing file %s: %s\n", argv[3], strerror(errno)); - exit(2); - } - } - - } else { - // setup the firmware flags magic number - const struct model *m; - const char *df = argv[1]; - - if (*df != '-') - usage("first argument must start with -"); - if (*++df == '-') - ++df; /* allow but don't require second - */ - - for (m = models; ; m++) { - if (m->digit == '\0') - usage("unrecognized device specified"); - if ((df[0] == m->digit && df[1] == '\0') || strcasecmp(df, m->name) == 0) { - flags = m->flags; - break; - } - } - - - // create a firmware image in memory - // and copy the trx to it - firmware = malloc(sizeof(struct motorola) + len); - memcpy(&firmware[1], trx, len); - - // setup the motorola headers - firmware->flags = htonl(flags); - - // CRC of flags + firmware - firmware->crc = htonl(crc32buf((unsigned char *)&firmware->flags, sizeof(firmware->flags) + len)); - - // write the firmware - if ((fd = open(argv[3], O_CREAT|O_WRONLY|O_TRUNC,0644)) < 0 - || write(fd, firmware, sizeof(struct motorola) + len) != sizeof(struct motorola) + len - || close(fd) < 0) - { - fprintf(stderr, "Error storing file %s: %s\n", argv[3], strerror(errno)); - exit(2); - } - - free(firmware); - } - - munmap(trx,len); - - return 0; -} diff --git a/tools/firmware-utils/src/myloader.h b/tools/firmware-utils/src/myloader.h deleted file mode 100644 index 039f2df6d2..0000000000 --- a/tools/firmware-utils/src/myloader.h +++ /dev/null @@ -1,171 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2006-2008 Gabor Juhos <juhosg@openwrt.org> - */ - -#ifndef _MYLOADER_H_ -#define _MYLOADER_H_ - -/* - * Firmware file format: - * - * <header> - * [<block descriptor 0>] - * ... - * [<block descriptor n>] - * <null block descriptor> - * [<block data 0>] - * ... - * [<block data n>] - * - * - */ - -/* Myloader specific magic numbers */ -#define MYLO_MAGIC_FIRMWARE 0x4C594D00 -#define MYLO_MAGIC_20021103 0x20021103 -#define MYLO_MAGIC_20021107 0x20021107 - -#define MYLO_MAGIC_SYS_PARAMS MYLO_MAGIC_20021107 -#define MYLO_MAGIC_PARTITIONS MYLO_MAGIC_20021103 -#define MYLO_MAGIC_BOARD_PARAMS MYLO_MAGIC_20021103 - -/* - * Addresses of the data structures provided by MyLoader - */ -#define MYLO_MIPS_SYS_PARAMS 0x80000800 /* System Parameters */ -#define MYLO_MIPS_BOARD_PARAMS 0x80000A00 /* Board Parameters */ -#define MYLO_MIPS_PARTITIONS 0x80000C00 /* Partition Table */ -#define MYLO_MIPS_BOOT_PARAMS 0x80000E00 /* Boot Parameters */ - -/* Vendor ID's (seems to be same as the PCI vendor ID's) */ -#define VENID_COMPEX 0x11F6 - -/* Devices based on the ADM5120 */ -#define DEVID_COMPEX_NP27G 0x0078 -#define DEVID_COMPEX_NP28G 0x044C -#define DEVID_COMPEX_NP28GHS 0x044E -#define DEVID_COMPEX_WP54Gv1C 0x0514 -#define DEVID_COMPEX_WP54G 0x0515 -#define DEVID_COMPEX_WP54AG 0x0546 -#define DEVID_COMPEX_WPP54AG 0x0550 -#define DEVID_COMPEX_WPP54G 0x0555 - -/* Devices based on the Atheros AR2317 */ -#define DEVID_COMPEX_NP25G 0x05e6 -#define DEVID_COMPEX_WPE53G 0x05dc - -/* Devices based on the Atheros AR71xx */ -#define DEVID_COMPEX_WP543 0x0640 -#define DEVID_COMPEX_WPE72 0x0672 - -/* Devices based on the IXP422 */ -#define DEVID_COMPEX_WP18 0x047E -#define DEVID_COMPEX_NP18A 0x0489 - -/* Other devices */ -#define DEVID_COMPEX_NP26G8M 0x03E8 -#define DEVID_COMPEX_NP26G16M 0x03E9 - -struct mylo_fw_header { - uint32_t magic; /* must be MYLO_MAGIC_FIRMWARE */ - uint32_t crc; /* CRC of the whole firmware */ - uint32_t res0; /* unknown/unused */ - uint32_t res1; /* unknown/unused */ - uint16_t vid; /* vendor ID */ - uint16_t did; /* device ID */ - uint16_t svid; /* sub vendor ID */ - uint16_t sdid; /* sub device ID */ - uint32_t rev; /* device revision */ - uint32_t fwhi; /* FIXME: firmware version high? */ - uint32_t fwlo; /* FIXME: firmware version low? */ - uint32_t flags; /* firmware flags */ -}; - -#define FW_FLAG_BOARD_PARAMS_WP 0x01 /* board parameters are write protected */ -#define FW_FLAG_BOOT_SECTOR_WE 0x02 /* enable of write boot sectors (below 64K) */ - -struct mylo_fw_blockdesc { - uint32_t type; /* block type */ - uint32_t addr; /* relative address to flash start */ - uint32_t dlen; /* size of block data in bytes */ - uint32_t blen; /* total size of block in bytes */ -}; - -#define FW_DESC_TYPE_UNUSED 0 -#define FW_DESC_TYPE_USED 1 - -struct mylo_partition { - uint16_t flags; /* partition flags */ - uint16_t type; /* type of the partition */ - uint32_t addr; /* relative address of the partition from the - flash start */ - uint32_t size; /* size of the partition in bytes */ - uint32_t param; /* if this is the active partition, the - MyLoader load code to this address */ -}; - -#define PARTITION_FLAG_ACTIVE 0x8000 /* this is the active partition, - * MyLoader loads firmware from here */ -#define PARTITION_FLAG_ISRAM 0x2000 /* FIXME: this is a RAM partition? */ -#define PARTIIION_FLAG_RAMLOAD 0x1000 /* FIXME: load this partition into the RAM? */ -#define PARTITION_FLAG_PRELOAD 0x0800 /* the partition data preloaded to RAM - * before decompression */ -#define PARTITION_FLAG_LZMA 0x0100 /* the partition data compressed with LZMA */ -#define PARTITION_FLAG_HAVEHDR 0x0002 /* the partition data have a header */ - -#define PARTITION_TYPE_FREE 0 -#define PARTITION_TYPE_USED 1 - -#define MYLO_MAX_PARTITIONS 8 /* maximum number of partitions in the - partition table */ - -struct mylo_partition_table { - uint32_t magic; /* must be MYLO_MAGIC_PARTITIONS */ - uint32_t res0; /* unknown/unused */ - uint32_t res1; /* unknown/unused */ - uint32_t res2; /* unknown/unused */ - struct mylo_partition partitions[MYLO_MAX_PARTITIONS]; -}; - -struct mylo_partition_header { - uint32_t len; /* length of the partition data */ - uint32_t crc; /* CRC value of the partition data */ -}; - -struct mylo_system_params { - uint32_t magic; /* must be MYLO_MAGIC_SYS_PARAMS */ - uint32_t res0; - uint32_t res1; - uint32_t mylo_ver; - uint16_t vid; /* Vendor ID */ - uint16_t did; /* Device ID */ - uint16_t svid; /* Sub Vendor ID */ - uint16_t sdid; /* Sub Device ID */ - uint32_t rev; /* device revision */ - uint32_t fwhi; - uint32_t fwlo; - uint32_t tftp_addr; - uint32_t prog_start; - uint32_t flash_size; /* Size of boot FLASH in bytes */ - uint32_t dram_size; /* Size of onboard RAM in bytes */ -}; - - -struct mylo_eth_addr { - uint8_t mac[6]; - uint8_t csum[2]; -}; - -#define MYLO_ETHADDR_COUNT 8 /* maximum number of ethernet address - in the board parameters */ - -struct mylo_board_params { - uint32_t magic; /* must be MYLO_MAGIC_BOARD_PARAMS */ - uint32_t res0; - uint32_t res1; - uint32_t res2; - struct mylo_eth_addr addr[MYLO_ETHADDR_COUNT]; -}; - -#endif /* _MYLOADER_H_*/ diff --git a/tools/firmware-utils/src/nand_ecc.c b/tools/firmware-utils/src/nand_ecc.c deleted file mode 100644 index 7189278011..0000000000 --- a/tools/firmware-utils/src/nand_ecc.c +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only -/* - * calculate ecc code for nand flash - * - * Copyright (C) 2008 yajin <yajin@vm-kernel.org> - * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name> - */ - - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdint.h> -#include <fcntl.h> -#include <stdio.h> - -#define DEF_NAND_PAGE_SIZE 2048 -#define DEF_NAND_OOB_SIZE 64 -#define DEF_NAND_ECC_OFFSET 0x28 - -static int page_size = DEF_NAND_PAGE_SIZE; -static int oob_size = DEF_NAND_OOB_SIZE; -static int ecc_offset = DEF_NAND_ECC_OFFSET; - -/* - * Pre-calculated 256-way 1 byte column parity - */ -static const uint8_t nand_ecc_precalc_table[] = { - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, - 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, - 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, - 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, - 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, - 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, - 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, - 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 -}; - -/** - * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block - * @dat: raw data - * @ecc_code: buffer for ECC - */ -int nand_calculate_ecc(const uint8_t *dat, - uint8_t *ecc_code) -{ - uint8_t idx, reg1, reg2, reg3, tmp1, tmp2; - int i; - - /* Initialize variables */ - reg1 = reg2 = reg3 = 0; - - /* Build up column parity */ - for(i = 0; i < 256; i++) { - /* Get CP0 - CP5 from table */ - idx = nand_ecc_precalc_table[*dat++]; - reg1 ^= (idx & 0x3f); - - /* All bit XOR = 1 ? */ - if (idx & 0x40) { - reg3 ^= (uint8_t) i; - reg2 ^= ~((uint8_t) i); - } - } - - /* Create non-inverted ECC code from line parity */ - tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */ - tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */ - tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */ - tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */ - tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */ - tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */ - tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */ - tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */ - - tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */ - tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */ - tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */ - tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */ - tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */ - tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */ - tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */ - tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */ - - /* Calculate final ECC code */ -#ifdef CONFIG_MTD_NAND_ECC_SMC - ecc_code[0] = ~tmp2; - ecc_code[1] = ~tmp1; -#else - ecc_code[0] = ~tmp1; - ecc_code[1] = ~tmp2; -#endif - ecc_code[2] = ((~reg1) << 2) | 0x03; - - return 0; -} - -/* - * usage: bb-nandflash-ecc start_address size - */ -void usage(const char *prog) -{ - fprintf(stderr, "Usage: %s [options] <input> <output>\n" - "Options:\n" - " -p <pagesize> NAND page size (default: %d)\n" - " -o <oobsize> NAND OOB size (default: %d)\n" - " -e <offset> NAND ECC offset (default: %d)\n" - "\n", prog, DEF_NAND_PAGE_SIZE, DEF_NAND_OOB_SIZE, - DEF_NAND_ECC_OFFSET); - exit(1); -} - -/*start_address/size does not include oob - */ -int main(int argc, char **argv) -{ - uint8_t *page_data = NULL; - uint8_t *ecc_data; - int infd = -1, outfd = -1; - int ret = 1; - ssize_t bytes; - int ch; - - while ((ch = getopt(argc, argv, "e:o:p:")) != -1) { - switch(ch) { - case 'p': - page_size = strtoul(optarg, NULL, 0); - break; - case 'o': - oob_size = strtoul(optarg, NULL, 0); - break; - case 'e': - ecc_offset = strtoul(optarg, NULL, 0); - break; - default: - usage(argv[0]); - } - } - argc -= optind; - if (argc < 2) - usage(argv[0]); - - argv += optind; - - infd = open(argv[0], O_RDONLY, 0); - if (infd < 0) { - perror("open input file"); - goto out; - } - - outfd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC, 0644); - if (outfd < 0) { - perror("open output file"); - goto out; - } - - page_data = malloc(page_size + oob_size); - - while ((bytes = read(infd, page_data, page_size)) == page_size) { - int j; - - ecc_data = page_data + page_size + ecc_offset; - for (j = 0; j < page_size / 256; j++) - { - nand_calculate_ecc(page_data + j * 256, ecc_data); - ecc_data += 3; - } - write(outfd, page_data, page_size + oob_size); - } - - ret = 0; -out: - if (infd >= 0) - close(infd); - if (outfd >= 0) - close(outfd); - if (page_data) - free(page_data); - return ret; -} - diff --git a/tools/firmware-utils/src/nec-enc.c b/tools/firmware-utils/src/nec-enc.c deleted file mode 100644 index a2be378586..0000000000 --- a/tools/firmware-utils/src/nec-enc.c +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * nec-enc.c - encode/decode nec firmware with key - * - * based on xorimage.c in OpenWrt - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> - -#define KEY_LEN 16 -#define PATTERN_LEN 251 - -static int -xor_pattern(uint8_t *data, size_t len, const char *key, int k_len, int k_off) -{ - int offset = k_off; - - while (len--) { - *data ^= key[offset]; - data++; - offset = (offset + 1) % k_len; - } - - return offset; -} - -static void xor_data(uint8_t *data, size_t len, const uint8_t *pattern) -{ - for (int i = 0; i < len; i++) { - *data ^= pattern[i]; - data++; - } -} - -static void __attribute__((noreturn)) usage(void) -{ - fprintf(stderr, "Usage: nec-enc -i infile -o outfile -k <key>\n"); - exit(EXIT_FAILURE); -} - -static unsigned char buf_pattern[4096], buf[4096]; - -int main(int argc, char **argv) -{ - int k_off = 0, ptn = 1, c, ret = EXIT_SUCCESS; - char *ifn = NULL, *ofn = NULL, *key = NULL; - size_t n, k_len; - FILE *out, *in; - - while ((c = getopt(argc, argv, "i:o:k:h")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'k': - key = optarg; - break; - case 'h': - default: - usage(); - } - } - - if (optind != argc || optind == 1) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - in = fopen(ifn, "r"); - if (!in) { - perror("can not open input file"); - usage(); - } - - out = fopen(ofn, "w"); - if (!out) { - perror("can not open output file"); - usage(); - } - - if (!key) { - fprintf(stderr, "key is not specified\n"); - usage(); - } - - k_len = strnlen(key, KEY_LEN + 1); - if (k_len == 0 || k_len > KEY_LEN) { - fprintf(stderr, "key length is not in range (0,%d)\n", KEY_LEN); - usage(); - } - - while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { - for (int i = 0; i < n; i++) { - buf_pattern[i] = ptn; - ptn++; - - if (ptn > PATTERN_LEN) - ptn = 1; - } - - k_off = xor_pattern(buf_pattern, n, key, k_len, k_off); - xor_data(buf, n, buf_pattern); - - if (fwrite(buf, 1, n, out) != n) { - perror("failed to write"); - ret = EXIT_FAILURE; - goto out; - } - } - - if (ferror(in)) { - perror("failed to read"); - ret = EXIT_FAILURE; - goto out; - } - -out: - fclose(in); - fclose(out); - return ret; -} diff --git a/tools/firmware-utils/src/osbridge-crc.c b/tools/firmware-utils/src/osbridge-crc.c deleted file mode 100644 index e9c577d8ed..0000000000 --- a/tools/firmware-utils/src/osbridge-crc.c +++ /dev/null @@ -1,303 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -# define HOST_TO_LE16(x) (x) -# define HOST_TO_LE32(x) (x) -# define LE16_TO_HOST(x) (x) -# define LE32_TO_HOST(x) (x) -#else -# define HOST_TO_LE16(x) bswap_16(x) -# define HOST_TO_LE32(x) bswap_32(x) -# define LE16_TO_HOST(x) bswap_16(x) -# define LE32_TO_HOST(x) bswap_32(x) -#endif - -uint32_t crc32buf(char *buf, size_t len); - -/* - * Globals - */ -static char *ifname; -static char *progname; -static char *ofname; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -h show this screen\n" - ); - - exit(status); -} - -int main(int argc, char *argv[]) -{ - int res = EXIT_FAILURE; - int buflen; - int err; - struct stat st; - char *buf; - uint32_t *hdr; - uint32_t crc; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "i:o:h"); - if (c == -1) - break; - - switch (c) { - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - buflen = st.st_size; - buf = malloc(buflen); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - errno = 0; - fread(buf, buflen, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto err_close_in; - } - - crc = crc32buf(buf, buflen); - hdr = (uint32_t *)buf; - *hdr = HOST_TO_LE32(crc); - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto err_close_in; - } - - errno = 0; - fwrite(buf, buflen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto err_close_out; - } - - res = EXIT_SUCCESS; - - fflush(outfile); - - err_close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } - - err_close_in: - fclose(infile); - - err_free: - free(buf); - - err: - return res; -} - -/**********************************************************************/ -/* The following was grabbed and tweaked from the old snippets collection - * of public domain C code. */ - -/**********************************************************************\ -|* Demonstration program to compute the 32-bit CRC used as the frame *| -|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| -|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| -|* protocol). The 32-bit FCS was added via the Federal Register, *| -|* 1 June 1982, p.23798. I presume but don't know for certain that *| -|* this polynomial is or will be included in CCITT V.41, which *| -|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| -|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| -|* errors by a factor of 10^-5 over 16-bit FCS. *| -\**********************************************************************/ - -/* Copyright (C) 1986 Gary S. Brown. You may use this program, or - code or tables extracted from it, as desired without restriction.*/ - -/* First, the polynomial itself and its table of feedback terms. The */ -/* polynomial is */ -/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ -/* Note that we take it "backwards" and put the highest-order term in */ -/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ -/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ -/* the MSB being 1. */ - -/* Note that the usual hardware shift register implementation, which */ -/* is what we're using (we're merely optimizing it by doing eight-bit */ -/* chunks at a time) shifts bits into the lowest-order term. In our */ -/* implementation, that means shifting towards the right. Why do we */ -/* do it this way? Because the calculated CRC must be transmitted in */ -/* order from highest-order term to lowest-order term. UARTs transmit */ -/* characters in order from LSB to MSB. By storing the CRC this way, */ -/* we hand it to the UART in the order low-byte to high-byte; the UART */ -/* sends each low-bit to hight-bit; and the result is transmission bit */ -/* by bit from highest- to lowest-order term without requiring any bit */ -/* shuffling on our part. Reception works similarly. */ - -/* The feedback terms table consists of 256, 32-bit entries. Notes: */ -/* */ -/* 1. The table can be generated at runtime if desired; code to do so */ -/* is shown later. It might not be obvious, but the feedback */ -/* terms simply represent the results of eight shift/xor opera- */ -/* tions for all combinations of data and CRC register values. */ -/* */ -/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ -/* be they sixteen or thirty-two bits wide. You simply choose the */ -/* appropriate table. Alternatively, because the table can be */ -/* generated at runtime, you can start by generating the table for */ -/* the polynomial in question and use exactly the same "updcrc", */ -/* if your application needn't simultaneously handle two CRC */ -/* polynomials. (Note, however, that XMODEM is strange.) */ -/* */ -/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ -/* of course, 32-bit entries work OK if the high 16 bits are zero. */ -/* */ -/* 4. The values must be right-shifted by eight bits by the "updcrc" */ -/* logic; the shift must be unsigned (bring in zeroes). On some */ -/* hardware you could probably optimize the shift in assembler by */ -/* using byte-swap instructions. */ - -static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ -0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, -0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, -0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, -0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, -0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, -0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, -0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, -0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, -0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, -0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, -0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, -0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, -0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, -0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, -0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, -0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, -0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, -0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, -0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, -0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, -0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, -0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, -0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, -0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, -0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, -0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, -0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, -0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, -0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, -0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, -0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, -0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, -0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, -0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, -0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) - -uint32_t crc32buf(char *buf, size_t len) -{ - uint32_t crc; - - crc = 0xFFFFFFFF; - - for ( ; len; --len, ++buf) - { - crc = UPDC32(*buf, crc); - } - - return crc ^ 0xFFFFFFFF; -} - diff --git a/tools/firmware-utils/src/oseama.c b/tools/firmware-utils/src/oseama.c deleted file mode 100644 index 75580e6cf5..0000000000 --- a/tools/firmware-utils/src/oseama.c +++ /dev/null @@ -1,552 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * oseama - * - * Copyright (C) 2016 Rafał Miłecki <zajec5@gmail.com> - */ - -#include <byteswap.h> -#include <endian.h> -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "md5.h" - -#if !defined(__BYTE_ORDER) -#error "Unknown byte order" -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_be32(x) (x) -#define be32_to_cpu(x) (x) -#define cpu_to_be16(x) (x) -#define be16_to_cpu(x) (x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_be32(x) bswap_32(x) -#define be32_to_cpu(x) bswap_32(x) -#define cpu_to_be16(x) bswap_16(x) -#define be16_to_cpu(x) bswap_16(x) -#else -#error "Unsupported endianness" -#endif - -#define SEAMA_MAGIC 0x5ea3a417 - -struct seama_seal_header { - uint32_t magic; - uint16_t reserved; - uint16_t metasize; - uint32_t imagesize; -} __attribute__ ((packed)); - -struct seama_entity_header { - uint32_t magic; - uint16_t reserved; - uint16_t metasize; - uint32_t imagesize; - uint8_t md5[16]; -} __attribute__ ((packed)); - -char *seama_path; -int entity_idx = -1; -char *out_path; - -static inline size_t oseama_min(size_t x, size_t y) { - return x < y ? x : y; -} - -/************************************************** - * Info - **************************************************/ - -static void oseama_info_parse_options(int argc, char **argv) { - int c; - - while ((c = getopt(argc, argv, "e:")) != -1) { - switch (c) { - case 'e': - entity_idx = atoi(optarg); - break; - } - } -} - -static int oseama_info_entities(FILE *seama) { - struct seama_entity_header hdr; - size_t bytes, metasize, imagesize; - uint8_t buf[1024]; - char *end, *tmp; - int i = 0; - int err = 0; - - while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) { - if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { - fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); - err = -EINVAL; - goto err_out; - } - metasize = be16_to_cpu(hdr.metasize); - imagesize = be32_to_cpu(hdr.imagesize); - - if (entity_idx >= 0 && i != entity_idx) { - fseek(seama, metasize + imagesize, SEEK_CUR); - i++; - continue; - } - - if (metasize >= sizeof(buf)) { - fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%zd B)\n", sizeof(buf), metasize); - err = -EINVAL; - goto err_out; - } - - if (entity_idx < 0) - printf("\n"); - printf("Entity offset:\t%ld\n", ftell(seama) - sizeof(hdr)); - printf("Entity size:\t%zd\n", sizeof(hdr) + metasize + imagesize); - printf("Meta size:\t%zd\n", metasize); - printf("Image size:\t%zd\n", imagesize); - - bytes = fread(buf, 1, metasize, seama); - if (bytes != metasize) { - fprintf(stderr, "Couldn't read %zd B of meta\n", metasize); - err = -EIO; - goto err_out; - } - - end = (char *)&buf[metasize - 1]; - *end = '\0'; - for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) { - printf("Meta entry:\t%s\n", tmp); - } - - fseek(seama, imagesize, SEEK_CUR); - i++; - } - -err_out: - return err; -} - -static int oseama_info(int argc, char **argv) { - FILE *seama; - struct seama_seal_header hdr; - size_t bytes; - uint16_t metasize; - uint32_t imagesize; - uint8_t buf[1024]; - int err = 0; - - if (argc < 3) { - fprintf(stderr, "No Seama file passed\n"); - err = -EINVAL; - goto out; - } - seama_path = argv[2]; - - optind = 3; - oseama_info_parse_options(argc, argv); - - seama = fopen(seama_path, "r"); - if (!seama) { - fprintf(stderr, "Couldn't open %s\n", seama_path); - err = -EACCES; - goto out; - } - - bytes = fread(&hdr, 1, sizeof(hdr), seama); - if (bytes != sizeof(hdr)) { - fprintf(stderr, "Couldn't read %s header\n", seama_path); - err = -EIO; - goto err_close; - } - metasize = be16_to_cpu(hdr.metasize); - imagesize = be32_to_cpu(hdr.imagesize); - - if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { - fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); - err = -EINVAL; - goto err_close; - } - - if (metasize >= sizeof(buf)) { - fprintf(stderr, "Too small buffer (%zu B) to read all meta info (%d B)\n", sizeof(buf), metasize); - err = -EINVAL; - goto err_close; - } - - if (imagesize) { - fprintf(stderr, "Invalid Seama image size: 0x%08x (should be 0)\n", imagesize); - err = -EINVAL; - goto err_close; - } - - bytes = fread(buf, 1, metasize, seama); - if (bytes != metasize) { - fprintf(stderr, "Couldn't read %d B of meta\n", metasize); - err = -EIO; - goto err_close; - } - - if (entity_idx < 0) { - char *end, *tmp; - - printf("Meta size:\t%d\n", metasize); - printf("Image size:\t%d\n", imagesize); - - end = (char *)&buf[metasize - 1]; - *end = '\0'; - for (tmp = (char *)buf; tmp < end && strlen(tmp); tmp += strlen(tmp) + 1) { - printf("Meta entry:\t%s\n", tmp); - } - } - - oseama_info_entities(seama); - -err_close: - fclose(seama); -out: - return err; -} - -/************************************************** - * Create - **************************************************/ - -static ssize_t oseama_entity_append_file(FILE *seama, const char *in_path) { - FILE *in; - size_t bytes; - ssize_t length = 0; - uint8_t buf[128]; - - in = fopen(in_path, "r"); - if (!in) { - fprintf(stderr, "Couldn't open %s\n", in_path); - return -EACCES; - } - - while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { - if (fwrite(buf, 1, bytes, seama) != bytes) { - fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, seama_path); - length = -EIO; - break; - } - length += bytes; - } - - fclose(in); - - return length; -} - -static ssize_t oseama_entity_append_zeros(FILE *seama, size_t length) { - uint8_t *buf; - - buf = malloc(length); - if (!buf) - return -ENOMEM; - memset(buf, 0, length); - - if (fwrite(buf, 1, length, seama) != length) { - fprintf(stderr, "Couldn't write %zu B to %s\n", length, seama_path); - return -EIO; - } - - return length; -} - -static ssize_t oseama_entity_align(FILE *seama, size_t curr_offset, size_t alignment) { - if (curr_offset & (alignment - 1)) { - size_t length = alignment - (curr_offset % alignment); - - return oseama_entity_append_zeros(seama, length); - } - - return 0; -} - -static int oseama_entity_write_hdr(FILE *seama, size_t metasize, size_t imagesize) { - struct seama_entity_header hdr = {}; - uint8_t buf[128]; - size_t length = imagesize; - size_t bytes; - MD5_CTX ctx; - - fseek(seama, sizeof(hdr) + metasize, SEEK_SET); - MD5_Init(&ctx); - while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) { - MD5_Update(&ctx, buf, bytes); - length -= bytes; - } - MD5_Final(hdr.md5, &ctx); - - hdr.magic = cpu_to_be32(SEAMA_MAGIC); - hdr.metasize = cpu_to_be16(metasize); - hdr.imagesize = cpu_to_be32(imagesize); - - fseek(seama, 0, SEEK_SET); - bytes = fwrite(&hdr, 1, sizeof(hdr), seama); - if (bytes != sizeof(hdr)) { - fprintf(stderr, "Couldn't write Seama entity header to %s\n", seama_path); - return -EIO; - } - - return 0; -} - -static int oseama_entity(int argc, char **argv) { - FILE *seama; - ssize_t sbytes; - size_t curr_offset = sizeof(struct seama_entity_header); - size_t metasize = 0, imagesize = 0; - int c; - int err = 0; - - if (argc < 3) { - fprintf(stderr, "No Seama file passed\n"); - err = -EINVAL; - goto out; - } - seama_path = argv[2]; - - seama = fopen(seama_path, "w+"); - if (!seama) { - fprintf(stderr, "Couldn't open %s\n", seama_path); - err = -EACCES; - goto out; - } - fseek(seama, curr_offset, SEEK_SET); - - optind = 3; - while ((c = getopt(argc, argv, "m:f:b:")) != -1) { - switch (c) { - case 'm': - sbytes = fwrite(optarg, 1, strlen(optarg) + 1, seama); - if (sbytes < 0) { - fprintf(stderr, "Failed to write meta %s\n", optarg); - } else { - curr_offset += sbytes; - metasize += sbytes; - } - - sbytes = oseama_entity_align(seama, curr_offset, 4); - if (sbytes < 0) { - fprintf(stderr, "Failed to append zeros\n"); - } else { - curr_offset += sbytes; - metasize += sbytes; - } - - break; - case 'f': - case 'b': - break; - } - } - - optind = 3; - while ((c = getopt(argc, argv, "m:f:b:")) != -1) { - switch (c) { - case 'm': - break; - case 'f': - sbytes = oseama_entity_append_file(seama, optarg); - if (sbytes < 0) { - fprintf(stderr, "Failed to append file %s\n", optarg); - } else { - curr_offset += sbytes; - imagesize += sbytes; - } - break; - case 'b': - sbytes = strtol(optarg, NULL, 0) - curr_offset; - if (sbytes < 0) { - fprintf(stderr, "Current Seama entity length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0)); - } else { - sbytes = oseama_entity_append_zeros(seama, sbytes); - if (sbytes < 0) { - fprintf(stderr, "Failed to append zeros\n"); - } else { - curr_offset += sbytes; - imagesize += sbytes; - } - } - break; - } - if (err) - break; - } - - oseama_entity_write_hdr(seama, metasize, imagesize); - - fclose(seama); -out: - return err; -} - -/************************************************** - * Extract - **************************************************/ - -static void oseama_extract_parse_options(int argc, char **argv) { - int c; - - while ((c = getopt(argc, argv, "e:o:")) != -1) { - switch (c) { - case 'e': - entity_idx = atoi(optarg); - break; - case 'o': - out_path = optarg; - break; - } - } -} - -static int oseama_extract_entity(FILE *seama, FILE *out) { - struct seama_entity_header hdr; - size_t bytes, metasize, imagesize, length; - uint8_t buf[1024]; - int i = 0; - int err = 0; - - while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) { - if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { - fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); - err = -EINVAL; - break; - } - metasize = be16_to_cpu(hdr.metasize); - imagesize = be32_to_cpu(hdr.imagesize); - - if (i != entity_idx) { - fseek(seama, metasize + imagesize, SEEK_CUR); - i++; - continue; - } - - fseek(seama, -sizeof(hdr), SEEK_CUR); - - length = sizeof(hdr) + metasize + imagesize; - while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) { - if (fwrite(buf, 1, bytes, out) != bytes) { - fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); - err = -EIO; - break; - } - length -= bytes; - } - - if (length) { - fprintf(stderr, "Couldn't extract whole entity %d from %s (%zu B left)\n", entity_idx, seama_path, length); - err = -EIO; - break; - } - - break; - } - - return err; -} - -static int oseama_extract(int argc, char **argv) { - FILE *seama; - FILE *out; - struct seama_seal_header hdr; - size_t bytes; - uint16_t metasize; - int err = 0; - - if (argc < 3) { - fprintf(stderr, "No Seama file passed\n"); - err = -EINVAL; - goto out; - } - seama_path = argv[2]; - - optind = 3; - oseama_extract_parse_options(argc, argv); - if (entity_idx < 0) { - fprintf(stderr, "No entity specified\n"); - err = -EINVAL; - goto out; - } else if (!out_path) { - fprintf(stderr, "No output file specified\n"); - err = -EINVAL; - goto out; - } - - seama = fopen(seama_path, "r"); - if (!seama) { - fprintf(stderr, "Couldn't open %s\n", seama_path); - err = -EACCES; - goto out; - } - - out = fopen(out_path, "w"); - if (!out) { - fprintf(stderr, "Couldn't open %s\n", out_path); - err = -EACCES; - goto err_close_seama; - } - - bytes = fread(&hdr, 1, sizeof(hdr), seama); - if (bytes != sizeof(hdr)) { - fprintf(stderr, "Couldn't read %s header\n", seama_path); - err = -EIO; - goto err_close_out; - } - metasize = be16_to_cpu(hdr.metasize); - - fseek(seama, metasize, SEEK_CUR); - - oseama_extract_entity(seama, out); - -err_close_out: - fclose(out); -err_close_seama: - fclose(seama); -out: - return err; -} - -/************************************************** - * Start - **************************************************/ - -static void usage() { - printf("Usage:\n"); - printf("\n"); - printf("Info about Seama seal (container):\n"); - printf("\toseama info <file> [options]\n"); - printf("\t-e\t\t\t\tprint info about specified entity only\n"); - printf("\n"); - printf("Create Seama entity:\n"); - printf("\toseama entity <file> [options]\n"); - printf("\t-m meta\t\t\t\tmeta into to put in header\n"); - printf("\t-f file\t\t\t\tappend content from file\n"); - printf("\t-b offset\t\t\tappend zeros till reaching absolute offset\n"); - printf("\n"); - printf("Extract from Seama seal (container):\n"); - printf("\toseama extract <file> [options]\n"); - printf("\t-e\t\t\t\tindex of entity to extract\n"); - printf("\t-o file\t\t\t\toutput file\n"); -} - -int main(int argc, char **argv) { - if (argc > 1) { - if (!strcmp(argv[1], "info")) - return oseama_info(argc, argv); - else if (!strcmp(argv[1], "entity")) - return oseama_entity(argc, argv); - else if (!strcmp(argv[1], "extract")) - return oseama_extract(argc, argv); - } - - usage(); - return 0; -} diff --git a/tools/firmware-utils/src/otrx.c b/tools/firmware-utils/src/otrx.c deleted file mode 100644 index b5cd70d6c8..0000000000 --- a/tools/firmware-utils/src/otrx.c +++ /dev/null @@ -1,599 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * otrx - * - * Copyright (C) 2015-2017 Rafał Miłecki <zajec5@gmail.com> - */ - -#include <byteswap.h> -#include <endian.h> -#include <errno.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#if !defined(__BYTE_ORDER) -#error "Unknown byte order" -#endif - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le32(x) bswap_32(x) -#define le32_to_cpu(x) bswap_32(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le32(x) (x) -#define le32_to_cpu(x) (x) -#else -#error "Unsupported endianness" -#endif - -#define TRX_MAGIC 0x30524448 -#define TRX_FLAGS_OFFSET 12 -#define TRX_MAX_PARTS 3 - -struct trx_header { - uint32_t magic; - uint32_t length; - uint32_t crc32; - uint16_t flags; - uint16_t version; - uint32_t offset[3]; -}; - -char *trx_path; -size_t trx_offset = 0; -char *partition[TRX_MAX_PARTS] = {}; - -static inline size_t otrx_min(size_t x, size_t y) { - return x < y ? x : y; -} - -/************************************************** - * CRC32 - **************************************************/ - -static const uint32_t crc32_tbl[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - -uint32_t otrx_crc32(uint32_t crc, uint8_t *buf, size_t len) { - while (len) { - crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8); - buf++; - len--; - } - - return crc; -} - -/************************************************** - * Check - **************************************************/ - -static void otrx_check_parse_options(int argc, char **argv) { - int c; - - while ((c = getopt(argc, argv, "o:")) != -1) { - switch (c) { - case 'o': - trx_offset = atoi(optarg); - break; - } - } -} - -static int otrx_check(int argc, char **argv) { - FILE *trx; - struct trx_header hdr; - size_t bytes, length; - uint8_t buf[1024]; - uint32_t crc32; - int err = 0; - - if (argc < 3) { - fprintf(stderr, "No TRX file passed\n"); - err = -EINVAL; - goto out; - } - trx_path = argv[2]; - - optind = 3; - otrx_check_parse_options(argc, argv); - - trx = fopen(trx_path, "r"); - if (!trx) { - fprintf(stderr, "Couldn't open %s\n", trx_path); - err = -EACCES; - goto out; - } - - fseek(trx, trx_offset, SEEK_SET); - bytes = fread(&hdr, 1, sizeof(hdr), trx); - if (bytes != sizeof(hdr)) { - fprintf(stderr, "Couldn't read %s header\n", trx_path); - err = -EIO; - goto err_close; - } - - if (le32_to_cpu(hdr.magic) != TRX_MAGIC) { - fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic)); - err = -EINVAL; - goto err_close; - } - - length = le32_to_cpu(hdr.length); - if (length < sizeof(hdr)) { - fprintf(stderr, "Length read from TRX too low (%zu B)\n", length); - err = -EINVAL; - goto err_close; - } - - crc32 = 0xffffffff; - fseek(trx, trx_offset + TRX_FLAGS_OFFSET, SEEK_SET); - length -= TRX_FLAGS_OFFSET; - while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) { - crc32 = otrx_crc32(crc32, buf, bytes); - length -= bytes; - } - - if (length) { - fprintf(stderr, "Couldn't read last %zd B of data from %s\n", length, trx_path); - err = -EIO; - goto err_close; - } - - if (crc32 != le32_to_cpu(hdr.crc32)) { - fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(hdr.crc32)); - err = -EINVAL; - goto err_close; - } - - printf("Found a valid TRX version %d\n", le32_to_cpu(hdr.version)); - -err_close: - fclose(trx); -out: - return err; -} - -/************************************************** - * Create - **************************************************/ - -static ssize_t otrx_create_append_file(FILE *trx, const char *in_path) { - FILE *in; - size_t bytes; - ssize_t length = 0; - uint8_t buf[1024]; - - in = fopen(in_path, "r"); - if (!in) { - fprintf(stderr, "Couldn't open %s\n", in_path); - return -EACCES; - } - - while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) { - if (fwrite(buf, 1, bytes, trx) != bytes) { - fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, trx_path); - length = -EIO; - break; - } - length += bytes; - } - - fclose(in); - - return length; -} - -static ssize_t otrx_create_append_zeros(FILE *trx, size_t length) { - uint8_t *buf; - - buf = malloc(length); - if (!buf) - return -ENOMEM; - memset(buf, 0, length); - - if (fwrite(buf, 1, length, trx) != length) { - fprintf(stderr, "Couldn't write %zu B to %s\n", length, trx_path); - free(buf); - return -EIO; - } - - free(buf); - - return length; -} - -static ssize_t otrx_create_align(FILE *trx, size_t curr_offset, size_t alignment) { - if (curr_offset & (alignment - 1)) { - size_t length = alignment - (curr_offset % alignment); - return otrx_create_append_zeros(trx, length); - } - - return 0; -} - -static int otrx_create_write_hdr(FILE *trx, struct trx_header *hdr) { - size_t bytes, length; - uint8_t buf[1024]; - uint32_t crc32; - - hdr->version = 1; - - fseek(trx, 0, SEEK_SET); - bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx); - if (bytes != sizeof(struct trx_header)) { - fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path); - return -EIO; - } - - length = le32_to_cpu(hdr->length); - - crc32 = 0xffffffff; - fseek(trx, TRX_FLAGS_OFFSET, SEEK_SET); - length -= TRX_FLAGS_OFFSET; - while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) { - crc32 = otrx_crc32(crc32, buf, bytes); - length -= bytes; - } - hdr->crc32 = cpu_to_le32(crc32); - - fseek(trx, 0, SEEK_SET); - bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx); - if (bytes != sizeof(struct trx_header)) { - fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path); - return -EIO; - } - - return 0; -} - -static int otrx_create(int argc, char **argv) { - FILE *trx; - struct trx_header hdr = {}; - ssize_t sbytes; - size_t curr_idx = 0; - size_t curr_offset = sizeof(hdr); - char *e; - uint32_t magic; - int c; - int err = 0; - - hdr.magic = cpu_to_le32(TRX_MAGIC); - - if (argc < 3) { - fprintf(stderr, "No TRX file passed\n"); - err = -EINVAL; - goto out; - } - trx_path = argv[2]; - - trx = fopen(trx_path, "w+"); - if (!trx) { - fprintf(stderr, "Couldn't open %s\n", trx_path); - err = -EACCES; - goto out; - } - fseek(trx, curr_offset, SEEK_SET); - - optind = 3; - while ((c = getopt(argc, argv, "f:A:a:b:M:")) != -1) { - switch (c) { - case 'f': - if (curr_idx >= TRX_MAX_PARTS) { - err = -ENOSPC; - fprintf(stderr, "Reached TRX partitions limit, no place for %s\n", optarg); - goto err_close; - } - - sbytes = otrx_create_append_file(trx, optarg); - if (sbytes < 0) { - fprintf(stderr, "Failed to append file %s\n", optarg); - } else { - hdr.offset[curr_idx++] = curr_offset; - curr_offset += sbytes; - } - - sbytes = otrx_create_align(trx, curr_offset, 4); - if (sbytes < 0) - fprintf(stderr, "Failed to append zeros\n"); - else - curr_offset += sbytes; - - break; - case 'A': - sbytes = otrx_create_append_file(trx, optarg); - if (sbytes < 0) { - fprintf(stderr, "Failed to append file %s\n", optarg); - } else { - curr_offset += sbytes; - } - - sbytes = otrx_create_align(trx, curr_offset, 4); - if (sbytes < 0) - fprintf(stderr, "Failed to append zeros\n"); - else - curr_offset += sbytes; - break; - case 'a': - sbytes = otrx_create_align(trx, curr_offset, strtol(optarg, NULL, 0)); - if (sbytes < 0) - fprintf(stderr, "Failed to append zeros\n"); - else - curr_offset += sbytes; - break; - case 'b': - sbytes = strtol(optarg, NULL, 0) - curr_offset; - if (sbytes < 0) { - fprintf(stderr, "Current TRX length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0)); - } else { - sbytes = otrx_create_append_zeros(trx, sbytes); - if (sbytes < 0) - fprintf(stderr, "Failed to append zeros\n"); - else - curr_offset += sbytes; - } - break; - case 'M': - errno = 0; - magic = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) - fprintf(stderr, "illegal magic string %s\n", optarg); - else - hdr.magic = cpu_to_le32(magic); - break; - } - if (err) - break; - } - - sbytes = otrx_create_align(trx, curr_offset, 0x1000); - if (sbytes < 0) - fprintf(stderr, "Failed to append zeros\n"); - else - curr_offset += sbytes; - - hdr.length = curr_offset; - otrx_create_write_hdr(trx, &hdr); -err_close: - fclose(trx); -out: - return err; -} - -/************************************************** - * Extract - **************************************************/ - -static void otrx_extract_parse_options(int argc, char **argv) { - int c; - - while ((c = getopt(argc, argv, "c:e:o:1:2:3:")) != -1) { - switch (c) { - case 'o': - trx_offset = atoi(optarg); - break; - case '1': - partition[0] = optarg; - break; - case '2': - partition[1] = optarg; - break; - case '3': - partition[2] = optarg; - break; - } - } -} - -static int otrx_extract_copy(FILE *trx, size_t offset, size_t length, char *out_path) { - FILE *out; - size_t bytes; - uint8_t *buf; - int err = 0; - - out = fopen(out_path, "w"); - if (!out) { - fprintf(stderr, "Couldn't open %s\n", out_path); - err = -EACCES; - goto out; - } - - buf = malloc(length); - if (!buf) { - fprintf(stderr, "Couldn't alloc %zu B buffer\n", length); - err = -ENOMEM; - goto err_close; - } - - fseek(trx, offset, SEEK_SET); - bytes = fread(buf, 1, length, trx); - if (bytes != length) { - fprintf(stderr, "Couldn't read %zu B of data from %s\n", length, trx_path); - err = -ENOMEM; - goto err_free_buf; - }; - - bytes = fwrite(buf, 1, length, out); - if (bytes != length) { - fprintf(stderr, "Couldn't write %zu B to %s\n", length, out_path); - err = -ENOMEM; - goto err_free_buf; - } - - printf("Extracted 0x%zx bytes into %s\n", length, out_path); - -err_free_buf: - free(buf); -err_close: - fclose(out); -out: - return err; -} - -static int otrx_extract(int argc, char **argv) { - FILE *trx; - struct trx_header hdr; - size_t bytes; - int i; - int err = 0; - - if (argc < 3) { - fprintf(stderr, "No TRX file passed\n"); - err = -EINVAL; - goto out; - } - trx_path = argv[2]; - - optind = 3; - otrx_extract_parse_options(argc, argv); - - trx = fopen(trx_path, "r"); - if (!trx) { - fprintf(stderr, "Couldn't open %s\n", trx_path); - err = -EACCES; - goto out; - } - - fseek(trx, trx_offset, SEEK_SET); - bytes = fread(&hdr, 1, sizeof(hdr), trx); - if (bytes != sizeof(hdr)) { - fprintf(stderr, "Couldn't read %s header\n", trx_path); - err = -EIO; - goto err_close; - } - - if (le32_to_cpu(hdr.magic) != TRX_MAGIC) { - fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic)); - err = -EINVAL; - goto err_close; - } - - for (i = 0; i < TRX_MAX_PARTS; i++) { - size_t length; - - if (!partition[i]) - continue; - if (!hdr.offset[i]) { - printf("TRX doesn't contain partition %d, can't extract %s\n", i + 1, partition[i]); - continue; - } - - if (i + 1 >= TRX_MAX_PARTS || !hdr.offset[i + 1]) - length = le32_to_cpu(hdr.length) - le32_to_cpu(hdr.offset[i]); - else - length = le32_to_cpu(hdr.offset[i + 1]) - le32_to_cpu(hdr.offset[i]); - - otrx_extract_copy(trx, trx_offset + le32_to_cpu(hdr.offset[i]), length, partition[i]); - } - -err_close: - fclose(trx); -out: - return err; -} - -/************************************************** - * Start - **************************************************/ - -static void usage() { - printf("Usage:\n"); - printf("\n"); - printf("Checking TRX file:\n"); - printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n"); - printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n"); - printf("\n"); - printf("Creating new TRX file:\n"); - printf("\totrx create <file> [options] [partitions]\n"); - printf("\t-f file\t\t\t\t[partition] start new partition with content copied from file\n"); - printf("\t-A file\t\t\t\t[partition] append current partition with content copied from file\n"); - printf("\t-a alignment\t\t\t[partition] align current partition\n"); - printf("\t-b offset\t\t\t[partition] append zeros to partition till reaching absolute offset\n"); - printf("\n"); - printf("Extracting from TRX file:\n"); - printf("\totrx extract <file> [options]\textract partitions from TRX file\n"); - printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n"); - printf("\t-1 file\t\t\t\tfile to extract 1st partition to (optional)\n"); - printf("\t-2 file\t\t\t\tfile to extract 2nd partition to (optional)\n"); - printf("\t-3 file\t\t\t\tfile to extract 3rd partition to (optional)\n"); -} - -int main(int argc, char **argv) { - if (argc > 1) { - if (!strcmp(argv[1], "check")) - return otrx_check(argc, argv); - else if (!strcmp(argv[1], "create")) - return otrx_create(argc, argv); - else if (!strcmp(argv[1], "extract")) - return otrx_extract(argc, argv); - } - - usage(); - return 0; -} diff --git a/tools/firmware-utils/src/pc1crypt.c b/tools/firmware-utils/src/pc1crypt.c deleted file mode 100644 index be1038b781..0000000000 --- a/tools/firmware-utils/src/pc1crypt.c +++ /dev/null @@ -1,356 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> - * - * This code was based on: - * PC1 Cipher Algorithm ( Pukall Cipher 1 ) - * By Alexander PUKALL 1991 - * free code no restriction to use - * please include the name of the Author in the final software - * the Key is 128 bits - * http://membres.lycos.fr/pc1/ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> /* for unlink() */ -#include <libgen.h> -#include <getopt.h> /* for getopt() */ -#include <stdarg.h> -#include <errno.h> -#include <sys/stat.h> - -struct pc1_ctx { - unsigned short ax; - unsigned short bx; - unsigned short cx; - unsigned short dx; - unsigned short si; - unsigned short tmp; - unsigned short x1a2; - unsigned short x1a0[8]; - unsigned short res; - unsigned short i; - unsigned short inter; - unsigned short cfc; - unsigned short cfd; - unsigned short compte; - unsigned char cle[17]; - short c; -}; - -static void pc1_finish(struct pc1_ctx *pc1) -{ - /* erase all variables */ - memset(pc1, 0, sizeof(struct pc1_ctx)); -} - -static void pc1_code(struct pc1_ctx *pc1) -{ - pc1->dx = pc1->x1a2 + pc1->i; - pc1->ax = pc1->x1a0[pc1->i]; - pc1->cx = 0x015a; - pc1->bx = 0x4e35; - - pc1->tmp = pc1->ax; - pc1->ax = pc1->si; - pc1->si = pc1->tmp; - - pc1->tmp = pc1->ax; - pc1->ax = pc1->dx; - pc1->dx = pc1->tmp; - - if (pc1->ax != 0) { - pc1->ax = pc1->ax * pc1->bx; - } - - pc1->tmp = pc1->ax; - pc1->ax = pc1->cx; - pc1->cx = pc1->tmp; - - if (pc1->ax != 0) { - pc1->ax = pc1->ax * pc1->si; - pc1->cx = pc1->ax + pc1->cx; - } - - pc1->tmp = pc1->ax; - pc1->ax = pc1->si; - pc1->si = pc1->tmp; - pc1->ax = pc1->ax * pc1->bx; - pc1->dx = pc1->cx + pc1->dx; - - pc1->ax = pc1->ax + 1; - - pc1->x1a2 = pc1->dx; - pc1->x1a0[pc1->i] = pc1->ax; - - pc1->res = pc1->ax ^ pc1->dx; - pc1->i = pc1->i + 1; -} - -static void pc1_assemble(struct pc1_ctx *pc1) -{ - pc1->x1a0[0] = (pc1->cle[0] * 256) + pc1->cle[1]; - - pc1_code(pc1); - pc1->inter = pc1->res; - - pc1->x1a0[1] = pc1->x1a0[0] ^ ((pc1->cle[2]*256) + pc1->cle[3]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->x1a0[2] = pc1->x1a0[1] ^ ((pc1->cle[4]*256) + pc1->cle[5]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->x1a0[3] = pc1->x1a0[2] ^ ((pc1->cle[6]*256) + pc1->cle[7]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->x1a0[4] = pc1->x1a0[3] ^ ((pc1->cle[8]*256) + pc1->cle[9]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->x1a0[5] = pc1->x1a0[4] ^ ((pc1->cle[10]*256) + pc1->cle[11]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->x1a0[6] = pc1->x1a0[5] ^ ((pc1->cle[12]*256) + pc1->cle[13]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->x1a0[7] = pc1->x1a0[6] ^ ((pc1->cle[14]*256) + pc1->cle[15]); - pc1_code(pc1); - pc1->inter = pc1->inter ^ pc1->res; - - pc1->i = 0; -} - -static unsigned char pc1_decrypt(struct pc1_ctx *pc1, short c) -{ - pc1_assemble(pc1); - pc1->cfc = pc1->inter >> 8; - pc1->cfd = pc1->inter & 255; /* cfc^cfd = random byte */ - - c = c ^ (pc1->cfc ^ pc1->cfd); - for (pc1->compte = 0; pc1->compte <= 15; pc1->compte++) { - /* we mix the plaintext byte with the key */ - pc1->cle[pc1->compte] = pc1->cle[pc1->compte] ^ c; - } - - return c; -} - -static unsigned char pc1_encrypt(struct pc1_ctx *pc1, short c) -{ - pc1_assemble(pc1); - pc1->cfc = pc1->inter >> 8; - pc1->cfd = pc1->inter & 255; /* cfc^cfd = random byte */ - - for (pc1->compte = 0; pc1->compte <= 15; pc1->compte++) { - /* we mix the plaintext byte with the key */ - pc1->cle[pc1->compte] = pc1->cle[pc1->compte] ^ c; - } - c = c ^ (pc1->cfc ^ pc1->cfd); - - return c; -} - -static void pc1_init(struct pc1_ctx *pc1) -{ - memset(pc1, 0, sizeof(struct pc1_ctx)); - - /* ('Remsaalps!123456') is the key used, you can change it */ - strcpy(pc1->cle, "Remsaalps!123456"); -} - -static void pc1_decrypt_buf(struct pc1_ctx *pc1, unsigned char *buf, - unsigned len) -{ - unsigned i; - - for (i = 0; i < len; i++) - buf[i] = pc1_decrypt(pc1, buf[i]); -} - -static void pc1_encrypt_buf(struct pc1_ctx *pc1, unsigned char *buf, - unsigned len) -{ - unsigned i; - - for (i = 0; i < len; i++) - buf[i] = pc1_encrypt(pc1, buf[i]); -} - -/* - * Globals - */ -static char *ifname; -static char *progname; -static char *ofname; -static int decrypt; - -/* - * Message macros - */ -#define ERR(fmt, ...) do { \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt "\n", \ - progname, ## __VA_ARGS__ ); \ -} while (0) - -#define ERRS(fmt, ...) do { \ - int save = errno; \ - fflush(0); \ - fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ - progname, ## __VA_ARGS__, strerror(save)); \ -} while (0) - -void usage(int status) -{ - FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; - - fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); - fprintf(stream, -"\n" -"Options:\n" -" -d decrypt instead of encrypt" -" -i <file> read input from the file <file>\n" -" -o <file> write output to the file <file>\n" -" -h show this screen\n" - ); - - exit(status); -} - -#define BUFSIZE (64 * 1024) - -int main(int argc, char *argv[]) -{ - struct pc1_ctx pc1; - int res = EXIT_FAILURE; - int err; - struct stat st; - char *buf; - unsigned total; - - FILE *outfile, *infile; - - progname = basename(argv[0]); - - while ( 1 ) { - int c; - - c = getopt(argc, argv, "di:o:h"); - if (c == -1) - break; - - switch (c) { - case 'd': - decrypt = 1; - break; - case 'i': - ifname = optarg; - break; - case 'o': - ofname = optarg; - break; - case 'h': - usage(EXIT_SUCCESS); - break; - default: - usage(EXIT_FAILURE); - break; - } - } - - if (ifname == NULL) { - ERR("no input file specified"); - goto err; - } - - if (ofname == NULL) { - ERR("no output file specified"); - goto err; - } - - err = stat(ifname, &st); - if (err){ - ERRS("stat failed on %s", ifname); - goto err; - } - - total = st.st_size; - buf = malloc(BUFSIZE); - if (!buf) { - ERR("no memory for buffer\n"); - goto err; - } - - infile = fopen(ifname, "r"); - if (infile == NULL) { - ERRS("could not open \"%s\" for reading", ifname); - goto err_free; - } - - outfile = fopen(ofname, "w"); - if (outfile == NULL) { - ERRS("could not open \"%s\" for writing", ofname); - goto err_close_in; - } - - pc1_init(&pc1); - while (total > 0) { - unsigned datalen; - - if (total > BUFSIZE) - datalen = BUFSIZE; - else - datalen = total; - - errno = 0; - fread(buf, datalen, 1, infile); - if (errno != 0) { - ERRS("unable to read from file %s", ifname); - goto err_close_out; - } - - if (decrypt) - pc1_decrypt_buf(&pc1, buf, datalen); - else - pc1_encrypt_buf(&pc1, buf, datalen); - - errno = 0; - fwrite(buf, datalen, 1, outfile); - if (errno) { - ERRS("unable to write to file %s", ofname); - goto err_close_out; - } - - total -= datalen; - } - pc1_finish(&pc1); - - res = EXIT_SUCCESS; - - fflush(outfile); - - err_close_out: - fclose(outfile); - if (res != EXIT_SUCCESS) { - unlink(ofname); - } - - err_close_in: - fclose(infile); - - err_free: - free(buf); - - err: - return res; -} - diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c deleted file mode 100644 index 665c5f7a04..0000000000 --- a/tools/firmware-utils/src/ptgen.c +++ /dev/null @@ -1,654 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * ptgen - partition table generator - * Copyright (C) 2006 by Felix Fietkau <nbd@nbd.name> - * - * uses parts of afdisk - * Copyright (C) 2002 by David Roetzel <david@roetzel.de> - * - * UUID/GUID definition stolen from kernel/include/uapi/linux/uuid.h - * Copyright (C) 2010, Intel Corp. Huang Ying <ying.huang@intel.com> - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <stdbool.h> -#include <ctype.h> -#include <inttypes.h> -#include <fcntl.h> -#include <stdint.h> -#include "cyg_crc.h" - -#if __BYTE_ORDER == __BIG_ENDIAN -#define cpu_to_le16(x) bswap_16(x) -#define cpu_to_le32(x) bswap_32(x) -#define cpu_to_le64(x) bswap_64(x) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_le16(x) (x) -#define cpu_to_le32(x) (x) -#define cpu_to_le64(x) (x) -#else -#error unknown endianness! -#endif - -#define swap(a, b) \ - do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) - -#define BIT(_x) (1UL << (_x)) - -typedef struct { - uint8_t b[16]; -} guid_t; - -#define GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ -((guid_t) \ -{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ - (b) & 0xff, ((b) >> 8) & 0xff, \ - (c) & 0xff, ((c) >> 8) & 0xff, \ - (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}) - -#define GUID_STRING_LENGTH 36 - -#define GPT_SIGNATURE 0x5452415020494645ULL -#define GPT_REVISION 0x00010000 - -#define GUID_PARTITION_SYSTEM \ - GUID_INIT( 0xC12A7328, 0xF81F, 0x11d2, \ - 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B) - -#define GUID_PARTITION_BASIC_DATA \ - GUID_INIT( 0xEBD0A0A2, 0xB9E5, 0x4433, \ - 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7) - -#define GUID_PARTITION_BIOS_BOOT \ - GUID_INIT( 0x21686148, 0x6449, 0x6E6F, \ - 0x74, 0x4E, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49) - -#define GUID_PARTITION_LINUX_FIT_GUID \ - GUID_INIT( 0xcae9be83, 0xb15f, 0x49cc, \ - 0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93) - -#define GUID_PARTITION_LINUX_FS_GUID \ - GUID_INIT( 0x0fc63daf, 0x8483, 0x4772, \ - 0x8e, 0x79, 0x3d, 0x69, 0xd8, 0x47, 0x7d, 0xe4) - -#define GPT_HEADER_SIZE 92 -#define GPT_ENTRY_SIZE 128 -#define GPT_ENTRY_MAX 128 -#define GPT_ENTRY_NAME_SIZE 72 -#define GPT_SIZE GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE - -#define GPT_ATTR_PLAT_REQUIRED BIT(0) -#define GPT_ATTR_EFI_IGNORE BIT(1) -#define GPT_ATTR_LEGACY_BOOT BIT(2) - -#define GPT_HEADER_SECTOR 1 -#define GPT_FIRST_ENTRY_SECTOR 2 - -#define MBR_ENTRY_MAX 4 -#define MBR_DISK_SIGNATURE_OFFSET 440 -#define MBR_PARTITION_ENTRY_OFFSET 446 -#define MBR_BOOT_SIGNATURE_OFFSET 510 - -#define DISK_SECTOR_SIZE 512 - -/* Partition table entry */ -struct pte { - uint8_t active; - uint8_t chs_start[3]; - uint8_t type; - uint8_t chs_end[3]; - uint32_t start; - uint32_t length; -}; - -struct partinfo { - unsigned long actual_start; - unsigned long start; - unsigned long size; - int type; - int hybrid; - char *name; - short int required; - guid_t guid; -}; - -/* GPT Partition table header */ -struct gpth { - uint64_t signature; - uint32_t revision; - uint32_t size; - uint32_t crc32; - uint32_t reserved; - uint64_t self; - uint64_t alternate; - uint64_t first_usable; - uint64_t last_usable; - guid_t disk_guid; - uint64_t first_entry; - uint32_t entry_num; - uint32_t entry_size; - uint32_t entry_crc32; -} __attribute__((packed)); - -/* GPT Partition table entry */ -struct gpte { - guid_t type; - guid_t guid; - uint64_t start; - uint64_t end; - uint64_t attr; - char name[GPT_ENTRY_NAME_SIZE]; -} __attribute__((packed)); - - -int verbose = 0; -int active = 1; -int heads = -1; -int sectors = -1; -int kb_align = 0; -bool ignore_null_sized_partition = false; -bool use_guid_partition_table = false; -struct partinfo parts[GPT_ENTRY_MAX]; -char *filename = NULL; - - -/* - * parse the size argument, which is either - * a simple number (K assumed) or - * K, M or G - * - * returns the size in KByte - */ -static long to_kbytes(const char *string) -{ - int exp = 0; - long result; - char *end; - - result = strtoul(string, &end, 0); - switch (tolower(*end)) { - case 'k' : - case '\0' : exp = 0; break; - case 'm' : exp = 1; break; - case 'g' : exp = 2; break; - default: return 0; - } - - if (*end) - end++; - - if (*end) { - fputs("garbage after end of number\n", stderr); - return 0; - } - - /* result: number + 1024^(exp) */ - if (exp == 0) - return result; - return result * (2 << ((10 * exp) - 1)); -} - -/* convert the sector number into a CHS value for the partition table */ -static void to_chs(long sect, unsigned char chs[3]) -{ - int c,h,s; - - s = (sect % sectors) + 1; - sect = sect / sectors; - h = sect % heads; - sect = sect / heads; - c = sect; - - chs[0] = h; - chs[1] = s | ((c >> 2) & 0xC0); - chs[2] = c & 0xFF; - - return; -} - -/* round the sector number up to the next cylinder */ -static inline unsigned long round_to_cyl(long sect) -{ - int cyl_size = heads * sectors; - - return sect + cyl_size - (sect % cyl_size); -} - -/* round the sector number up to the kb_align boundary */ -static inline unsigned long round_to_kb(long sect) { - return ((sect - 1) / kb_align + 1) * kb_align; -} - -/* Compute a CRC for guid partition table */ -static inline unsigned long gpt_crc32(void *buf, unsigned long len) -{ - return cyg_crc32_accumulate(~0L, buf, len) ^ ~0L; -} - -/* Parse a guid string to guid_t struct */ -static inline int guid_parse(char *buf, guid_t *guid) -{ - char b[4] = {0}; - char *p = buf; - unsigned i = 0; - if (strnlen(buf, GUID_STRING_LENGTH) != GUID_STRING_LENGTH) - return -1; - for (i = 0; i < sizeof(guid_t); i++) { - if (*p == '-') - p++; - if (*p == '\0') - return -1; - memcpy(b, p, 2); - guid->b[i] = strtol(b, 0, 16); - p += 2; - } - swap(guid->b[0], guid->b[3]); - swap(guid->b[1], guid->b[2]); - swap(guid->b[4], guid->b[5]); - swap(guid->b[6], guid->b[7]); - return 0; -} - -/* init an utf-16 string from utf-8 string */ -static inline void init_utf16(char *str, uint16_t *buf, unsigned bufsize) -{ - unsigned i, n = 0; - for (i = 0; i < bufsize; i++) { - if (str[n] == 0x00) { - buf[i] = 0x00; - return ; - } else if ((str[n] & 0x80) == 0x00) {//0xxxxxxx - buf[i] = cpu_to_le16(str[n++]); - } else if ((str[n] & 0xE0) == 0xC0) {//110xxxxx - buf[i] = cpu_to_le16((str[n] & 0x1F) << 6 | (str[n + 1] & 0x3F)); - n += 2; - } else if ((str[n] & 0xF0) == 0xE0) {//1110xxxx - buf[i] = cpu_to_le16((str[n] & 0x0F) << 12 | (str[n + 1] & 0x3F) << 6 | (str[n + 2] & 0x3F)); - n += 3; - } else { - buf[i] = cpu_to_le16('?'); - n++; - } - } -} - -/* check the partition sizes and write the partition table */ -static int gen_ptable(uint32_t signature, int nr) -{ - struct pte pte[MBR_ENTRY_MAX]; - unsigned long start, len, sect = 0; - int i, fd, ret = -1; - - memset(pte, 0, sizeof(struct pte) * MBR_ENTRY_MAX); - for (i = 0; i < nr; i++) { - if (!parts[i].size) { - if (ignore_null_sized_partition) - continue; - fprintf(stderr, "Invalid size in partition %d!\n", i); - return ret; - } - - pte[i].active = ((i + 1) == active) ? 0x80 : 0; - pte[i].type = parts[i].type; - - start = sect + sectors; - if (parts[i].start != 0) { - if (parts[i].start * 2 < start) { - fprintf(stderr, "Invalid start %ld for partition %d!\n", - parts[i].start, i); - return ret; - } - start = parts[i].start * 2; - } else if (kb_align != 0) { - start = round_to_kb(start); - } - pte[i].start = cpu_to_le32(start); - - sect = start + parts[i].size * 2; - if (kb_align == 0) - sect = round_to_cyl(sect); - pte[i].length = cpu_to_le32(len = sect - start); - - to_chs(start, pte[i].chs_start); - to_chs(start + len - 1, pte[i].chs_end); - - if (verbose) - fprintf(stderr, "Partition %d: start=%ld, end=%ld, size=%ld\n", - i, - (long)start * DISK_SECTOR_SIZE, - (long)(start + len) * DISK_SECTOR_SIZE, - (long)len * DISK_SECTOR_SIZE); - printf("%ld\n", (long)start * DISK_SECTOR_SIZE); - printf("%ld\n", (long)len * DISK_SECTOR_SIZE); - } - - if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { - fprintf(stderr, "Can't open output file '%s'\n",filename); - return ret; - } - - lseek(fd, MBR_DISK_SIGNATURE_OFFSET, SEEK_SET); - if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { - fputs("write failed.\n", stderr); - goto fail; - } - - lseek(fd, MBR_PARTITION_ENTRY_OFFSET, SEEK_SET); - if (write(fd, pte, sizeof(struct pte) * MBR_ENTRY_MAX) != sizeof(struct pte) * MBR_ENTRY_MAX) { - fputs("write failed.\n", stderr); - goto fail; - } - lseek(fd, MBR_BOOT_SIGNATURE_OFFSET, SEEK_SET); - if (write(fd, "\x55\xaa", 2) != 2) { - fputs("write failed.\n", stderr); - goto fail; - } - - ret = 0; -fail: - close(fd); - return ret; -} - -/* check the partition sizes and write the guid partition table */ -static int gen_gptable(uint32_t signature, guid_t guid, unsigned nr) -{ - struct pte pte[MBR_ENTRY_MAX]; - struct gpth gpth = { - .signature = cpu_to_le64(GPT_SIGNATURE), - .revision = cpu_to_le32(GPT_REVISION), - .size = cpu_to_le32(GPT_HEADER_SIZE), - .self = cpu_to_le64(GPT_HEADER_SECTOR), - .first_usable = cpu_to_le64(GPT_FIRST_ENTRY_SECTOR + GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE), - .first_entry = cpu_to_le64(GPT_FIRST_ENTRY_SECTOR), - .disk_guid = guid, - .entry_num = cpu_to_le32(GPT_ENTRY_MAX), - .entry_size = cpu_to_le32(GPT_ENTRY_SIZE), - }; - struct gpte gpte[GPT_ENTRY_MAX]; - uint64_t start, end; - uint64_t sect = GPT_SIZE + GPT_FIRST_ENTRY_SECTOR; - int fd, ret = -1; - unsigned i, pmbr = 1; - - memset(pte, 0, sizeof(struct pte) * MBR_ENTRY_MAX); - memset(gpte, 0, GPT_ENTRY_SIZE * GPT_ENTRY_MAX); - for (i = 0; i < nr; i++) { - if (!parts[i].size) { - if (ignore_null_sized_partition) - continue; - fprintf(stderr, "Invalid size in partition %d!\n", i); - return ret; - } - start = sect; - if (parts[i].start != 0) { - if (parts[i].start * 2 < start) { - fprintf(stderr, "Invalid start %ld for partition %d!\n", - parts[i].start, i); - return ret; - } - start = parts[i].start * 2; - } else if (kb_align != 0) { - start = round_to_kb(start); - } - parts[i].actual_start = start; - gpte[i].start = cpu_to_le64(start); - - sect = start + parts[i].size * 2; - gpte[i].end = cpu_to_le64(sect -1); - gpte[i].guid = guid; - gpte[i].guid.b[sizeof(guid_t) -1] += i + 1; - gpte[i].type = parts[i].guid; - - if (parts[i].hybrid && pmbr < MBR_ENTRY_MAX) { - pte[pmbr].active = ((i + 1) == active) ? 0x80 : 0; - pte[pmbr].type = parts[i].type; - pte[pmbr].start = cpu_to_le32(start); - pte[pmbr].length = cpu_to_le32(sect - start); - to_chs(start, pte[1].chs_start); - to_chs(sect - 1, pte[1].chs_end); - pmbr++; - } - - if (parts[i].name) - init_utf16(parts[i].name, (uint16_t *)gpte[i].name, GPT_ENTRY_NAME_SIZE / sizeof(uint16_t)); - - if ((i + 1) == (unsigned)active) - gpte[i].attr |= GPT_ATTR_LEGACY_BOOT; - - if (parts[i].required) - gpte[i].attr |= GPT_ATTR_PLAT_REQUIRED; - - if (verbose) - fprintf(stderr, "Partition %d: start=%" PRIu64 ", end=%" PRIu64 ", size=%" PRIu64 "\n", - i, - start * DISK_SECTOR_SIZE, sect * DISK_SECTOR_SIZE, - (sect - start) * DISK_SECTOR_SIZE); - printf("%" PRIu64 "\n", start * DISK_SECTOR_SIZE); - printf("%" PRIu64 "\n", (sect - start) * DISK_SECTOR_SIZE); - } - - if (parts[0].actual_start > GPT_FIRST_ENTRY_SECTOR + GPT_SIZE) { - gpte[GPT_ENTRY_MAX - 1].start = cpu_to_le64(GPT_FIRST_ENTRY_SECTOR + GPT_SIZE); - gpte[GPT_ENTRY_MAX - 1].end = cpu_to_le64(parts[0].actual_start - 1); - gpte[GPT_ENTRY_MAX - 1].type = GUID_PARTITION_BIOS_BOOT; - gpte[GPT_ENTRY_MAX - 1].guid = guid; - gpte[GPT_ENTRY_MAX - 1].guid.b[sizeof(guid_t) -1] += GPT_ENTRY_MAX; - } - - end = sect + GPT_SIZE; - - pte[0].type = 0xEE; - pte[0].start = cpu_to_le32(GPT_HEADER_SECTOR); - pte[0].length = cpu_to_le32(end - GPT_HEADER_SECTOR); - to_chs(GPT_HEADER_SECTOR, pte[0].chs_start); - to_chs(end, pte[0].chs_end); - - gpth.last_usable = cpu_to_le64(end - GPT_SIZE - 1); - gpth.alternate = cpu_to_le64(end); - gpth.entry_crc32 = cpu_to_le32(gpt_crc32(gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX)); - gpth.crc32 = cpu_to_le32(gpt_crc32((char *)&gpth, GPT_HEADER_SIZE)); - - if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { - fprintf(stderr, "Can't open output file '%s'\n",filename); - return ret; - } - - lseek(fd, MBR_DISK_SIGNATURE_OFFSET, SEEK_SET); - if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { - fputs("write failed.\n", stderr); - goto fail; - } - - lseek(fd, MBR_PARTITION_ENTRY_OFFSET, SEEK_SET); - if (write(fd, pte, sizeof(struct pte) * MBR_ENTRY_MAX) != sizeof(struct pte) * MBR_ENTRY_MAX) { - fputs("write failed.\n", stderr); - goto fail; - } - - lseek(fd, MBR_BOOT_SIGNATURE_OFFSET, SEEK_SET); - if (write(fd, "\x55\xaa", 2) != 2) { - fputs("write failed.\n", stderr); - goto fail; - } - - if (write(fd, &gpth, GPT_HEADER_SIZE) != GPT_HEADER_SIZE) { - fputs("write failed.\n", stderr); - goto fail; - } - - lseek(fd, GPT_FIRST_ENTRY_SECTOR * DISK_SECTOR_SIZE, SEEK_SET); - if (write(fd, &gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX) != GPT_ENTRY_SIZE * GPT_ENTRY_MAX) { - fputs("write failed.\n", stderr); - goto fail; - } - -#ifdef WANT_ALTERNATE_PTABLE - /* The alternate partition table (We omit it by default) */ - swap(gpth.self, gpth.alternate); - gpth.first_entry = cpu_to_le64(end - GPT_ENTRY_SIZE * GPT_ENTRY_MAX / DISK_SECTOR_SIZE), - gpth.crc32 = 0; - gpth.crc32 = cpu_to_le32(gpt_crc32(&gpth, GPT_HEADER_SIZE)); - - lseek(fd, end * DISK_SECTOR_SIZE - GPT_ENTRY_SIZE * GPT_ENTRY_MAX, SEEK_SET); - if (write(fd, &gpte, GPT_ENTRY_SIZE * GPT_ENTRY_MAX) != GPT_ENTRY_SIZE * GPT_ENTRY_MAX) { - fputs("write failed.\n", stderr); - goto fail; - } - - lseek(fd, end * DISK_SECTOR_SIZE, SEEK_SET); - if (write(fd, &gpth, GPT_HEADER_SIZE) != GPT_HEADER_SIZE) { - fputs("write failed.\n", stderr); - goto fail; - } - lseek(fd, (end + 1) * DISK_SECTOR_SIZE -1, SEEK_SET); - if (write(fd, "\x00", 1) != 1) { - fputs("write failed.\n", stderr); - goto fail; - } -#endif - - ret = 0; -fail: - close(fd); - return ret; -} - -static void usage(char *prog) -{ - fprintf(stderr, "Usage: %s [-v] [-n] [-g] -h <heads> -s <sectors> -o <outputfile> [-a 0..4] [-l <align kB>] [-G <guid>] [[-t <type>] [-r] [-N <name>] -p <size>[@<start>]...] \n", prog); - exit(EXIT_FAILURE); -} - -static guid_t type_to_guid_and_name(unsigned char type, char **name) -{ - guid_t guid = GUID_PARTITION_BASIC_DATA; - - switch (type) { - case 0xef: - if(*name == NULL) - *name = "EFI System Partition"; - guid = GUID_PARTITION_SYSTEM; - break; - case 0x83: - guid = GUID_PARTITION_LINUX_FS_GUID; - break; - case 0x2e: - guid = GUID_PARTITION_LINUX_FIT_GUID; - break; - } - - return guid; -} - -int main (int argc, char **argv) -{ - unsigned char type = 0x83; - char *p; - int ch; - int part = 0; - char *name = NULL; - unsigned short int hybrid = 0, required = 0; - uint32_t signature = 0x5452574F; /* 'OWRT' */ - guid_t guid = GUID_INIT( signature, 0x2211, 0x4433, \ - 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0x00); - guid_t part_guid = GUID_PARTITION_BASIC_DATA; - - while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vnHN:gl:rS:G:")) != -1) { - switch (ch) { - case 'o': - filename = optarg; - break; - case 'v': - verbose++; - break; - case 'n': - ignore_null_sized_partition = true; - break; - case 'g': - use_guid_partition_table = 1; - break; - case 'H': - hybrid = 1; - break; - case 'h': - heads = (int)strtoul(optarg, NULL, 0); - break; - case 's': - sectors = (int)strtoul(optarg, NULL, 0); - break; - case 'p': - if (part > GPT_ENTRY_MAX - 1 || (!use_guid_partition_table && part > 3)) { - fputs("Too many partitions\n", stderr); - exit(EXIT_FAILURE); - } - p = strchr(optarg, '@'); - if (p) { - *(p++) = 0; - parts[part].start = to_kbytes(p); - } - part_guid = type_to_guid_and_name(type, &name); - parts[part].size = to_kbytes(optarg); - parts[part].required = required; - parts[part].name = name; - parts[part].hybrid = hybrid; - parts[part].guid = part_guid; - fprintf(stderr, "part %ld %ld\n", parts[part].start, parts[part].size); - parts[part++].type = type; - /* - * reset 'name','required' and 'hybrid' - * 'type' is deliberately inherited from the previous delcaration - */ - name = NULL; - required = 0; - hybrid = 0; - break; - case 'N': - name = optarg; - break; - case 'r': - required = 1; - break; - case 't': - type = (char)strtoul(optarg, NULL, 16); - break; - case 'a': - active = (int)strtoul(optarg, NULL, 0); - if ((active < 0) || (active > 4)) - active = 0; - break; - case 'l': - kb_align = (int)strtoul(optarg, NULL, 0) * 2; - break; - case 'S': - signature = strtoul(optarg, NULL, 0); - break; - case 'G': - if (guid_parse(optarg, &guid)) { - fputs("Invalid guid string\n", stderr); - exit(EXIT_FAILURE); - } - break; - case '?': - default: - usage(argv[0]); - } - } - argc -= optind; - if (argc || (!use_guid_partition_table && ((heads <= 0) || (sectors <= 0))) || !filename) - usage(argv[0]); - - if (use_guid_partition_table) { - heads = 254; - sectors = 63; - return gen_gptable(signature, guid, part) ? EXIT_FAILURE : EXIT_SUCCESS; - } - - return gen_ptable(signature, part) ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/seama.c b/tools/firmware-utils/src/seama.c deleted file mode 100644 index 89eeac90c4..0000000000 --- a/tools/firmware-utils/src/seama.c +++ /dev/null @@ -1,499 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -/* vi: set sw=4 ts=4: */ -/* - * Copyright (C) 2008, Alpha Networks, Inc. - * Created by David Hsieh <david_hsieh@alphanetworks.com> - * All right reserved. - * - * (SEA)ttle i(MA)ge is the image which used in project seattle. - */ - -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <string.h> -#include <arpa/inet.h> - -#include "md5.h" -#include "seama.h" - -#define PROGNAME "seama" -#define VERSION "0.20" -#define MAX_SEAMA_META_SIZE 1024 -#define MAX_META 128 -#define MAX_IMAGE 128 - -extern int optind; -extern char * optarg; - -static int o_verbose = 0; /* verbose mode. */ -static char * o_dump = NULL; /* Seama file to dump. */ -static char * o_seal = NULL; /* Seal the input images when file name exist. */ -static char * o_extract = NULL; /* Extract the seama file. */ -static char * o_images[MAX_IMAGE];/* The image files to pack or seal */ -static int o_isize = 0; /* number of images */ -static char * o_meta[MAX_META]; /* meta data array */ -static int o_msize = 0; /* size of meta array */ - -static void verbose(const char * format, ...) -{ - va_list marker; - if (o_verbose) - { - va_start(marker, format); - vfprintf(stdout, format, marker); - va_end(marker); - } -} - -static void cleanup_exit(int exit_code) -{ - verbose("%s: exit with code %d\n", PROGNAME, exit_code); - exit(exit_code); -} - -static void show_usage(int exit_code) -{ - printf( PROGNAME " version " VERSION "\n" - "usage: " PROGNAME " [OPTIONS]\n" - " -h show this help message.\n" - " -v verbose mode.\n" - " -m {META data} META data.\n" - " -d {file} dump the info of the seama file.\n" - " -i {input file} image file name.\n" - " -s {file} Seal the images to the seama file.\n" - " -x {seama file} Extract the seama file.\n" - "\n" - " SEAMA can pack the input file (with -i) into a seama file.\n" - " ex: seama -i target.file\n" - " SEAMA can also seal multiple seama files into a single seama file.\n" - " ex: seama -s final.file -i taget1.seama -i target2.seama\n" - " To extract the raw image from SEAMA, you need to specify the meta.\n" - " The first image match the specified meta will be extract to\n" - " the output file which was specified with '-x'.\n" - " ex: seama -x output -i seama.image -m file=sealpac\n" - ); - cleanup_exit(exit_code); -} - -static int parse_args(int argc, char * argv[]) -{ - int opt; - - while ((opt = getopt(argc, argv, "hvd:s:i:m:x:")) > 0) - { - switch (opt) - { - default: show_usage(-1); break; - case 'h': show_usage(0); break; - case 'v': o_verbose++; break; - case 'd': o_dump = optarg; break; - case 's': o_seal = optarg; break; - case 'x': o_extract = optarg; break; - case 'i': - if (o_isize < MAX_IMAGE) o_images[o_isize++] = optarg; - else printf("Exceed the maximum acceptable image files.!\n"); - break; - case 'm': - if (o_msize < MAX_META) o_meta[o_msize++] = optarg; - else printf("Exceed the maximum acceptable META data.!\n"); - break; - } - } - return 0; -} - -/*******************************************************************/ - -static size_t calculate_digest(FILE * fh, size_t size, uint8_t * digest) -{ - MD5_CTX ctx; - size_t bytes_left, bytes_read, i; - uint8_t buf[MAX_SEAMA_META_SIZE]; - - bytes_left = size ? size : sizeof(buf); - bytes_read = 0; - - MD5_Init(&ctx); - while (!feof(fh) && !ferror(fh) && bytes_left > 0) - { - i = bytes_left < sizeof(buf) ? bytes_left : sizeof(buf); - i = fread(buf, sizeof(char), i, fh); - if (i > 0) - { - MD5_Update(&ctx, buf, i); - bytes_read += i; - } - if (size) bytes_left -= i; - } - MD5_Final(digest, &ctx); - return bytes_read; -} - -#define READ_BUFF_SIZE 8*1024 -static size_t copy_file(FILE * to, FILE * from) -{ - size_t i, fsize = 0; - uint8_t buf[READ_BUFF_SIZE]; - - while (!feof(from) && !ferror(from)) - { - i = fread(buf, sizeof(uint8_t), READ_BUFF_SIZE, from); - if (i > 0) - { - fsize += i; - fwrite(buf, sizeof(uint8_t), i, to); - } - } - return fsize; -} - -static int verify_seama(const char * fname, int msg) -{ - FILE * fh = NULL; - struct stat st; - seamahdr_t shdr; - uint8_t checksum[16]; - uint8_t digest[16]; - uint8_t buf[MAX_SEAMA_META_SIZE]; - size_t msize, isize, i; - int ret = -1; - -#define ERRBREAK(fmt, args...) { if (msg) printf(fmt, ##args); break; } - - do - { - if (stat(fname, &st) < 0) ERRBREAK("Unable to get the info of '%s'\n",fname); - if ((fh = fopen(fname, "r+"))==NULL) ERRBREAK("Unable to open '%s' for reading!\n",fname); - - /* Dump SEAMA header */ - if (msg) printf("FILE - %s (%d bytes)\n", fname, (int)st.st_size); - - /* SEAMA */ - while (!feof(fh) && !ferror(fh)) - { - /* read header */ - if (fread(&shdr, sizeof(shdr), 1, fh) != 1) break; - - /* Check the magic number */ - if (shdr.magic != htonl(SEAMA_MAGIC)) ERRBREAK("Invalid SEAMA magic. Probably no more SEAMA!\n"); - - /* Get the size */ - isize = ntohl(shdr.size); - msize = ntohs(shdr.metasize); - - /* The checksum exist only if size is greater than zero. */ - if (isize > 0) - { - if (fread(checksum, sizeof(checksum), 1, fh) != 1) - ERRBREAK("Error reading checksum !\n"); - } - - /* Check the META size. */ - if (msize > sizeof(buf)) ERRBREAK("META data in SEAMA header is too large!\n"); - - /* Read META data. */ - if (fread(buf, sizeof(char), msize, fh) != msize) - ERRBREAK("Unable to read SEAMA META data!\n"); - - /* dump header */ - if (msg) - { - printf("SEAMA ==========================================\n"); - printf(" magic : %08x\n", ntohl(shdr.magic)); - printf(" meta size : %zu bytes\n", msize); - for (i=0; i<msize; i+=(strlen((const char *)&buf[i])+1)) - printf(" meta data : %s\n", &buf[i]); - printf(" image size : %zu bytes\n", isize); - } - - /* verify checksum */ - if (isize > 0) - { - if (msg) - { - printf(" checksum : "); - for (i=0; i<16; i++) printf("%02X", checksum[i]); - printf("\n"); - } - - /* Calculate the checksum */ - calculate_digest(fh, isize, digest); - if (msg) - { - printf(" digest : "); - for (i=0; i<16; i++) printf("%02X", digest[i]); - printf("\n"); - } - - if (memcmp(checksum, digest, 16)!=0) ERRBREAK("!!ERROR!! checksum error !!\n"); - ret = 0; - } - } - if (msg) printf("================================================\n"); - } while (0); - if (fh) fclose(fh); - return ret; -} - -static size_t write_seama_header(FILE * fh, char * meta[], size_t msize, size_t size) -{ - seamahdr_t shdr; - size_t i; - uint16_t metasize = 0; - - /* Calculate the META size */ - for (i=0; i<msize; i++) metasize += (strlen(meta[i]) + 1); - //+++ let meta data end on 4 alignment by siyou. 2010/3/1 03:58pm - metasize = ((metasize+3)/4)*4; - verbose("SEAMA META : %d bytes\n", metasize); - - /* Fill up the header, all the data endian should be network byte order. */ - shdr.magic = htonl(SEAMA_MAGIC); - shdr.reserved = 0; - shdr.metasize = htons(metasize); - shdr.size = htonl(size); - - /* Write the header */ - return fwrite(&shdr, sizeof(seamahdr_t), 1, fh); -} - -static size_t write_checksum(FILE * fh, uint8_t * checksum) -{ - return fwrite(checksum, sizeof(uint8_t), 16, fh); -} - -static size_t write_meta_data(FILE * fh, char * meta[], size_t size) -{ - size_t i,j; - size_t ret = 0; - - for (i=0; i<size; i++) - { - verbose("SEAMA META data : %s\n", meta[i]); - j = fwrite(meta[i], sizeof(char), strlen(meta[i])+1, fh); - if (j != strlen(meta[i])+1) return 0; - ret += j; - } - //+++ let meta data end on 4 alignment by siyou. 2010/3/1 03:58pm - j = ((ret+3)/4)*4; - for ( ; ret < j; ret++) - fwrite("", sizeof(char), 1, fh); - - return ret; -} - -/*******************************************************************/ - -static void dump_seama(const char * fname) -{ - verify_seama(fname, 1); -} - -static void seal_files(const char * file) -{ - FILE * fh; - FILE * ifh; - size_t i; - - /* Each image should be seama. */ - for (i = 0; i < o_isize; i++) - { - if (verify_seama(o_images[i], 0) < 0) - { - printf("'%s' is not a seama file !\n",o_images[i]); - return; - } - } - - /* Open file for write */ - fh = fopen(file, "w+"); - if (fh) - { - /* Write the header. */ - write_seama_header(fh, o_meta, o_msize, 0); - write_meta_data(fh, o_meta, o_msize); - - /* Write image files */ - for (i=0; i<o_isize; i++) - { - ifh = fopen(o_images[i], "r+"); - if (ifh) - { - copy_file(fh, ifh); - fclose(ifh); - } - } - - fclose(fh); - } -} - -static void pack_files(void) -{ - FILE * fh; - FILE * ifh; - size_t i, fsize; - char filename[512]; - uint8_t digest[16]; - - for (i=0; i<o_isize; i++) - { - /* Open the input file. */ - ifh = fopen(o_images[i], "r+"); - if (ifh) - { - fsize = calculate_digest(ifh, 0, digest); - verbose("file size (%s) : %d\n", o_images[i], fsize); - rewind(ifh); - - /* Open the output file. */ - sprintf(filename, "%s.seama", o_images[i]); - fh = fopen(filename, "w+"); - if (fh) - { - write_seama_header(fh, o_meta, o_msize, fsize); - write_checksum(fh, digest); - write_meta_data(fh, o_meta, o_msize); - copy_file(fh, ifh); - fclose(fh); - } - fclose(ifh); - } - else - { - printf("Unable to open image file '%s'\n",o_images[i]); - } - } -} - -/**************************************************************************/ - -static int match_meta(const char * meta, size_t size) -{ - size_t i, j; - int match; - - for (i = 0; i < o_msize; i++) - { - for (match = 0, j = 0; j < size; j += (strlen(&meta[j])+1)) - if (strcmp(&meta[j], o_meta[i])==0) { match++; break; } - if (!match) return 0; - } - return 1; -} - - -static void extract_file(const char * output) -{ - FILE * ifh = NULL; - FILE * ofh = NULL; - size_t msize, isize, i, m; - seamahdr_t shdr; - uint8_t buf[MAX_SEAMA_META_SIZE]; - int done = 0; - - /* We need meta for searching the target image. */ - if (o_msize == 0) - { - printf("SEAMA: need meta for searching image.\n"); - return; - } - - /* Walk through each input file */ - for (i = 0; i < o_isize; i++) - { - /* verify the input file */ - if (verify_seama(o_images[i], 0) < 0) - { - printf("SEAMA: '%s' is not a seama file !\n", o_images[i]); - continue; - } - /* open the input file */ - ifh = fopen(o_images[i], "r"); - if (!ifh) continue; - /* read file */ - while (!feof(ifh) && !ferror(ifh)) - { - /* read header */ - fread(&shdr, sizeof(shdr), 1, ifh); - if (shdr.magic != htonl(SEAMA_MAGIC)) break; - /* Get the size */ - isize = ntohl(shdr.size); - msize = ntohs(shdr.metasize); - if (isize == 0) - { - while (msize > 0) - { - m = fread(buf, sizeof(char), (msize < MAX_SEAMA_META_SIZE) ? msize : MAX_SEAMA_META_SIZE, ifh); - if (m <= 0) break; - msize -= m; - } - continue; - } - /* read checksum */ - fread(buf, sizeof(char), 16, ifh); - if (msize > 0) - { - /* read META */ - fread(buf, sizeof(char), msize, ifh); - if (match_meta((const char *)buf, msize)) - { - printf("SEAMA: found image @ '%s', image size: %zu\n", o_images[i], isize); - /* open output file */ - ofh = fopen(output, "w"); - if (!ofh) printf("SEAMA: unable to open '%s' for writting.\n",output); - else - { - while (isize > 0) - { - m = fread(buf, sizeof(char), (isize < MAX_SEAMA_META_SIZE) ? isize : MAX_SEAMA_META_SIZE, ifh); - if (m <= 0) break; - fwrite(buf, sizeof(char), m, ofh); - isize -= m; - } - fclose(ofh); - } - done++; - break; - } - } - while (isize > 0) - { - m = fread(buf, sizeof(char), (isize < MAX_SEAMA_META_SIZE) ? isize : MAX_SEAMA_META_SIZE, ifh); - if (m <= 0) break; - isize -= m; - } - } - /* close the file. */ - fclose(ifh); - if (done) break; - } - return; -} - -/*******************************************************************/ -#ifdef RGBIN_BOX -int seama_main(int argc, char * argv[], char * env[]) -#else -int main(int argc, char * argv[], char * env[]) -#endif -{ - verbose("SEAMA version " VERSION "\n"); - - /* parse the arguments */ - if (parse_args(argc, argv) < 0) show_usage(9); - - /* Do the works */ - if (o_dump) dump_seama(o_dump); - else if (o_seal) seal_files(o_seal); - else if (o_extract) extract_file(o_extract); - else pack_files(); - - cleanup_exit(0); - return 0; -} diff --git a/tools/firmware-utils/src/seama.h b/tools/firmware-utils/src/seama.h deleted file mode 100644 index bc58338a62..0000000000 --- a/tools/firmware-utils/src/seama.h +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* vi: set sw=4 ts=4: */ -/* - * (SEA)ttle i(MA)ge is the image which used in project seattle. - * - * Created by David Hsieh <david_hsieh@alphanetworks.com> - * Copyright (C) 2008-2009 Alpha Networks, Inc. - */ - -#ifndef __SEAMA_HEADER_FILE__ -#define __SEAMA_HEADER_FILE__ - -#include <stdint.h> - -#define SEAMA_MAGIC 0x5EA3A417 - -/* - * SEAMA looks like the following map. - * All the data of the header should be in network byte order. - * - * +-------------+-------------+------------ - * | SEAMA magic | ^ - * +-------------+-------------+ | - * | reserved | meta size | | - * +-------------+-------------+ header - * | image size (0 bytes) | | - * +-------------+-------------+ | - * ~ Meta data ~ v - * +-------------+-------------+------------ - * | SEAMA magic | ^ ^ - * +-------------+-------------+ | | - * | reserved | meta size | | | - * +-------------+-------------+ | | - * | image size | | | - * +-------------+-------------+ header | - * | | | | - * | 16 bytes of MD5 digest | | | - * | | | | - * | | | | - * +-------------+-------------+ | | - * ~ Meta data ~ v | - * +-------------+-------------+------- | - * | | | - * | Image of the 1st entity | | - * ~ ~ 1st entity - * | | | - * | | v - * +-------------+-------------+------------- - * | SEAMA magic | ^ ^ - * +-------------+-------------+ | | - * | reserved | meta size | | | - * +-------------+-------------+ | | - * | image size | | | - * +-------------+-------------+ header | - * | | | | - * | 16 bytes of MD5 digest | | | - * | | | | - * | | | | - * +-------------+-------------+ | | - * ~ Meta data ~ v | - * +-------------+-------------+------- | - * | | | - * | Image of the 2nd entity | | - * ~ ~ 2nd entity - * | | | - * | | v - * +-------------+-------------+------------- - */ - - -/* - * SEAMA header - * - * |<-------- 32 bits -------->| - * +-------------+-------------+ - * | SEAMA magic | - * +-------------+-------------+ - * | reserved | meta size | - * +-------------+-------------+ - * | image size | - * +-------------+-------------+ - */ -/* seama header */ -typedef struct seama_hdr seamahdr_t; -struct seama_hdr -{ - uint32_t magic; /* should always be SEAMA_MAGIC. */ - uint16_t reserved; /* reserved for */ - uint16_t metasize; /* size of the META data */ - uint32_t size; /* size of the image */ -} __attribute__ ((packed)); - - -#endif diff --git a/tools/firmware-utils/src/sha1.c b/tools/firmware-utils/src/sha1.c deleted file mode 100644 index 40cc78ca08..0000000000 --- a/tools/firmware-utils/src/sha1.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Copyright (C) 2003-2006 Christophe Devine - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License, version 2.1 as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#ifndef _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -#include <string.h> -#include <stdio.h> - -#include "sha1.h" - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_UINT32_BE -#define GET_UINT32_BE(n,b,i) \ -{ \ - (n) = ( (ulong) (b)[(i) ] << 24 ) \ - | ( (ulong) (b)[(i) + 1] << 16 ) \ - | ( (ulong) (b)[(i) + 2] << 8 ) \ - | ( (ulong) (b)[(i) + 3] ); \ -} -#endif -#ifndef PUT_UINT32_BE -#define PUT_UINT32_BE(n,b,i) \ -{ \ - (b)[(i) ] = (uchar) ( (n) >> 24 ); \ - (b)[(i) + 1] = (uchar) ( (n) >> 16 ); \ - (b)[(i) + 2] = (uchar) ( (n) >> 8 ); \ - (b)[(i) + 3] = (uchar) ( (n) ); \ -} -#endif - -/* - * Core SHA-1 functions - */ -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -void sha1_process( sha1_context *ctx, uchar data[64] ) -{ - ulong temp, W[16], A, B, C, D, E; - - GET_UINT32_BE( W[0], data, 0 ); - GET_UINT32_BE( W[1], data, 4 ); - GET_UINT32_BE( W[2], data, 8 ); - GET_UINT32_BE( W[3], data, 12 ); - GET_UINT32_BE( W[4], data, 16 ); - GET_UINT32_BE( W[5], data, 20 ); - GET_UINT32_BE( W[6], data, 24 ); - GET_UINT32_BE( W[7], data, 28 ); - GET_UINT32_BE( W[8], data, 32 ); - GET_UINT32_BE( W[9], data, 36 ); - GET_UINT32_BE( W[10], data, 40 ); - GET_UINT32_BE( W[11], data, 44 ); - GET_UINT32_BE( W[12], data, 48 ); - GET_UINT32_BE( W[13], data, 52 ); - GET_UINT32_BE( W[14], data, 56 ); - GET_UINT32_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -void sha1_update( sha1_context *ctx, void *data, uint length ) -{ - uchar *input = data; - ulong left, fill; - - if( ! length ) return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += length; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < length ) - ctx->total[1]++; - - if( left && length >= fill ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, fill ); - sha1_process( ctx, ctx->buffer ); - length -= fill; - input += fill; - left = 0; - } - - while( length >= 64 ) - { - sha1_process( ctx, input ); - length -= 64; - input += 64; - } - - if( length ) - { - memcpy( (void *) (ctx->buffer + left), - (void *) input, length ); - } -} - -static uchar sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void sha1_finish( sha1_context *ctx, uchar digest[20] ) -{ - ulong last, padn; - ulong high, low; - uchar msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_UINT32_BE( high, msglen, 0 ); - PUT_UINT32_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_UINT32_BE( ctx->state[0], digest, 0 ); - PUT_UINT32_BE( ctx->state[1], digest, 4 ); - PUT_UINT32_BE( ctx->state[2], digest, 8 ); - PUT_UINT32_BE( ctx->state[3], digest, 12 ); - PUT_UINT32_BE( ctx->state[4], digest, 16 ); -} - -/* - * Output SHA-1(file contents), returns 0 if successful. - */ -int sha1_file( char *filename, uchar digest[20] ) -{ - FILE *f; - size_t n; - sha1_context ctx; - uchar buf[1024]; - - if( ( f = fopen( filename, "rb" ) ) == NULL ) - return( 1 ); - - sha1_starts( &ctx ); - - while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - sha1_update( &ctx, buf, (uint) n ); - - sha1_finish( &ctx, digest ); - - fclose( f ); - return( 0 ); -} - -/* - * Output SHA-1(buf) - */ -void sha1_csum( uchar *buf, uint buflen, uchar digest[20] ) -{ - sha1_context ctx; - - sha1_starts( &ctx ); - sha1_update( &ctx, buf, buflen ); - sha1_finish( &ctx, digest ); -} - -/* - * Output HMAC-SHA-1(key,buf) - */ -void sha1_hmac( uchar *key, uint keylen, uchar *buf, uint buflen, - uchar digest[20] ) -{ - uint i; - sha1_context ctx; - uchar k_ipad[64]; - uchar k_opad[64]; - uchar tmpbuf[20]; - - memset( k_ipad, 0x36, 64 ); - memset( k_opad, 0x5C, 64 ); - - for( i = 0; i < keylen; i++ ) - { - if( i >= 64 ) break; - - k_ipad[i] ^= key[i]; - k_opad[i] ^= key[i]; - } - - sha1_starts( &ctx ); - sha1_update( &ctx, k_ipad, 64 ); - sha1_update( &ctx, buf, buflen ); - sha1_finish( &ctx, tmpbuf ); - - sha1_starts( &ctx ); - sha1_update( &ctx, k_opad, 64 ); - sha1_update( &ctx, tmpbuf, 20 ); - sha1_finish( &ctx, digest ); - - memset( k_ipad, 0, 64 ); - memset( k_opad, 0, 64 ); - memset( tmpbuf, 0, 20 ); - memset( &ctx, 0, sizeof( sha1_context ) ); -} - -#ifdef SELF_TEST -/* - * FIPS-180-1 test vectors - */ -static char *sha1_test_str[3] = -{ - "abc", - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - NULL -}; - -static uchar sha1_test_sum[3][20] = -{ - { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, - 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, - { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, - 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, - { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, - 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } -}; - -/* - * Checkup routine - */ -int sha1_self_test( void ) -{ - int i, j; - uchar buf[1000]; - uchar sha1sum[20]; - sha1_context ctx; - - for( i = 0; i < 3; i++ ) - { - printf( " SHA-1 test #%d: ", i + 1 ); - - sha1_starts( &ctx ); - - if( i < 2 ) - sha1_update( &ctx, (uchar *) sha1_test_str[i], - strlen( sha1_test_str[i] ) ); - else - { - memset( buf, 'a', 1000 ); - for( j = 0; j < 1000; j++ ) - sha1_update( &ctx, (uchar *) buf, 1000 ); - } - - sha1_finish( &ctx, sha1sum ); - - if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) - { - printf( "failed\n" ); - return( 1 ); - } - - printf( "passed\n" ); - } - - printf( "\n" ); - return( 0 ); -} -#else -int sha1_self_test( void ) -{ - printf( "SHA-1 self-test not available\n\n" ); - return( 1 ); -} -#endif diff --git a/tools/firmware-utils/src/sha1.h b/tools/firmware-utils/src/sha1.h deleted file mode 100644 index 990a52765c..0000000000 --- a/tools/firmware-utils/src/sha1.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _SHA1_H -#define _SHA1_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _STD_TYPES -#define _STD_TYPES - -#define uchar unsigned char -#define uint unsigned int -#define ulong unsigned long int - -#endif - -typedef struct -{ - ulong total[2]; - ulong state[5]; - uchar buffer[64]; -} -sha1_context; - -/* - * Core SHA-1 functions - */ -void sha1_starts( sha1_context *ctx ); -void sha1_update( sha1_context *ctx, void *input, uint length ); -void sha1_finish( sha1_context *ctx, uchar digest[20] ); - -/* - * Output SHA-1(file contents), returns 0 if successful. - */ -int sha1_file( char *filename, uchar digest[20] ); - -/* - * Output SHA-1(buf) - */ -void sha1_csum( uchar *buf, uint buflen, uchar digest[20] ); - -/* - * Output HMAC-SHA-1(key,buf) - */ -void sha1_hmac( uchar *key, uint keylen, uchar *buf, uint buflen, - uchar digest[20] ); - -/* - * Checkup routine - */ -int sha1_self_test( void ); - -#ifdef __cplusplus -} -#endif - -#endif /* sha1.h */ diff --git a/tools/firmware-utils/src/sign_dlink_ru.c b/tools/firmware-utils/src/sign_dlink_ru.c deleted file mode 100644 index 50f2e67bf4..0000000000 --- a/tools/firmware-utils/src/sign_dlink_ru.c +++ /dev/null @@ -1,213 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * This program is designed to sign firmware images so they are accepted - * by D-Link DIR-882 R1 WebUIs. - * - * Copyright (C) 2020 Andrew Pikler - */ - -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include "md5.h" - -#define BUF_SIZE 4096 -#define MD5_HASH_LEN 16 - - -typedef struct _md5_digest_t { - uint8_t digest[MD5_HASH_LEN]; -} md5_digest_t; - -typedef struct _salt_t { - char* salt_ascii; - uint8_t* salt_bin; - size_t salt_bin_len; -} salt_t; - -void read_file_bytes(FILE* f, MD5_CTX* md5_ctx) { - uint8_t buf[BUF_SIZE]; - size_t bytes_read; - rewind(f); - - while (0 != (bytes_read = fread(buf, sizeof(uint8_t), BUF_SIZE, f))) { - MD5_Update(md5_ctx, buf, bytes_read); - } - - if (!feof(f)) { - printf("Error: expected to be at EOF\n"); - exit(-1); - } -} - -void add_magic_bytes(FILE* f) { - char magic_bytes[] = { 0x00, 0xc0, 0xff, 0xee }; - size_t magic_bytes_len = 4; - fwrite(magic_bytes, magic_bytes_len, 1, f); -} - -/** - * Add the signature produced by this salt to the file - * The signature consists by creating an MD5 digest wht the salt bytes plus - * all of the bytes in the firmware file, then adding the magic bytes to the - * file - */ -void add_signature(FILE* f, salt_t* salt) { - md5_digest_t digest; - MD5_CTX md5_context; - - MD5_Init(&md5_context); - MD5_Update(&md5_context, salt->salt_bin, salt->salt_bin_len); - read_file_bytes(f, &md5_context); - MD5_Final(digest.digest, &md5_context); - - fwrite(&digest.digest, sizeof(uint8_t), MD5_HASH_LEN, f); - add_magic_bytes(f); -} - -void add_version_suffix(FILE* f) { - char* version_suffix = "c0ffeef0rge"; - fseek(f, 0, SEEK_END); - fwrite(version_suffix, sizeof(char), strlen(version_suffix), f); -} - -int asciihex_to_int(char c) { - if(c >= '0' && c <= 'F') - return c - '0'; - - if(c >= 'a' && c <= 'f') - return 10 + c - 'a'; - return -1; -} - -/** - * Verify this is a valid hex string to convert - */ -void verify_valid_hex_str(char* s) { - int i; - int s_len = strlen(s); - if (s_len == 0) { - printf("invalid empty salt: %s\n", s); - exit(-1); - } - - if (s_len % 2 != 0) { - printf("invalid odd len salt: %s\n", s); - exit(-1); - } - - for (i = 0; i < s_len; ++i) { - if (asciihex_to_int(s[i]) < 0) { - printf("invalid salt (invalid hex char): %s\n", s); - exit(-1); - } - } -} - -/** - * Convert a hex ascii string to an allocated binary array. This array must be free'd - */ -uint8_t* convert_hex_to_bin(char * s) { - int i; - int s_len = strlen(s); - - uint8_t* ret = malloc(s_len / 2); - for (i = 0; i < s_len; i += 2) { - ret[i / 2] = (asciihex_to_int(s[i]) << 4) | asciihex_to_int(s[i + 1]); - } - - return ret; -} - -void init_salt(salt_t* salt, char * salt_ascii) { - salt->salt_ascii = salt_ascii; - salt->salt_bin = convert_hex_to_bin(salt_ascii); - salt->salt_bin_len = strlen(salt_ascii) / 2; -} - -void free_salt(salt_t* salt) { - free(salt->salt_bin); -} - -/** - * Verify that the arguments are valid, or exit with failure - */ -void verify_args(int argc, char** argv) { - int i; - - if (argc < 3) { - printf("Usage: %s <firmware file> <signing hash1> <signing hash2> ... <signing hash n>\n", argv[0]); - exit(1); - } - - for (i = 2; i < argc; i++) { - verify_valid_hex_str(argv[i]); - } -} - -FILE* make_out_file(char* filename) { - uint8_t buf[BUF_SIZE]; - int bytes_read; - char* suffix = ".new"; - int new_filename_len = strlen(filename) + strlen(suffix) + 1; - char* new_filename = malloc(new_filename_len); - strcpy(new_filename, filename); - strcat(new_filename, suffix); - - FILE* f = fopen(filename, "r+"); - if (!f) { - printf("cannot open file %s\n", filename); - exit(2); - } - - FILE* out = fopen(new_filename, "w+"); - free(new_filename); - if (!out) { - printf("cannot open file %s\n", filename); - exit(2); - } - - while (0 != (bytes_read = fread(buf, sizeof(uint8_t), BUF_SIZE, f))) { - fwrite(buf, sizeof(uint8_t), bytes_read, out); - } - fclose(f); - return out; -} - -/** - * Sign the firmware file after all of our checks have completed - */ -void sign_firmware(char* filename, char** salts, int num_salts) { - int i; - salt_t salt; - FILE* f = make_out_file(filename); - - // add a version suffix string - dlink versions do something similar before the first signature - add_version_suffix(f); - - //for each of the salts we are supplied with - for (i = 0; i < num_salts; i++) { - char* salt_str = salts[i]; - // convert this str to binary - init_salt(&salt, salt_str); - - // add the signature to the firmware file produced from this salt - add_signature(f, &salt); - free_salt(&salt); - printf("Signed with salt: %s\n", salt_str); - } - - fclose(f); -} - - -int main(int argc, char ** argv) { - verify_args(argc, argv); - sign_firmware(argv[1], argv+2, argc-2); - return 0; -} diff --git a/tools/firmware-utils/src/spw303v.c b/tools/firmware-utils/src/spw303v.c deleted file mode 100644 index 3244a73a2f..0000000000 --- a/tools/firmware-utils/src/spw303v.c +++ /dev/null @@ -1,230 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * spw303v.c - partially based on OpenWrt's imagetag.c and addpattern.c - * - * Copyright (C) 2011 Jonas Gorski <jonas.gorski@gmail.com> - */ - -#include <arpa/inet.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/stat.h> - -#define IMAGE_LEN 10 /* Length of Length Field */ -#define ADDRESS_LEN 12 /* Length of Address field */ -#define TAGID_LEN 6 /* Length of tag ID */ -#define TAGINFO_LEN 20 /* Length of vendor information field in tag */ -#define TAGVER_LEN 4 /* Length of Tag Version */ -#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ - - -struct spw303v_tag -{ - unsigned char tagVersion[4]; // tag version. Will be 2 here. - unsigned char signiture_1[20]; // text line for company info - unsigned char signiture_2[14]; // additional info (can be version number) - unsigned char chipId[6]; // chip id - unsigned char boardId[16]; // board id - unsigned char bigEndian[2]; // if = 1 - big, = 0 - little endia of the host - unsigned char totalImageLen[IMAGE_LEN]; // the sum of all the following length - unsigned char cfeAddress[ADDRESS_LEN]; // if non zero, cfe starting address - unsigned char cfeLen[IMAGE_LEN]; // if non zero, cfe size in clear ASCII text. - unsigned char rootfsAddress[ADDRESS_LEN]; // if non zero, filesystem starting address - unsigned char rootfsLen[IMAGE_LEN]; // if non zero, filesystem size in clear ASCII text. - unsigned char kernelAddress[ADDRESS_LEN]; // if non zero, kernel starting address - unsigned char kernelLen[IMAGE_LEN]; // if non zero, kernel size in clear ASCII text. - - unsigned char certf1Address[ADDRESS_LEN]; - unsigned char certf1Len[6]; - unsigned char certf2Address[ADDRESS_LEN]; - unsigned char certf2Len[6]; - unsigned char certf3Address[ADDRESS_LEN]; - unsigned char certf3Len[6]; - unsigned char httpsFileSize[4]; - unsigned char tr64FileSize[4]; - unsigned char tr69FileSize[4]; - unsigned char filesmap[4]; - - unsigned char imageSequence[4]; // incrments everytime an image is flashed - unsigned char reserved[4]; // reserved for later use - unsigned char imageCRC[4]; // 216-219: CRC32 of images - unsigned char reserved2[16]; // 220-235: Unused at present - unsigned char headerCRC[4]; // 236-239: CRC32 of header excluding tagVersion - unsigned char reserved3[16]; // 240-255: Unused at present -}; - -static uint32_t crc32tab[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; -#define IMAGETAG_CRC_START 0xFFFFFFFF - -#define IMAGETAG_MAGIC1_TCOM "AAAAAAAA Corporatio" - -static char fake_data[] = { - 0x18, 0x21, 0x21, 0x18, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 ,0x18, - 0x21, 0x24, 0x21, 0x1b, 0x18, 0x18, 0x24, 0x24, 0x18, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x1b, 0x18, 0x18, 0x24, 0x24, 0x21, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, 0x18, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x18, - 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x18, 0x21, 0x21, - 0x21, 0x21, 0x21, 0x21, -}; - - -uint32_t crc32(uint32_t crc, const void *data, size_t len) -{ - const uint8_t *in = data; - - while (len--) - crc = (crc >> 8) ^ crc32tab[(crc ^ *in++) & 0xFF]; - - return crc; -} - -void fix_header(void *buf) -{ - struct spw303v_tag *tag = buf; - uint32_t crc; - /* Replace signature with custom t-com one */ - memset(tag->signiture_1, 0, 20); - memcpy(tag->signiture_1, IMAGETAG_MAGIC1_TCOM, strlen(IMAGETAG_MAGIC1_TCOM)); - - /* Clear cert fields to remove information_* data */ - memset(tag->certf1Address, 0, 74); - - /* replace image crc with modified one */ - crc = ntohl(*((uint32_t *)&tag->imageCRC)); - - crc = htonl(crc32(crc, fake_data, 64)); - - memcpy(tag->imageCRC, &crc, 4); - - /* Update tag crc */ - crc = htonl(crc32(IMAGETAG_CRC_START, buf, 236)); - memcpy(tag->headerCRC, &crc, 4); -} - - - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: spw303v [-i <inputfile>] [-o <outputfile>]\n"); - exit(EXIT_FAILURE); -} - - -int main(int argc, char **argv) -{ - char buf[1024]; /* keep this at 1k or adjust garbage calc below */ - FILE *in = stdin; - FILE *out = stdout; - char *ifn = NULL; - char *ofn = NULL; - int c; - size_t n; - int first_block = 1; - - uint32_t image_crc = IMAGETAG_CRC_START; - - while ((c = getopt(argc, argv, "i:o:h")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'h': - default: - usage(); - } - } - - if (optind != argc || optind == 1) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - if (ifn && !(in = fopen(ifn, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", ifn); - usage(); - } - - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - - - while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { - if (n < sizeof(buf)) { - if (ferror(in)) { - FREAD_ERROR: - fprintf(stderr, "fread error\n"); - return EXIT_FAILURE; - } - } - - if (first_block && n >= 256) { - fix_header(buf); - first_block = 0; - } - - image_crc = crc32(image_crc, buf, n); - - if (!fwrite(buf, n, 1, out)) { - FWRITE_ERROR: - fprintf(stderr, "fwrite error\n"); - return EXIT_FAILURE; - } - } - - if (ferror(in)) { - goto FREAD_ERROR; - } - - if (fflush(out)) { - goto FWRITE_ERROR; - } - - fclose(in); - fclose(out); - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/srec2bin.c b/tools/firmware-utils/src/srec2bin.c deleted file mode 100644 index ad4222d693..0000000000 --- a/tools/firmware-utils/src/srec2bin.c +++ /dev/null @@ -1,524 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdio.h> -#include <ctype.h> -#include <string.h> - -//Rev 0.1 Original -// 8 Jan 2001 MJH Added code to write data to Binary file -// note: outputfile is name.bin, where name is first part -// of input file. ie tmp.rec -> tmp.bin -// -// srec2bin <input SREC file> <Output Binary File> <If Present, Big Endian> -// -// TAG -// bit32u TAG_BIG = 0xDEADBE42; -// bit32u TAG_LITTLE = 0xFEEDFA42; -// -// File Structure -// -// TAG : 32 Bits -// [DATA RECORDS] -// -// Data Records Structure -// -// LENGTH : 32 Bits <- Length of DATA, excludes ADDRESS and CHECKSUM -// ADDRESS : 32 Bits -// DATA : 8 Bits * LENGTH -// CHECKSUM: 32 Bits <- 0 - (Sum of Length --> End of Data) -// -// Note : If Length == 0, Address will be Program Start -// -// -// -// -// - -#define MajRevNum 0 -#define MinRevNum 2 - - -#define EndianSwitch(x) ((x >> 24) | (x << 24) | ((x << 8) & (0x00FF0000)) | ((x >> 8) & (0x0000FF00)) ) - -typedef unsigned char bit8u; -typedef unsigned int bit32u; -typedef int bit32; - -#define FALSE 0 -#define TRUE (!FALSE) - - -bit32u CheckSum; -int RecStart; -int debug; -int verbose; - -FILE *OpenOutputFile( char *Name ); -FILE *fOut; -bit32u RecLength=0; - -bit32u AddressCurrent; - -bit32u gh(char *cp,int nibs); - -int BigEndian; - -int inputline; - -// char buf[16*1024]; - -char buffer[2048]; -char *cur_ptr; -int cur_line=0; -int cur_len=0; - -int s1s2s3_total=0; - -bit32u PBVal; -int PBValid; -bit32u PBAdr; - - -void dumpfTell(char *s, bit32u Value) -{ - int Length; - Length = (int) RecLength; - if (debug) - printf("[%s ] ftell()[0x%08lX] Length[0x%4X] Length[%4d] Value[0x%08x]\n", - s, ftell(fOut), Length, Length, Value); -} - -void DispHex(bit32u Hex) -{ -// printf("%X", Hex); -} - -void WaitDisplay(void) -{ - static int Count=0; - static int Index=0; - char iline[]={"-\\|/"}; - - Count++; - if ((Count % 32)==0) - { - if (verbose) - printf("%c%c",iline[Index++],8); - Index &= 3; - } -} - - -void binOut32 ( bit32u Data ) -{ -// On UNIX machine all 32bit writes need ENDIAN switched -// Data = EndianSwitch(Data); -// fwrite( &Data, sizeof(bit32u), 1, fOut); - - char sdat[4]; - int i; - - for(i=0;i<4;i++) - sdat[i]=(char)(Data>>(i*8)); - fwrite( sdat, 1, 4, fOut); - dumpfTell("Out32" , Data); -} - -// Only update RecLength on Byte Writes -// All 32 bit writes will be for Length etc - -void binOut8 ( bit8u Data ) -{ - int n; - dumpfTell("B4Data" , (bit32u) (Data & 0xFF) ); - n = fwrite( &Data, sizeof(bit8u), 1, fOut); - if (n != 1) - printf("Error in writing %X for Address 0x%8X\n", Data, AddressCurrent); - RecLength += 1; -} - -// Currently ONLY used for outputting Program Start - -void binRecStart(bit32u Address) -{ - RecLength = 0; - CheckSum = Address; - RecStart = TRUE; - - if (debug) - printf("[RecStart] CheckSum[0x%08X] Length[%4d] Address[0x%08X]\n", - CheckSum, RecLength, Address); - - - dumpfTell("RecLength", RecLength); - binOut32( RecLength ); - dumpfTell("Address", Address); - binOut32( Address ); -} - -void binRecEnd(void) -{ - long RecEnd; - - if (!RecStart) // if no record started, do not end it - { - return; - } - - RecStart = FALSE; - - - RecEnd = ftell(fOut); // Save Current position - - if (debug) - printf("[RecEnd ] CheckSum[0x%08X] Length[%4d] Length[0x%X] RecEnd[0x%08lX]\n", - CheckSum, RecLength, RecLength, RecEnd); - - fseek( fOut, -((long) RecLength), SEEK_CUR); // move back Start Of Data - - dumpfTell("Data ", -1); - - fseek( fOut, -4, SEEK_CUR); // move back Start Of Address - - dumpfTell("Address ", -1); - - fseek( fOut, -4, SEEK_CUR); // move back Start Of Length - - dumpfTell("Length ", -1); - - binOut32( RecLength ); - - fseek( fOut, RecEnd, SEEK_SET); // move to end of Record - - CheckSum += RecLength; - - CheckSum = ~CheckSum + 1; // Two's complement - - binOut32( CheckSum ); - - if (verbose) - printf("[Created Record of %d Bytes with CheckSum [0x%8X]\n", RecLength, CheckSum); -} - -void binRecOutProgramStart(bit32u Address) -{ - if (Address != (AddressCurrent+1)) - { - binRecEnd(); - binRecStart(Address); - } - AddressCurrent = Address; -} -void binRecOutByte(bit32u Address, bit8u Data) -{ - // If Address is one after Current Address, output Byte - // If not, close out last record, update Length, write checksum - // Then Start New Record, updating Current Address - - if (Address != (AddressCurrent+1)) - { - binRecEnd(); - binRecStart(Address); - } - AddressCurrent = Address; - CheckSum += Data; - binOut8( Data ); -} - -//============================================================================= -// SUPPORT FUNCTIONS -//============================================================================= -int readline(FILE *fil,char *buf,int len) -{ - int rlen; - - rlen=0; - if (len==0) return(0); - while(1) - { - if (cur_len==0) - { - cur_len=fread(buffer, 1, sizeof(buffer), fil); - if (cur_len==0) - { - if (rlen) - { - *buf=0; - return(rlen); - } - return(-1); - } - cur_ptr=buffer; - } - if (cur_len) - { - if (*cur_ptr=='\n') - { - *buf=0; - cur_ptr++; - cur_len--; - return(rlen); - } - else - { - if ((len>1)&&(*cur_ptr!='\r')) - { - *buf++=*cur_ptr++; - len--; - } - else - cur_ptr++; - - rlen++; - cur_len--; - } - } - else - { - *buf=0; - cur_ptr++; - cur_len--; - return(rlen); - } - } -} - - -int SRLerrorout(char *c1,char *c2) -{ - printf("\nERROR: %s - '%s'.",c1,c2); - return(FALSE); -} - - -int checksum(char *cp,int count) -{ - char *scp; - int cksum; - int dum; - - scp=cp; - while(*scp) - { - if (!isxdigit(*scp++)) - return(SRLerrorout("Invalid hex digits",cp)); - } - scp=cp; - - cksum=count; - - while(count) - { - cksum += gh(scp,2); - if (count == 2) - dum = ~cksum; - scp += 2; - count--; - } - cksum&=0x0ff; - // printf("\nCk:%02x",cksum); - return(cksum==0x0ff); -} - -bit32u gh(char *cp,int nibs) -{ - int i; - bit32u j; - - j=0; - - for(i=0;i<nibs;i++) - { - j<<=4; - if ((*cp>='a')&&(*cp<='z')) *cp &= 0x5f; - if ((*cp>='0')&&(*cp<='9')) - j += (*cp-0x30); - else - if ((*cp>='A')&&(*cp<='F')) - j += (*cp-0x37); - else - SRLerrorout("Bad Hex char", cp); - cp++; - } - return(j); -} - - -//============================================================================= -// PROCESS SREC LINE -//============================================================================= - -int srecLine(char *pSrecLine) -{ - char *scp,ch; - int itmp,count,dat; - bit32u adr; - static bit32u RecordCounter=0; - - cur_line++; - scp=pSrecLine; - - if (*pSrecLine!='S') - return(SRLerrorout("Not an Srecord file",scp)); - pSrecLine++; - if (strlen(pSrecLine)<4) - return(SRLerrorout("Srecord too short",scp)); - - ch=*pSrecLine++; - - count=gh(pSrecLine,2); - - pSrecLine += 2; - - // if(debug) - // printf("count %d, strlen(pSrecLine) = %d, pSrecLine =[%s]\n", count, strlen(pSrecLine), pSrecLine); - RecordCounter++; - DispHex(RecordCounter); - - if ((count*2) != strlen(pSrecLine)) return(SRLerrorout("Count field larger than record",scp)); - - if (!checksum(pSrecLine, count)) return(SRLerrorout("Bad Checksum",scp)); - - switch(ch) - { - case '0': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2; - if (itmp) return(SRLerrorout("Srecord 1 address not zero",scp)); - break; - case '1': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - case '2': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - case '3': if (count<5) return(SRLerrorout("Invalid Srecord count field",scp)); - adr=gh(pSrecLine,8); pSrecLine+=8; count-=4; - count--; - while(count) - { - dat=gh(pSrecLine,2); pSrecLine+=2; count--; - binRecOutByte(adr, (char) (dat & 0xFF)); - adr++; - } - s1s2s3_total++; - break; - case '4': return(SRLerrorout("Invalid Srecord type",scp)); - break; - case '5': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2; - if (itmp|=s1s2s3_total) return(SRLerrorout("Incorrect number of S3 Record processed",scp)); - break; - case '6': return(SRLerrorout("Invalid Srecord type",scp)); - break; - case '7': // PROGRAM START - if (count<5) return(SRLerrorout("Invalid Srecord count field",scp)); - adr=gh(pSrecLine,8); pSrecLine+=8; count-=4; - if (count!=1) return(SRLerrorout("Invalid Srecord count field",scp)); - binRecOutProgramStart(adr); - break; - case '8': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - case '9': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp)); - return(SRLerrorout("Srecord Not valid for MIPS",scp)); - break; - default: - break; - } - return(TRUE); -} - - -//============================================================================= -// MAIN LOGIC, READS IN LINE AND OUTPUTS BINARY -//============================================================================= - -int srec2bin(int argc,char *argv[],int verbose) -{ - int rlen,sts; - FILE *fp; - char buff[256]; - bit32u TAG_BIG = 0xDEADBE42; - bit32u TAG_LITTLE = 0xFEEDFA42; - - bit32u Tag; - - - if(argc < 3) - { - printf("\nError: <srec2bin <srec input file> <bin output file>\n\n"); - return(0); - } - - if (argc > 3) BigEndian=TRUE; else BigEndian=FALSE; - - if (BigEndian) - Tag = TAG_BIG; - else - Tag = TAG_LITTLE; - - if (verbose) - printf("\nEndian: %s, Tag is 0x%8X\n",(BigEndian)?"BIG":"LITTLE", Tag); - - fp = fopen(argv[1],"rt"); - - if (fp==NULL) - { - printf("\nError: Opening input file, %s.", argv[1]); - return(0); - } - - fOut = fopen( argv[2], "wb"); - - if (fOut==NULL) - { - printf("\nError: Opening Output file, %s.", argv[2]); - if(fp) fclose(fp); - return(0); - } - - RecStart = FALSE; - - AddressCurrent = 0xFFFFFFFFL; - - // Setup Tag - - dumpfTell("Tag", Tag); - - binOut32(Tag); - - - inputline=0; - sts=TRUE; - - rlen = readline(fp,buff,sizeof buff); - - while( (sts) && (rlen != -1)) - { - if (strlen(buff)) - { - sts &= srecLine(buff); - WaitDisplay(); - } - rlen = readline(fp,buff,sizeof buff); - } - - - // printf("PC: 0x%08X, Length 0x%08X, Tag 0x%08X\n", ProgramStart, RecLength, TAG_LITTLE); - - binRecEnd(); - - if(fp) fclose(fp); - if(fOut) fclose(fOut); - - return(1); -} - -int main(int argc, char *argv[]) -{ - debug = TRUE; - debug = FALSE; - verbose = FALSE; - srec2bin(argc,argv,verbose); - return 0; -} - diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c deleted file mode 100644 index 03329a3926..0000000000 --- a/tools/firmware-utils/src/tplink-safeloader.c +++ /dev/null @@ -1,3704 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net> - All rights reserved. -*/ - - -/* - tplink-safeloader - - Image generation tool for the TP-LINK SafeLoader as seen on - TP-LINK Pharos devices (CPE210/220/510/520) -*/ - - -#include <assert.h> -#include <ctype.h> -#include <errno.h> -#include <stdbool.h> -#include <stddef.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include <arpa/inet.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <limits.h> - -#include "md5.h" - - -#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) - - -#define MAX_PARTITIONS 32 - -/** An image partition table entry */ -struct image_partition_entry { - const char *name; - size_t size; - uint8_t *data; -}; - -/** A flash partition table entry */ -struct flash_partition_entry { - char *name; - uint32_t base; - uint32_t size; -}; - -/** Partition trailing padding definitions - * Values 0x00 to 0xff are reserved to indicate the padding value - * Values from 0x100 are reserved to indicate other behaviour */ -enum partition_trail_value { - PART_TRAIL_00 = 0x00, - PART_TRAIL_FF = 0xff, - PART_TRAIL_MAX = 0xff, - PART_TRAIL_NONE = 0x100 -}; - -/** soft-version value overwrite types - * The default (for an uninitialised soft_ver field) is to use the numerical - * version number "0.0.0" - */ -enum soft_ver_type { - SOFT_VER_TYPE_NUMERIC = 0, - SOFT_VER_TYPE_TEXT = 1, -}; - -/** Firmware layout description */ -struct device_info { - const char *id; - const char *vendor; - const char *support_list; - enum partition_trail_value part_trail; - struct { - enum soft_ver_type type; - union { - const char *text; - uint8_t num[3]; - }; - } soft_ver; - uint32_t soft_ver_compat_level; - struct flash_partition_entry partitions[MAX_PARTITIONS+1]; - const char *first_sysupgrade_partition; - const char *last_sysupgrade_partition; -}; - -#define SOFT_VER_TEXT(_t) {.type = SOFT_VER_TYPE_TEXT, .text = _t} -#define SOFT_VER_NUMERIC(_maj, _min, _patch) { \ - .type = SOFT_VER_TYPE_NUMERIC, \ - .num = {_maj, _min, _patch}} -#define SOFT_VER_DEFAULT SOFT_VER_NUMERIC(0, 0, 0) - -struct __attribute__((__packed__)) meta_header { - uint32_t length; - uint32_t zero; -}; - -/** The content of the soft-version structure */ -struct __attribute__((__packed__)) soft_version { - uint8_t pad1; - uint8_t version_major; - uint8_t version_minor; - uint8_t version_patch; - uint8_t year_hi; - uint8_t year_lo; - uint8_t month; - uint8_t day; - uint32_t rev; - uint32_t compat_level; -}; - - -static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; - - -/** - Salt for the MD5 hash - - Fortunately, TP-LINK seems to use the same salt for most devices which use - the new image format. -*/ -static const uint8_t md5_salt[16] = { - 0x7a, 0x2b, 0x15, 0xed, - 0x9b, 0x98, 0x59, 0x6d, - 0xe5, 0x04, 0xab, 0x44, - 0xac, 0x2a, 0x9f, 0x4e, -}; - - -/** Firmware layout table */ -static struct device_info boards[] = { - /** Firmware layout for the CPE210/220 V1 */ - { - .id = "CPE210", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE210(TP-LINK|UN|N300-2):1.0\r\n" - "CPE210(TP-LINK|UN|N300-2):1.1\r\n" - "CPE210(TP-LINK|US|N300-2):1.1\r\n" - "CPE210(TP-LINK|EU|N300-2):1.1\r\n" - "CPE220(TP-LINK|UN|N300-2):1.1\r\n" - "CPE220(TP-LINK|US|N300-2):1.1\r\n" - "CPE220(TP-LINK|EU|N300-2):1.1\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE210 V2 */ - { - .id = "CPE210V2", - .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n" - "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n" - "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n" - "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n" - "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n" - "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n" - "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n" - "CPE210(TP-LINK|UN|N300-2):2.0\r\n" - "CPE210(TP-LINK|EU|N300-2):2.0\r\n" - "CPE210(TP-LINK|US|N300-2):2.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"device-info", 0x31400, 0x00400}, - {"signature", 0x32000, 0x00400}, - {"device-id", 0x33000, 0x00100}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x01000}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE210 V3 */ - { - .id = "CPE210V3", - .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n" - "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n" - "CPE210(TP-LINK|US|N300-2|55530000):3.0\r\n" - "CPE210(TP-LINK|UN|N300-2):3.0\r\n" - "CPE210(TP-LINK|EU|N300-2):3.0\r\n" - "CPE210(TP-LINK|EU|N300-2|45550000):3.1\r\n" - "CPE210(TP-LINK|UN|N300-2|00000000):3.1\r\n" - "CPE210(TP-LINK|US|N300-2|55530000):3.1\r\n" - "CPE210(TP-LINK|EU|N300-2|45550000):3.20\r\n" - "CPE210(TP-LINK|UN|N300-2|00000000):3.20\r\n" - "CPE210(TP-LINK|US|N300-2|55530000):3.20\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x01000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"device-info", 0x31400, 0x00400}, - {"signature", 0x32000, 0x00400}, - {"device-id", 0x33000, 0x00100}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x01000}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE220 V2 */ - { - .id = "CPE220V2", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE220(TP-LINK|EU|N300-2|00000000):2.0\r\n" - "CPE220(TP-LINK|EU|N300-2|45550000):2.0\r\n" - "CPE220(TP-LINK|EU|N300-2|55530000):2.0\r\n" - "CPE220(TP-LINK|UN|N300-2|00000000):2.0\r\n" - "CPE220(TP-LINK|UN|N300-2|45550000):2.0\r\n" - "CPE220(TP-LINK|UN|N300-2|55530000):2.0\r\n" - "CPE220(TP-LINK|US|N300-2|55530000):2.0\r\n" - "CPE220(TP-LINK|UN|N300-2):2.0\r\n" - "CPE220(TP-LINK|EU|N300-2):2.0\r\n" - "CPE220(TP-LINK|US|N300-2):2.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE220 V3 */ - { - .id = "CPE220V3", - .vendor = "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE220(TP-LINK|EU|N300-2|00000000):3.0\r\n" - "CPE220(TP-LINK|EU|N300-2|45550000):3.0\r\n" - "CPE220(TP-LINK|EU|N300-2|55530000):3.0\r\n" - "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n" - "CPE220(TP-LINK|UN|N300-2|45550000):3.0\r\n" - "CPE220(TP-LINK|UN|N300-2|55530000):3.0\r\n" - "CPE220(TP-LINK|US|N300-2|55530000):3.0\r\n" - "CPE220(TP-LINK|UN|N300-2):3.0\r\n" - "CPE220(TP-LINK|EU|N300-2):3.0\r\n" - "CPE220(TP-LINK|US|N300-2):3.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"device-info", 0x31400, 0x00400}, - {"signature", 0x32000, 0x00400}, - {"device-id", 0x33000, 0x00100}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x01000}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE510/520 V1 */ - { - .id = "CPE510", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE510(TP-LINK|UN|N300-5):1.0\r\n" - "CPE510(TP-LINK|UN|N300-5):1.1\r\n" - "CPE510(TP-LINK|UN|N300-5):1.1\r\n" - "CPE510(TP-LINK|US|N300-5):1.1\r\n" - "CPE510(TP-LINK|EU|N300-5):1.1\r\n" - "CPE520(TP-LINK|UN|N300-5):1.1\r\n" - "CPE520(TP-LINK|US|N300-5):1.1\r\n" - "CPE520(TP-LINK|EU|N300-5):1.1\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE510 V2 */ - { - .id = "CPE510V2", - .vendor = "CPE510(TP-LINK|UN|N300-5):2.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n" - "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n" - "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n" - "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n" - "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n" - "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n" - "CPE510(TP-LINK|US|N300-5|00000000):2.0\r\n" - "CPE510(TP-LINK|US|N300-5|45550000):2.0\r\n" - "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n" - "CPE510(TP-LINK|UN|N300-5):2.0\r\n" - "CPE510(TP-LINK|EU|N300-5):2.0\r\n" - "CPE510(TP-LINK|US|N300-5):2.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE510 V3 */ - { - .id = "CPE510V3", - .vendor = "CPE510(TP-LINK|UN|N300-5):3.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE510(TP-LINK|EU|N300-5|00000000):3.0\r\n" - "CPE510(TP-LINK|EU|N300-5|45550000):3.0\r\n" - "CPE510(TP-LINK|EU|N300-5|55530000):3.0\r\n" - "CPE510(TP-LINK|UN|N300-5|00000000):3.0\r\n" - "CPE510(TP-LINK|UN|N300-5|45550000):3.0\r\n" - "CPE510(TP-LINK|UN|N300-5|55530000):3.0\r\n" - "CPE510(TP-LINK|US|N300-5|00000000):3.0\r\n" - "CPE510(TP-LINK|US|N300-5|45550000):3.0\r\n" - "CPE510(TP-LINK|US|N300-5|55530000):3.0\r\n" - "CPE510(TP-LINK|UN|N300-5):3.0\r\n" - "CPE510(TP-LINK|EU|N300-5):3.0\r\n" - "CPE510(TP-LINK|US|N300-5):3.0\r\n" - "CPE510(TP-LINK|UN|N300-5|00000000):3.20\r\n" - "CPE510(TP-LINK|US|N300-5|55530000):3.20\r\n" - "CPE510(TP-LINK|EU|N300-5|45550000):3.20\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE610V1 */ - { - .id = "CPE610V1", - .vendor = "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE610(TP-LINK|EU|N300-5|00000000):1.0\r\n" - "CPE610(TP-LINK|EU|N300-5|45550000):1.0\r\n" - "CPE610(TP-LINK|EU|N300-5|55530000):1.0\r\n" - "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n" - "CPE610(TP-LINK|UN|N300-5|45550000):1.0\r\n" - "CPE610(TP-LINK|UN|N300-5|55530000):1.0\r\n" - "CPE610(TP-LINK|US|N300-5|55530000):1.0\r\n" - "CPE610(TP-LINK|UN|N300-5):1.0\r\n" - "CPE610(TP-LINK|EU|N300-5):1.0\r\n" - "CPE610(TP-LINK|US|N300-5):1.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the CPE610V2 */ - { - .id = "CPE610V2", - .vendor = "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE610(TP-LINK|EU|N300-5|00000000):2.0\r\n" - "CPE610(TP-LINK|EU|N300-5|45550000):2.0\r\n" - "CPE610(TP-LINK|EU|N300-5|55530000):2.0\r\n" - "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n" - "CPE610(TP-LINK|UN|N300-5|45550000):2.0\r\n" - "CPE610(TP-LINK|UN|N300-5|55530000):2.0\r\n" - "CPE610(TP-LINK|US|N300-5|55530000):2.0\r\n" - "CPE610(TP-LINK|UN|N300-5):2.0\r\n" - "CPE610(TP-LINK|EU|N300-5):2.0\r\n" - "CPE610(TP-LINK|US|N300-5):2.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - /** Firmware layout for the CPE710 V1 */ - { - .id = "CPE710V1", - .vendor = "CPE710(TP-LINK|UN|AC866-5|00000000):1.0\r\n", - .support_list = - "SupportList:\r\n" - "CPE710(TP-LINK|UN|AC866-5|00000000):1.0\r\n" - "CPE710(TP-LINK|EU|AC866-5|45550000):1.0\r\n" - "CPE710(TP-LINK|US|AC866-5|55530000):1.0\r\n" - "CPE710(TP-LINK|UN|AC866-5):1.0\r\n" - "CPE710(TP-LINK|EU|AC866-5):1.0\r\n" - "CPE710(TP-LINK|US|AC866-5):1.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x50000}, - {"partition-table", 0x50000, 0x02000}, - {"default-mac", 0x60000, 0x00020}, - {"serial-number", 0x60100, 0x00020}, - {"product-info", 0x61100, 0x00100}, - {"device-info", 0x61400, 0x00400}, - {"signature", 0x62000, 0x00400}, - {"device-id", 0x63000, 0x00100}, - {"firmware", 0x70000, 0xf40000}, - {"soft-version", 0xfb0000, 0x00100}, - {"support-list", 0xfb1000, 0x01000}, - {"user-config", 0xfc0000, 0x10000}, - {"default-config", 0xfd0000, 0x10000}, - {"log", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - { - .id = "WBS210", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "WBS210(TP-LINK|UN|N300-2):1.20\r\n" - "WBS210(TP-LINK|US|N300-2):1.20\r\n" - "WBS210(TP-LINK|EU|N300-2):1.20\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - { - .id = "WBS210V2", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "WBS210(TP-LINK|UN|N300-2|00000000):2.0\r\n" - "WBS210(TP-LINK|US|N300-2|55530000):2.0\r\n" - "WBS210(TP-LINK|EU|N300-2|45550000):2.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - { - .id = "WBS510", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "WBS510(TP-LINK|UN|N300-5):1.20\r\n" - "WBS510(TP-LINK|US|N300-5):1.20\r\n" - "WBS510(TP-LINK|EU|N300-5):1.20\r\n" - "WBS510(TP-LINK|CA|N300-5):1.20\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - { - .id = "WBS510V2", - .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", - .support_list = - "SupportList:\r\n" - "WBS510(TP-LINK|UN|N300-5|00000000):2.0\r\n" - "WBS510(TP-LINK|US|N300-5|55530000):2.0\r\n" - "WBS510(TP-LINK|EU|N300-5|45550000):2.0\r\n" - "WBS510(TP-LINK|CA|N300-5|43410000):2.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"product-info", 0x31100, 0x00100}, - {"signature", 0x32000, 0x00400}, - {"firmware", 0x40000, 0x770000}, - {"soft-version", 0x7b0000, 0x00100}, - {"support-list", 0x7b1000, 0x00400}, - {"user-config", 0x7c0000, 0x10000}, - {"default-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "support-list", - }, - - /** Firmware layout for the AD7200 */ - { - .id = "AD7200", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:AD7200,product_ver:1.0.0,special_id:00000000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"SBL1", 0x00000, 0x20000}, - {"MIBIB", 0x20000, 0x20000}, - {"SBL2", 0x40000, 0x20000}, - {"SBL3", 0x60000, 0x30000}, - {"DDRCONFIG", 0x90000, 0x10000}, - {"SSD", 0xa0000, 0x10000}, - {"TZ", 0xb0000, 0x30000}, - {"RPM", 0xe0000, 0x20000}, - {"fs-uboot", 0x100000, 0x70000}, - {"uboot-env", 0x170000, 0x40000}, - {"radio", 0x1b0000, 0x40000}, - {"os-image", 0x1f0000, 0x400000}, - {"file-system", 0x5f0000, 0x1900000}, - {"default-mac", 0x1ef0000, 0x00200}, - {"pin", 0x1ef0200, 0x00200}, - {"device-id", 0x1ef0400, 0x00200}, - {"product-info", 0x1ef0600, 0x0fa00}, - {"partition-table", 0x1f00000, 0x10000}, - {"soft-version", 0x1f10000, 0x10000}, - {"support-list", 0x1f20000, 0x10000}, - {"profile", 0x1f30000, 0x10000}, - {"default-config", 0x1f40000, 0x10000}, - {"user-config", 0x1f50000, 0x40000}, - {"qos-db", 0x1f90000, 0x40000}, - {"usb-config", 0x1fd0000, 0x10000}, - {"log", 0x1fe0000, 0x20000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the C2600 */ - { - .id = "C2600", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /** - We use a bigger os-image partition than the stock images (and thus - smaller file-system), as our kernel doesn't fit in the stock firmware's - 2 MB os-image since kernel 4.14. - */ - .partitions = { - {"SBL1", 0x00000, 0x20000}, - {"MIBIB", 0x20000, 0x20000}, - {"SBL2", 0x40000, 0x20000}, - {"SBL3", 0x60000, 0x30000}, - {"DDRCONFIG", 0x90000, 0x10000}, - {"SSD", 0xa0000, 0x10000}, - {"TZ", 0xb0000, 0x30000}, - {"RPM", 0xe0000, 0x20000}, - {"fs-uboot", 0x100000, 0x70000}, - {"uboot-env", 0x170000, 0x40000}, - {"radio", 0x1b0000, 0x40000}, - {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */ - {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */ - {"default-mac", 0x1ef0000, 0x00200}, - {"pin", 0x1ef0200, 0x00200}, - {"product-info", 0x1ef0400, 0x0fc00}, - {"partition-table", 0x1f00000, 0x10000}, - {"soft-version", 0x1f10000, 0x10000}, - {"support-list", 0x1f20000, 0x10000}, - {"profile", 0x1f30000, 0x10000}, - {"default-config", 0x1f40000, 0x10000}, - {"user-config", 0x1f50000, 0x40000}, - {"qos-db", 0x1f90000, 0x40000}, - {"usb-config", 0x1fd0000, 0x10000}, - {"log", 0x1fe0000, 0x20000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the A7-V5 */ - { - .id = "ARCHER-A7-V5", - .support_list = - "SupportList:\n" - "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n" - "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n" - "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n" - "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n" - "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n" - "{product_name:Archer A7,product_ver:5.0.0,special_id:52550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"firmware", 0x40000, 0xec0000}, /* Stock: name os-image base 0x40000 size 0x120000 */ - /* Stock: name file-system base 0x160000 size 0xda0000 */ - {"default-mac", 0xf40000, 0x00200}, - {"pin", 0xf40200, 0x00200}, - {"device-id", 0xf40400, 0x00100}, - {"product-info", 0xf40500, 0x0fb00}, - {"soft-version", 0xf50000, 0x00100}, - {"extra-para", 0xf51000, 0x01000}, - {"support-list", 0xf52000, 0x0a000}, - {"profile", 0xf5c000, 0x04000}, - {"default-config", 0xf60000, 0x10000}, - {"user-config", 0xf70000, 0x40000}, - {"certificate", 0xfb0000, 0x10000}, - {"partition-table", 0xfc0000, 0x10000}, - {"log", 0xfd0000, 0x20000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C2v3 */ - { - .id = "ARCHER-C2-V3", - .support_list = - "SupportList:\n" - "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n" - "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n" - "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.1\n"), - - /** We're using a dynamic kernel/rootfs split here */ - - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x10000}, - {"firmware", 0x30000, 0x7a0000}, - {"user-config", 0x7d0000, 0x04000}, - {"default-mac", 0x7e0000, 0x00100}, - {"device-id", 0x7e0100, 0x00100}, - {"extra-para", 0x7e0200, 0x00100}, - {"pin", 0x7e0300, 0x00100}, - {"support-list", 0x7e0400, 0x00400}, - {"soft-version", 0x7e0800, 0x00400}, - {"product-info", 0x7e0c00, 0x01400}, - {"partition-table", 0x7e2000, 0x01000}, - {"profile", 0x7e3000, 0x01000}, - {"default-config", 0x7e4000, 0x04000}, - {"merge-config", 0x7ec000, 0x02000}, - {"qos-db", 0x7ee000, 0x02000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C25v1 */ - { - .id = "ARCHER-C25-V1", - .support_list = - "SupportList:\n" - "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n" - "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n" - "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x10000}, - {"firmware", 0x30000, 0x7a0000}, /* Stock: name os-image base 0x30000 size 0x100000 */ - /* Stock: name file-system base 0x130000 size 0x6a0000 */ - {"user-config", 0x7d0000, 0x04000}, - {"default-mac", 0x7e0000, 0x00100}, - {"device-id", 0x7e0100, 0x00100}, - {"extra-para", 0x7e0200, 0x00100}, - {"pin", 0x7e0300, 0x00100}, - {"support-list", 0x7e0400, 0x00400}, - {"soft-version", 0x7e0800, 0x00400}, - {"product-info", 0x7e0c00, 0x01400}, - {"partition-table", 0x7e2000, 0x01000}, - {"profile", 0x7e3000, 0x01000}, - {"default-config", 0x7e4000, 0x04000}, - {"merge-config", 0x7ec000, 0x02000}, - {"qos-db", 0x7ee000, 0x02000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C58v1 */ - { - .id = "ARCHER-C58-V1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x10000}, - {"default-mac", 0x10000, 0x00200}, - {"pin", 0x10200, 0x00200}, - {"product-info", 0x10400, 0x00100}, - {"partition-table", 0x10500, 0x00800}, - {"soft-version", 0x11300, 0x00200}, - {"support-list", 0x11500, 0x00100}, - {"device-id", 0x11600, 0x00100}, - {"profile", 0x11700, 0x03900}, - {"default-config", 0x15000, 0x04000}, - {"user-config", 0x19000, 0x04000}, - {"firmware", 0x20000, 0x7c8000}, - {"certyficate", 0x7e8000, 0x08000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C59v1 */ - { - .id = "ARCHER-C59-V1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n" - "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x10000}, - {"default-mac", 0x10000, 0x00200}, - {"pin", 0x10200, 0x00200}, - {"device-id", 0x10400, 0x00100}, - {"product-info", 0x10500, 0x0fb00}, - {"firmware", 0x20000, 0xe30000}, - {"partition-table", 0xe50000, 0x10000}, - {"soft-version", 0xe60000, 0x10000}, - {"support-list", 0xe70000, 0x10000}, - {"profile", 0xe80000, 0x10000}, - {"default-config", 0xe90000, 0x10000}, - {"user-config", 0xea0000, 0x40000}, - {"usb-config", 0xee0000, 0x10000}, - {"certificate", 0xef0000, 0x10000}, - {"qos-db", 0xf00000, 0x40000}, - {"log", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C59v2 */ - { - .id = "ARCHER-C59-V2", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n" - "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n" - "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0 Build 20161206 rel.7303\n"), - - /** We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x10000}, - {"default-mac", 0x30000, 0x00200}, - {"pin", 0x30200, 0x00200}, - {"device-id", 0x30400, 0x00100}, - {"product-info", 0x30500, 0x0fb00}, - {"firmware", 0x40000, 0xe10000}, - {"partition-table", 0xe50000, 0x10000}, - {"soft-version", 0xe60000, 0x10000}, - {"support-list", 0xe70000, 0x10000}, - {"profile", 0xe80000, 0x10000}, - {"default-config", 0xe90000, 0x10000}, - {"user-config", 0xea0000, 0x40000}, - {"usb-config", 0xee0000, 0x10000}, - {"certificate", 0xef0000, 0x10000}, - {"extra-para", 0xf00000, 0x10000}, - {"qos-db", 0xf10000, 0x30000}, - {"log", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the Archer C6 v2 (EU/RU/JP) */ - { - .id = "ARCHER-C6-V2", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n" - "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n" - "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"default-mac", 0x20000, 0x00200}, - {"pin", 0x20200, 0x00100}, - {"product-info", 0x20300, 0x00200}, - {"device-id", 0x20500, 0x0fb00}, - {"firmware", 0x30000, 0x7a9400}, - {"soft-version", 0x7d9400, 0x00100}, - {"extra-para", 0x7d9500, 0x00100}, - {"support-list", 0x7d9600, 0x00200}, - {"profile", 0x7d9800, 0x03000}, - {"default-config", 0x7dc800, 0x03000}, - {"partition-table", 0x7df800, 0x00800}, - {"user-config", 0x7e0000, 0x0c000}, - {"certificate", 0x7ec000, 0x04000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */ - { - .id = "ARCHER-C6-V2-US", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n" - "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n" - "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"), - - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"default-mac", 0x20000, 0x00200}, - {"pin", 0x20200, 0x00100}, - {"product-info", 0x20300, 0x00200}, - {"device-id", 0x20500, 0x0fb00}, - {"fs-uboot", 0x30000, 0x20000}, - {"firmware", 0x50000, 0xf89400}, - {"soft-version", 0xfd9400, 0x00100}, - {"extra-para", 0xfd9500, 0x00100}, - {"support-list", 0xfd9600, 0x00200}, - {"profile", 0xfd9800, 0x03000}, - {"default-config", 0xfdc800, 0x03000}, - {"partition-table", 0xfdf800, 0x00800}, - {"user-config", 0xfe0000, 0x0c000}, - {"certificate", 0xfec000, 0x04000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - /** Firmware layout for the Archer C6 v3 */ - { - .id = "ARCHER-C6-V3", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:Archer C6,product_ver:3.20,special_id:55530000}" - "{product_name:Archer C6,product_ver:3.20,special_id:45550000}" - "{product_name:Archer C6,product_ver:3.20,special_id:52550000}" - "{product_name:Archer C6,product_ver:3.20,special_id:4A500000}" - "{product_name:Archer C6,product_ver:3.20,special_id:4B520000}", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.9\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x40000}, - {"firmware", 0x40000, 0xf60000}, - {"default-mac", 0xfa0000, 0x00200}, - {"pin", 0xfa0200, 0x00100}, - {"device-id", 0xfa0300, 0x00100}, - {"product-info", 0xfa0400, 0x0fc00}, - {"default-config", 0xfb0000, 0x08000}, - {"ap-def-config", 0xfb8000, 0x08000}, - {"user-config", 0xfc0000, 0x0a000}, - {"ag-config", 0xfca000, 0x04000}, - {"certificate", 0xfce000, 0x02000}, - {"ap-config", 0xfd0000, 0x06000}, - {"router-config", 0xfd6000, 0x06000}, - {"favicon", 0xfdc000, 0x02000}, - {"logo", 0xfde000, 0x02000}, - {"partition-table", 0xfe0000, 0x00800}, - {"soft-version", 0xfe0800, 0x00100}, - {"support-list", 0xfe0900, 0x00200}, - {"profile", 0xfe0b00, 0x03000}, - {"extra-para", 0xfe3b00, 0x00100}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - /** Firmware layout for the Archer A6 v3 */ - { - .id = "ARCHER-A6-V3", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:Archer A6,product_ver:3.0.0,special_id:43410000}\n" - "{product_name:Archer A6,product_ver:3.0.0,special_id:55530000}\n" - "{product_name:Archer A6,product_ver:3.0.0,special_id:54570000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.5\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x40000}, - {"firmware", 0x40000, 0xf60000}, - {"default-mac", 0xfa0000, 0x00200}, - {"pin", 0xfa0200, 0x00100}, - {"device-id", 0xfa0300, 0x00100}, - {"product-info", 0xfa0400, 0x0fc00}, - {"default-config", 0xfb0000, 0x08000}, - {"ap-def-config", 0xfb8000, 0x08000}, - {"user-config", 0xfc0000, 0x0a000}, - {"ag-config", 0xfca000, 0x04000}, - {"certificate", 0xfce000, 0x02000}, - {"ap-config", 0xfd0000, 0x06000}, - {"router-config", 0xfd6000, 0x06000}, - {"favicon", 0xfdc000, 0x02000}, - {"logo", 0xfde000, 0x02000}, - {"partition-table", 0xfe0000, 0x00800}, - {"soft-version", 0xfe0800, 0x00100}, - {"support-list", 0xfe0900, 0x00200}, - {"profile", 0xfe0b00, 0x03000}, - {"extra-para", 0xfe3b00, 0x00100}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - /** Firmware layout for the Archer C6U v1 */ - { - .id = "ARCHER-C6U-V1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.2\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x40000}, - {"firmware", 0x40000, 0xf60000}, - {"default-mac", 0xfa0000, 0x00200}, - {"pin", 0xfa0200, 0x00100}, - {"device-id", 0xfa0300, 0x00100}, - {"product-info", 0xfa0400, 0x0fc00}, - {"default-config", 0xfb0000, 0x08000}, - {"ap-def-config", 0xfb8000, 0x08000}, - {"user-config", 0xfc0000, 0x0c000}, - {"certificate", 0xfcc000, 0x04000}, - {"ap-config", 0xfd0000, 0x08000}, - {"router-config", 0xfd8000, 0x08000}, - {"partition-table", 0xfe0000, 0x00800}, - {"soft-version", 0xfe0800, 0x00100}, - {"support-list", 0xfe0900, 0x00200}, - {"profile", 0xfe0b00, 0x03000}, - {"extra-para", 0xfe3b00, 0x00100}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - /** Firmware layout for the C60v1 */ - { - .id = "ARCHER-C60-V1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x10000}, - {"default-mac", 0x10000, 0x00200}, - {"pin", 0x10200, 0x00200}, - {"product-info", 0x10400, 0x00100}, - {"partition-table", 0x10500, 0x00800}, - {"soft-version", 0x11300, 0x00200}, - {"support-list", 0x11500, 0x00100}, - {"device-id", 0x11600, 0x00100}, - {"profile", 0x11700, 0x03900}, - {"default-config", 0x15000, 0x04000}, - {"user-config", 0x19000, 0x04000}, - {"firmware", 0x20000, 0x7c8000}, - {"certyficate", 0x7e8000, 0x08000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C60v2 */ - { - .id = "ARCHER-C60-V2", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n" - "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n" - "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"), - - .partitions = { - {"factory-boot", 0x00000, 0x1fb00}, - {"default-mac", 0x1fb00, 0x00200}, - {"pin", 0x1fd00, 0x00100}, - {"product-info", 0x1fe00, 0x00100}, - {"device-id", 0x1ff00, 0x00100}, - {"fs-uboot", 0x20000, 0x10000}, - {"firmware", 0x30000, 0x7a0000}, - {"soft-version", 0x7d9500, 0x00100}, - {"support-list", 0x7d9600, 0x00100}, - {"extra-para", 0x7d9700, 0x00100}, - {"profile", 0x7d9800, 0x03000}, - {"default-config", 0x7dc800, 0x03000}, - {"partition-table", 0x7df800, 0x00800}, - {"user-config", 0x7e0000, 0x0c000}, - {"certificate", 0x7ec000, 0x04000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C60v3 */ - { - .id = "ARCHER-C60-V3", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n" - "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n" - "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.0\n"), - - .partitions = { - {"factory-boot", 0x00000, 0x1fb00}, - {"default-mac", 0x1fb00, 0x00200}, - {"pin", 0x1fd00, 0x00100}, - {"product-info", 0x1fe00, 0x00100}, - {"device-id", 0x1ff00, 0x00100}, - {"fs-uboot", 0x20000, 0x10000}, - {"firmware", 0x30000, 0x7a0000}, - {"soft-version", 0x7d9500, 0x00100}, - {"support-list", 0x7d9600, 0x00100}, - {"extra-para", 0x7d9700, 0x00100}, - {"profile", 0x7d9800, 0x03000}, - {"default-config", 0x7dc800, 0x03000}, - {"partition-table", 0x7df800, 0x00800}, - {"user-config", 0x7e0000, 0x0c000}, - {"certificate", 0x7ec000, 0x04000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C5 */ - { - .id = "ARCHER-C5-V2", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n" - "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n" - "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */ - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x40000}, - {"os-image", 0x40000, 0x200000}, - {"file-system", 0x240000, 0xc00000}, - {"default-mac", 0xe40000, 0x00200}, - {"pin", 0xe40200, 0x00200}, - {"product-info", 0xe40400, 0x00200}, - {"partition-table", 0xe50000, 0x10000}, - {"soft-version", 0xe60000, 0x00200}, - {"support-list", 0xe61000, 0x0f000}, - {"profile", 0xe70000, 0x10000}, - {"default-config", 0xe80000, 0x10000}, - {"user-config", 0xe90000, 0x50000}, - {"log", 0xee0000, 0x100000}, - {"radio_bk", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the C7 */ - { - .id = "ARCHER-C7-V4", - .support_list = - "SupportList:\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n" - "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */ - /* Stock: name file-system base 0x160000 size 0xda0000 */ - {"default-mac", 0xf00000, 0x00200}, - {"pin", 0xf00200, 0x00200}, - {"device-id", 0xf00400, 0x00100}, - {"product-info", 0xf00500, 0x0fb00}, - {"soft-version", 0xf10000, 0x00100}, - {"extra-para", 0xf11000, 0x01000}, - {"support-list", 0xf12000, 0x0a000}, - {"profile", 0xf1c000, 0x04000}, - {"default-config", 0xf20000, 0x10000}, - {"user-config", 0xf30000, 0x40000}, - {"qos-db", 0xf70000, 0x40000}, - {"certificate", 0xfb0000, 0x10000}, - {"partition-table", 0xfc0000, 0x10000}, - {"log", 0xfd0000, 0x20000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C7 v5*/ - { - .id = "ARCHER-C7-V5", - .support_list = - "SupportList:\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n" - "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n", - - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"), - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"partition-table", 0x40000, 0x10000}, - {"radio", 0x50000, 0x10000}, - {"default-mac", 0x60000, 0x00200}, - {"pin", 0x60200, 0x00200}, - {"device-id", 0x60400, 0x00100}, - {"product-info", 0x60500, 0x0fb00}, - {"soft-version", 0x70000, 0x01000}, - {"extra-para", 0x71000, 0x01000}, - {"support-list", 0x72000, 0x0a000}, - {"profile", 0x7c000, 0x04000}, - {"user-config", 0x80000, 0x40000}, - - - {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */ - /* Stock: name file-system base 0x1e0000 size 0xde0000 */ - - {"log", 0xfc0000, 0x20000}, - {"certificate", 0xfe0000, 0x10000}, - {"default-config", 0xff0000, 0x10000}, - {NULL, 0, 0} - - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the C9 */ - { - .id = "ARCHERC9", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:ArcherC9," - "product_ver:1.0.0," - "special_id:00000000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x40000}, - {"os-image", 0x40000, 0x200000}, - {"file-system", 0x240000, 0xc00000}, - {"default-mac", 0xe40000, 0x00200}, - {"pin", 0xe40200, 0x00200}, - {"product-info", 0xe40400, 0x00200}, - {"partition-table", 0xe50000, 0x10000}, - {"soft-version", 0xe60000, 0x00200}, - {"support-list", 0xe61000, 0x0f000}, - {"profile", 0xe70000, 0x10000}, - {"default-config", 0xe80000, 0x10000}, - {"user-config", 0xe90000, 0x50000}, - {"log", 0xee0000, 0x100000}, - {"radio_bk", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP120 */ - { - .id = "EAP120", - .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n", - .support_list = - "SupportList:\r\n" - "EAP120(TP-LINK|UN|N300-2):1.0\r\n", - .part_trail = 0xff, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x00020}, - {"support-list", 0x31000, 0x00100}, - {"product-info", 0x31100, 0x00100}, - {"soft-version", 0x32000, 0x00100}, - {"os-image", 0x40000, 0x180000}, - {"file-system", 0x1c0000, 0x600000}, - {"user-config", 0x7c0000, 0x10000}, - {"backup-config", 0x7d0000, 0x10000}, - {"log", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP225-Outdoor v1 */ - { - .id = "EAP225-OUTDOOR-V1", - .support_list = - "SupportList:\r\n" - "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n", - .part_trail = PART_TRAIL_NONE, - .soft_ver = SOFT_VER_DEFAULT, - .soft_ver_compat_level = 1, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x01000}, - {"support-list", 0x31000, 0x00100}, - {"product-info", 0x31100, 0x00400}, - {"soft-version", 0x32000, 0x00100}, - {"firmware", 0x40000, 0xd80000}, - {"user-config", 0xdc0000, 0x30000}, - {"mutil-log", 0xf30000, 0x80000}, - {"oops", 0xfb0000, 0x40000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP225 v3 */ - { - .id = "EAP225-V3", - .support_list = - "SupportList:\r\n" - "EAP225(TP-Link|UN|AC1350-D):3.0\r\n", - .part_trail = PART_TRAIL_NONE, - .soft_ver = SOFT_VER_DEFAULT, - .soft_ver_compat_level = 1, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x01000}, - {"support-list", 0x31000, 0x00100}, - {"product-info", 0x31100, 0x00400}, - {"soft-version", 0x32000, 0x00100}, - {"firmware", 0x40000, 0xd80000}, - {"user-config", 0xdc0000, 0x30000}, - {"mutil-log", 0xf30000, 0x80000}, - {"oops", 0xfb0000, 0x40000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP225-Wall v2 */ - { - .id = "EAP225-WALL-V2", - .support_list = - "SupportList:\r\n" - "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n", - .part_trail = PART_TRAIL_NONE, - .soft_ver = SOFT_VER_DEFAULT, - .soft_ver_compat_level = 1, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x01000}, - {"support-list", 0x31000, 0x00100}, - {"product-info", 0x31100, 0x00400}, - {"soft-version", 0x32000, 0x00100}, - {"firmware", 0x40000, 0xd80000}, - {"user-config", 0xdc0000, 0x30000}, - {"mutil-log", 0xf30000, 0x80000}, - {"oops", 0xfb0000, 0x40000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP235-Wall v1 */ - { - .id = "EAP235-WALL-V1", - .support_list = - "SupportList:\r\n" - "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n", - .part_trail = PART_TRAIL_NONE, - .soft_ver = SOFT_VER_NUMERIC(3, 0, 0), - .soft_ver_compat_level = 1, - - .partitions = { - {"fs-uboot", 0x00000, 0x80000}, - {"partition-table", 0x80000, 0x02000}, - {"default-mac", 0x90000, 0x01000}, - {"support-list", 0x91000, 0x00100}, - {"product-info", 0x91100, 0x00400}, - {"soft-version", 0x92000, 0x00100}, - {"firmware", 0xa0000, 0xd20000}, - {"user-config", 0xdc0000, 0x30000}, - {"mutil-log", 0xf30000, 0x80000}, - {"oops", 0xfb0000, 0x40000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP245 v1 */ - { - .id = "EAP245-V1", - .support_list = - "SupportList:\r\n" - "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n", - .part_trail = PART_TRAIL_NONE, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"partition-table", 0x20000, 0x02000}, - {"default-mac", 0x30000, 0x01000}, - {"support-list", 0x31000, 0x00100}, - {"product-info", 0x31100, 0x00400}, - {"soft-version", 0x32000, 0x00100}, - {"firmware", 0x40000, 0xd80000}, - {"user-config", 0xdc0000, 0x30000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the EAP245 v3 */ - { - .id = "EAP245-V3", - .support_list = - "SupportList:\r\n" - "EAP245(TP-Link|UN|AC1750-D):3.0\r\n", - .part_trail = PART_TRAIL_NONE, - .soft_ver = SOFT_VER_DEFAULT, - .soft_ver_compat_level = 1, - - /** Firmware partition with dynamic kernel/rootfs split */ - .partitions = { - {"factroy-boot", 0x00000, 0x40000}, - {"fs-uboot", 0x40000, 0x40000}, - {"partition-table", 0x80000, 0x10000}, - {"default-mac", 0x90000, 0x01000}, - {"support-list", 0x91000, 0x00100}, - {"product-info", 0x91100, 0x00400}, - {"soft-version", 0x92000, 0x00100}, - {"radio", 0xa0000, 0x10000}, - {"extra-para", 0xb0000, 0x10000}, - {"firmware", 0xc0000, 0xe40000}, - {"config", 0xf00000, 0x30000}, - {"mutil-log", 0xf30000, 0x80000}, - {"oops", 0xfb0000, 0x40000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WA1201 v2 */ - { - .id = "TL-WA1201-V2", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WA1201,product_ver:2.0.0,special_id:45550000}\n" - "{product_name:TL-WA1201,product_ver:2.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.1 Build 20200709 rel.66244\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"default-mac", 0x20000, 0x00200}, - {"pin", 0x20200, 0x00100}, - {"product-info", 0x20300, 0x00200}, - {"device-id", 0x20500, 0x0fb00}, - {"firmware", 0x30000, 0xce0000}, - {"portal-logo", 0xd10000, 0x20000}, - {"portal-back", 0xd30000, 0x200000}, - {"soft-version", 0xf30000, 0x00200}, - {"extra-para", 0xf30200, 0x00200}, - {"support-list", 0xf30400, 0x00200}, - {"profile", 0xf30600, 0x0fa00}, - {"apdef-config", 0xf40000, 0x10000}, - {"ap-config", 0xf50000, 0x10000}, - {"redef-config", 0xf60000, 0x10000}, - {"re-config", 0xf70000, 0x10000}, - {"multidef-config", 0xf80000, 0x10000}, - {"multi-config", 0xf90000, 0x10000}, - {"clientdef-config", 0xfa0000, 0x10000}, - {"client-config", 0xfb0000, 0x10000}, - {"partition-table", 0xfc0000, 0x10000}, - {"user-config", 0xfd0000, 0x10000}, - {"certificate", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the TL-WA850RE v2 */ - { - .id = "TLWA850REV2", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n" - "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /** - 576KB were moved from file-system to os-image - in comparison to the stock image - */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x390000}, - {"partition-table", 0x3b0000, 0x02000}, - {"default-mac", 0x3c0000, 0x00020}, - {"pin", 0x3c0100, 0x00020}, - {"product-info", 0x3c1000, 0x01000}, - {"soft-version", 0x3c2000, 0x00100}, - {"support-list", 0x3c3000, 0x01000}, - {"profile", 0x3c4000, 0x08000}, - {"user-config", 0x3d0000, 0x10000}, - {"default-config", 0x3e0000, 0x10000}, - {"radio", 0x3f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WA855RE v1 */ - { - .id = "TLWA855REV1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n" - "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"os-image", 0x20000, 0x150000}, - {"file-system", 0x170000, 0x240000}, - {"partition-table", 0x3b0000, 0x02000}, - {"default-mac", 0x3c0000, 0x00020}, - {"pin", 0x3c0100, 0x00020}, - {"product-info", 0x3c1000, 0x01000}, - {"soft-version", 0x3c2000, 0x00100}, - {"support-list", 0x3c3000, 0x01000}, - {"profile", 0x3c4000, 0x08000}, - {"user-config", 0x3d0000, 0x10000}, - {"default-config", 0x3e0000, 0x10000}, - {"radio", 0x3f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WPA8630P v2 (EU)*/ - { - .id = "TL-WPA8630P-V2.0-EU", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"factory-uboot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"firmware", 0x40000, 0x5e0000}, - {"partition-table", 0x620000, 0x02000}, - {"default-mac", 0x630000, 0x00020}, - {"pin", 0x630100, 0x00020}, - {"device-id", 0x630200, 0x00030}, - {"product-info", 0x631100, 0x01000}, - {"extra-para", 0x632100, 0x01000}, - {"soft-version", 0x640000, 0x01000}, - {"support-list", 0x641000, 0x01000}, - {"profile", 0x642000, 0x08000}, - {"user-config", 0x650000, 0x10000}, - {"default-config", 0x660000, 0x10000}, - {"default-nvm", 0x670000, 0xc0000}, - {"default-pib", 0x730000, 0x40000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WPA8630P v2 (INT)*/ - { - .id = "TL-WPA8630P-V2-INT", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n" - "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n" - "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"factory-uboot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"firmware", 0x40000, 0x5e0000}, - {"partition-table", 0x620000, 0x02000}, - {"extra-para", 0x632100, 0x01000}, - {"soft-version", 0x640000, 0x01000}, - {"support-list", 0x641000, 0x01000}, - {"profile", 0x642000, 0x08000}, - {"user-config", 0x650000, 0x10000}, - {"default-config", 0x660000, 0x10000}, - {"default-nvm", 0x670000, 0xc0000}, - {"default-pib", 0x730000, 0x40000}, - {"default-mac", 0x7e0000, 0x00020}, - {"pin", 0x7e0100, 0x00020}, - {"device-id", 0x7e0200, 0x00030}, - {"product-info", 0x7e1100, 0x01000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/ - { - .id = "TL-WPA8630P-V2.1-EU", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"factory-uboot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"firmware", 0x40000, 0x5e0000}, - {"extra-para", 0x680000, 0x01000}, - {"product-info", 0x690000, 0x01000}, - {"partition-table", 0x6a0000, 0x02000}, - {"soft-version", 0x6b0000, 0x01000}, - {"support-list", 0x6b1000, 0x01000}, - {"profile", 0x6b2000, 0x08000}, - {"user-config", 0x6c0000, 0x10000}, - {"default-config", 0x6d0000, 0x10000}, - {"default-nvm", 0x6e0000, 0xc0000}, - {"default-pib", 0x7a0000, 0x40000}, - {"default-mac", 0x7e0000, 0x00020}, - {"pin", 0x7e0100, 0x00020}, - {"device-id", 0x7e0200, 0x00030}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WR1043 v5 */ - { - .id = "TLWR1043NV5", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n" - "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), - .partitions = { - {"factory-boot", 0x00000, 0x20000}, - {"fs-uboot", 0x20000, 0x20000}, - {"firmware", 0x40000, 0xec0000}, - {"default-mac", 0xf00000, 0x00200}, - {"pin", 0xf00200, 0x00200}, - {"device-id", 0xf00400, 0x00100}, - {"product-info", 0xf00500, 0x0fb00}, - {"soft-version", 0xf10000, 0x01000}, - {"extra-para", 0xf11000, 0x01000}, - {"support-list", 0xf12000, 0x0a000}, - {"profile", 0xf1c000, 0x04000}, - {"default-config", 0xf20000, 0x10000}, - {"user-config", 0xf30000, 0x40000}, - {"qos-db", 0xf70000, 0x40000}, - {"certificate", 0xfb0000, 0x10000}, - {"partition-table", 0xfc0000, 0x10000}, - {"log", 0xfd0000, 0x20000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WR1043 v4 */ - { - .id = "TLWR1043NDV4", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0xf30000}, - {"default-mac", 0xf50000, 0x00200}, - {"pin", 0xf50200, 0x00200}, - {"product-info", 0xf50400, 0x0fc00}, - {"soft-version", 0xf60000, 0x0b000}, - {"support-list", 0xf6b000, 0x04000}, - {"profile", 0xf70000, 0x04000}, - {"default-config", 0xf74000, 0x0b000}, - {"user-config", 0xf80000, 0x40000}, - {"partition-table", 0xfc0000, 0x10000}, - {"log", 0xfd0000, 0x20000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the TL-WR902AC v1 */ - { - .id = "TL-WR902AC-V1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n" - "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /** - 384KB were moved from file-system to os-image - in comparison to the stock image - */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x730000}, - {"default-mac", 0x750000, 0x00200}, - {"pin", 0x750200, 0x00200}, - {"product-info", 0x750400, 0x0fc00}, - {"soft-version", 0x760000, 0x0b000}, - {"support-list", 0x76b000, 0x04000}, - {"profile", 0x770000, 0x04000}, - {"default-config", 0x774000, 0x0b000}, - {"user-config", 0x780000, 0x40000}, - {"partition-table", 0x7c0000, 0x10000}, - {"log", 0x7d0000, 0x20000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the TL-WR941HP v1 */ - { - .id = "TL-WR941HP-V1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x730000}, - {"default-mac", 0x750000, 0x00200}, - {"pin", 0x750200, 0x00200}, - {"product-info", 0x750400, 0x0fc00}, - {"soft-version", 0x760000, 0x0b000}, - {"support-list", 0x76b000, 0x04000}, - {"profile", 0x770000, 0x04000}, - {"default-config", 0x774000, 0x0b000}, - {"user-config", 0x780000, 0x40000}, - {"partition-table", 0x7c0000, 0x10000}, - {"log", 0x7d0000, 0x20000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the TL-WR942N V1 */ - { - .id = "TLWR942NV1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0xe20000}, - {"default-mac", 0xe40000, 0x00200}, - {"pin", 0xe40200, 0x00200}, - {"product-info", 0xe40400, 0x0fc00}, - {"partition-table", 0xe50000, 0x10000}, - {"soft-version", 0xe60000, 0x10000}, - {"support-list", 0xe70000, 0x10000}, - {"profile", 0xe80000, 0x10000}, - {"default-config", 0xe90000, 0x10000}, - {"user-config", 0xea0000, 0x40000}, - {"qos-db", 0xee0000, 0x40000}, - {"certificate", 0xf20000, 0x10000}, - {"usb-config", 0xfb0000, 0x10000}, - {"log", 0xfc0000, 0x20000}, - {"radio-bk", 0xfe0000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system", - }, - - /** Firmware layout for the RE200 v2 */ - { - .id = "RE200-V2", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n" - "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x7a0000}, - {"partition-table", 0x7c0000, 0x02000}, - {"default-mac", 0x7c2000, 0x00020}, - {"pin", 0x7c2100, 0x00020}, - {"product-info", 0x7c3100, 0x01000}, - {"soft-version", 0x7c4200, 0x01000}, - {"support-list", 0x7c5200, 0x01000}, - {"profile", 0x7c6200, 0x08000}, - {"config-info", 0x7ce200, 0x00400}, - {"user-config", 0x7d0000, 0x10000}, - {"default-config", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE200 v3 */ - { - .id = "RE200-V3", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n" - "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x7a0000}, - {"partition-table", 0x7c0000, 0x02000}, - {"default-mac", 0x7c2000, 0x00020}, - {"pin", 0x7c2100, 0x00020}, - {"product-info", 0x7c3100, 0x01000}, - {"soft-version", 0x7c4200, 0x01000}, - {"support-list", 0x7c5200, 0x01000}, - {"profile", 0x7c6200, 0x08000}, - {"config-info", 0x7ce200, 0x00400}, - {"user-config", 0x7d0000, 0x10000}, - {"default-config", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE200 v4 */ - { - .id = "RE200-V4", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n" - "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"), - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x7a0000}, - {"partition-table", 0x7c0000, 0x02000}, - {"default-mac", 0x7c2000, 0x00020}, - {"pin", 0x7c2100, 0x00020}, - {"product-info", 0x7c3100, 0x01000}, - {"soft-version", 0x7c4200, 0x01000}, - {"support-list", 0x7c5200, 0x01000}, - {"profile", 0x7c6200, 0x08000}, - {"config-info", 0x7ce200, 0x00400}, - {"user-config", 0x7d0000, 0x10000}, - {"default-config", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE220 v2 */ - { - .id = "RE220-V2", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n" - "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x7a0000}, - {"partition-table", 0x7c0000, 0x02000}, - {"default-mac", 0x7c2000, 0x00020}, - {"pin", 0x7c2100, 0x00020}, - {"product-info", 0x7c3100, 0x01000}, - {"soft-version", 0x7c4200, 0x01000}, - {"support-list", 0x7c5200, 0x01000}, - {"profile", 0x7c6200, 0x08000}, - {"config-info", 0x7ce200, 0x00400}, - {"user-config", 0x7d0000, 0x10000}, - {"default-config", 0x7e0000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE305 v1 */ - { - .id = "RE305-V1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n" - "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n" - "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n" - "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n" - "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n" - "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n" - "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x5e0000}, - {"partition-table", 0x600000, 0x02000}, - {"default-mac", 0x610000, 0x00020}, - {"pin", 0x610100, 0x00020}, - {"product-info", 0x611100, 0x01000}, - {"soft-version", 0x620000, 0x01000}, - {"support-list", 0x621000, 0x01000}, - {"profile", 0x622000, 0x08000}, - {"user-config", 0x630000, 0x10000}, - {"default-config", 0x640000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE350 v1 */ - { - .id = "RE350-V1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n" - "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n" - "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n" - "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n" - "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n" - "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n" - "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /** We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x5e0000}, - {"partition-table", 0x600000, 0x02000}, - {"default-mac", 0x610000, 0x00020}, - {"pin", 0x610100, 0x00020}, - {"product-info", 0x611100, 0x01000}, - {"soft-version", 0x620000, 0x01000}, - {"support-list", 0x621000, 0x01000}, - {"profile", 0x622000, 0x08000}, - {"user-config", 0x630000, 0x10000}, - {"default-config", 0x640000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE350K v1 */ - { - .id = "RE350K-V1", - .vendor = "", - .support_list = - "SupportList:\n" - "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /** We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0xd70000}, - {"partition-table", 0xd90000, 0x02000}, - {"default-mac", 0xda0000, 0x00020}, - {"pin", 0xda0100, 0x00020}, - {"product-info", 0xda1100, 0x01000}, - {"soft-version", 0xdb0000, 0x01000}, - {"support-list", 0xdb1000, 0x01000}, - {"profile", 0xdb2000, 0x08000}, - {"user-config", 0xdc0000, 0x10000}, - {"default-config", 0xdd0000, 0x10000}, - {"device-id", 0xde0000, 0x00108}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE355 */ - { - .id = "RE355", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n" - "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x5e0000}, - {"partition-table", 0x600000, 0x02000}, - {"default-mac", 0x610000, 0x00020}, - {"pin", 0x610100, 0x00020}, - {"product-info", 0x611100, 0x01000}, - {"soft-version", 0x620000, 0x01000}, - {"support-list", 0x621000, 0x01000}, - {"profile", 0x622000, 0x08000}, - {"user-config", 0x630000, 0x10000}, - {"default-config", 0x640000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE450 */ - { - .id = "RE450", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n" - "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /** We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x5e0000}, - {"partition-table", 0x600000, 0x02000}, - {"default-mac", 0x610000, 0x00020}, - {"pin", 0x610100, 0x00020}, - {"product-info", 0x611100, 0x01000}, - {"soft-version", 0x620000, 0x01000}, - {"support-list", 0x621000, 0x01000}, - {"profile", 0x622000, 0x08000}, - {"user-config", 0x630000, 0x10000}, - {"default-config", 0x640000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE450 v2 */ - { - .id = "RE450-V2", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n" - "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0x5e0000}, - {"partition-table", 0x600000, 0x02000}, - {"default-mac", 0x610000, 0x00020}, - {"pin", 0x610100, 0x00020}, - {"product-info", 0x611100, 0x01000}, - {"soft-version", 0x620000, 0x01000}, - {"support-list", 0x621000, 0x01000}, - {"profile", 0x622000, 0x08000}, - {"user-config", 0x630000, 0x10000}, - {"default-config", 0x640000, 0x10000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE450 v3 */ - { - .id = "RE450-V3", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n" - "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"default-mac", 0x20000, 0x00020}, - {"pin", 0x20020, 0x00020}, - {"product-info", 0x21000, 0x01000}, - {"partition-table", 0x22000, 0x02000}, - {"soft-version", 0x24000, 0x01000}, - {"support-list", 0x25000, 0x01000}, - {"profile", 0x26000, 0x08000}, - {"user-config", 0x2e000, 0x10000}, - {"default-config", 0x3e000, 0x10000}, - {"config-info", 0x4e000, 0x00400}, - {"firmware", 0x50000, 0x7a0000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE455 v1 */ - { - .id = "RE455-V1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n" - "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"default-mac", 0x20000, 0x00020}, - {"pin", 0x20020, 0x00020}, - {"product-info", 0x21000, 0x01000}, - {"partition-table", 0x22000, 0x02000}, - {"soft-version", 0x24000, 0x01000}, - {"support-list", 0x25000, 0x01000}, - {"profile", 0x26000, 0x08000}, - {"user-config", 0x2e000, 0x10000}, - {"default-config", 0x3e000, 0x10000}, - {"config-info", 0x4e000, 0x00400}, - {"firmware", 0x50000, 0x7a0000}, - {"radio", 0x7f0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE500 */ - { - .id = "RE500-V1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n" - "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0xde0000}, - {"partition-table", 0xe00000, 0x02000}, - {"default-mac", 0xe10000, 0x00020}, - {"pin", 0xe10100, 0x00020}, - {"product-info", 0xe11100, 0x01000}, - {"soft-version", 0xe20000, 0x01000}, - {"support-list", 0xe21000, 0x01000}, - {"profile", 0xe22000, 0x08000}, - {"user-config", 0xe30000, 0x10000}, - {"default-config", 0xe40000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - /** Firmware layout for the RE650 */ - { - .id = "RE650-V1", - .vendor = "", - .support_list = - "SupportList:\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n" - "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n", - .part_trail = 0x00, - .soft_ver = SOFT_VER_DEFAULT, - - /* We're using a dynamic kernel/rootfs split here */ - .partitions = { - {"fs-uboot", 0x00000, 0x20000}, - {"firmware", 0x20000, 0xde0000}, - {"partition-table", 0xe00000, 0x02000}, - {"default-mac", 0xe10000, 0x00020}, - {"pin", 0xe10100, 0x00020}, - {"product-info", 0xe11100, 0x01000}, - {"soft-version", 0xe20000, 0x01000}, - {"support-list", 0xe21000, 0x01000}, - {"profile", 0xe22000, 0x08000}, - {"user-config", 0xe30000, 0x10000}, - {"default-config", 0xe40000, 0x10000}, - {"radio", 0xff0000, 0x10000}, - {NULL, 0, 0} - }, - - .first_sysupgrade_partition = "os-image", - .last_sysupgrade_partition = "file-system" - }, - - {} -}; - -#define error(_ret, _errno, _str, ...) \ - do { \ - fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \ - strerror(_errno)); \ - if (_ret) \ - exit(_ret); \ - } while (0) - - -/** Stores a uint32 as big endian */ -static inline void put32(uint8_t *buf, uint32_t val) { - buf[0] = val >> 24; - buf[1] = val >> 16; - buf[2] = val >> 8; - buf[3] = val; -} - -static inline bool meta_partition_should_pad(enum partition_trail_value pv) -{ - return (pv >= 0) && (pv <= PART_TRAIL_MAX); -} - -/** Allocate a padded meta partition with a correctly initialised header - * If the `data` pointer is NULL, then the required space is only allocated, - * otherwise `data_len` bytes will be copied from `data` into the partition - * entry. */ -static struct image_partition_entry init_meta_partition_entry( - const char *name, const void *data, uint32_t data_len, - enum partition_trail_value pad_value) -{ - uint32_t total_len = sizeof(struct meta_header) + data_len; - if (meta_partition_should_pad(pad_value)) - total_len += 1; - - struct image_partition_entry entry = { - .name = name, - .size = total_len, - .data = malloc(total_len) - }; - if (!entry.data) - error(1, errno, "failed to allocate meta partition entry"); - - struct meta_header *header = (struct meta_header *)entry.data; - header->length = htonl(data_len); - header->zero = 0; - - if (data) - memcpy(entry.data+sizeof(*header), data, data_len); - - if (meta_partition_should_pad(pad_value)) - entry.data[total_len - 1] = (uint8_t) pad_value; - - return entry; -} - -/** Allocates a new image partition */ -static struct image_partition_entry alloc_image_partition(const char *name, size_t len) { - struct image_partition_entry entry = {name, len, malloc(len)}; - if (!entry.data) - error(1, errno, "malloc"); - - return entry; -} - -/** Frees an image partition */ -static void free_image_partition(struct image_partition_entry entry) { - free(entry.data); -} - -static time_t source_date_epoch = -1; -static void set_source_date_epoch() { - char *env = getenv("SOURCE_DATE_EPOCH"); - char *endptr = env; - errno = 0; - if (env && *env) { - source_date_epoch = strtoull(env, &endptr, 10); - if (errno || (endptr && *endptr != '\0')) { - fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); - exit(1); - } - } -} - -/** Generates the partition-table partition */ -static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) { - struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800); - - char *s = (char *)entry.data, *end = (char *)(s+entry.size); - - *(s++) = 0x00; - *(s++) = 0x04; - *(s++) = 0x00; - *(s++) = 0x00; - - size_t i; - for (i = 0; p[i].name; i++) { - size_t len = end-s; - size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size); - - if (w > len-1) - error(1, 0, "flash partition table overflow?"); - - s += w; - } - - s++; - - memset(s, 0xff, end-s); - - return entry; -} - - -/** Generates a binary-coded decimal representation of an integer in the range [0, 99] */ -static inline uint8_t bcd(uint8_t v) { - return 0x10 * (v/10) + v%10; -} - - -/** Generates the soft-version partition */ -static struct image_partition_entry make_soft_version( - const struct device_info *info, uint32_t rev) -{ - /** If an info string is provided, use this instead of - * the structured data, and include the null-termination */ - if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) { - uint32_t len = strlen(info->soft_ver.text) + 1; - return init_meta_partition_entry("soft-version", - info->soft_ver.text, len, info->part_trail); - } - - time_t t; - - if (source_date_epoch != -1) - t = source_date_epoch; - else if (time(&t) == (time_t)(-1)) - error(1, errno, "time"); - - struct tm *tm = gmtime(&t); - - struct soft_version s = { - .pad1 = 0xff, - - .version_major = info->soft_ver.num[0], - .version_minor = info->soft_ver.num[1], - .version_patch = info->soft_ver.num[2], - - .year_hi = bcd((1900+tm->tm_year)/100), - .year_lo = bcd(tm->tm_year%100), - .month = bcd(tm->tm_mon+1), - .day = bcd(tm->tm_mday), - .rev = htonl(rev), - - .compat_level = htonl(info->soft_ver_compat_level) - }; - - if (info->soft_ver_compat_level == 0) - return init_meta_partition_entry("soft-version", &s, - (uint8_t *)(&s.compat_level) - (uint8_t *)(&s), - info->part_trail); - else - return init_meta_partition_entry("soft-version", &s, - sizeof(s), info->part_trail); -} - -/** Generates the support-list partition */ -static struct image_partition_entry make_support_list( - const struct device_info *info) -{ - uint32_t len = strlen(info->support_list); - return init_meta_partition_entry("support-list", info->support_list, - len, info->part_trail); -} - -/** Partition with extra-para data */ -static struct image_partition_entry make_extra_para( - const struct device_info *info, const uint8_t *extra_para, size_t len) -{ - return init_meta_partition_entry("extra-para", extra_para, len, - info->part_trail); -} - -/** Creates a new image partition with an arbitrary name from a file */ -static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof, struct flash_partition_entry *file_system_partition) { - struct stat statbuf; - - if (stat(filename, &statbuf) < 0) - error(1, errno, "unable to stat file `%s'", filename); - - size_t len = statbuf.st_size; - - if (add_jffs2_eof) { - if (file_system_partition) - len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base; - else - len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark); - } - - struct image_partition_entry entry = alloc_image_partition(part_name, len); - - FILE *file = fopen(filename, "rb"); - if (!file) - error(1, errno, "unable to open file `%s'", filename); - - if (fread(entry.data, statbuf.st_size, 1, file) != 1) - error(1, errno, "unable to read file `%s'", filename); - - if (add_jffs2_eof) { - uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size; - - memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark)); - memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark)); - } - - fclose(file); - - return entry; -} - -/** - Copies a list of image partitions into an image buffer and generates the image partition table while doing so - - Example image partition table: - - fwup-ptn partition-table base 0x00800 size 0x00800 - fwup-ptn os-image base 0x01000 size 0x113b45 - fwup-ptn file-system base 0x114b45 size 0x1d0004 - fwup-ptn support-list base 0x2e4b49 size 0x000d1 - - Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"), - the end of the partition table is marked with a zero byte. - - The firmware image must contain at least the partition-table and support-list partitions - to be accepted. There aren't any alignment constraints for the image partitions. - - The partition-table partition contains the actual flash layout; partitions - from the image partition table are mapped to the corresponding flash partitions during - the firmware upgrade. The support-list partition contains a list of devices supported by - the firmware image. - - The base offsets in the firmware partition table are relative to the end - of the vendor information block, so the partition-table partition will - actually start at offset 0x1814 of the image. - - I think partition-table must be the first partition in the firmware image. -*/ -static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) { - size_t i, j; - char *image_pt = (char *)buffer, *end = image_pt + 0x800; - - size_t base = 0x800; - for (i = 0; parts[i].name; i++) { - for (j = 0; flash_parts[j].name; j++) { - if (!strcmp(flash_parts[j].name, parts[i].name)) { - if (parts[i].size > flash_parts[j].size) - error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size); - break; - } - } - - assert(flash_parts[j].name); - - memcpy(buffer + base, parts[i].data, parts[i].size); - - size_t len = end-image_pt; - size_t w = snprintf(image_pt, len, "fwup-ptn %s base 0x%05x size 0x%05x\t\r\n", parts[i].name, (unsigned)base, (unsigned)parts[i].size); - - if (w > len-1) - error(1, 0, "image partition table overflow?"); - - image_pt += w; - - base += parts[i].size; - } -} - -/** Generates and writes the image MD5 checksum */ -static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) { - MD5_CTX ctx; - - MD5_Init(&ctx); - MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt)); - MD5_Update(&ctx, buffer, len); - MD5_Final(md5, &ctx); -} - - -/** - Generates the firmware image in factory format - - Image format: - - Bytes (hex) Usage - ----------- ----- - 0000-0003 Image size (4 bytes, big endian) - 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14) - 0014-0017 Vendor information length (without padding) (4 bytes, big endian) - 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older - (VxWorks-based) TP-LINK devices which use a smaller vendor information block) - 1014-1813 Image partition table (2048 bytes, padded with 0xff) - 1814-xxxx Firmware partitions -*/ -static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) { - *len = 0x1814; - - size_t i; - for (i = 0; parts[i].name; i++) - *len += parts[i].size; - - uint8_t *image = malloc(*len); - if (!image) - error(1, errno, "malloc"); - - memset(image, 0xff, *len); - put32(image, *len); - - if (info->vendor) { - size_t vendor_len = strlen(info->vendor); - put32(image+0x14, vendor_len); - memcpy(image+0x18, info->vendor, vendor_len); - } - - put_partitions(image + 0x1014, info->partitions, parts); - put_md5(image+0x04, image+0x14, *len-0x14); - - return image; -} - -/** - Generates the firmware image in sysupgrade format - - This makes some assumptions about the provided flash and image partition tables and - should be generalized when TP-LINK starts building its safeloader into hardware with - different flash layouts. -*/ -static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) { - size_t i, j; - size_t flash_first_partition_index = 0; - size_t flash_last_partition_index = 0; - const struct flash_partition_entry *flash_first_partition = NULL; - const struct flash_partition_entry *flash_last_partition = NULL; - const struct image_partition_entry *image_last_partition = NULL; - - /** Find first and last partitions */ - for (i = 0; info->partitions[i].name; i++) { - if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) { - flash_first_partition = &info->partitions[i]; - flash_first_partition_index = i; - } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) { - flash_last_partition = &info->partitions[i]; - flash_last_partition_index = i; - } - } - - assert(flash_first_partition && flash_last_partition); - assert(flash_first_partition_index < flash_last_partition_index); - - /** Find last partition from image to calculate needed size */ - for (i = 0; image_parts[i].name; i++) { - if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) { - image_last_partition = &image_parts[i]; - break; - } - } - - assert(image_last_partition); - - *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size; - - uint8_t *image = malloc(*len); - if (!image) - error(1, errno, "malloc"); - - memset(image, 0xff, *len); - - for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) { - for (j = 0; image_parts[j].name; j++) { - if (!strcmp(info->partitions[i].name, image_parts[j].name)) { - if (image_parts[j].size > info->partitions[i].size) - error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size); - memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size); - break; - } - - assert(image_parts[j].name); - } - } - - return image; -} - -/** Generates an image according to a given layout and writes it to a file */ -static void build_image(const char *output, - const char *kernel_image, - const char *rootfs_image, - uint32_t rev, - bool add_jffs2_eof, - bool sysupgrade, - struct device_info *info) { - - size_t i; - - struct image_partition_entry parts[7] = {}; - - struct flash_partition_entry *firmware_partition = NULL; - struct flash_partition_entry *os_image_partition = NULL; - struct flash_partition_entry *file_system_partition = NULL; - size_t firmware_partition_index = 0; - - for (i = 0; info->partitions[i].name; i++) { - if (!strcmp(info->partitions[i].name, "firmware")) - { - firmware_partition = &info->partitions[i]; - firmware_partition_index = i; - } - } - - if (firmware_partition) - { - os_image_partition = &info->partitions[firmware_partition_index]; - file_system_partition = &info->partitions[firmware_partition_index + 1]; - - struct stat kernel; - if (stat(kernel_image, &kernel) < 0) - error(1, errno, "unable to stat file `%s'", kernel_image); - - if (kernel.st_size > firmware_partition->size) - error(1, 0, "kernel overflowed firmware partition\n"); - - for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--) - info->partitions[i+1] = info->partitions[i]; - - file_system_partition->name = "file-system"; - file_system_partition->base = firmware_partition->base + kernel.st_size; - - /* Align partition start to erase blocks for factory images only */ - if (!sysupgrade) - file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000); - - file_system_partition->size = firmware_partition->size - file_system_partition->base; - - os_image_partition->name = "os-image"; - os_image_partition->size = kernel.st_size; - } - - parts[0] = make_partition_table(info->partitions); - parts[1] = make_soft_version(info, rev); - parts[2] = make_support_list(info); - parts[3] = read_file("os-image", kernel_image, false, NULL); - parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof, file_system_partition); - - /* Some devices need the extra-para partition to accept the firmware */ - if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 || - strcasecmp(info->id, "ARCHER-A7-V5") == 0 || - strcasecmp(info->id, "ARCHER-C2-V3") == 0 || - strcasecmp(info->id, "ARCHER-C7-V4") == 0 || - strcasecmp(info->id, "ARCHER-C7-V5") == 0 || - strcasecmp(info->id, "ARCHER-C25-V1") == 0 || - strcasecmp(info->id, "ARCHER-C59-V2") == 0 || - strcasecmp(info->id, "ARCHER-C60-V2") == 0 || - strcasecmp(info->id, "ARCHER-C60-V3") == 0 || - strcasecmp(info->id, "ARCHER-C6U-V1") == 0 || - strcasecmp(info->id, "ARCHER-C6-V3") == 0 || - strcasecmp(info->id, "TLWR1043NV5") == 0) { - const uint8_t extra_para[2] = {0x01, 0x00}; - parts[5] = make_extra_para(info, extra_para, - sizeof(extra_para)); - } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 || - strcasecmp(info->id, "TL-WA1201-V2") == 0) { - const uint8_t extra_para[2] = {0x00, 0x01}; - parts[5] = make_extra_para(info, extra_para, - sizeof(extra_para)); - } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 || - strcasecmp(info->id, "EAP245-V3") == 0) { - const uint8_t extra_para[2] = {0x01, 0x01}; - parts[5] = make_extra_para(info, extra_para, - sizeof(extra_para)); - } - - size_t len; - void *image; - if (sysupgrade) - image = generate_sysupgrade_image(info, parts, &len); - else - image = generate_factory_image(info, parts, &len); - - FILE *file = fopen(output, "wb"); - if (!file) - error(1, errno, "unable to open output file"); - - if (fwrite(image, len, 1, file) != 1) - error(1, 0, "unable to write output file"); - - fclose(file); - - free(image); - - for (i = 0; parts[i].name; i++) - free_image_partition(parts[i]); -} - -/** Usage output */ -static void usage(const char *argv0) { - fprintf(stderr, - "Usage: %s [OPTIONS...]\n" - "\n" - "Options:\n" - " -h show this help\n" - "\n" - "Info about an image:\n" - " -i <file> input file to read from\n" - "Create a new image:\n" - " -B <board> create image for the board specified with <board>\n" - " -k <file> read kernel image from the file <file>\n" - " -r <file> read rootfs image from the file <file>\n" - " -o <file> write output to the file <file>\n" - " -V <rev> sets the revision number to <rev>\n" - " -j add jffs2 end-of-filesystem markers\n" - " -S create sysupgrade instead of factory image\n" - "Extract an old image:\n" - " -x <file> extract all oem firmware partition\n" - " -d <dir> destination to extract the firmware partition\n" - " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n", - argv0 - ); -}; - - -static struct device_info *find_board(const char *id) -{ - struct device_info *board = NULL; - - for (board = boards; board->id != NULL; board++) - if (strcasecmp(id, board->id) == 0) - return board; - - return NULL; -} - -static int add_flash_partition( - struct flash_partition_entry *part_list, - size_t max_entries, - const char *name, - unsigned long base, - unsigned long size) -{ - size_t ptr; - /* check if the list has a free entry */ - for (ptr = 0; ptr < max_entries; ptr++, part_list++) { - if (part_list->name == NULL && - part_list->base == 0 && - part_list->size == 0) - break; - } - - if (ptr == max_entries) { - error(1, 0, "No free flash part entry available."); - } - - part_list->name = calloc(1, strlen(name) + 1); - if (!part_list->name) { - error(1, 0, "Unable to allocate memory"); - } - - memcpy((char *)part_list->name, name, strlen(name)); - part_list->base = base; - part_list->size = size; - - return 0; -} - -/** read the partition table into struct flash_partition_entry */ -static int read_partition_table( - FILE *file, long offset, - struct flash_partition_entry *entries, size_t max_entries, - int type) -{ - char buf[2048]; - char *ptr, *end; - const char *parthdr = NULL; - const char *fwuphdr = "fwup-ptn"; - const char *flashhdr = "partition"; - - /* TODO: search for the partition table */ - - switch(type) { - case 0: - parthdr = fwuphdr; - break; - case 1: - parthdr = flashhdr; - break; - default: - error(1, 0, "Invalid partition table"); - } - - if (fseek(file, offset, SEEK_SET) < 0) - error(1, errno, "Can not seek in the firmware"); - - if (fread(buf, 2048, 1, file) != 1) - error(1, errno, "Can not read fwup-ptn from the firmware"); - - buf[2047] = '\0'; - - /* look for the partition header */ - if (memcmp(buf, parthdr, strlen(parthdr)) != 0) { - fprintf(stderr, "DEBUG: can not find fwuphdr\n"); - return 1; - } - - ptr = buf; - end = buf + sizeof(buf); - while ((ptr + strlen(parthdr)) < end && - memcmp(ptr, parthdr, strlen(parthdr)) == 0) { - char *end_part; - char *end_element; - - char name[32] = { 0 }; - int name_len = 0; - unsigned long base = 0; - unsigned long size = 0; - - end_part = memchr(ptr, '\n', (end - ptr)); - if (end_part == NULL) { - /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */ - break; - } - - for (int i = 0; i <= 4; i++) { - if (end_part <= ptr) - break; - - end_element = memchr(ptr, 0x20, (end_part - ptr)); - if (end_element == NULL) { - error(1, errno, "Ignoring the rest of the partition entries."); - break; - } - - switch (i) { - /* partition header */ - case 0: - ptr = end_element + 1; - continue; - /* name */ - case 1: - name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr); - strncpy(name, ptr, name_len); - name[name_len] = '\0'; - ptr = end_element + 1; - continue; - - /* string "base" */ - case 2: - ptr = end_element + 1; - continue; - - /* actual base */ - case 3: - base = strtoul(ptr, NULL, 16); - ptr = end_element + 1; - continue; - - /* string "size" */ - case 4: - ptr = end_element + 1; - /* actual size. The last element doesn't have a sepeartor */ - size = strtoul(ptr, NULL, 16); - /* the part ends with 0x09, 0x0d, 0x0a */ - ptr = end_part + 1; - add_flash_partition(entries, max_entries, name, base, size); - continue; - } - } - } - - return 0; -} - -static void write_partition( - FILE *input_file, - size_t firmware_offset, - struct flash_partition_entry *entry, - FILE *output_file) -{ - char buf[4096]; - size_t offset; - - fseek(input_file, entry->base + firmware_offset, SEEK_SET); - - for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) { - if (fread(buf, sizeof(buf), 1, input_file) != 1) - error(1, errno, "Can not read partition from input_file"); - - if (fwrite(buf, sizeof(buf), 1, output_file) != 1) - error(1, errno, "Can not write partition to output_file"); - } - /* write last chunk smaller than buffer */ - if (offset < entry->size) { - offset = entry->size - offset; - if (fread(buf, offset, 1, input_file) != 1) - error(1, errno, "Can not read partition from input_file"); - if (fwrite(buf, offset, 1, output_file) != 1) - error(1, errno, "Can not write partition to output_file"); - } -} - -static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory) -{ - FILE *output_file; - char output[PATH_MAX]; - - snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name); - output_file = fopen(output, "wb+"); - if (output_file == NULL) { - error(1, errno, "Can not open output file %s", output); - } - - write_partition(input_file, firmware_offset, entry, output_file); - - fclose(output_file); - - return 0; -} - -/** extract all partitions from the firmware file */ -static int extract_firmware(const char *input, const char *output_directory) -{ - struct flash_partition_entry entries[16] = { 0 }; - size_t max_entries = 16; - size_t firmware_offset = 0x1014; - FILE *input_file; - - struct stat statbuf; - - /* check input file */ - if (stat(input, &statbuf)) { - error(1, errno, "Can not read input firmware %s", input); - } - - /* check if output directory exists */ - if (stat(output_directory, &statbuf)) { - error(1, errno, "Failed to stat output directory %s", output_directory); - } - - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { - error(1, errno, "Given output directory is not a directory %s", output_directory); - } - - input_file = fopen(input, "rb"); - - if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) { - error(1, 0, "Error can not read the partition table (fwup-ptn)"); - } - - for (size_t i = 0; i < max_entries; i++) { - if (entries[i].name == NULL && - entries[i].base == 0 && - entries[i].size == 0) - continue; - - extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory); - } - - return 0; -} - -static struct flash_partition_entry *find_partition( - struct flash_partition_entry *entries, size_t max_entries, - const char *name, const char *error_msg) -{ - for (size_t i = 0; i < max_entries; i++, entries++) { - if (strcmp(entries->name, name) == 0) - return entries; - } - - if (error_msg) { - error(1, 0, "%s", error_msg); - } - - return NULL; -} - -static int firmware_info(const char *input) -{ - struct flash_partition_entry pointers[MAX_PARTITIONS] = { }; - struct flash_partition_entry *e; - FILE *fp; - int i; - - fp = fopen(input, "r"); - - if (read_partition_table(fp, 0x1014, pointers, MAX_PARTITIONS, 0)) { - error(1, 0, "Error can not read the partition table (fwup-ptn)"); - } - - printf("Firmware image partitions:\n"); - printf("%-8s %-8s %s\n", "base", "size", "name"); - for (i = 0; i < MAX_PARTITIONS; i++) { - e = &pointers[i]; - - if (!e->name && !e->base && !e->size) - continue; - - printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : ""); - } - - e = find_partition(pointers, MAX_PARTITIONS, "soft-version", NULL); - if (e) { - size_t data_len = e->size - sizeof(struct meta_header); - char *buf = malloc(data_len); - struct soft_version *s; - bool isstr; - int i; - - if (!buf) - error(1, errno, "Failed to alloc buffer"); - - if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET)) - error(1, errno, "Can not seek in the firmware"); - - if (fread(buf, data_len, 1, fp) != 1) - error(1, errno, "Can not read fwup-ptn data from the firmware"); - - /* Check for string ignoring padding character */ - isstr = true; - for (i = 0; i < data_len - 1; i++) { - if (!isascii(buf[i])) { - isstr = false; - break; - } - } - - printf("\n[Software version]\n"); - if (isstr) { - fwrite(buf, data_len, 1, stdout); - putchar('\n'); - } else if (data_len >= offsetof(struct soft_version, rev)) { - s = (struct soft_version *)buf; - - printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch); - printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day); - printf("Revision: %d\n", ntohl(s->rev)); - } else { - printf("Failed to parse data\n"); - } - - free(buf); - } - - e = find_partition(pointers, MAX_PARTITIONS, "support-list", NULL); - if (e) { - char buf[128]; - size_t length; - size_t bytes; - - if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET)) - error(1, errno, "Can not seek in the firmware"); - - printf("\n[Support list]\n"); - for (length = e->size - sizeof(struct meta_header); length; length -= bytes) { - bytes = fread(buf, 1, length > sizeof(buf) ? sizeof(buf) : length, fp); - if (bytes <= 0) - error(1, errno, "Can not read fwup-ptn data from the firmware"); - - puts(buf); - } - } - - e = find_partition(pointers, MAX_PARTITIONS, "partition-table", NULL); - if (e) { - struct flash_partition_entry parts[MAX_PARTITIONS] = { }; - - if (read_partition_table(fp, 0x1014 + e->base + 4, parts, MAX_PARTITIONS, 1)) { - error(1, 0, "Error can not read the partition table (partition)"); - } - - printf("\n[Partition table]\n"); - printf("%-8s %-8s %s\n", "base", "size", "name"); - for (i = 0; i < MAX_PARTITIONS; i++) { - e = &parts[i]; - - if (!e->name && !e->base && !e->size) - continue; - - printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : ""); - } - } - - fclose(fp); - - return 0; -} - -static void write_ff(FILE *output_file, size_t size) -{ - char buf[4096]; - size_t offset; - - memset(buf, 0xff, sizeof(buf)); - - for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) { - if (fwrite(buf, sizeof(buf), 1, output_file) != 1) - error(1, errno, "Can not write 0xff to output_file"); - } - - /* write last chunk smaller than buffer */ - if (offset < size) { - offset = size - offset; - if (fwrite(buf, offset, 1, output_file) != 1) - error(1, errno, "Can not write partition to output_file"); - } -} - -static void convert_firmware(const char *input, const char *output) -{ - struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 }; - struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 }; - struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL; - struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL; - struct flash_partition_entry *fwup_partition_table = NULL; - size_t firmware_offset = 0x1014; - FILE *input_file, *output_file; - - struct stat statbuf; - - /* check input file */ - if (stat(input, &statbuf)) { - error(1, errno, "Can not read input firmware %s", input); - } - - input_file = fopen(input, "rb"); - if (!input_file) - error(1, 0, "Can not open input firmware %s", input); - - output_file = fopen(output, "wb"); - if (!output_file) - error(1, 0, "Can not open output firmware %s", output); - - if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) { - error(1, 0, "Error can not read the partition table (fwup-ptn)"); - } - - fwup_os_image = find_partition(fwup, MAX_PARTITIONS, - "os-image", "Error can not find os-image partition (fwup)"); - fwup_file_system = find_partition(fwup, MAX_PARTITIONS, - "file-system", "Error can not find file-system partition (fwup)"); - fwup_partition_table = find_partition(fwup, MAX_PARTITIONS, - "partition-table", "Error can not find partition-table partition"); - - /* the flash partition table has a 0x00000004 magic haeder */ - if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0) - error(1, 0, "Error can not read the partition table (flash)"); - - flash_os_image = find_partition(flash, MAX_PARTITIONS, - "os-image", "Error can not find os-image partition (flash)"); - flash_file_system = find_partition(flash, MAX_PARTITIONS, - "file-system", "Error can not find file-system partition (flash)"); - - /* write os_image to 0x0 */ - write_partition(input_file, firmware_offset, fwup_os_image, output_file); - write_ff(output_file, flash_os_image->size - fwup_os_image->size); - - /* write file-system behind os_image */ - fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET); - write_partition(input_file, firmware_offset, fwup_file_system, output_file); - write_ff(output_file, flash_file_system->size - fwup_file_system->size); - - fclose(output_file); - fclose(input_file); -} - -int main(int argc, char *argv[]) { - const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL; - const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL; - bool add_jffs2_eof = false, sysupgrade = false; - unsigned rev = 0; - struct device_info *info; - set_source_date_epoch(); - - while (true) { - int c; - - c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:"); - if (c == -1) - break; - - switch (c) { - case 'i': - info_image = optarg; - break; - - case 'B': - board = optarg; - break; - - case 'k': - kernel_image = optarg; - break; - - case 'r': - rootfs_image = optarg; - break; - - case 'o': - output = optarg; - break; - - case 'V': - sscanf(optarg, "r%u", &rev); - break; - - case 'j': - add_jffs2_eof = true; - break; - - case 'S': - sysupgrade = true; - break; - - case 'h': - usage(argv[0]); - return 0; - - case 'd': - output_directory = optarg; - break; - - case 'x': - extract_image = optarg; - break; - - case 'z': - convert_image = optarg; - break; - - default: - usage(argv[0]); - return 1; - } - } - - if (info_image) { - firmware_info(info_image); - } else if (extract_image || output_directory) { - if (!extract_image) - error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x"); - if (!output_directory) - error(1, 0, "Can not extract an image without output directory. Use -d <dir>"); - extract_firmware(extract_image, output_directory); - } else if (convert_image) { - if (!output) - error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>"); - convert_firmware(convert_image, output); - } else { - if (!board) - error(1, 0, "no board has been specified"); - if (!kernel_image) - error(1, 0, "no kernel image has been specified"); - if (!rootfs_image) - error(1, 0, "no rootfs image has been specified"); - if (!output) - error(1, 0, "no output filename has been specified"); - - info = find_board(board); - - if (info == NULL) - error(1, 0, "unsupported board %s", board); - - build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info); - } - - return 0; -} diff --git a/tools/firmware-utils/src/trx.c b/tools/firmware-utils/src/trx.c deleted file mode 100644 index e09d671f02..0000000000 --- a/tools/firmware-utils/src/trx.c +++ /dev/null @@ -1,414 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org> - */ - -/* July 29, 2004 - * - * This is a hacked replacement for the 'trx' utility used to create - * wrt54g .trx firmware files. It isn't pretty, but it does the job - * for me. - * - * As an extension, you can specify a larger maximum length for the - * .trx file using '-m'. It will be rounded up to be a multiple of 4K. - * NOTE: This space will be malloc()'d. - * - * August 16, 2004 - * - * Sigh... Make it endian-neutral. - * - * TODO: Support '-b' option to specify offsets for each file. - * - * February 19, 2005 - mbm - * - * Add -a (align offset) and -b (absolute offset) - * - * March 24, 2010 - markus - * - * extend trx header struct for new version - * assume v1 for as default - * Add option -2 to allow v2 header - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> - -#if __BYTE_ORDER == __BIG_ENDIAN -#define STORE32_LE(X) bswap_32(X) -#define LOAD32_LE(X) bswap_32(X) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define STORE32_LE(X) (X) -#define LOAD32_LE(X) (X) -#else -#error unkown endianness! -#endif - -uint32_t crc32buf(char *buf, size_t len); - -/**********************************************************************/ -/* from trxhdr.h */ - -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_MAX_LEN 0x720000 -#define TRX_NO_HEADER 1 /* Do not write TRX header */ - -struct trx_header { - uint32_t magic; /* "HDR0" */ - uint32_t len; /* Length of file including header */ - uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ - uint32_t flag_version; /* 0:15 flags, 16:31 version */ - uint32_t offsets[4]; /* Offsets of partitions from start of header */ -}; - -/**********************************************************************/ - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " trx [-2] [-o outfile] [-m maxlen] [-a align] [-b absolute offset] [-x relative offset]\n"); - fprintf(stderr, " [-f file] [-f file [-f file [-f file (v2 only)]]]\n"); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) -{ - FILE *out = stdout; - FILE *in; - char *ofn = NULL; - char *buf; - char *e; - int c, i, append = 0; - size_t n; - ssize_t n2; - uint32_t cur_len, fsmark=0, magic; - unsigned long maxlen = TRX_MAX_LEN; - struct trx_header *p; - char trx_version = 1; - unsigned char binheader[32]; - - fprintf(stderr, "mjn3's trx replacement - v0.81.1\n"); - - if (!(buf = malloc(maxlen))) { - fprintf(stderr, "malloc failed\n"); - return EXIT_FAILURE; - } - - p = (struct trx_header *) buf; - - p->magic = STORE32_LE(TRX_MAGIC); - cur_len = sizeof(struct trx_header) - 4; /* assume v1 header */ - - in = NULL; - i = 0; - - while ((c = getopt(argc, argv, "-:2o:m:a:x:b:f:A:F:M:")) != -1) { - switch (c) { - case '2': - /* take care that nothing was written to buf so far */ - if (cur_len != sizeof(struct trx_header) - 4) { - fprintf(stderr, "-2 has to be used before any other argument!\n"); - } - else { - trx_version = 2; - cur_len += 4; - } - break; - case 'F': - fsmark = cur_len; - case 'A': - append = 1; - /* fall through */ - case 'f': - case 1: - if (!append) - p->offsets[i++] = STORE32_LE(cur_len); - - if (!(in = fopen(optarg, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", optarg); - usage(); - } - n = fread(buf + cur_len, 1, maxlen - cur_len, in); - if (!feof(in)) { - fprintf(stderr, "fread failure or file \"%s\" too large\n",optarg); - fclose(in); - return EXIT_FAILURE; - } - fclose(in); -#undef ROUND -#define ROUND 4 - if (n & (ROUND-1)) { - memset(buf + cur_len + n, 0, ROUND - (n & (ROUND-1))); - n += ROUND - (n & (ROUND-1)); - } - cur_len += n; - append = 0; - - break; - case 'o': - ofn = optarg; - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - break; - case 'm': - errno = 0; - maxlen = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } -#undef ROUND -#define ROUND 0x1000 - if (maxlen & (ROUND-1)) { - maxlen += (ROUND - (maxlen & (ROUND-1))); - } - if (maxlen < ROUND) { - fprintf(stderr, "maxlen too small (or wrapped)\n"); - usage(); - } - if (maxlen > TRX_MAX_LEN) { - fprintf(stderr, "WARNING: maxlen exceeds default maximum! Beware of overwriting nvram!\n"); - } - if (!(buf = realloc(buf,maxlen))) { - fprintf(stderr, "realloc failed"); - return EXIT_FAILURE; - } - p = (struct trx_header *) buf; - break; - case 'a': - errno = 0; - n = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } - if (cur_len & (n-1)) { - n = n - (cur_len & (n-1)); - memset(buf + cur_len, 0, n); - cur_len += n; - } - break; - case 'b': - errno = 0; - n = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } - if (n < cur_len) { - fprintf(stderr, "WARNING: current length exceeds -b %d offset\n",(int) n); - } else { - memset(buf + cur_len, 0, n - cur_len); - cur_len = n; - } - break; - case 'x': - errno = 0; - n2 = strtol(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } - if (n2 < 0) { - if (-n2 > cur_len) { - fprintf(stderr, "WARNING: current length smaller then -x %d offset\n",(int) n2); - cur_len = 0; - } else - cur_len += n2; - } else { - memset(buf + cur_len, 0, n2); - cur_len += n2; - } - - break; - case 'M': - errno = 0; - magic = strtoul(optarg, &e, 0); - if (errno || (e == optarg) || *e) { - fprintf(stderr, "illegal numeric string\n"); - usage(); - } - p->magic = STORE32_LE(magic); - break; - default: - usage(); - } - } - p->flag_version = STORE32_LE((trx_version << 16)); - - if (!in) { - fprintf(stderr, "we require atleast one filename\n"); - usage(); - } - -#undef ROUND -#define ROUND 0x1000 - n = cur_len & (ROUND-1); - if (n) { - memset(buf + cur_len, 0, ROUND - n); - cur_len += ROUND - n; - } - - /* for TRXv2 set bin-header Flags to 0xFF for CRC calculation like CFE does */ - if (trx_version == 2) { - if(cur_len - LOAD32_LE(p->offsets[3]) < sizeof(binheader)) { - fprintf(stderr, "TRXv2 binheader too small!\n"); - return EXIT_FAILURE; - } - memcpy(binheader, buf + LOAD32_LE(p->offsets[3]), sizeof(binheader)); /* save header */ - memset(buf + LOAD32_LE(p->offsets[3]) + 22, 0xFF, 8); /* set stable and try1-3 to 0xFF */ - } - - p->crc32 = crc32buf((char *) &p->flag_version, - ((fsmark)?fsmark:cur_len) - offsetof(struct trx_header, flag_version)); - p->crc32 = STORE32_LE(p->crc32); - - p->len = STORE32_LE((fsmark) ? fsmark : cur_len); - - /* restore TRXv2 bin-header */ - if (trx_version == 2) { - memcpy(buf + LOAD32_LE(p->offsets[3]), binheader, sizeof(binheader)); - } - - if (!fwrite(buf, cur_len, 1, out) || fflush(out)) { - fprintf(stderr, "fwrite failed\n"); - return EXIT_FAILURE; - } - - fclose(out); - - return EXIT_SUCCESS; -} - -/**********************************************************************/ -/* The following was grabbed and tweaked from the old snippets collection - * of public domain C code. */ - -/**********************************************************************\ -|* Demonstration program to compute the 32-bit CRC used as the frame *| -|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| -|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| -|* protocol). The 32-bit FCS was added via the Federal Register, *| -|* 1 June 1982, p.23798. I presume but don't know for certain that *| -|* this polynomial is or will be included in CCITT V.41, which *| -|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| -|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| -|* errors by a factor of 10^-5 over 16-bit FCS. *| -\**********************************************************************/ - -/* Copyright (C) 1986 Gary S. Brown. You may use this program, or - code or tables extracted from it, as desired without restriction.*/ - -/* First, the polynomial itself and its table of feedback terms. The */ -/* polynomial is */ -/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ -/* Note that we take it "backwards" and put the highest-order term in */ -/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ -/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ -/* the MSB being 1. */ - -/* Note that the usual hardware shift register implementation, which */ -/* is what we're using (we're merely optimizing it by doing eight-bit */ -/* chunks at a time) shifts bits into the lowest-order term. In our */ -/* implementation, that means shifting towards the right. Why do we */ -/* do it this way? Because the calculated CRC must be transmitted in */ -/* order from highest-order term to lowest-order term. UARTs transmit */ -/* characters in order from LSB to MSB. By storing the CRC this way, */ -/* we hand it to the UART in the order low-byte to high-byte; the UART */ -/* sends each low-bit to hight-bit; and the result is transmission bit */ -/* by bit from highest- to lowest-order term without requiring any bit */ -/* shuffling on our part. Reception works similarly. */ - -/* The feedback terms table consists of 256, 32-bit entries. Notes: */ -/* */ -/* 1. The table can be generated at runtime if desired; code to do so */ -/* is shown later. It might not be obvious, but the feedback */ -/* terms simply represent the results of eight shift/xor opera- */ -/* tions for all combinations of data and CRC register values. */ -/* */ -/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ -/* be they sixteen or thirty-two bits wide. You simply choose the */ -/* appropriate table. Alternatively, because the table can be */ -/* generated at runtime, you can start by generating the table for */ -/* the polynomial in question and use exactly the same "updcrc", */ -/* if your application needn't simultaneously handle two CRC */ -/* polynomials. (Note, however, that XMODEM is strange.) */ -/* */ -/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ -/* of course, 32-bit entries work OK if the high 16 bits are zero. */ -/* */ -/* 4. The values must be right-shifted by eight bits by the "updcrc" */ -/* logic; the shift must be unsigned (bring in zeroes). On some */ -/* hardware you could probably optimize the shift in assembler by */ -/* using byte-swap instructions. */ - -static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ -0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, -0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, -0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, -0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, -0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, -0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, -0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, -0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, -0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, -0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, -0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, -0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, -0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, -0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, -0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, -0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, -0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, -0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, -0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, -0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, -0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, -0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, -0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, -0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, -0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, -0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, -0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, -0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, -0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, -0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, -0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, -0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, -0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, -0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, -0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) - -uint32_t crc32buf(char *buf, size_t len) -{ - uint32_t crc; - - crc = 0xFFFFFFFF; - - for ( ; len; --len, ++buf) - { - crc = UPDC32(*buf, crc); - } - - return crc; -} diff --git a/tools/firmware-utils/src/trx2edips.c b/tools/firmware-utils/src/trx2edips.c deleted file mode 100644 index e8ac14d830..0000000000 --- a/tools/firmware-utils/src/trx2edips.c +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> - -#if __BYTE_ORDER == __BIG_ENDIAN -#define STORE32_LE(X) bswap_32(X) -#define LOAD32_LE(X) bswap_32(X) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define STORE32_LE(X) (X) -#define LOAD32_LE(X) (X) -#else -#error unkown endianness! -#endif - -/**********************************************************************/ -/* from trxhdr.h */ - -#define TRX_MAGIC 0x30524448 /* "HDR0" */ -#define TRX_VERSION 1 -#define TRX_MAX_LEN 0x5A0000 -#define TRX_NO_HEADER 1 /* Do not write TRX header */ - -struct trx_header { - uint32_t magic; /* "HDR0" */ - uint32_t len; /* Length of file including header */ - uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ - uint32_t flag_version; /* 0:15 flags, 16:31 version */ - uint32_t offsets[3]; /* Offsets of partitions from start of header */ -}; - - -struct edimax_header { - uint32_t sign; /* signature for header */ - uint32_t length; /* start address but doesn't seems to be used... */ - uint32_t start_addr; /* length of data, not used too ...*/ -}; - - -#define EDIMAX_PS16 0x36315350 /* "PS16" */ -#define EDIMAX_HDR_LEN 0xc - - -/**********************************************************************/ -static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ -0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, -0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, -0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, -0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, -0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, -0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, -0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, -0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, -0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, -0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, -0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, -0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, -0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, -0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, -0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, -0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, -0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, -0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, -0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, -0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, -0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, -0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, -0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, -0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, -0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, -0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, -0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, -0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, -0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, -0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, -0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, -0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, -0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, -0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, -0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, -0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, -0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, -0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, -0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, -0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, -0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, -0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, -0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) - -uint32_t crc32buf(char *buf, size_t len) -{ - uint32_t crc; - - crc = 0xFFFFFFFF; - - for (; len; --len, ++buf) - crc = UPDC32(*buf, crc); - - return crc; -} - - -int main(int argc, char *argv[]) -{ - FILE *fpIn = NULL; - FILE *fpOut = NULL; - struct edimax_header eh; - size_t res; - int length; - - char *buf; - struct trx_header *p; - - if (argc != 3) { - printf("Usage: %s <input file> <output file>\n", argv[0]); - return -1; - } - - fpIn = fopen(argv[1], "rb"); - if (fpIn == NULL) { - fprintf(stderr, "Unable to open %s\n", argv[1]); - return EXIT_FAILURE; - } - /* compute the length of the file */ - fseek(fpIn, 0, SEEK_END); - length = ftell(fpIn); - /* alloc enough memory to store the file */ - buf = (char *)malloc(length); - if (!buf) { - fprintf(stderr, "malloc of buffers failed\n"); - return EXIT_FAILURE; - } - - rewind(fpIn); - /* read the whole file*/ - res = fread(buf, 1, length, fpIn); - if (res != length) { - fprintf(stderr, "Unable to fread from input file\n"); - return EXIT_FAILURE; - } - - p = (struct trx_header *)buf; - if (LOAD32_LE(p->magic) != TRX_MAGIC) { - fprintf(stderr, "Not a trx file...%x\n", LOAD32_LE(p->magic)); - return EXIT_FAILURE; - } - - fclose(fpIn); - - fpOut = fopen(argv[2], "wb+"); - if (fpOut == NULL) { - fprintf(stderr, "Unable to open %s\n", argv[2]); - return EXIT_FAILURE; - } - /* make the 3 partition beeing 12 bytes closer from the header */ - memcpy(buf + LOAD32_LE(p->offsets[2]) - EDIMAX_HDR_LEN, buf + LOAD32_LE(p->offsets[2]), length - LOAD32_LE(p->offsets[2])); - /* recompute the crc32 check */ - p->crc32 = STORE32_LE(crc32buf((char *) &p->flag_version, length - offsetof(struct trx_header, flag_version))); - - eh.sign = STORE32_LE(EDIMAX_PS16); - eh.length = STORE32_LE(length); - eh.start_addr = STORE32_LE(0x80500000); - - /* write the modified file */ - fwrite(&eh, sizeof(struct edimax_header), 1, fpOut); - fwrite(buf, sizeof(char), length, fpOut); - fclose(fpOut); -} - diff --git a/tools/firmware-utils/src/trx2usr.c b/tools/firmware-utils/src/trx2usr.c deleted file mode 100644 index 96c0ab285e..0000000000 --- a/tools/firmware-utils/src/trx2usr.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * trx2usr - Convert a TRX firmware image to a U.S. Robotics firmware - * image by prepending a 28-byte header. - * - * This program was modeled after the usr-hdr.c program from the GPL'ed - * firmware for the U.S. Robotics Wireless MAXg Router (USR5461). The - * output file of this program can be uploaded via the web interface - * of the original U.S. Robotics firmware. Note that this program only - * works on a little-endian host platform. - * - * Copyright (C) 2006 Dick Streefland - * - * This is free software, licensed under the terms of the GNU General - * Public License as published by the Free Software Foundation. - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#define TRX_MAGIC "HDR0" - -#define USR_MAGIC 0x30525355 // "USR0" -#define EPI_VERSION 0x06235d03 -#define COMPAT_ID 1 // USR5461 -#define HARDWARE_REV 1 - -#define CRC32_INIT 0xffffffff -#define CHUNK (64*1024) - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; - -struct usr_header -{ - uint32 magic; // "USR0" - uint32 len; // file length without this header - uint32 crc32; // CRC32 of the file without header - uint32 version; // EPI_VERSION - uint16 compatibility_id; // COMPAT_ID - uint16 hardware_revision; // HARDWARE_REV - uint32 reserved[2]; -}; - -static const uint32 crc_32_tab [] = // CRC polynomial 0xedb88320 -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - -static char buf[CHUNK]; - -static uint32 crc32(uint32 crc, uint8* p, size_t n) -{ - while (n--) - { - crc = crc_32_tab[(crc ^ *p++) & 0xff] ^ (crc >> 8); - } - return crc; -} - -static int trx2usr(FILE* trx, FILE* usr) -{ - struct usr_header hdr; - size_t n; - - hdr.magic = USR_MAGIC; - hdr.len = 0; - hdr.crc32 = CRC32_INIT; - hdr.version = EPI_VERSION; - hdr.compatibility_id = COMPAT_ID; - hdr.hardware_revision = HARDWARE_REV; - hdr.reserved[0] = 0; - hdr.reserved[1] = 0; - fwrite(& hdr, sizeof(hdr), 1, usr); - while ((n = fread(buf, 1, CHUNK, trx))) - { - if (hdr.len == 0 && strncmp(buf, TRX_MAGIC, strlen(TRX_MAGIC)) != 0) - { - break; - } - fwrite(& buf, 1, n, usr); - hdr.len += n; - hdr.crc32 = crc32( hdr.crc32, (uint8 *) & buf, n); - } - fseek(usr, 0L, SEEK_SET); - fwrite(& hdr, sizeof(hdr), 1, usr); - if (n != 0) - { - fprintf(stderr, "Input is not a TRX file\n"); - return 1; - } - if (hdr.len == 0) - { - fprintf(stderr, "Empty input\n"); - return 1; - } - if (ferror(trx)) - { - fprintf(stderr, "Read error\n"); - return 1; - } - if (ferror(usr)) - { - fprintf(stderr, "Write error\n"); - return 1; - } - return 0; -} - -extern int main(int argc, char *argv[]) -{ - FILE* in; - FILE* out; - int ret; - - if (argc != 3) - { - fprintf(stderr, "Usage: trx2usr <trx input> <usr output>\n"); - exit(2); - } - in = fopen(argv[1], "rb"); - if (!in) - { - fprintf(stderr, "Cannot open \"%s\": %s\n", argv[1], strerror(errno)); - exit(1); - } - out = fopen(argv[2], "wb"); - if (!out) - { - fprintf(stderr, "Cannot create \"%s\": %s\n", argv[2], strerror(errno)); - exit(1); - } - ret = trx2usr(in, out); - fclose(in); - fclose(out); - if (ret) - { - unlink(argv[2]); - } - return ret; -} diff --git a/tools/firmware-utils/src/uimage_padhdr.c b/tools/firmware-utils/src/uimage_padhdr.c deleted file mode 100644 index a56b646403..0000000000 --- a/tools/firmware-utils/src/uimage_padhdr.c +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * uimage_padhdr.c : add zero paddings after the tail of uimage header - * - * 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_MAGIC 0x27051956 /* Image Magic Number */ -#define IH_NMLEN 32 /* Image Name Length */ - -/* - * Legacy format image header, - * all data in network byte order (aka natural aka bigendian). - */ -typedef 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 */ -} image_header_t; - - -/* default padding size */ -#define IH_PAD_BYTES (32) - - -static void usage(char *prog) -{ - fprintf(stderr, - "%s -i <input_uimage_file> -o <output_file> [-l <padding bytes>]\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; - image_header_t *imgh; - int opt; - char *infname = NULL; - char *outfname = NULL; - int padsz = IH_PAD_BYTES; - int ltmp; - - while ((opt = getopt(argc, argv, "i:o:l:")) != -1) { - switch (opt) { - case 'i': - infname = optarg; - break; - case 'o': - outfname = optarg; - break; - case 'l': - ltmp = strtol(optarg, NULL, 0); - if (ltmp > 0) - padsz = ltmp; - 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, sizeof(*imgh)); - if (rsz != sizeof(*imgh)) { - fprintf(stderr, - "could not read input file (errno = %d).\n", errno); - exit(1); - } - - memset(&(filebuf[sizeof(*imgh)]), 0, padsz); - - rsz = read(ifd, &(filebuf[sizeof(*imgh) + padsz]), - statbuf.st_size - sizeof(*imgh)); - if (rsz != (int32_t)(statbuf.st_size - sizeof(*imgh))) { - fprintf(stderr, - "could not read input file (errno = %d).\n", errno); - exit(1); - } - - imgh = (image_header_t *)filebuf; - - imgh->ih_hcrc = 0; - crc_recalc = crc32(0, filebuf, sizeof(*imgh) + padsz); - 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; -} diff --git a/tools/firmware-utils/src/uimage_sgehdr.c b/tools/firmware-utils/src/uimage_sgehdr.c deleted file mode 100644 index 28143a8b22..0000000000 --- a/tools/firmware-utils/src/uimage_sgehdr.c +++ /dev/null @@ -1,167 +0,0 @@ -// 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; -} diff --git a/tools/firmware-utils/src/utils.h b/tools/firmware-utils/src/utils.h deleted file mode 100644 index b051f5e6c7..0000000000 --- a/tools/firmware-utils/src/utils.h +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include <stdint.h> -#include <string.h> - -#pragma once - -#define FW_MEMCPY_STR(dst, src) \ - do { \ - size_t slen = strlen(src); \ - size_t dlen = sizeof(dst); \ - memcpy(dst, src, slen > dlen ? dlen : slen); \ - } while (0); diff --git a/tools/firmware-utils/src/wrt400n.c b/tools/firmware-utils/src/wrt400n.c deleted file mode 100644 index a6c1f8038b..0000000000 --- a/tools/firmware-utils/src/wrt400n.c +++ /dev/null @@ -1,337 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * WRT400n - Firmware Generation Creator - * - * Creates a firmware image for the Linksys WRT400n router, - * that can be uploaded via the firmware upload page, - * from a kernel image file and root fs file - * - * Author: Sandeep Mistry - */ -#include <arpa/inet.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "cyg_crc.h" - -// https://dev.openwrt.org/browser/trunk/target/linux/rdc-2.6/files/drivers/mtd/maps/rdc3210.c -static uint32_t crctab[257] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, - 0 -}; - -static uint32_t crc32(uint8_t* buf, uint32_t len) -{ - register int i; - uint32_t sum; - register uint32_t s0; - s0 = ~0; - for (i = 0; i < len; i++) - { - s0 = (s0 >> 8) ^ crctab[(uint8_t) (s0 & 0xFF) ^ buf[i]]; - } - sum = ~s0; - return sum; -} - -#define HEADERSIZE 60 -#define MAGIC "GMTKRT400N" - -// global variables -uint8_t kernelbuf[0x100000]; // kernel - lzma - uImage -uint8_t rootfsbuf[0x2FFFC4]; // root - squashfs - -uint8_t buf[0x400000]; // buffer for image - - -// Header format: -// -// GPL Tarball: http://downloads.linksysbycisco.com/downloads/WRT400N_1.0.01.19_US.tar,0.gz -// File: WRT400N_1.0.01.19_US/FW_WRT400N_1.0.01.19_US_20081229/GTK/user/include/fw_upgrade.h -// -// -// Struct: -// typedef struct -// { -// UINT32 checksum; /* CRC32 */ -// UINT8 magic[11]; /* The value of GTIMG_MAGIC */ -// UINT32 kernel_length; /* The length of the kernel image */ -// //UINT32 kernel_entry_point; /* Kernel's entry point for RedBoot's information */ -// UINT32 kernel_upgrade_flag; /* Set to 1 if we need to upgrade the kernel parition of the Flash */ -// UINT32 rootfs_length; /* The length of the rootfs image */ -// //UINT32 rootfs_entry_point; /* Not in use */ -// UINT32 rootfs_upgrade_flag; /* Set to 1 if we need to upgrade the rootfs parition of the Flash */ -// -// // Add 3 items by Vic Yu, 2006-05/10 -// UINT32 kernel_checksum; -// UINT32 rootfs_checksum; -// UINT32 fw_totalsize; -// UINT32 reserved[4]; -// }imghdr_t , *pLinuxFWHeader_T; -// -// -// Description -// - checksum: CRC32 of kernel and root fs, back to back -// - magic: GMTKRT400N -// - kernel_length: kernel length in bytes -// - kernel_upgrade_flag: should we upgrade the kernel - set to 1 -// - rootfs_length: root fs length in byte -// - rootfs_upgrade_flag: should we upgrade the root fs - set to 1 -// - kernel_checksum: Gary S. Brown's 32 bit CRC algorithm for kernel, with remaining bits -// set to 0xFF upto 0x100000 bytes (total length) -// - rootfs_checksum: Gary S. Brown's 32 bit CRC algorithm for root fs, with remaining bits -// set to 0xFF upto 0x2FFFC4 bytes (total length) -// - fw_totalsize: total firmware image file length (header length + kernel length + root fs length) -// - reserved[4]: reserved ??? - set to all 0xFF - - - -int main(int argc, char *argv[]) -{ - // file descriptors ... - int kernelfd = -1; - int rootfsfd = -1; - int outfd = -1; - - char* kernelfilename = NULL; - char* rootfsfilename = NULL; - char* outputfilename = NULL; - - // file sizes - uint32_t kernelsize = 0; - uint32_t rootfssize = 0; - uint32_t totalsize = 0; - - // header flags - uint32_t kernelflag = 0; - uint32_t rootfsflag = 0; - - // checksums - uint32_t kernelchecksum = 0; - uint32_t rootfschecksum = 0; - uint32_t crc = 0; - - if(argc != 4) - { - printf("Usage:\n\t%s <kernel file> <rootfs file> <output file>\n", argv[0]); - return 1; - } - - kernelfilename = argv[1]; - rootfsfilename = argv[2]; - outputfilename = argv[3]; - - // Fill the kernel, rootfs, main buffer - memset(kernelbuf, 0xFF, sizeof(kernelbuf)); - memset(rootfsbuf, 0xFF, sizeof(rootfsbuf)); - memset(buf, 0xFF, sizeof(buf)); - - // open the kernel .. - kernelfd = open(kernelfilename, O_RDONLY); - - if(kernelfd == -1) - { - printf("Error: opening '%s'\n", kernelfilename); - goto done; - } - - // read in the kernel ... - kernelsize = read(kernelfd, kernelbuf, sizeof(kernelbuf)); - - if(kernelsize == -1) - { - printf("Error: reading '%s'\n", kernelfilename); - goto done; - } - - // calculate the kernel checksum ... - kernelchecksum = cyg_crc32_accumulate(0, kernelbuf, sizeof(kernelbuf)); - - // print out stats - printf("%s: size %d (0x%x), crc32 = 0x%x\n", kernelfilename, kernelsize, kernelsize, kernelchecksum); - - - // open the root fs .. - rootfsfd = open(rootfsfilename, O_RDONLY); - - if(rootfsfd == -1) - { - printf("Error: opening '%s'\n", rootfsfilename); - goto done; - } - - // read in the root fs .. - rootfssize = read(rootfsfd, rootfsbuf, sizeof(rootfsbuf)); - - if(rootfssize == -1) - { - printf("Error: reading '%s'\n", rootfsfilename); - goto done; - } - - // calculate the root fs checksum ... - rootfschecksum = cyg_crc32_accumulate(0, rootfsbuf, sizeof(rootfsbuf)); - - // print out stats - printf("%s: size %d (0x%x), crc32 = 0x%x\n", rootfsfilename, rootfssize, rootfssize, rootfschecksum); - - - // now for the header ... - - totalsize = HEADERSIZE; - - // copy over kernel - memcpy(buf + totalsize, kernelbuf, kernelsize); - totalsize += kernelsize; - - // copy over root fs - memcpy(buf + totalsize, rootfsbuf, rootfssize); - totalsize += rootfssize; - - // calculate crc - crc = crc32(buf + HEADERSIZE, totalsize - HEADERSIZE); - - // print some stats out - printf("crc = 0x%x, total size = %d (0x%x)\n", crc, totalsize, totalsize); - - // copy crc into header - crc = htonl(crc); - memcpy(buf, &crc, sizeof(crc)); - - // copy over magic - strcpy((char *)buf + 4, MAGIC); - - // copy over kernel size - kernelsize = htonl(kernelsize); - memcpy(buf + 16, &kernelsize, sizeof(kernelsize)); - - // copy over kernal flag - kernelflag = htonl(0x1); - memcpy(buf + 20, &kernelflag, sizeof(kernelflag)); - - // copy over root fs size - rootfssize = htonl(rootfssize); - memcpy(buf + 24, &rootfssize, sizeof(rootfssize)); - - // copy over root fs flag - rootfsflag = htonl(0x1); - memcpy(buf + 28, &rootfsflag, sizeof(rootfsflag)); - - // copy over kernel check sum - kernelchecksum = htonl(kernelchecksum); - memcpy(buf + 32, &kernelchecksum, sizeof(kernelchecksum)); - - // copy over root fs checksum - rootfschecksum = htonl(rootfschecksum); - memcpy(buf + 36, &rootfschecksum, sizeof(rootfschecksum)); - - // copy over total size - totalsize = htonl(totalsize); - memcpy(buf + 40, &totalsize, sizeof(totalsize)); - - // undo the htonl (for write) - totalsize = htonl(totalsize); - - - // write out the file from the buffer - outfd = open(outputfilename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - - if(outfd == -1) - { - printf("ERROR: opening '%s' for write\n", outputfilename); - } - - write(outfd, buf, totalsize); - -done: - // close open fd's - - if(kernelfd != -1) - { - close(kernelfd); - kernelfd = -1; - } - - if(rootfsfd != -1) - { - close(rootfsfd); - rootfsfd = -1; - } - - if(outfd != -1) - { - close(outfd); - outfd = -1; - } - - return 0; -} diff --git a/tools/firmware-utils/src/xorimage.c b/tools/firmware-utils/src/xorimage.c deleted file mode 100644 index 94190fd181..0000000000 --- a/tools/firmware-utils/src/xorimage.c +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * xorimage.c - partially based on OpenWrt's addpattern.c - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/stat.h> - -static char default_pattern[] = "12345678"; -static int is_hex_pattern; - - -int xor_data(void *data, size_t len, const void *pattern, int p_len, int p_off) -{ - const uint8_t *key = pattern; - uint8_t *d = data; - - while (len--) { - *d ^= key[p_off]; - d++; - p_off = (p_off + 1) % p_len; - } - return p_off; -} - - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: xorimage [-i infile] [-o outfile] [-p <pattern>] [-x]\n"); - exit(EXIT_FAILURE); -} - - -int main(int argc, char **argv) -{ - char buf[1024]; /* keep this at 1k or adjust garbage calc below */ - FILE *in = stdin; - FILE *out = stdout; - char *ifn = NULL; - char *ofn = NULL; - const char *pattern = default_pattern; - char hex_pattern[128]; - unsigned int hex_buf; - int c; - size_t n; - int p_len, p_off = 0; - - while ((c = getopt(argc, argv, "i:o:p:xh")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'p': - pattern = optarg; - break; - case 'x': - is_hex_pattern = true; - break; - case 'h': - default: - usage(); - } - } - - if (optind != argc || optind == 1) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - if (ifn && !(in = fopen(ifn, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", ifn); - usage(); - } - - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - p_len = strlen(pattern); - - if (p_len == 0) { - fprintf(stderr, "pattern cannot be empty\n"); - usage(); - } - - if (is_hex_pattern) { - int i; - - if ((p_len / 2) > sizeof(hex_pattern)) { - fprintf(stderr, "provided hex pattern is too long\n"); - usage(); - } - - if (p_len % 2 != 0) { - fprintf(stderr, "the number of characters (hex) is incorrect\n"); - usage(); - } - - for (i = 0; i < (p_len / 2); i++) { - if (sscanf(pattern + (i * 2), "%2x", &hex_buf) < 0) { - fprintf(stderr, "invalid hex digit around %d\n", i * 2); - usage(); - } - hex_pattern[i] = (char)hex_buf; - } - } - - while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { - if (n < sizeof(buf)) { - if (ferror(in)) { - FREAD_ERROR: - fprintf(stderr, "fread error\n"); - return EXIT_FAILURE; - } - } - - if (is_hex_pattern) { - p_off = xor_data(buf, n, hex_pattern, (p_len / 2), - p_off); - } else { - p_off = xor_data(buf, n, pattern, p_len, p_off); - } - - if (!fwrite(buf, n, 1, out)) { - FWRITE_ERROR: - fprintf(stderr, "fwrite error\n"); - return EXIT_FAILURE; - } - } - - if (ferror(in)) { - goto FREAD_ERROR; - } - - if (fflush(out)) { - goto FWRITE_ERROR; - } - - fclose(in); - fclose(out); - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/zyimage.c b/tools/firmware-utils/src/zyimage.c deleted file mode 100644 index 51a5cf7573..0000000000 --- a/tools/firmware-utils/src/zyimage.c +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2014 Soul Trace <S-trace@list.ru> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <string.h> -#include <unistd.h> - -#define szbuf 32768 - -u_int32_t crc_tab[256]; - -u_int32_t chksum_crc32 (FILE *f) -{ - register unsigned long crc; - unsigned long i, j; - char *buffer = malloc(szbuf); - char *buf; - - crc = 0xFFFFFFFF; - while (!feof(f)) - { - j = fread(buffer, 1, szbuf, f); - buf = buffer; - for (i = 0; i < j; i++) - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ *buf++) & 0xFF]; - } - free(buffer); - return crc; -} - -void chksum_crc32gentab () -{ - unsigned long crc, poly; - int i, j; - - poly = 0xEDB88320L; - for (i = 0; i < 256; i++) - { - crc = i; - for (j = 8; j > 0; j--) - { - if (crc & 1) - crc = (crc >> 1) ^ poly; - else - crc >>= 1; - } - crc_tab[i] = crc; - } -} - -void usage(char *progname) -{ - printf("Usage: %s [ -v Version ] [ -d Device_ID ] <input file>\n", progname); - exit(1); -} - -int main(int argc, char *argv[]) { - struct signature - { - const char magic[4]; - unsigned int device_id; - char firmware_version[48]; - unsigned int crc32; - } - sign = - { - { 'Z', 'N', 'B', 'G' }, - 1, - { "V.1.0.0(1.0.0)" }, - 0 - }; - FILE *f; - struct signature oldsign; - char *filename; - static const char *optString; - int opt; - - if (argc < 1) - usage(argv[0]); - - optString = "v:d:h"; - opt = getopt( argc, argv, optString ); - while( opt != -1 ) { - switch( opt ) { - case 'v': - if (optarg == NULL) - usage(argv[0]); - strncpy(sign.firmware_version, optarg, sizeof(sign.firmware_version)-1); - sign.firmware_version[sizeof(sign.firmware_version)-1]='\0'; /* Make sure that string is terminated correctly */ - break; - - case 'd': - sign.device_id = atoi(optarg); - if (sign.device_id == 0) - sign.device_id = (int)strtol(optarg, NULL, 16); - break; - - case '?': - case 'h': - usage(argv[0]); - break; - - default: - break; - } - - opt = getopt( argc, argv, optString ); - } - - chksum_crc32gentab(); - - filename=argv[optind]; - if (access(filename, W_OK) || access(filename, R_OK)) - { - printf("Not open input file %s\n", filename); - exit(1); - } - f = fopen(argv[optind], "r+"); - if (f != NULL) - { - fseek(f, sizeof(sign)*-1, SEEK_END); - fread(&oldsign, sizeof(oldsign), 1, f); - - if (strncmp(oldsign.magic,"ZNBG", sizeof(oldsign.magic)) == 0 ) - { - printf("Image is already signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", oldsign.device_id, oldsign.firmware_version, oldsign.crc32); - exit(0); - } - - fseek(f, 0, SEEK_SET); - sign.crc32 = chksum_crc32(f); - fwrite(&sign, sizeof(sign), 1, f); - fclose(f); - - printf("Image signed as:\nDevice ID: 0x%08x\nFirmware version: %s\nImage CRC32: 0x%x\n", sign.device_id, sign.firmware_version, sign.crc32); - } - return 0; -} diff --git a/tools/firmware-utils/src/zynos.h b/tools/firmware-utils/src/zynos.h deleted file mode 100644 index 6c9c1a0cbd..0000000000 --- a/tools/firmware-utils/src/zynos.h +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * - * Copyright (C) 2007-2008 OpenWrt.org - * Copyright (C) 2007-2008 Gabor Juhos <juhosg at openwrt.org> - * - * This code was based on the information of the ZyXEL's firmware - * image format written by Kolja Waschk, can be found at: - * http://www.ixo.de/info/zyxel_uclinux - */ - -#ifndef _ZYNOS_H -#define _ZYNOS_H - -#define BOOTBASE_NAME_LEN 32 -#define BOOTBASE_MAC_LEN 6 -#define BOOTBASE_FEAT_LEN 22 - -#define BOOTEXT_DEF_SIZE 0x18000 - -struct zyn_bootbase_info { - char vendor[BOOTBASE_NAME_LEN]; /* Vendor name */ - char model[BOOTBASE_NAME_LEN]; /* Model name */ - uint32_t bootext_addr; /* absolute address of the Boot Extension */ - uint16_t res0; /* reserved/unknown */ - uint8_t sys_type; /* system type */ - uint8_t res1; /* reserved/unknown */ - uint16_t model_id; /* model id */ - uint8_t feat_other[BOOTBASE_FEAT_LEN]; /* other feature bits */ - uint8_t feat_main; /* main feature bits */ - uint8_t res2; /* reserved/unknown */ - uint8_t mac[BOOTBASE_MAC_LEN]; /* mac address */ - uint8_t country; /* default country code */ - uint8_t dbgflag; /* debug flag */ -} __attribute__((packed)); - -#define ROMBIN_SIG_LEN 3 -#define ROMBIN_VER_LEN 15 - -struct zyn_rombin_hdr { - uint32_t addr; /* load address of the object */ - uint16_t res0; /* unknown/unused */ - char sig[ROMBIN_SIG_LEN]; /* magic, must be "SIG" */ - uint8_t type; /* type of the object */ - uint32_t osize; /* size of the uncompressed data */ - uint32_t csize; /* size of the compressed data */ - uint8_t flags; /* various flags */ - uint8_t res1; /* unknown/unused */ - uint16_t ocsum; /* csum of the uncompressed data */ - uint16_t ccsum; /* csum of the compressed data */ - char ver[ROMBIN_VER_LEN]; - uint32_t mmap_addr; /* address of the Memory Map Table*/ - uint32_t res2; /* unknown/unused*/ - uint8_t res3; /* unknown/unused*/ -} __attribute__((packed)); - -#define ROMBIN_SIGNATURE "SIG" - -/* Rombin flag bits */ -#define ROMBIN_FLAG_01 0x01 -#define ROMBIN_FLAG_02 0x02 -#define ROMBIN_FLAG_04 0x04 -#define ROMBIN_FLAG_08 0x08 -#define ROMBIN_FLAG_10 0x10 -#define ROMBIN_FLAG_CCSUM 0x20 /* compressed checksum is valid */ -#define ROMBIN_FLAG_OCSUM 0x40 /* original checksum is valid */ -#define ROMBIN_FLAG_COMPRESSED 0x80 /* the binary is compressed */ - -/* Object types */ -#define OBJECT_TYPE_ROMIMG 0x01 -#define OBJECT_TYPE_ROMBOOT 0x02 -#define OBJECT_TYPE_BOOTEXT 0x03 -#define OBJECT_TYPE_ROMBIN 0x04 -#define OBJECT_TYPE_ROMDIR 0x05 -#define OBJECT_TYPE_6 0x06 -#define OBJECT_TYPE_ROMMAP 0x07 -#define OBJECT_TYPE_RAM 0x80 -#define OBJECT_TYPE_RAMCODE 0x81 -#define OBJECT_TYPE_RAMBOOT 0x82 - -/* - * Memory Map Table header - */ -struct zyn_mmt_hdr { - uint16_t count; - uint32_t user_start; - uint32_t user_end; - uint16_t csum; - uint8_t res[12]; -} __attribute__((packed)); - -#define OBJECT_NAME_LEN 8 - -struct zyn_mmt_item { - uint8_t type; /* type of the object */ - uint8_t name[OBJECT_NAME_LEN]; /* name of the object */ - uint8_t res0; /* unused/unknown */ - uint32_t addr; - uint32_t size; /* size of the object */ - uint8_t res1[3]; /* unused/unknown */ - uint8_t type2; -} __attribute__((packed)); - -/* - * Vendor IDs - */ -#define ZYNOS_VENDOR_ID_ZYXEL 0 -#define ZYNOS_VENDOR_ID_NETGEAR 1 -#define ZYNOS_VENDOR_ID_DLINK 2 -#define ZYNOS_VENDOR_ID_03 3 -#define ZYNOS_VENDOR_ID_LUCENT 4 -#define ZYNOS_VENDOR_ID_O2 10 - -/* - * Model IDs (in big-endian format) - */ -#define MID(x) (((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8) - -/* - * Infineon/ADMtek ADM5120 based models - */ -#define ZYNOS_MODEL_ES_2024A MID( 221) -#define ZYNOS_MODEL_ES_2024PWR MID( 4097) -#define ZYNOS_MODEL_ES_2108 MID(61952) -#define ZYNOS_MODEL_ES_2108_F MID(44801) -#define ZYNOS_MODEL_ES_2108_G MID(62208) -#define ZYNOS_MODEL_ES_2108_LC MID(64512) -#define ZYNOS_MODEL_ES_2108PWR MID(62464) -#define ZYNOS_MODEL_HS_100 MID(61855) -#define ZYNOS_MODEL_HS_100W ZYNOS_MODEL_HS_100 -#define ZYNOS_MODEL_P_334 MID(62879) -#define ZYNOS_MODEL_P_334U MID(56735) -#define ZYNOS_MODEL_P_334W MID(62367) -#define ZYNOS_MODEL_P_334WH MID(57344) -#define ZYNOS_MODEL_P_334WHD MID(57600) -#define ZYNOS_MODEL_P_334WT MID(61343) -#define ZYNOS_MODEL_P_335 MID(60831) -#define ZYNOS_MODEL_P_335PLUS MID( 9472) -#define ZYNOS_MODEL_P_335U MID(56479) -#define ZYNOS_MODEL_P_335WT ZYNOS_MODEL_P_335 - -/* - * Texas Instruments AR7 based models - */ -#define ZYNOS_MODEL_P_2602H_61C MID( 3229) -#define ZYNOS_MODEL_P_2602H_63C MID( 3485) -#define ZYNOS_MODEL_P_2602H_D1A /* n.a. */ -#define ZYNOS_MODEL_P_2602H_D3A /* n.a. */ -#define ZYNOS_MODEL_P_2602HW_61C /* n.a. */ -#define ZYNOS_MODEL_P_2602HW_63 /* n.a. */ -#define ZYNOS_MODEL_P_2602HW_63C ZYNOS_MODEL_P_2602H_63C -#define ZYNOS_MODEL_P_2602HW_D1A MID( 6301) -#define ZYNOS_MODEL_P_2602HW_D3A /* n.a. */ -#define ZYNOS_MODEL_P_2602HWL_61 MID( 1181) -#define ZYNOS_MODEL_P_2602HWL_61C ZYNOS_MODEL_P_2602H_61C -#define ZYNOS_MODEL_P_2602HWL_63C ZYNOS_MODEL_P_2602H_63C -#define ZYNOS_MODEL_P_2602HWL_D1A ZYNOS_MODEL_P_2602HW_D1A -#define ZYNOS_MODEL_P_2602HWL_D3A MID( 7581) -#define ZYNOS_MODEL_P_2602HWN_D7A MID(30464) -#define ZYNOS_MODEL_P_2602HWNLI_D7A MID( 6813) - -#define ZYNOS_MODEL_P_2602R_61 MID( 2205) -#define ZYNOS_MODEL_P_2602R_63 MID( 3997) -#define ZYNOS_MODEL_P_2602R_D1A /* n.a. */ -#define ZYNOS_MODEL_P_2602R_D3A /* n.a. */ -#define ZYNOS_MODEL_P_2602RL_D1A MID( 6045) -#define ZYNOS_MODEL_P_2602RL_D3A MID( 7069) - -#define ZYNOS_MODEL_P_660H_61 MID(19346) -#define ZYNOS_MODEL_P_660H_63 MID(22162) -#define ZYNOS_MODEL_P_660H_67 /* n.a. */ -#define ZYNOS_MODEL_P_660H_D1 MID( 7066) -#define ZYNOS_MODEL_P_660H_D3 MID(13210) - -#define ZYNOS_MODEL_P_660HW_61 ZYNOS_MODEL_P_660H_61 -#define ZYNOS_MODEL_P_660HW_63 ZYNOS_MODEL_P_660H_63 -#define ZYNOS_MODEL_P_660HW_67 ZYNOS_MODEL_P_660HW_63 -#define ZYNOS_MODEL_P_660HW_D1 MID( 9114) -#define ZYNOS_MODEL_P_660HW_D3 MID(12698) - -#define ZYNOS_MODEL_P_660R_61 MID(20882) -#define ZYNOS_MODEL_P_660R_61C MID( 1178) -#define ZYNOS_MODEL_P_660R_63 MID(21138) -#define ZYNOS_MODEL_P_660R_63C MID( 922) -#define ZYNOS_MODEL_P_660R_67 ZYNOS_MODEL_P_660R_63 -#define ZYNOS_MODEL_P_660R_67C /* n.a. */ -#define ZYNOS_MODEL_P_660R_D1 MID( 7322) -#define ZYNOS_MODEL_P_660R_D3 MID(10138) - -#define ZYNOS_MODEL_P_661H_61 MID(19346) -#define ZYNOS_MODEL_P_661H_63 MID( 1946) -#define ZYNOS_MODEL_P_661H_D1 MID(10650) -#define ZYNOS_MODEL_P_661H_D3 MID(12442) - -#define ZYNOS_MODEL_P_661HW_61 ZYNOS_MODEL_P_661H_61 -#define ZYNOS_MODEL_P_661HW_63 ZYNOS_MODEL_P_661H_63 -#define ZYNOS_MODEL_P_661HW_D1 MID(10906) -#define ZYNOS_MODEL_P_661HW_D3 MID(14746) - -#define ZYNOS_MODEL_P_662H_61 MID(22418) -#define ZYNOS_MODEL_P_662H_63 /* n.a. */ -#define ZYNOS_MODEL_P_662H_67 /* n.a. */ -#define ZYNOS_MODEL_P_662H_D1 /* n.a. */ -#define ZYNOS_MODEL_P_662H_D3 /* n.a. */ - -#define ZYNOS_MODEL_P_662HW_61 /* n.a. */ -#define ZYNOS_MODEL_P_662HW_63 MID(22674) -#define ZYNOS_MODEL_P_662HW_67 /* n.a. */ -#define ZYNOS_MODEL_P_662HW_D1 MID(10394) -#define ZYNOS_MODEL_P_662HW_D3 MID(12954) - -/* OEM boards */ -#define ZYNOS_MODEL_O2SURF ZYNOS_MODEL_P_2602HWN_D7A - -/* Atheros AR2318 based boards */ -#define ZYNOS_MODEL_NBG_318S MID(59392) - -/* Atheros AR71xx based boards */ -#define ZYNOS_MODEL_NBG_460N MID(61441) - -#endif /* _ZYNOS_H */ diff --git a/tools/firmware-utils/src/zytrx.c b/tools/firmware-utils/src/zytrx.c deleted file mode 100644 index 8c113d6d79..0000000000 --- a/tools/firmware-utils/src/zytrx.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * zytrx - add header to images for ZyXEL NR7101 - * - * Based on add_header.c - partially based on OpenWrt's - * motorola-bin.c - * - * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> - * Gabor Juhos <juhosg@openwrt.org> - * Copyright (C) 2021 Bjørn Mork <bjorn@mork.no> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <string.h> -#include <netinet/in.h> -#include <inttypes.h> - -#define BPB 8 /* bits/byte */ - -static uint32_t crc32[1<<BPB]; - -static void init_crc32(void) -{ - const uint32_t poly = ntohl(0x2083b8ed); - int n; - - for (n = 0; n < 1<<BPB; n++) { - uint32_t crc = n; - int bit; - - for (bit = 0; bit < BPB; bit++) - crc = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1); - crc32[n] = crc; - } -} - -static uint32_t crc32buf(const unsigned char *buf, size_t len) -{ - uint32_t crc = 0xFFFFFFFF; - - for (; len; len--, buf++) - crc = crc32[(uint8_t)crc ^ *buf] ^ (crc >> BPB); - return ~crc; -} - -/* HDR0 reversed, to be stored as BE */ -#define MAGIC 0x30524448 /* HDR0 reversed, to be stored as BE */ - -/* All numbers are stored as BE */ -struct zytrx_t { - uint32_t magic; - uint32_t len_h; /* Length of this header */ - uint32_t len_t; /* Total length of file */ - uint32_t crc32_p; /* Bit inverted 32-bit CRC of image payload */ - uint8_t verInt[32]; /* String "5.0.0.0\n" zero padded */ - uint8_t verExt[32]; /* String "\n" zero padded */ - uint32_t len_p; /* Length of image payload */ - uint8_t pad1[12]; /* zero padding(?) */ - uint8_t code[164]; /* string "3 6035 122 0\n" zero padded */ - uint8_t chipid[8]; /* string "MT7621A" zero padded */ - uint8_t boardid[16]; /* string "NR7101" zero padded */ - uint32_t modelid; /* modelid as 4 BCD digits: 0x07010001 */ - uint8_t pad2[8]; /* zero padding(?) */ - uint8_t swVersionInt[32]; /* ZyXEL version string: "1.00(ABUV.0)D0" zero padded */ - uint8_t swVersionExt[32]; /* identical to swVersionInt */ - uint8_t pad4[4]; /* zero padding(?) */ - uint32_t kernelChksum; /* no idea how this is computed - reported but not validated */ - uint8_t pad5[4]; /* zero padding(?) */ - uint32_t crc32_h; /* Bit inverted 32-bit CRC of this header payload */ - uint8_t pad6[4]; /* zero padding(?) */ -}; - -/* static?() field values of unknown meaning - maybe ove to board - * table when we know the significance - */ -#define VER_INT "5.0.0.0\n" -#define VER_EXT "\n" -#define CODE "3 6035 122 0\n" -#define KERNELCHKSUM 0x12345678 - -/* table of supported devices using this header format */ -static struct board_t { - uint8_t chipid[8]; - uint8_t boardid[16]; - uint32_t modelid; -} boards[] = { - { "MT7621A", "NR7101", 0x07010001 }, - {} -}; - -static int find_board(struct zytrx_t *h, char *board) -{ - struct board_t *p; - - for (p = boards; p->modelid; p++) { - if (strncmp((const char *)p->boardid, board, sizeof(p->boardid))) - continue; - memcpy(h->chipid, p->chipid, sizeof(h->chipid)); - memcpy(h->boardid, p->boardid, sizeof(h->boardid)); - h->modelid = htonl(p->modelid); - return 0; - } - return -1; -} - -static void usage(const char *name) -{ - struct board_t *p; - - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s -B <board> -v <versionstr> -i <file> [-o <outputfile>]\n\n", name); - fprintf(stderr, "Supported <board> values:\n"); - for (p = boards; p->modelid; p++) - fprintf(stderr, "\t%-12s\n", p->boardid); - fprintf(stderr, "\nExample:\n"); - fprintf(stderr, " %s -B %s -v foobar-1.0 -i my.img -o out.img\n\n", name, - boards[0].boardid); - exit(EXIT_FAILURE); -} - -static void errexit(const char *msg) -{ - fprintf(stderr, "ERR: %s: %s\n", msg, errno ? strerror(errno) : "unknown"); - exit(EXIT_FAILURE); -} - -static void *map_input(const char *name, size_t *len) -{ - struct stat stat; - void *mapped; - int fd; - - fd = open(name, O_RDONLY); - if (fd < 0) - return NULL; - if (fstat(fd, &stat) < 0) { - close(fd); - return NULL; - } - *len = stat.st_size; - mapped = mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (close(fd) < 0) { - (void) munmap(mapped, stat.st_size); - return NULL; - } - return mapped; -} - -int main(int argc, char **argv) -{ - int c, fdout = STDOUT_FILENO; - void *input_file = NULL; - size_t file_len, len; - uint32_t crc; - struct zytrx_t h = { - .magic = htonl(MAGIC), - .len_h = htonl(sizeof(h)), - .verInt = VER_INT, - .verExt = VER_EXT, - .code = CODE, - .kernelChksum = htonl(KERNELCHKSUM), - }; - - while ((c = getopt(argc, argv, "B:v:i:o:")) != -1) { - switch (c) { - case 'B': - if (find_board(&h, optarg) < 0) - errexit("unsupported board"); - break; - case 'v': - len = strlen(optarg); - if (len > sizeof(h.swVersionInt)) - errexit("version string too long"); - memcpy(h.swVersionInt, optarg, len); - memcpy(h.swVersionExt, optarg, len); - break; - case 'i': - input_file = map_input(optarg, &file_len); - if (!input_file) - errexit(optarg); - break; - case 'o': - fdout = open(optarg, O_WRONLY | O_CREAT, 0644); - if (fdout < 0) - errexit(optarg); - break; - default: - usage(argv[0]); - } - } - - /* required paremeters */ - if (!input_file || !h.modelid || !h.swVersionInt[0]) - usage(argv[0]); - - /* length fields */ - h.len_t = htonl(sizeof(h) + file_len); - h.len_p = htonl(file_len); - - /* crc fields */ - init_crc32(); - crc = crc32buf(input_file, file_len); - h.crc32_p = htonl(~crc); - crc = crc32buf((unsigned char *)&h, sizeof(h)); - h.crc32_h = htonl(~crc); - - /* dump new image */ - write(fdout, &h, sizeof(h)); - write(fdout, input_file, file_len); - - /* close files */ - munmap(input_file, file_len); - if (fdout != STDOUT_FILENO) - close(fdout); - - return EXIT_SUCCESS; -} diff --git a/tools/firmware-utils/src/zyxbcm.c b/tools/firmware-utils/src/zyxbcm.c deleted file mode 100644 index 0266c82caf..0000000000 --- a/tools/firmware-utils/src/zyxbcm.c +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * zyxbcm.c - based on Jonas Gorski's spw303v.c - * - * Copyright (C) 2014 Álvaro Fernández Rojas <noltari@gmail.com> - */ - -#include <arpa/inet.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <unistd.h> -#include <sys/stat.h> - -#define TAGVER_LEN 4 /* Length of Tag Version */ -#define SIG1_LEN 20 /* Company Signature 1 Length */ -#define SIG2_LEN 14 /* Company Signature 2 Lenght */ -#define BOARDID_LEN 16 /* Length of BoardId */ -#define ENDIANFLAG_LEN 2 /* Endian Flag Length */ -#define CHIPID_LEN 6 /* Chip Id Length */ -#define IMAGE_LEN 10 /* Length of Length Field */ -#define ADDRESS_LEN 12 /* Length of Address field */ -#define DUALFLAG_LEN 2 /* Dual Image flag Length */ -#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ -#define RSASIG_LEN 20 /* Length of RSA Signature in tag */ -#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ -#define ZYX_TAGINFO1_LEN 20 /* Length of vendor information field1 in tag */ -#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ -#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ -#define CRC_LEN 4 /* Length of CRC in bytes */ - -#define IMAGETAG_CRC_START 0xFFFFFFFF - -struct bcm_tag { - char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag - char sig_1[SIG1_LEN]; // 4-23: Company Line 1 - char sig_2[SIG2_LEN]; // 24-37: Company Line 2 - char chipid[CHIPID_LEN]; // 38-43: Chip this image is for - char boardid[BOARDID_LEN]; // 44-59: Board name - char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE - char totalLength[IMAGE_LEN]; // 62-71: Total length of image - char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE - char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE - char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) - char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing - char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel - char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel - char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present - char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present - char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) - char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT) - char flashLayoutVer[FLASHLAYOUTVER_LEN]; // 192-195: Version flash layout - char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32 - char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information - char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) - char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition - char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition - char imageSequence[4]; // 228-231: Image sequence number - char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot - char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion - char reserved2[16]; // 240-255: Unused at present -}; - -struct zyxbcm_tag { - char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag - char sig_1[SIG1_LEN]; // 4-23: Company Line 1 - char sig_2[SIG2_LEN]; // 24-37: Company Line 2 - char chipid[CHIPID_LEN]; // 38-43: Chip this image is for - char boardid[BOARDID_LEN]; // 44-59: Board name - char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE - char totalLength[IMAGE_LEN]; // 62-71: Total length of image - char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE - char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE - char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) - char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing - char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel - char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel - char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present - char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present - char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) - char information1[ZYX_TAGINFO1_LEN]; // 162-181: Compilation and related information (not generated/used by OpenWRT) - char flashImageEnd[ADDRESS_LEN]; // 182-193: Address in memory of image end - char fskernelCRC[CRC_LEN]; // 194-197: kernel+rootfs CRC32 - char reserved1[2]; // 198-199: Unused at present - char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information - char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) - char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition - char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition - char imageSequence[4]; // 228-231: Image sequence number - char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot - char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion - char reserved2[16]; // 240-255: Unused at present -}; - -static uint32_t crc32tab[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -uint32_t crc32(uint32_t crc, uint8_t *data, size_t len) -{ - while (len--) - crc = (crc >> 8) ^ crc32tab[(crc ^ *data++) & 0xFF]; - - return crc; -} - -void fix_header(void *buf) -{ - struct bcm_tag *bcmtag = buf; - struct zyxbcm_tag *zyxtag = buf; - uint8_t fskernel_crc[CRC_LEN]; - uint32_t crc; - uint64_t flash_start, rootfs_len, kernel_len; - - /* Backup values */ - flash_start = strtoul(bcmtag->flashImageStart, NULL, 10); - rootfs_len = strtoul(bcmtag->flashRootLength, NULL, 10); - kernel_len = strtoul(bcmtag->kernelLength, NULL, 10); - memcpy(fskernel_crc, bcmtag->fskernelCRC, CRC_LEN); - - /* Clear values */ - zyxtag->information1[ZYX_TAGINFO1_LEN - 1] = 0; - memset(zyxtag->flashImageEnd, 0, ADDRESS_LEN); - memset(zyxtag->fskernelCRC, 0, CRC_LEN); - memset(zyxtag->reserved1, 0, 2); - - /* Replace values */ - sprintf(zyxtag->flashImageEnd, "%lu", flash_start + rootfs_len + kernel_len); - memcpy(zyxtag->fskernelCRC, fskernel_crc, CRC_LEN); - - /* Update tag crc */ - crc = htonl(crc32(IMAGETAG_CRC_START, buf, 236)); - memcpy(zyxtag->headerCRC, &crc, 4); -} - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: zyxbcm [-i <inputfile>] [-o <outputfile>]\n"); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) -{ - char buf[1024]; /* keep this at 1k or adjust garbage calc below */ - FILE *in = stdin, *out = stdout; - char *ifn = NULL, *ofn = NULL; - size_t n; - int c, first_block = 1; - - while ((c = getopt(argc, argv, "i:o:h")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'h': - default: - usage(); - } - } - - if (optind != argc || optind == 1) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - if (ifn && !(in = fopen(ifn, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", ifn); - usage(); - } - - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { - if (n < sizeof(buf)) { - if (ferror(in)) { - FREAD_ERROR: - fprintf(stderr, "fread error\n"); - return EXIT_FAILURE; - } - } - - if (first_block && n >= 256) { - fix_header(buf); - first_block = 0; - } - - if (!fwrite(buf, n, 1, out)) { - FWRITE_ERROR: - fprintf(stderr, "fwrite error\n"); - return EXIT_FAILURE; - } - } - - if (ferror(in)) { - goto FREAD_ERROR; - } - - if (fflush(out)) { - goto FWRITE_ERROR; - } - - fclose(in); - fclose(out); - - return EXIT_SUCCESS; -} |