Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 "")
Expand Down
123 changes: 123 additions & 0 deletions src/mktag_kernel.c
Original file line number Diff line number Diff line change
@@ -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 <[email protected]>
*/

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/stat.h>

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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tool just writes the root fs length into the first 4 bytes and nulls the rest. I think we can do this better in a shell script.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will have a look into it, are there any endianess helpers so that the struct is written the correct way?

int32_t binCrc32;
int32_t reserved[126];
}LINUX_FILE_TAG;

void usage(void) __attribute__ (( __noreturn__ ));

void usage(void)
{
fprintf(stderr, "Usage: mktag_kernel [-s <rootfsLen>] [-o <outputfile>] [-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;
}

40 changes: 40 additions & 0 deletions src/tplink-safeloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
{
Expand Down Expand Up @@ -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};
Expand Down