diff --git a/CMakeLists.txt b/CMakeLists.txt index c2b7199..f4bbedd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,7 @@ FW_UTIL(mkrasimage "" --std=gnu99 "") FW_UTIL(mkrtn56uimg "" "" "${ZLIB_LIBRARIES}") FW_UTIL(mksenaofw src/md5.c --std=gnu99 "") FW_UTIL(mksercommfw "" "" "") +FW_UTIL(mktag_kernel "" "" "") FW_UTIL(mktitanimg "" "" "") FW_UTIL(mktplinkfw "src/mktplinkfw-lib.c;src/md5.c" -fgnu89-inline "") FW_UTIL(mktplinkfw2 "src/mktplinkfw-lib.c;src/md5.c" -fgnu89-inline "") diff --git a/src/mktag_kernel.c b/src/mktag_kernel.c new file mode 100644 index 0000000..4d8b860 --- /dev/null +++ b/src/mktag_kernel.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * mktag_kernel.c - utility to write the tag_kernel file for TP Link Deco X20 jffs2 filesystem lookup + * + * Copyright (C) 2024 Damien Mascord + */ + +#include +#include +#include +#include +#include +#include +#include + +int fpread(void *buffer, size_t size, size_t nitems, size_t offset, FILE *fp); + +typedef struct __attribute__((scalar_storage_order("little-endian"))) _LINUX_FILE_TAG +{ + int32_t rootfsLen; + int32_t binCrc32; + int32_t reserved[126]; +}LINUX_FILE_TAG; + +void usage(void) __attribute__ (( __noreturn__ )); + +void usage(void) +{ + fprintf(stderr, "Usage: mktag_kernel [-s ] [-o ] [-t (test mode)]\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 *ofn = NULL, *rootfsLen = NULL; + size_t n; + int c, first_block = 1; + unsigned char tag_buf[sizeof(LINUX_FILE_TAG)]; + LINUX_FILE_TAG * pKern_tag = (LINUX_FILE_TAG *)tag_buf; + int testMode = 0; + + while ((c = getopt(argc, argv, "s:o:h:t")) != -1) { + switch (c) { + case 's': + rootfsLen = optarg; + break; + case 'o': + ofn = optarg; + break; + case 't': + testMode = 1; + break; + case 'h': + default: + usage(); + } + } + + if (ofn && !(out = fopen(ofn, "wb"))) { + fprintf(stderr, "can not open \"%s\" for writing\n", ofn); + usage(); + } + + memset(tag_buf, 0, sizeof(LINUX_FILE_TAG)); + + if (!rootfsLen) + { + usage(); + } + + pKern_tag->rootfsLen = strtol(rootfsLen, NULL, 10); + pKern_tag->binCrc32 = 0; + + if (testMode) + { + for (int xx = 0; xx < sizeof(LINUX_FILE_TAG); xx++) + { + printf("%.2X", ((unsigned char *)pKern_tag)[xx]); + } + printf("\n"); + } + + int flag = 0; + flag = fwrite(pKern_tag, sizeof(LINUX_FILE_TAG), 1, out); + fflush(out); + fclose(out); + + if (testMode) + { + if (ofn && !(out = fopen(ofn, "rb"))) { + fprintf(stderr, "can not open \"%s\" for reading\n", ofn); + usage(); + } + //clear it out + memset(tag_buf, 0, sizeof(LINUX_FILE_TAG)); + fpread(tag_buf, 1, sizeof(LINUX_FILE_TAG), 0, out); + } + +} + + +int fpread(void *buffer, size_t size, size_t nitems, size_t offset, FILE *fp) +{ + printf("fpread %d %d %d \n", size, nitems, offset); + int seekPosition = fseek(fp, offset, SEEK_SET); + printf("seekPosition: %d\n", seekPosition); + if(seekPosition != 0) + { + printf("unable to seek to %d\n", offset); + return 0; + } + int returnValue = fread(buffer, size, nitems, fp); + printf("returnValue %d:\n",returnValue); + for (int i = 0; i < nitems; i++) + { + printf("%.2X", ((unsigned char *)buffer)[i]); + } + printf(".\n"); + return returnValue; +} + diff --git a/src/tplink-safeloader.c b/src/tplink-safeloader.c index cb028d2..3bc2083 100644 --- a/src/tplink-safeloader.c +++ b/src/tplink-safeloader.c @@ -1919,6 +1919,45 @@ static struct device_info boards[] = { .first_sysupgrade_partition = "os-image", .last_sysupgrade_partition = "file-system", }, + + /** Firmware layout for the Deco X20 v3 */ + { + .id = "DECO-X20-V3", + .vendor = "", + .support_list = + "SupportList:\n" + "{product_name:X20,product_ver:3.0.0,special_id:55530000}\n" + "{product_name:X20,product_ver:3.0.0,special_id:45550000}\n" + "{product_name:X20,product_ver:3.0.0,special_id:42340000}\n" + "{product_name:X20,product_ver:3.0.0,special_id:45470000}\n" + "{product_name:X20,product_ver:3.0.0,special_id:4A500000}\n" + "{product_name:X20,product_ver:3.0.0,special_id:53450000}\n" + "{product_name:X25,product_ver:3.0.0,special_id:55530000}\n" + "{product_name:W3600,product_ver:3.0.0,special_id:55530000}\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, + + .partitions = { + {"fs-uboot", 0x00000, 0x80000}, + {"product-info", 0x80000, 0x05000}, + {"default-mac", 0x85000, 0x01000}, + {"device-id", 0x86000, 0x01000}, + {"support-list", 0x87000, 0x10000}, + {"user-config", 0xa7000, 0x10000}, + {"device-config", 0xb7000, 0x10000}, + {"group-info", 0xc7000, 0x10000}, + {"partition-table", 0xd7000, 0x02000}, + {"soft-version", 0xd9000, 0x10000}, + {"profile", 0xe9000, 0x10000}, + {"default-config", 0xf9000, 0x10000}, + {"url-sig", 0x1e0000, 0x10000}, + {"radio", 0x1f0000, 0x10000}, + {"firmware", 0x200000, 0xe00000}, + {NULL, 0, 0} + }, + .first_sysupgrade_partition = "os-image", + .last_sysupgrade_partition = "file-system", + }, /** Firmware layout for the EAP120 */ { @@ -3921,6 +3960,7 @@ static void build_image(const char *output, strcasecmp(info->id, "ARCHER-C6U-V1") == 0 || strcasecmp(info->id, "ARCHER-C6-V3") == 0 || strcasecmp(info->id, "DECO-M4R-V4") == 0 || + strcasecmp(info->id, "DECO-X20-V3") == 0 || strcasecmp(info->id, "MR70X") == 0 || strcasecmp(info->id, "TLWR1043NV5") == 0) { const uint8_t extra_para[2] = {0x01, 0x00};