X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=tools%2Ffirmware-utils%2Fsrc%2Ftplink-safeloader.c;h=03329a392617442da926fda17519f1aec7a43ee7;hp=31b9c032d1b451c24993c5cbcdef85279b694df5;hb=ac03e246351fbfa98e98f0319cce3a8663f836d3;hpb=e3af1666f4f735ca36d17a6b8d0a97e2f23c2cda diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c index 31b9c032d1..03329a3926 100644 --- a/tools/firmware-utils/src/tplink-safeloader.c +++ b/tools/firmware-utils/src/tplink-safeloader.c @@ -1,26 +1,7 @@ +// SPDX-License-Identifier: BSD-2-Clause /* Copyright (c) 2014, Matthias Schiffer All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -33,8 +14,10 @@ #include +#include #include #include +#include #include #include #include @@ -70,23 +53,57 @@ struct flash_partition_entry { 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; - char support_trail; - const char *soft_ver; + 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 { - uint32_t data_len; - uint32_t zero; uint8_t pad1; uint8_t version_major; uint8_t version_minor; @@ -96,6 +113,7 @@ struct __attribute__((__packed__)) soft_version { uint8_t month; uint8_t day; uint32_t rev; + uint32_t compat_level; }; @@ -131,8 +149,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -140,8 +158,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -171,8 +188,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -213,8 +230,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -254,8 +271,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -263,8 +280,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -294,8 +310,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -333,8 +349,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -342,8 +358,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -375,8 +390,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -384,8 +399,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -416,9 +430,12 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + "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}, @@ -426,8 +443,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -457,8 +473,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -466,8 +482,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -497,8 +512,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -506,8 +521,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -520,6 +534,43 @@ static struct device_info boards[] = { .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", @@ -529,8 +580,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -538,8 +589,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -561,8 +611,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -570,8 +620,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -594,8 +643,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -603,8 +652,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -627,8 +675,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -636,8 +684,7 @@ static struct device_info boards[] = { {"default-mac", 0x30000, 0x00020}, {"product-info", 0x31100, 0x00100}, {"signature", 0x32000, 0x00400}, - {"os-image", 0x40000, 0x300000}, - {"file-system", 0x340000, 0x470000}, + {"firmware", 0x40000, 0x770000}, {"soft-version", 0x7b0000, 0x00100}, {"support-list", 0x7b1000, 0x00400}, {"user-config", 0x7c0000, 0x10000}, @@ -651,6 +698,50 @@ static struct device_info boards[] = { .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", @@ -658,8 +749,8 @@ static struct device_info boards[] = { .support_list = "SupportList:\r\n" "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /** We use a bigger os-image partition than the stock images (and thus @@ -708,9 +799,10 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\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 = { @@ -747,8 +839,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:3.0.1\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.1\n"), /** We're using a dynamic kernel/rootfs split here */ @@ -785,8 +877,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\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 = { @@ -824,8 +916,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), .partitions = { {"fs-uboot", 0x00000, 0x10000}, @@ -859,8 +951,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\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 = { @@ -897,8 +989,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:2.0.0 Build 20161206 rel.7303\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 = { @@ -937,8 +1029,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.9.1\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"), .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -972,8 +1064,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.9.1\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"), .partitions = { {"factory-boot", 0x00000, 0x20000}, @@ -997,7 +1089,120 @@ static struct device_info boards[] = { .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", @@ -1007,8 +1212,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), .partitions = { {"fs-uboot", 0x00000, 0x10000}, @@ -1041,8 +1246,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:2.0.0\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"), .partitions = { {"factory-boot", 0x00000, 0x1fb00}, @@ -1077,8 +1282,8 @@ static struct device_info boards[] = { "{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", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.0\n"), .partitions = { {"factory-boot", 0x00000, 0x1fb00}, @@ -1113,8 +1318,8 @@ static struct device_info boards[] = { "{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 */ - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x40000}, @@ -1154,8 +1359,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\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 = { @@ -1199,8 +1404,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\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 = { @@ -1242,8 +1447,8 @@ static struct device_info boards[] = { "{product_name:ArcherC9," "product_ver:1.0.0," "special_id:00000000}\n", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x40000}, @@ -1275,8 +1480,8 @@ static struct device_info boards[] = { .support_list = "SupportList:\r\n" "EAP120(TP-LINK|UN|N300-2):1.0\r\n", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = 0xff, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1298,14 +1503,72 @@ static struct device_info boards[] = { .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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = PART_TRAIL_NONE, + .soft_ver = SOFT_VER_DEFAULT, .soft_ver_compat_level = 1, .partitions = { @@ -1327,14 +1590,69 @@ static struct device_info boards[] = { .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", - .support_trail = '\xff', - .soft_ver = NULL, + .part_trail = PART_TRAIL_NONE, + .soft_ver = SOFT_VER_DEFAULT, .soft_ver_compat_level = 1, /** Firmware partition with dynamic kernel/rootfs split */ @@ -1359,6 +1677,48 @@ static struct device_info boards[] = { .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", @@ -1375,8 +1735,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /** 576KB were moved from file-system to os-image @@ -1417,8 +1777,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1448,8 +1808,8 @@ static struct device_info boards[] = { .support_list = "SupportList:\n" "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"factory-uboot", 0x00000, 0x20000}, @@ -1485,8 +1845,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"factory-uboot", 0x00000, 0x20000}, @@ -1520,8 +1880,8 @@ static struct device_info boards[] = { .support_list = "SupportList:\n" "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"factory-uboot", 0x00000, 0x20000}, @@ -1556,8 +1916,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\x00', - .soft_ver = "soft_ver:1.0.0\n", + .part_trail = 0x00, + .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"), .partitions = { {"factory-boot", 0x00000, 0x20000}, {"fs-uboot", 0x20000, 0x20000}, @@ -1590,8 +1950,8 @@ static struct device_info boards[] = { .support_list = "SupportList:\n" "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /* We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -1623,8 +1983,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /** 384KB were moved from file-system to os-image @@ -1651,6 +2011,37 @@ static struct device_info boards[] = { .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", @@ -1659,8 +2050,8 @@ static struct device_info boards[] = { "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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1706,8 +2097,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1750,8 +2141,52 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .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}, @@ -1793,8 +2228,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1830,8 +2265,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, .partitions = { {"fs-uboot", 0x00000, 0x20000}, @@ -1866,8 +2301,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /** We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -1897,8 +2332,8 @@ static struct device_info boards[] = { .support_list = "SupportList:\n" "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /** We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -1936,8 +2371,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /* We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -1974,8 +2409,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /** We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -2013,8 +2448,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /* We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -2052,8 +2487,48 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .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 = { @@ -2090,8 +2565,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /* We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -2127,8 +2602,8 @@ static struct device_info boards[] = { "{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", - .support_trail = '\x00', - .soft_ver = NULL, + .part_trail = 0x00, + .soft_ver = SOFT_VER_DEFAULT, /* We're using a dynamic kernel/rootfs split here */ .partitions = { @@ -2171,6 +2646,44 @@ static inline void put32(uint8_t *buf, uint32_t val) { 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)}; @@ -2236,14 +2749,16 @@ static inline uint8_t bcd(uint8_t v) { /** Generates the soft-version partition */ -static struct image_partition_entry make_soft_version(struct device_info *info, uint32_t rev) { - size_t part_len = sizeof(struct soft_version); - if (info->soft_ver_compat_level > 0) - part_len += sizeof(uint32_t); - - struct image_partition_entry entry = - alloc_image_partition("soft-version", part_len+1); - struct soft_version *s = (struct soft_version *)entry.data; +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; @@ -2254,58 +2769,46 @@ static struct image_partition_entry make_soft_version(struct device_info *info, struct tm *tm = gmtime(&t); - /* Partition contents size, minus 8 byte header and trailing byte */ - s->data_len = htonl(entry.size-9); - s->zero = 0; - s->pad1 = 0xff; - - s->version_major = 0; - s->version_minor = 0; - s->version_patch = 0; - - s->year_hi = bcd((1900+tm->tm_year)/100); - s->year_lo = bcd(tm->tm_year%100); - s->month = bcd(tm->tm_mon+1); - s->day = bcd(tm->tm_mday); - s->rev = htonl(rev); - - if (info->soft_ver_compat_level > 0) - *(uint32_t *)(entry.data + sizeof(struct soft_version)) = - htonl(info->soft_ver_compat_level); - - entry.data[entry.size-1] = 0xff; + struct soft_version s = { + .pad1 = 0xff, - return entry; -} - -static struct image_partition_entry make_soft_version_from_string(const char *soft_ver) { - /** String length _including_ the terminating zero byte */ - uint32_t ver_len = strlen(soft_ver) + 1; - /** Partition contains 64 bit header, the version string, and one additional null byte */ - size_t partition_len = 2*sizeof(uint32_t) + ver_len + 1; - struct image_partition_entry entry = alloc_image_partition("soft-version", partition_len); + .version_major = info->soft_ver.num[0], + .version_minor = info->soft_ver.num[1], + .version_patch = info->soft_ver.num[2], - uint32_t *len = (uint32_t *)entry.data; - len[0] = htonl(ver_len); - len[1] = 0; - memcpy(&len[2], soft_ver, ver_len); + .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), - entry.data[partition_len - 1] = 0; + .compat_level = htonl(info->soft_ver_compat_level) + }; - return entry; + 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(struct device_info *info) { - size_t len = strlen(info->support_list); - struct image_partition_entry entry = alloc_image_partition("support-list", len + 9); - - put32(entry.data, len); - memset(entry.data+4, 0, 4); - memcpy(entry.data+8, info->support_list, len); - entry.data[len+8] = info->support_trail; +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); +} - return entry; +/** 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 */ @@ -2345,16 +2848,6 @@ static struct image_partition_entry read_file(const char *part_name, const char return entry; } -/** Creates a new image partition from arbitrary data */ -static struct image_partition_entry put_data(const char *part_name, const char *datain, size_t len) { - - struct image_partition_entry entry = alloc_image_partition(part_name, len); - - memcpy(entry.data, datain, len); - - return entry; -} - /** Copies a list of image partitions into an image buffer and generates the image partition table while doing so @@ -2582,36 +3075,37 @@ static void build_image(const char *output, } parts[0] = make_partition_table(info->partitions); - if (info->soft_ver) - parts[1] = make_soft_version_from_string(info->soft_ver); - else - parts[1] = make_soft_version(info, rev); - + 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-C2-V3") == 0 || + 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 char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; - parts[5] = put_data("extra-para", mdat, 11); - } else if (strcasecmp(info->id, "ARCHER-A7-V5") == 0 || strcasecmp(info->id, "ARCHER-C7-V4") == 0 || strcasecmp(info->id, "ARCHER-C7-V5") == 0) { - const char mdat[11] = {0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x01, 0x00, 0x00}; - parts[5] = put_data("extra-para", mdat, 11); - } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0) { - const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; - parts[5] = put_data("extra-para", mdat, 11); - } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0) { - const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}; - parts[5] = put_data("extra-para", mdat, 11); - } else if (strcasecmp(info->id, "EAP245-V3") == 0) { - const char mdat[10] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}; - parts[5] = put_data("extra-para", mdat, 10); + 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; @@ -2644,6 +3138,8 @@ static void usage(const char *argv0) { "Options:\n" " -h show this help\n" "\n" + "Info about an image:\n" + " -i input file to read from\n" "Create a new image:\n" " -B create image for the board specified with \n" " -k read kernel image from the file \n" @@ -2908,10 +3404,124 @@ static struct flash_partition_entry *find_partition( return entries; } - error(1, 0, "%s", error_msg); + 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]; @@ -2991,7 +3601,7 @@ static void convert_firmware(const char *input, const char *output) } int main(int argc, char *argv[]) { - const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL; + 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; @@ -3001,11 +3611,15 @@ int main(int argc, char *argv[]) { while (true) { int c; - c = getopt(argc, argv, "B:k:r:o:V:jSh:x:d:z:"); + 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; @@ -3056,7 +3670,9 @@ int main(int argc, char *argv[]) { } } - if (extract_image || output_directory) { + 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 . Output directory is only valid with -x"); if (!output_directory)