From 50f3cf27efbf45ae4c54d9193d072b7a827eee6f Mon Sep 17 00:00:00 2001 From: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com> Date: Sun, 31 May 2020 20:01:05 +0800 Subject: [PATCH] mtd: sync upstream source code --- package/system/mtd/Makefile | 4 +- package/system/mtd/src/Makefile | 5 +- package/system/mtd/src/fis.c | 26 +---- package/system/mtd/src/fis.h | 2 + package/system/mtd/src/linksys_bootcount.c | 108 +++++++++++++++--- package/system/mtd/src/mtd.c | 54 ++++++++- package/system/mtd/src/mtd.h | 1 + .../system/mtd/src/tpl_ramips_recoveryflag.c | 94 +++++++++++++++ package/system/mtd/src/wrgg.c | 27 +++-- tools/firmware-utils/Makefile | 2 +- tools/firmware-utils/src/mkfwimage.c | 9 ++ tools/firmware-utils/src/tplink-safeloader.c | 39 ++++++- 12 files changed, 310 insertions(+), 61 deletions(-) create mode 100644 package/system/mtd/src/tpl_ramips_recoveryflag.c diff --git a/package/system/mtd/Makefile b/package/system/mtd/Makefile index f31a34a612..166bb33281 100644 --- a/package/system/mtd/Makefile +++ b/package/system/mtd/Makefile @@ -3,13 +3,13 @@ # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. -# +# include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mtd -PKG_RELEASE:=23 +PKG_RELEASE:=25 PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME) STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS) diff --git a/package/system/mtd/src/Makefile b/package/system/mtd/src/Makefile index b8ba456c41..2812959d21 100644 --- a/package/system/mtd/src/Makefile +++ b/package/system/mtd/src/Makefile @@ -6,12 +6,15 @@ obj = mtd.o jffs2.o crc32.o md5.o obj.seama = seama.o md5.o obj.wrg = wrg.o md5.o obj.wrgg = wrgg.o md5.o +obj.tpl = tpl_ramips_recoveryflag.o obj.ar71xx = trx.o $(obj.seama) $(obj.wrgg) +obj.ath79 = $(obj.seama) +obj.gemini = $(obj.wrgg) obj.brcm = trx.o obj.brcm47xx = $(obj.brcm) obj.bcm53xx = $(obj.brcm) $(obj.seama) obj.brcm63xx = imagetag.o -obj.ramips = $(obj.seama) $(obj.wrg) linksys_bootcount.o +obj.ramips = $(obj.seama) $(obj.tpl) $(obj.wrg) linksys_bootcount.o obj.mvebu = linksys_bootcount.o obj.kirkwood = linksys_bootcount.o obj.ipq806x = linksys_bootcount.o diff --git a/package/system/mtd/src/fis.c b/package/system/mtd/src/fis.c index b50411cfeb..8bde9af6dc 100644 --- a/package/system/mtd/src/fis.c +++ b/package/system/mtd/src/fis.c @@ -139,8 +139,6 @@ done: int fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) { - struct fis_image_desc *fisdir = NULL; - struct fis_image_desc *redboot = NULL; struct fis_image_desc *first = NULL; struct fis_image_desc *last = NULL; struct fis_image_desc *first_fb = NULL; @@ -164,12 +162,6 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff)) break; - if (!strcmp((char *) desc->hdr.name, "FIS directory")) - fisdir = desc; - - if (!strcmp((char *) desc->hdr.name, "RedBoot")) - redboot = desc; - /* update max offset */ if (offset < desc->hdr.flash_base) offset = desc->hdr.flash_base; @@ -210,18 +202,6 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) size = offset - first_fb->hdr.flash_base; -#ifdef notyet - desc = first - 1; - if (redboot && (desc >= redboot)) { - if (first->hdr.flash_base - desc->hdr.size > desc->hdr.flash_base) { - int delta = first->hdr.flash_base - desc->hdr.size - desc->hdr.flash_base; - - offset -= delta; - size += delta; - } - } -#endif - last++; desc = first + n_new; offset = first_fb->hdr.flash_base; @@ -243,14 +223,14 @@ fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new) memset(desc, 0, sizeof(struct fis_image_desc)); memcpy(desc->hdr.name, part->name, sizeof(desc->hdr.name)); desc->crc.desc = 0; - desc->crc.file = 0; + desc->crc.file = part->crc; desc->hdr.flash_base = offset; desc->hdr.mem_base = part->loadaddr; desc->hdr.entry_point = part->loadaddr; desc->hdr.size = (part->size > 0) ? part->size : size; - desc->hdr.data_length = desc->hdr.size; - + desc->hdr.data_length = (part->length > 0) ? part->length : + desc->hdr.size; offset += desc->hdr.size; size -= desc->hdr.size; } diff --git a/package/system/mtd/src/fis.h b/package/system/mtd/src/fis.h index bdf1103d8a..2be2cb1f04 100644 --- a/package/system/mtd/src/fis.h +++ b/package/system/mtd/src/fis.h @@ -6,6 +6,8 @@ struct fis_part { uint32_t offset; uint32_t loadaddr; uint32_t size; + uint32_t length; + uint32_t crc; }; int fis_validate(struct fis_part *old, int n_old, struct fis_part *new, int n_new); diff --git a/package/system/mtd/src/linksys_bootcount.c b/package/system/mtd/src/linksys_bootcount.c index 500ede4972..bd06728696 100644 --- a/package/system/mtd/src/linksys_bootcount.c +++ b/package/system/mtd/src/linksys_bootcount.c @@ -2,6 +2,7 @@ * Linksys boot counter reset code for mtd * * Copyright (C) 2013 Jonas Gorski + * Portions Copyright (c) 2019, Jeff Kletsky * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License v2 @@ -29,6 +30,7 @@ #include #include #include +#include #include #include @@ -37,6 +39,30 @@ #define BOOTCOUNT_MAGIC 0x20110811 +/* + * EA6350v3, and potentially other NOR-boot devices, + * use an offset increment of 16 between records, + * not mtd_info_user.writesize (often 1 on NOR devices). + */ + +#define BC_OFFSET_INCREMENT_MIN 16 + + + +#define DLOG_OPEN() + +#define DLOG_ERR(...) do { \ + fprintf(stderr, "ERROR: " __VA_ARGS__); fprintf(stderr, "\n"); \ + } while (0) + +#define DLOG_NOTICE(...) do { \ + fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); \ + } while (0) + +#define DLOG_DEBUG(...) + + + struct bootcounter { uint32_t magic; uint32_t count; @@ -50,25 +76,50 @@ int mtd_resetbc(const char *mtd) struct mtd_info_user mtd_info; struct bootcounter *curr = (struct bootcounter *)page; unsigned int i; + unsigned int bc_offset_increment; int last_count = 0; int num_bc; int fd; int ret; + int retval = 0; + + DLOG_OPEN(); fd = mtd_check_open(mtd); if (ioctl(fd, MEMGETINFO, &mtd_info) < 0) { - fprintf(stderr, "failed to get mtd info!\n"); - return -1; + DLOG_ERR("Unable to obtain mtd_info for given partition name."); + + retval = -1; + goto out; } - num_bc = mtd_info.size / mtd_info.writesize; + + /* Detect need to override increment (for EA6350v3) */ + + if (mtd_info.writesize < BC_OFFSET_INCREMENT_MIN) { + + bc_offset_increment = BC_OFFSET_INCREMENT_MIN; + DLOG_DEBUG("Offset increment set to %i for writesize of %i", + bc_offset_increment, mtd_info.writesize); + } else { + + bc_offset_increment = mtd_info.writesize; + } + + num_bc = mtd_info.size / bc_offset_increment; for (i = 0; i < num_bc; i++) { - pread(fd, curr, sizeof(*curr), i * mtd_info.writesize); + pread(fd, curr, sizeof(*curr), i * bc_offset_increment); - if (curr->magic != BOOTCOUNT_MAGIC && curr->magic != 0xffffffff) { - fprintf(stderr, "unexpected magic %08x, bailing out\n", curr->magic); + /* Existing code assumes erase is to 0xff; left as-is (2019) */ + + if (curr->magic != BOOTCOUNT_MAGIC && + curr->magic != 0xffffffff) { + DLOG_ERR("Unexpected magic %08x at offset %08x; aborting.", + curr->magic, i * bc_offset_increment); + + retval = -2; goto out; } @@ -78,38 +129,59 @@ int mtd_resetbc(const char *mtd) last_count = curr->count; } - /* no need to do writes when last boot count is already 0 */ - if (last_count == 0) + + if (last_count == 0) { /* bootcount is already 0 */ + + retval = 0; goto out; + } if (i == num_bc) { + DLOG_NOTICE("Boot-count log full with %i entries; erasing (expected occasionally).", + i); + struct erase_info_user erase_info; erase_info.start = 0; erase_info.length = mtd_info.size; - /* erase block */ ret = ioctl(fd, MEMERASE, &erase_info); if (ret < 0) { - fprintf(stderr, "failed to erase block: %i\n", ret); - return -1; + DLOG_ERR("Failed to erase boot-count log MTD; ioctl() MEMERASE returned %i", + ret); + + retval = -3; + goto out; } i = 0; } - memset(curr, 0xff, mtd_info.writesize); + memset(curr, 0xff, bc_offset_increment); curr->magic = BOOTCOUNT_MAGIC; curr->count = 0; curr->checksum = BOOTCOUNT_MAGIC; - ret = pwrite(fd, curr, mtd_info.writesize, i * mtd_info.writesize); - if (ret < 0) - fprintf(stderr, "failed to write: %i\n", ret); - sync(); + /* Assumes bc_offset_increment is a multiple of mtd_info.writesize */ + + ret = pwrite(fd, curr, bc_offset_increment, i * bc_offset_increment); + if (ret < 0) { + DLOG_ERR("Failed to write boot-count log entry; pwrite() returned %i", + errno); + retval = -4; + goto out; + + } else { + sync(); + + DLOG_NOTICE("Boot count sucessfully reset to zero."); + + retval = 0; + goto out; + } + out: close(fd); - - return 0; + return retval; } diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c index fa04c0f95b..9baed3fd5e 100644 --- a/package/system/mtd/src/mtd.c +++ b/package/system/mtd/src/mtd.c @@ -44,6 +44,7 @@ #include #include #include +#include "crc32.h" #include "fis.h" #include "mtd.h" @@ -85,6 +86,7 @@ static char *buf = NULL; static char *imagefile = NULL; static enum mtd_image_format imageformat = MTD_IMAGE_FORMAT_UNKNOWN; static char *jffs2file = NULL, *jffs2dir = JFFS2_DEFAULT_DIR; +static char *tpl_uboot_args_part; static int buflen = 0; int quiet; int no_erase; @@ -472,12 +474,14 @@ mtd_write(int imagefd, const char *mtd, char *fis_layout, size_t part_offset) ssize_t r, w, e; ssize_t skip = 0; uint32_t offset = 0; + int buflen_raw = 0; int jffs2_replaced = 0; int skip_bad_blocks = 0; #ifdef FIS_SUPPORT static struct fis_part new_parts[MAX_ARGS]; static struct fis_part old_parts[MAX_ARGS]; + struct fis_part *cur_part = NULL; int n_new = 0, n_old = 0; if (fis_layout) { @@ -487,6 +491,8 @@ mtd_write(int imagefd, const char *mtd, char *fis_layout, size_t part_offset) memset(&old_parts, 0, sizeof(old_parts)); memset(&new_parts, 0, sizeof(new_parts)); + if (!part_offset) + cur_part = new_parts; do { next = strchr(tmp, ':'); @@ -554,6 +560,17 @@ resume: lseek(fd, part_offset, SEEK_SET); } + /* Write TP-Link recovery flag */ + if (tpl_uboot_args_part && mtd_tpl_recoverflag_write) { + if (quiet < 2) + fprintf(stderr, "Writing recovery flag to %s\n", tpl_uboot_args_part); + result = mtd_tpl_recoverflag_write(tpl_uboot_args_part, true); + if (result < 0) { + fprintf(stderr, "Could not write TP-Link recovery flag to %s: %i", mtd, result); + exit(1); + } + } + indicate_writing(mtd); w = e = 0; @@ -576,6 +593,9 @@ resume: buflen += r; } + if (buflen_raw == 0) + buflen_raw = buflen; + if (buflen == 0) break; @@ -587,6 +607,7 @@ resume: if (skip > 0) { skip -= buflen; + buflen_raw = 0; buflen = 0; if (skip <= 0) indicate_writing(mtd); @@ -610,6 +631,7 @@ resume: w += skip; e += skip; skip -= buflen; + buflen_raw = 0; buflen = 0; offset = 0; continue; @@ -675,6 +697,17 @@ resume: } w += buflen; +#ifdef FIS_SUPPORT + if (cur_part && cur_part->size + && cur_part < &new_parts[MAX_ARGS - 1] + && cur_part->length + buflen_raw > cur_part->size) + cur_part++; + if (cur_part) { + cur_part->length += buflen_raw; + cur_part->crc = crc32(cur_part->crc, buf, buflen_raw); + } +#endif + buflen_raw = 0; buflen = 0; offset = 0; } @@ -716,6 +749,18 @@ resume: #endif close(fd); + + /* Clear TP-Link recovery flag */ + if (tpl_uboot_args_part && mtd_tpl_recoverflag_write) { + if (quiet < 2) + fprintf(stderr, "Removing recovery flag from %s\n", tpl_uboot_args_part); + result = mtd_tpl_recoverflag_write(tpl_uboot_args_part, false); + if (result < 0) { + fprintf(stderr, "Could not clear TP-Link recovery flag to %s: %i", mtd, result); + exit(1); + } + } + return 0; } @@ -771,6 +816,10 @@ static void usage(void) fprintf(stderr, " -c datasize amount of data to be used for checksum calculation (for fixtrx / fixseama / fixwrg / fixwrgg)\n"); } + if (mtd_tpl_recoverflag_write) { + fprintf(stderr, + " -t write TP-Link recovery-flag to (for write)\n"); + } fprintf(stderr, #ifdef FIS_SUPPORT " -F [:[:]][,...]\n" @@ -828,7 +877,7 @@ int main (int argc, char **argv) #ifdef FIS_SUPPORT "F:" #endif - "frnqe:d:s:j:p:o:c:l:")) != -1) + "frnqe:d:s:j:p:o:c:t:l:")) != -1) switch (ch) { case 'f': force = 1; @@ -896,6 +945,9 @@ int main (int argc, char **argv) usage(); } break; + case 't': + tpl_uboot_args_part = optarg; + break; #ifdef FIS_SUPPORT case 'F': fis_layout = optarg; diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h index 0250a90e0b..3eda6159c6 100644 --- a/package/system/mtd/src/mtd.h +++ b/package/system/mtd/src/mtd.h @@ -30,4 +30,5 @@ extern int mtd_fixseama(const char *mtd, size_t offset, size_t data_size) __attr extern int mtd_fixwrg(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak)); extern int mtd_fixwrgg(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak)); extern int mtd_resetbc(const char *mtd) __attribute__ ((weak)); +extern int mtd_tpl_recoverflag_write(const char *mtd, const bool recovery_active) __attribute__ ((weak)); #endif /* __mtd_h */ diff --git a/package/system/mtd/src/tpl_ramips_recoveryflag.c b/package/system/mtd/src/tpl_ramips_recoveryflag.c new file mode 100644 index 0000000000..3711e01317 --- /dev/null +++ b/package/system/mtd/src/tpl_ramips_recoveryflag.c @@ -0,0 +1,94 @@ +/* + * TP-Link recovery flag set and unset code for ramips target + * + * Copyright (C) 2018 David Bauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License v2 + * as published by the Free Software Foundation. + * + * This program 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mtd.h" + + +#define TPL_RECOVER_MAGIC 0x89abcdef +#define TPL_NO_RECOVER_MAGIC 0x00000000 + + +struct uboot_args { + uint32_t magic; +}; + +int mtd_tpl_recoverflag_write(const char *mtd, const bool recovery_active) +{ + struct erase_info_user erase_info; + struct uboot_args *args; + uint32_t magic; + int ret = 0; + int fd; + + args = malloc(erasesize); + if (!args) { + fprintf(stderr, "Could not allocate memory!\n"); + return -1; + } + + fd = mtd_check_open(mtd); + if (fd < 0) { + fprintf(stderr, "Could not open mtd device: %s\n", mtd); + ret = -1; + goto out; + } + + /* read first block (containing the magic) */ + pread(fd, args, erasesize, 0); + + /* set magic to desired value */ + magic = TPL_RECOVER_MAGIC; + if (!recovery_active) + magic = TPL_NO_RECOVER_MAGIC; + + /* no need to write when magic is already set correctly */ + if (magic == args->magic) + goto out; + + /* erase first block (containing the magic) */ + erase_info.start = 0; + erase_info.length = erasesize; + + ret = ioctl(fd, MEMERASE, &erase_info); + if (ret < 0) { + fprintf(stderr, "failed to erase block: %i\n", ret); + goto out; + } + + /* write magic to flash */ + args->magic = magic; + + ret = pwrite(fd, args, erasesize, 0); + if (ret < 0) + fprintf(stderr, "failed to write: %i\n", ret); + + sync(); +out: + free(args); + close(fd); + + return ret; +} diff --git a/package/system/mtd/src/wrgg.c b/package/system/mtd/src/wrgg.c index e0b5ca172d..c62f9f5507 100644 --- a/package/system/mtd/src/wrgg.c +++ b/package/system/mtd/src/wrgg.c @@ -39,13 +39,10 @@ #include "wrgg.h" #include "md5.h" -#if __BYTE_ORDER == __BIG_ENDIAN -#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24)) -#elif __BYTE_ORDER == __LITTLE_ENDIAN -#define STORE32_LE(X) (X) -#else -#error unknown endianness! -#endif +static inline uint32_t le32_to_cpu(uint8_t *buf) +{ + return buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24; +} ssize_t pread(int fd, void *buf, size_t count, off_t offset); ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); @@ -94,7 +91,7 @@ wrgg_fix_md5(struct wrgg03_header *shdr, int fd, size_t data_offset, size_t data } /* update the size in the image */ - shdr->size = htonl(data_size); + shdr->size = data_size; /* update the checksum in the image */ memcpy(shdr->digest, digest, sizeof(digest)); @@ -147,12 +144,14 @@ mtd_fixwrgg(const char *mtd, size_t offset, size_t data_size) } shdr = (struct wrgg03_header *)(first_block + offset); - if (shdr->magic1 != htonl(STORE32_LE(WRGG03_MAGIC))) { - fprintf(stderr, "magic1 %x\n", shdr->magic1); - fprintf(stderr, "htonl(WRGG03_MAGIC) %x\n", WRGG03_MAGIC); + + /* The magic is always stored in little-endian byte order */ + if (le32_to_cpu((uint8_t *)&shdr->magic1) != WRGG03_MAGIC) { + fprintf(stderr, "magic1 = %x\n", shdr->magic1); + fprintf(stderr, "WRGG03_MAGIC = %x\n", WRGG03_MAGIC); fprintf(stderr, "No WRGG header found\n"); exit(1); - } else if (!ntohl(shdr->size)) { + } else if (!shdr->size) { fprintf(stderr, "WRGG entity with empty image\n"); exit(1); } @@ -160,8 +159,8 @@ mtd_fixwrgg(const char *mtd, size_t offset, size_t data_size) data_offset = offset + sizeof(struct wrgg03_header); if (!data_size) data_size = mtdsize - data_offset; - if (data_size > ntohl(shdr->size)) - data_size = ntohl(shdr->size); + if (data_size > shdr->size) + data_size = shdr->size; if (wrgg_fix_md5(shdr, fd, data_offset, data_size)) goto out; diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile index 97c89eec27..561d6d868f 100644 --- a/tools/firmware-utils/Makefile +++ b/tools/firmware-utils/Makefile @@ -32,7 +32,7 @@ define Host/Compile $(call cc,dgfirmware) $(call cc,mksenaofw md5, -Wall --std=gnu99) $(call cc,trx2usr) - $(call cc,ptgen) + $(call cc,ptgen cyg_crc32) $(call cc,srec2bin) $(call cc,mkmylofw) $(call cc,mkcsysimg) diff --git a/tools/firmware-utils/src/mkfwimage.c b/tools/firmware-utils/src/mkfwimage.c index 9e6d8f5b9a..ff9011a0c4 100644 --- a/tools/firmware-utils/src/mkfwimage.c +++ b/tools/firmware-utils/src/mkfwimage.c @@ -137,6 +137,15 @@ struct fw_info fw_info[] = { }, .sign = true, }, + { + .name = "XC", + .fw_layout = { + .kern_start = 0x9f050000, + .kern_entry = 0x80002000, + .firmware_max_length= 0x00F60000, + }, + .sign = true, + }, { .name = "ACB-ISP", .fw_layout = { diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c index 0359c9f614..10178dc714 100644 --- a/tools/firmware-utils/src/tplink-safeloader.c +++ b/tools/firmware-utils/src/tplink-safeloader.c @@ -891,7 +891,7 @@ static struct device_info boards[] = { "{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", .support_trail = '\x00', - .soft_ver = "soft_ver:1.1.1\n", + .soft_ver = "soft_ver:1.2.1\n", .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1021,6 +1021,42 @@ static struct device_info boards[] = { .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", + .support_trail = '\x00', + .soft_ver = "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", @@ -2172,6 +2208,7 @@ static void build_image(const char *output, 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, "TLWR1043NV5") == 0) { const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; parts[5] = put_data("extra-para", mdat, 11);