[PATCH firmware-utils] tplink-safeloader: TP-Link Deco M4R-V2 and Deco M5 support

Ole Kristian Lona oklo at oklona.net
Thu Apr 21 00:42:39 PDT 2022


Support for creating images for TP-Link Deco M4R version 3, and for M5.

Partition table and supportlists were extracted from newest OEM image.

Both devices have partition tables with fallback partitions, like:
os-image at 0 and os-image at 1, file-system at 0 and file-system at 1

This is assumed to be a fail-safe built into the firmware of the devices.
Therefore, this naming scheme has been kept, and tplink-safeloader.c
has been slightly modified to account for this.

I have tested without these "@1" and "@0" names. This causes the firmware to be
marked as invalid. Therefore, I made changes to the logic in the app, 
(re?)adding a name parameter to functions, and (last part of the patch)  
 making sure these names are sent to the function correctly.

Signed-off-by: Ole Kristian Lona <oklo at oklona.net>
---
 src/tplink-safeloader.c | 169 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 159 insertions(+), 10 deletions(-)

diff --git a/src/tplink-safeloader.c b/src/tplink-safeloader.c
index c4727df..7b5d2d4 100644
--- a/src/tplink-safeloader.c
+++ b/src/tplink-safeloader.c
@@ -1518,6 +1518,137 @@ static struct device_info boards[] = {
 		.last_sysupgrade_partition = "file-system"
 	},
 
+	/** Firmware layout for the Deco M4R v3 */
+	{
+		.id = "DECO-M4R-V3",
+		.vendor = "",
+		.support_list =
+			"SupportList:\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:55530000}\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:45550000}\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:43410000}\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:4A500000}\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:41550000}\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:4B520000}\n"
+			"{product_name:M4R,product_ver:3.0.0,special_id:42340000}\n",
+		.part_trail = 0x00,
+		.soft_ver = SOFT_VER_DEFAULT,
+
+		.partitions = {
+			{"SBL1", 0x00000, 0x30000},
+			{"boot-config_0", 0x30000, 0x10000},
+			{"MIBIB", 0x40000, 0x10000},
+			{"boot-config_1", 0x50000, 0x10000},
+			{"QSEE", 0x60000, 0x60000},
+			{"CDT", 0xc0000, 0x10000},
+			{"DDRPARAMS", 0xd0000, 0x10000},
+			{"uboot-env", 0xe0000, 0x10000},
+			{"fs-uboot at 0", 0xf0000, 0x80000},
+			{"radio", 0x170000, 0x10000},
+			{"default-mac", 0x180000, 0x01000},
+			{"device-id", 0x182000, 0x01000},
+			{"product-info", 0x183000, 0x05000},
+			{"support-list", 0x190000, 0x10000},
+			{"user-config", 0x200000, 0x10000},
+			{"device-config", 0x210000, 0x10000},
+			{"group-info", 0x220000, 0x10000},
+			{"partition-table at 0", 0x230000, 0x02000},
+			{"os-image at 0", 0x240000, 0x320000},
+			{"file-system at 0", 0x560000, 0xa00000},
+			{"soft-version at 0", 0xf60000, 0x10000},
+			{"profile at 0", 0xf70000, 0x10000},
+			{"default-config at 0", 0xf80000, 0x10000},
+			{"partition-table at 1", 0xf90000, 0x02000},
+			{"fs-uboot at 1", 0xfa0000, 0x80000},
+			{"os-image at 1", 0x1020000, 0x320000},
+			{"file-system at 1", 0x1340000, 0xc40000},
+			{"soft-version at 1", 0x1fc0000, 0x10000},
+			{"profile at 1", 0x1fd0000, 0x10000},
+			{"default-config at 1", 0x1fe0000, 0x10000},
+			{"url-sig", 0x1ff0000, 0x10000},
+			{NULL, 0, 0}
+		},
+
+		.first_sysupgrade_partition = "os-image at 1",
+		.last_sysupgrade_partition = "file-system at 1"
+	},
+
+	/** Firmware layout for the Deco M5 */
+	{
+		.id = "DECO-M5",
+		.vendor = "",
+		.support_list =
+			"SupportList:\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:55530000}\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:45550000}\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:43410000}\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:4A500000}\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:41550000}\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:4B520000}\n"
+			"{product_name:M5,product_ver:1.0.0,special_id:49440000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:55530000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:45550000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:43410000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:4A500000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:41550000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:4B520000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:49440000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:53570000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:42340000}\n"
+			"{product_name:M5,product_ver:3.0.0,special_id:54570000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:55530000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:45550000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:43410000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:4A500000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:41550000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:4B520000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:49440000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:53570000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:42340000}\n"
+			"{product_name:M5,product_ver:3.2.0,special_id:54570000}\n",
+		.part_trail = 0x00,
+		.soft_ver = SOFT_VER_DEFAULT,
+
+		.partitions = {
+			{"SBL1", 0x00000, 0x30000},
+			{"boot-config_0", 0x30000, 0x10000},
+			{"MIBIB", 0x40000, 0x10000},
+			{"boot-config_1", 0x50000, 0x10000},
+			{"QSEE", 0x60000, 0x60000},
+			{"CDT", 0xc0000, 0x10000},
+			{"DDRPARAMS", 0xd0000, 0x10000},
+			{"uboot-env", 0xe0000, 0x10000},
+			{"fs-uboot at 0", 0xf0000, 0x80000},
+			{"radio", 0x170000, 0x0fff0},
+			{"bluetooth-XTAL", 0x17fff0, 0x00010},
+			{"default-mac", 0x180000, 0x01000},
+			{"device-id", 0x182000, 0x01000},
+			{"product-info", 0x183000, 0x05000},
+			{"support-list", 0x190000, 0x10000},
+			{"user-config", 0x200000, 0x10000},
+			{"device-config", 0x210000, 0x10000},
+			{"group-info", 0x220000, 0x10000},
+			{"partition-table at 0", 0x230000, 0x02000},
+			{"os-image at 0", 0x240000, 0x300000},
+			{"file-system at 0", 0x540000, 0x790000},
+			{"soft-version at 0", 0xcd0000, 0x10000},
+			{"profile at 0", 0xce0000, 0x10000},
+			{"default-config at 0", 0xcf0000, 0x10000},
+			{"partition-table at 1", 0xd00000, 0x02000},
+			{"fs-uboot at 1", 0xd10000, 0x80000},
+			{"os-image at 1", 0xd90000, 0x400000},
+			{"file-system at 1", 0x1190000, 0xc40000},
+			{"soft-version at 1", 0x1dd0000, 0x10000},
+			{"profile at 1", 0x1de0000, 0x10000},
+			{"default-config at 1", 0x1df0000, 0x10000},
+			{"tm-sig", 0x1e00000, 0x200000},
+			{NULL, 0, 0}
+		},
+
+		.first_sysupgrade_partition = "os-image at 1",
+		.last_sysupgrade_partition = "file-system at 1"
+	},
+
 	/** Firmware layout for the EAP120 */
 	{
 		.id     = "EAP120",
@@ -2895,8 +3026,8 @@ static void set_source_date_epoch() {
 }
 
 /** 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);
+static struct image_partition_entry make_partition_table(const char *name,const struct flash_partition_entry *p) {
+	struct image_partition_entry entry = alloc_image_partition(name, 0x800);
 
 	char *s = (char *)entry.data, *end = (char *)(s+entry.size);
 
@@ -2931,14 +3062,14 @@ static inline uint8_t bcd(uint8_t v) {
 
 
 /** Generates the soft-version partition */
-static struct image_partition_entry make_soft_version(
+static struct image_partition_entry make_soft_version(const char *name,
 	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",
+		return init_meta_partition_entry(name,
 			info->soft_ver.text, len, info->part_trail);
 	}
 
@@ -2968,11 +3099,11 @@ static struct image_partition_entry make_soft_version(
 	};
 
 	if (info->soft_ver_compat_level == 0)
-		return init_meta_partition_entry("soft-version", &s,
+		return init_meta_partition_entry(name, &s,
 			(uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
 			info->part_trail);
 	else
-		return init_meta_partition_entry("soft-version", &s,
+		return init_meta_partition_entry(name, &s,
 			sizeof(s), info->part_trail);
 }
 
@@ -3213,6 +3344,11 @@ static void build_image(const char *output,
 
 	size_t i;
 
+	char *part_table_name;
+	char *soft_ver_name;
+	char *os_im_name;
+	char *fs_name;
+
 	struct image_partition_entry parts[7] = {};
 
 	struct flash_partition_entry *firmware_partition = NULL;
@@ -3256,11 +3392,24 @@ static void build_image(const char *output,
 		os_image_partition->size = kernel.st_size;
 	}
 
-	parts[0] = make_partition_table(info->partitions);
-	parts[1] = make_soft_version(info, rev);
+	if (strcasecmp(info->id, "DECO-M4R-V3") == 0 ||
+		strcasecmp(info->id, "DECO-M5") == 0 ) {
+		part_table_name="partition-table at 1";
+		soft_ver_name="soft-version at 1";
+		os_im_name="os-image at 1";
+		fs_name="file-system at 1";
+	} else {
+		part_table_name="partition-table";
+		soft_ver_name="soft-version";
+		os_im_name="os-image";
+		fs_name="file-system";
+	}
+
+	parts[0] = make_partition_table(part_table_name,info->partitions);
+	parts[1] = make_soft_version(soft_ver_name,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);
+	parts[3] = read_file(os_im_name, kernel_image, false, NULL);
+	parts[4] = read_file(fs_name, 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 ||
-- 
2.32.0




More information about the openwrt-devel mailing list