• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/tplink-safeloader.c

  1 // SPDX-License-Identifier: BSD-2-Clause
  2 /*
  3   Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
  4   All rights reserved.
  5 */
  6 
  7 
  8 /*
  9    tplink-safeloader
 10 
 11    Image generation tool for the TP-LINK SafeLoader as seen on
 12    TP-LINK Pharos devices (CPE210/220/510/520)
 13 */
 14 
 15 
 16 #include <assert.h>
 17 #include <ctype.h>
 18 #include <errno.h>
 19 #include <stdbool.h>
 20 #include <stddef.h>
 21 #include <stdio.h>
 22 #include <stdint.h>
 23 #include <stdlib.h>
 24 #include <string.h>
 25 #include <time.h>
 26 #include <unistd.h>
 27 
 28 #include <arpa/inet.h>
 29 
 30 #include <sys/types.h>
 31 #include <sys/stat.h>
 32 #include <limits.h>
 33 
 34 #include "md5.h"
 35 
 36 
 37 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
 38 
 39 
 40 #define MAX_PARTITIONS  32
 41 
 42 /** An image partition table entry */
 43 struct image_partition_entry {
 44         const char *name;
 45         size_t size;
 46         uint8_t *data;
 47 };
 48 
 49 /** A flash partition table entry */
 50 struct flash_partition_entry {
 51         const char *name;
 52         uint32_t base;
 53         uint32_t size;
 54 };
 55 
 56 /** Flash partition names table entry */
 57 struct factory_partition_names {
 58         const char *partition_table;
 59         const char *soft_ver;
 60         const char *os_image;
 61         const char *support_list;
 62         const char *file_system;
 63         const char *extra_para;
 64 };
 65 
 66 /** Partition trailing padding definitions
 67  * Values 0x00 to 0xff are reserved to indicate the padding value
 68  * Values from 0x100 are reserved to indicate other behaviour */
 69 enum partition_trail_value {
 70         PART_TRAIL_00   = 0x00,
 71         PART_TRAIL_FF   = 0xff,
 72         PART_TRAIL_MAX  = 0xff,
 73         PART_TRAIL_NONE = 0x100
 74 };
 75 
 76 /** soft-version value overwrite types
 77  * The default (for an uninitialised soft_ver field) is to use the numerical
 78  * version number "0.0.0"
 79  */
 80 enum soft_ver_type {
 81         SOFT_VER_TYPE_NUMERIC = 0,
 82         SOFT_VER_TYPE_TEXT = 1,
 83 };
 84 
 85 /** Firmware layout description */
 86 struct device_info {
 87         const char *id;
 88         const char *vendor;
 89         const char *support_list;
 90         enum partition_trail_value part_trail;
 91         struct {
 92                 enum soft_ver_type type;
 93                 union {
 94                         const char *text;
 95                         uint8_t num[3];
 96                 };
 97         } soft_ver;
 98         uint32_t soft_ver_compat_level;
 99         struct flash_partition_entry partitions[MAX_PARTITIONS+1];
100         const char *first_sysupgrade_partition;
101         const char *last_sysupgrade_partition;
102         struct factory_partition_names partition_names;
103 };
104 
105 #define SOFT_VER_TEXT(_t) {.type = SOFT_VER_TYPE_TEXT, .text = _t}
106 #define SOFT_VER_NUMERIC(_maj, _min, _patch) {  \
107                 .type = SOFT_VER_TYPE_NUMERIC,          \
108                 .num = {_maj, _min, _patch}}
109 #define SOFT_VER_DEFAULT SOFT_VER_NUMERIC(0, 0, 0)
110 
111 struct __attribute__((__packed__)) meta_header {
112         uint32_t length;
113         uint32_t zero;
114 };
115 
116 /** The content of the soft-version structure */
117 struct __attribute__((__packed__)) soft_version {
118         uint8_t pad1;
119         uint8_t version_major;
120         uint8_t version_minor;
121         uint8_t version_patch;
122         uint8_t year_hi;
123         uint8_t year_lo;
124         uint8_t month;
125         uint8_t day;
126         uint32_t rev;
127         uint32_t compat_level;
128 };
129 
130 /*
131  * Safeloader image type
132  *   Safeloader images contain a 0x14 byte preamble with image size (big endian
133  *   UINT32) and md5 checksum (16 bytes).
134  *
135  * SAFEFLOADER_TYPE_DEFAULT
136  *   Standard preamble with size including preamble length, and checksum.
137  *   Header of 0x1000 bytes, contents of which are not specified.
138  *   Payload starts at offset 0x1014.
139  *
140  * SAFELOADER_TYPE_VENDOR
141  *   Standard preamble with size including preamble length, and checksum.
142  *   Header contains up to 0x1000 bytes of vendor data, starting with a big endian
143  *   UINT32 size, followed by that number of bytes containing (text) data.
144  *   Padded with 0xFF. Payload starts at offset 0x1014.
145  *
146  * SAFELOADER_TYPE_CLOUD
147  *   Standard preamble with size including preamble length, and checksum.
148  *   Followed by the 'fw-type:Cloud' string and some (unknown) data.
149  *   Payload starts at offset 0x1014.
150  *
151  * SAFELOADER_TYPE_QNEW
152  *   Reversed order preamble, with (apparent) md5 checksum before the image
153  *   size. The size does not include the preamble length.
154  *   Header starts with 0x3C bytes, starting with the string '?NEW' (format not
155  *   understood). Then another 0x1000 bytes follow, with the data payload
156  *   starting at 0x1050.
157  */
158 enum safeloader_image_type {
159         SAFELOADER_TYPE_DEFAULT,
160         SAFELOADER_TYPE_VENDOR,
161         SAFELOADER_TYPE_CLOUD,
162         SAFELOADER_TYPE_QNEW,
163 };
164 
165 /* Internal representation of safeloader image data */
166 struct safeloader_image_info {
167         enum safeloader_image_type type;
168         size_t payload_offset;
169         struct flash_partition_entry entries[MAX_PARTITIONS];
170 };
171 
172 #define SAFELOADER_PREAMBLE_SIZE        0x14
173 #define SAFELOADER_HEADER_SIZE          0x1000
174 #define SAFELOADER_PAYLOAD_OFFSET       (SAFELOADER_PREAMBLE_SIZE + SAFELOADER_HEADER_SIZE)
175 
176 #define SAFELOADER_QNEW_HEADER_SIZE     0x3C
177 #define SAFELOADER_QNEW_PAYLOAD_OFFSET  \
178         (SAFELOADER_PREAMBLE_SIZE + SAFELOADER_QNEW_HEADER_SIZE + SAFELOADER_HEADER_SIZE)
179 
180 #define SAFELOADER_PAYLOAD_TABLE_SIZE   0x800
181 
182 static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
183 
184 
185 /**
186    Salt for the MD5 hash
187 
188    Fortunately, TP-LINK seems to use the same salt for most devices which use
189    the new image format.
190 */
191 static const uint8_t md5_salt[16] = {
192         0x7a, 0x2b, 0x15, 0xed,
193         0x9b, 0x98, 0x59, 0x6d,
194         0xe5, 0x04, 0xab, 0x44,
195         0xac, 0x2a, 0x9f, 0x4e,
196 };
197 
198 
199 /** Firmware layout table */
200 static struct device_info boards[] = {
201         /** Firmware layout for the CPE210/220 V1 */
202         {
203                 .id     = "CPE210",
204                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
205                 .support_list =
206                         "SupportList:\r\n"
207                         "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
208                         "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
209                         "CPE210(TP-LINK|US|N300-2):1.1\r\n"
210                         "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
211                         "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
212                         "CPE220(TP-LINK|US|N300-2):1.1\r\n"
213                         "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
214                 .part_trail = 0xff,
215                 .soft_ver = SOFT_VER_DEFAULT,
216 
217                 .partitions = {
218                         {"fs-uboot", 0x00000, 0x20000},
219                         {"partition-table", 0x20000, 0x02000},
220                         {"default-mac", 0x30000, 0x00020},
221                         {"product-info", 0x31100, 0x00100},
222                         {"signature", 0x32000, 0x00400},
223                         {"firmware", 0x40000, 0x770000},
224                         {"soft-version", 0x7b0000, 0x00100},
225                         {"support-list", 0x7b1000, 0x00400},
226                         {"user-config", 0x7c0000, 0x10000},
227                         {"default-config", 0x7d0000, 0x10000},
228                         {"log", 0x7e0000, 0x10000},
229                         {"radio", 0x7f0000, 0x10000},
230                         {NULL, 0, 0}
231                 },
232 
233                 .first_sysupgrade_partition = "os-image",
234                 .last_sysupgrade_partition = "support-list",
235         },
236 
237         /** Firmware layout for the CPE210 V2 */
238         {
239                 .id     = "CPE210V2",
240                 .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
241                 .support_list =
242                         "SupportList:\r\n"
243                         "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
244                         "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
245                         "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
246                         "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
247                         "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
248                         "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
249                         "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
250                         "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
251                         "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
252                         "CPE210(TP-LINK|US|N300-2):2.0\r\n",
253                 .part_trail = 0xff,
254                 .soft_ver = SOFT_VER_DEFAULT,
255 
256                 .partitions = {
257                         {"fs-uboot", 0x00000, 0x20000},
258                         {"partition-table", 0x20000, 0x02000},
259                         {"default-mac", 0x30000, 0x00020},
260                         {"product-info", 0x31100, 0x00100},
261                         {"device-info", 0x31400, 0x00400},
262                         {"signature", 0x32000, 0x00400},
263                         {"device-id", 0x33000, 0x00100},
264                         {"firmware", 0x40000, 0x770000},
265                         {"soft-version", 0x7b0000, 0x00100},
266                         {"support-list", 0x7b1000, 0x01000},
267                         {"user-config", 0x7c0000, 0x10000},
268                         {"default-config", 0x7d0000, 0x10000},
269                         {"log", 0x7e0000, 0x10000},
270                         {"radio", 0x7f0000, 0x10000},
271                         {NULL, 0, 0}
272                 },
273 
274                 .first_sysupgrade_partition = "os-image",
275                 .last_sysupgrade_partition = "support-list",
276         },
277 
278         /** Firmware layout for the CPE210 V3 */
279         {
280                 .id     = "CPE210V3",
281                 .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n",
282                 .support_list =
283                         "SupportList:\r\n"
284                         "CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n"
285                         "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n"
286                         "CPE210(TP-LINK|US|N300-2|55530000):3.0\r\n"
287                         "CPE210(TP-LINK|UN|N300-2):3.0\r\n"
288                         "CPE210(TP-LINK|EU|N300-2):3.0\r\n"
289                         "CPE210(TP-LINK|EU|N300-2|45550000):3.1\r\n"
290                         "CPE210(TP-LINK|UN|N300-2|00000000):3.1\r\n"
291                         "CPE210(TP-LINK|US|N300-2|55530000):3.1\r\n"
292                         "CPE210(TP-LINK|EU|N300-2|45550000):3.20\r\n"
293                         "CPE210(TP-LINK|UN|N300-2|00000000):3.20\r\n"
294                         "CPE210(TP-LINK|US|N300-2|55530000):3.20\r\n",
295                 .part_trail = 0xff,
296                 .soft_ver = SOFT_VER_DEFAULT,
297 
298                 .partitions = {
299                         {"fs-uboot", 0x00000, 0x20000},
300                         {"partition-table", 0x20000, 0x01000},
301                         {"default-mac", 0x30000, 0x00020},
302                         {"product-info", 0x31100, 0x00100},
303                         {"device-info", 0x31400, 0x00400},
304                         {"signature", 0x32000, 0x00400},
305                         {"device-id", 0x33000, 0x00100},
306                         {"firmware", 0x40000, 0x770000},
307                         {"soft-version", 0x7b0000, 0x00100},
308                         {"support-list", 0x7b1000, 0x01000},
309                         {"user-config", 0x7c0000, 0x10000},
310                         {"default-config", 0x7d0000, 0x10000},
311                         {"log", 0x7e0000, 0x10000},
312                         {"radio", 0x7f0000, 0x10000},
313                         {NULL, 0, 0}
314                 },
315 
316                 .first_sysupgrade_partition = "os-image",
317                 .last_sysupgrade_partition = "support-list",
318         },
319 
320         /** Firmware layout for the CPE220 V2 */
321         {
322                 .id     = "CPE220V2",
323                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
324                 .support_list =
325                         "SupportList:\r\n"
326                         "CPE220(TP-LINK|EU|N300-2|00000000):2.0\r\n"
327                         "CPE220(TP-LINK|EU|N300-2|45550000):2.0\r\n"
328                         "CPE220(TP-LINK|EU|N300-2|55530000):2.0\r\n"
329                         "CPE220(TP-LINK|UN|N300-2|00000000):2.0\r\n"
330                         "CPE220(TP-LINK|UN|N300-2|45550000):2.0\r\n"
331                         "CPE220(TP-LINK|UN|N300-2|55530000):2.0\r\n"
332                         "CPE220(TP-LINK|US|N300-2|55530000):2.0\r\n"
333                         "CPE220(TP-LINK|UN|N300-2):2.0\r\n"
334                         "CPE220(TP-LINK|EU|N300-2):2.0\r\n"
335                         "CPE220(TP-LINK|US|N300-2):2.0\r\n",
336                 .part_trail = 0xff,
337                 .soft_ver = SOFT_VER_DEFAULT,
338 
339                 .partitions = {
340                         {"fs-uboot", 0x00000, 0x20000},
341                         {"partition-table", 0x20000, 0x02000},
342                         {"default-mac", 0x30000, 0x00020},
343                         {"product-info", 0x31100, 0x00100},
344                         {"signature", 0x32000, 0x00400},
345                         {"firmware", 0x40000, 0x770000},
346                         {"soft-version", 0x7b0000, 0x00100},
347                         {"support-list", 0x7b1000, 0x00400},
348                         {"user-config", 0x7c0000, 0x10000},
349                         {"default-config", 0x7d0000, 0x10000},
350                         {"log", 0x7e0000, 0x10000},
351                         {"radio", 0x7f0000, 0x10000},
352                         {NULL, 0, 0}
353                 },
354 
355                 .first_sysupgrade_partition = "os-image",
356                 .last_sysupgrade_partition = "support-list",
357         },
358 
359         /** Firmware layout for the CPE220 V3 */
360         {
361                 .id     = "CPE220V3",
362                 .vendor = "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n",
363                 .support_list =
364                         "SupportList:\r\n"
365                         "CPE220(TP-LINK|EU|N300-2|00000000):3.0\r\n"
366                         "CPE220(TP-LINK|EU|N300-2|45550000):3.0\r\n"
367                         "CPE220(TP-LINK|EU|N300-2|55530000):3.0\r\n"
368                         "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n"
369                         "CPE220(TP-LINK|UN|N300-2|45550000):3.0\r\n"
370                         "CPE220(TP-LINK|UN|N300-2|55530000):3.0\r\n"
371                         "CPE220(TP-LINK|US|N300-2|55530000):3.0\r\n"
372                         "CPE220(TP-LINK|UN|N300-2):3.0\r\n"
373                         "CPE220(TP-LINK|EU|N300-2):3.0\r\n"
374                         "CPE220(TP-LINK|US|N300-2):3.0\r\n",
375                 .part_trail = 0xff,
376                 .soft_ver = SOFT_VER_DEFAULT,
377 
378                 .partitions = {
379                         {"fs-uboot", 0x00000, 0x20000},
380                         {"partition-table", 0x20000, 0x02000},
381                         {"default-mac", 0x30000, 0x00020},
382                         {"product-info", 0x31100, 0x00100},
383                         {"device-info", 0x31400, 0x00400},
384                         {"signature", 0x32000, 0x00400},
385                         {"device-id", 0x33000, 0x00100},
386                         {"firmware", 0x40000, 0x770000},
387                         {"soft-version", 0x7b0000, 0x00100},
388                         {"support-list", 0x7b1000, 0x01000},
389                         {"user-config", 0x7c0000, 0x10000},
390                         {"default-config", 0x7d0000, 0x10000},
391                         {"log", 0x7e0000, 0x10000},
392                         {"radio", 0x7f0000, 0x10000},
393                         {NULL, 0, 0}
394                 },
395 
396                 .first_sysupgrade_partition = "os-image",
397                 .last_sysupgrade_partition = "support-list",
398         },
399 
400         /** Firmware layout for the CPE510/520 V1 */
401         {
402                 .id     = "CPE510",
403                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
404                 .support_list =
405                         "SupportList:\r\n"
406                         "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
407                         "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
408                         "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
409                         "CPE510(TP-LINK|US|N300-5):1.1\r\n"
410                         "CPE510(TP-LINK|CA|N300-5):1.1\r\n"
411                         "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
412                         "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
413                         "CPE520(TP-LINK|US|N300-5):1.1\r\n"
414                         "CPE520(TP-LINK|EU|N300-5):1.1\r\n",
415                 .part_trail = 0xff,
416                 .soft_ver = SOFT_VER_DEFAULT,
417 
418                 .partitions = {
419                         {"fs-uboot", 0x00000, 0x20000},
420                         {"partition-table", 0x20000, 0x02000},
421                         {"default-mac", 0x30000, 0x00020},
422                         {"product-info", 0x31100, 0x00100},
423                         {"signature", 0x32000, 0x00400},
424                         {"firmware", 0x40000, 0x770000},
425                         {"soft-version", 0x7b0000, 0x00100},
426                         {"support-list", 0x7b1000, 0x00400},
427                         {"user-config", 0x7c0000, 0x10000},
428                         {"default-config", 0x7d0000, 0x10000},
429                         {"log", 0x7e0000, 0x10000},
430                         {"radio", 0x7f0000, 0x10000},
431                         {NULL, 0, 0}
432                 },
433 
434                 .first_sysupgrade_partition = "os-image",
435                 .last_sysupgrade_partition = "support-list",
436         },
437 
438         /** Firmware layout for the CPE510 V2 */
439         {
440                 .id     = "CPE510V2",
441                 .vendor = "CPE510(TP-LINK|UN|N300-5):2.0\r\n",
442                 .support_list =
443                         "SupportList:\r\n"
444                         "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n"
445                         "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
446                         "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n"
447                         "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
448                         "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n"
449                         "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n"
450                         "CPE510(TP-LINK|US|N300-5|00000000):2.0\r\n"
451                         "CPE510(TP-LINK|US|N300-5|45550000):2.0\r\n"
452                         "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n"
453                         "CPE510(TP-LINK|UN|N300-5):2.0\r\n"
454                         "CPE510(TP-LINK|EU|N300-5):2.0\r\n"
455                         "CPE510(TP-LINK|US|N300-5):2.0\r\n",
456                 .part_trail = 0xff,
457                 .soft_ver = SOFT_VER_DEFAULT,
458 
459                 .partitions = {
460                         {"fs-uboot", 0x00000, 0x20000},
461                         {"partition-table", 0x20000, 0x02000},
462                         {"default-mac", 0x30000, 0x00020},
463                         {"product-info", 0x31100, 0x00100},
464                         {"signature", 0x32000, 0x00400},
465                         {"firmware", 0x40000, 0x770000},
466                         {"soft-version", 0x7b0000, 0x00100},
467                         {"support-list", 0x7b1000, 0x00400},
468                         {"user-config", 0x7c0000, 0x10000},
469                         {"default-config", 0x7d0000, 0x10000},
470                         {"log", 0x7e0000, 0x10000},
471                         {"radio", 0x7f0000, 0x10000},
472                         {NULL, 0, 0}
473                 },
474 
475                 .first_sysupgrade_partition = "os-image",
476                 .last_sysupgrade_partition = "support-list",
477         },
478 
479         /** Firmware layout for the CPE510 V3 */
480         {
481                 .id     = "CPE510V3",
482                 .vendor = "CPE510(TP-LINK|UN|N300-5):3.0\r\n",
483                 .support_list =
484                         "SupportList:\r\n"
485                         "CPE510(TP-LINK|EU|N300-5|00000000):3.0\r\n"
486                         "CPE510(TP-LINK|EU|N300-5|45550000):3.0\r\n"
487                         "CPE510(TP-LINK|EU|N300-5|55530000):3.0\r\n"
488                         "CPE510(TP-LINK|UN|N300-5|00000000):3.0\r\n"
489                         "CPE510(TP-LINK|UN|N300-5|45550000):3.0\r\n"
490                         "CPE510(TP-LINK|UN|N300-5|55530000):3.0\r\n"
491                         "CPE510(TP-LINK|US|N300-5|00000000):3.0\r\n"
492                         "CPE510(TP-LINK|US|N300-5|45550000):3.0\r\n"
493                         "CPE510(TP-LINK|US|N300-5|55530000):3.0\r\n"
494                         "CPE510(TP-LINK|UN|N300-5):3.0\r\n"
495                         "CPE510(TP-LINK|EU|N300-5):3.0\r\n"
496                         "CPE510(TP-LINK|US|N300-5):3.0\r\n"
497                         "CPE510(TP-LINK|UN|N300-5|00000000):3.20\r\n"
498                         "CPE510(TP-LINK|US|N300-5|55530000):3.20\r\n"
499                         "CPE510(TP-LINK|EU|N300-5|45550000):3.20\r\n",
500                 .part_trail = 0xff,
501                 .soft_ver = SOFT_VER_DEFAULT,
502 
503                 .partitions = {
504                         {"fs-uboot", 0x00000, 0x20000},
505                         {"partition-table", 0x20000, 0x02000},
506                         {"default-mac", 0x30000, 0x00020},
507                         {"product-info", 0x31100, 0x00100},
508                         {"signature", 0x32000, 0x00400},
509                         {"firmware", 0x40000, 0x770000},
510                         {"soft-version", 0x7b0000, 0x00100},
511                         {"support-list", 0x7b1000, 0x00400},
512                         {"user-config", 0x7c0000, 0x10000},
513                         {"default-config", 0x7d0000, 0x10000},
514                         {"log", 0x7e0000, 0x10000},
515                         {"radio", 0x7f0000, 0x10000},
516                         {NULL, 0, 0}
517                 },
518 
519                 .first_sysupgrade_partition = "os-image",
520                 .last_sysupgrade_partition = "support-list",
521         },
522 
523         /** Firmware layout for the CPE605V1 */
524         {
525                 .id     = "CPE605V1",
526                 .vendor = "CPE605(TP-LINK|UN|N150-5):1.0\r\n",
527                 .support_list =
528                         "SupportList:\r\n"
529                         "CPE605(TP-LINK|UN|N150-5|00000000):1.0\r\n"
530                         "CPE605(TP-LINK|EU|N150-5|45550000):1.0\r\n"
531                         "CPE605(TP-LINK|US|N150-5|55530000):1.0\r\n",
532                 .part_trail = 0x00,
533                 .soft_ver = SOFT_VER_DEFAULT,
534 
535                 .partitions = {
536                         {"fs-uboot", 0x00000, 0x20000},
537                         {"partition-table", 0x20000, 0x02000},
538                         {"default-mac", 0x30000, 0x00020},
539                         {"serial-number", 0x30100, 0x00020},
540                         {"product-info", 0x31100, 0x00100},
541                         {"device-info", 0x31400, 0x00400},
542                         {"signature", 0x32000, 0x00400},
543                         {"device-id", 0x33000, 0x00100},
544                         {"firmware", 0x40000, 0x770000},
545                         {"soft-version", 0x7b0000, 0x00100},
546                         {"support-list", 0x7b1000, 0x01000},
547                         {"user-config", 0x7c0000, 0x10000},
548                         {"default-config", 0x7d0000, 0x10000},
549                         {"log", 0x7e0000, 0x10000},
550                         {"radio", 0x7f0000, 0x10000},
551                         {NULL, 0, 0}
552                 },
553 
554                 .first_sysupgrade_partition = "os-image",
555                 .last_sysupgrade_partition = "support-list",
556         },
557 
558         /** Firmware layout for the CPE610V1 */
559         {
560                 .id     = "CPE610V1",
561                 .vendor = "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n",
562                 .support_list =
563                         "SupportList:\r\n"
564                         "CPE610(TP-LINK|EU|N300-5|00000000):1.0\r\n"
565                         "CPE610(TP-LINK|EU|N300-5|45550000):1.0\r\n"
566                         "CPE610(TP-LINK|EU|N300-5|55530000):1.0\r\n"
567                         "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n"
568                         "CPE610(TP-LINK|UN|N300-5|45550000):1.0\r\n"
569                         "CPE610(TP-LINK|UN|N300-5|55530000):1.0\r\n"
570                         "CPE610(TP-LINK|US|N300-5|55530000):1.0\r\n"
571                         "CPE610(TP-LINK|UN|N300-5):1.0\r\n"
572                         "CPE610(TP-LINK|EU|N300-5):1.0\r\n"
573                         "CPE610(TP-LINK|US|N300-5):1.0\r\n",
574                 .part_trail = 0xff,
575                 .soft_ver = SOFT_VER_DEFAULT,
576 
577                 .partitions = {
578                         {"fs-uboot", 0x00000, 0x20000},
579                         {"partition-table", 0x20000, 0x02000},
580                         {"default-mac", 0x30000, 0x00020},
581                         {"product-info", 0x31100, 0x00100},
582                         {"signature", 0x32000, 0x00400},
583                         {"firmware", 0x40000, 0x770000},
584                         {"soft-version", 0x7b0000, 0x00100},
585                         {"support-list", 0x7b1000, 0x00400},
586                         {"user-config", 0x7c0000, 0x10000},
587                         {"default-config", 0x7d0000, 0x10000},
588                         {"log", 0x7e0000, 0x10000},
589                         {"radio", 0x7f0000, 0x10000},
590                         {NULL, 0, 0}
591                 },
592 
593                 .first_sysupgrade_partition = "os-image",
594                 .last_sysupgrade_partition = "support-list",
595         },
596 
597         /** Firmware layout for the CPE610V2 */
598         {
599                 .id     = "CPE610V2",
600                 .vendor = "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n",
601                 .support_list =
602                         "SupportList:\r\n"
603                         "CPE610(TP-LINK|EU|N300-5|00000000):2.0\r\n"
604                         "CPE610(TP-LINK|EU|N300-5|45550000):2.0\r\n"
605                         "CPE610(TP-LINK|EU|N300-5|55530000):2.0\r\n"
606                         "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n"
607                         "CPE610(TP-LINK|UN|N300-5|45550000):2.0\r\n"
608                         "CPE610(TP-LINK|UN|N300-5|55530000):2.0\r\n"
609                         "CPE610(TP-LINK|US|N300-5|55530000):2.0\r\n"
610                         "CPE610(TP-LINK|UN|N300-5):2.0\r\n"
611                         "CPE610(TP-LINK|EU|N300-5):2.0\r\n"
612                         "CPE610(TP-LINK|US|N300-5):2.0\r\n",
613                 .part_trail = 0xff,
614                 .soft_ver = SOFT_VER_DEFAULT,
615 
616                 .partitions = {
617                         {"fs-uboot", 0x00000, 0x20000},
618                         {"partition-table", 0x20000, 0x02000},
619                         {"default-mac", 0x30000, 0x00020},
620                         {"product-info", 0x31100, 0x00100},
621                         {"signature", 0x32000, 0x00400},
622                         {"firmware", 0x40000, 0x770000},
623                         {"soft-version", 0x7b0000, 0x00100},
624                         {"support-list", 0x7b1000, 0x00400},
625                         {"user-config", 0x7c0000, 0x10000},
626                         {"default-config", 0x7d0000, 0x10000},
627                         {"log", 0x7e0000, 0x10000},
628                         {"radio", 0x7f0000, 0x10000},
629                         {NULL, 0, 0}
630                 },
631 
632                 .first_sysupgrade_partition = "os-image",
633                 .last_sysupgrade_partition = "support-list",
634         },
635         /** Firmware layout for the CPE710 V1 */
636         {
637                 .id     = "CPE710V1",
638                 .vendor = "CPE710(TP-LINK|UN|AC866-5|00000000):1.0\r\n",
639                 .support_list =
640                         "SupportList:\r\n"
641                         "CPE710(TP-LINK|UN|AC866-5|00000000):1.0\r\n"
642                         "CPE710(TP-LINK|EU|AC866-5|45550000):1.0\r\n"
643                         "CPE710(TP-LINK|US|AC866-5|55530000):1.0\r\n"
644                         "CPE710(TP-LINK|UN|AC866-5):1.0\r\n"
645                         "CPE710(TP-LINK|EU|AC866-5):1.0\r\n"
646                         "CPE710(TP-LINK|US|AC866-5):1.0\r\n",
647                 .part_trail = 0xff,
648                 .soft_ver = SOFT_VER_DEFAULT,
649 
650                 .partitions = {
651                         {"fs-uboot", 0x00000, 0x50000},
652                         {"partition-table", 0x50000, 0x02000},
653                         {"default-mac", 0x60000, 0x00020},
654                         {"serial-number", 0x60100, 0x00020},
655                         {"product-info", 0x61100, 0x00100},
656                         {"device-info", 0x61400, 0x00400},
657                         {"signature", 0x62000, 0x00400},
658                         {"device-id", 0x63000, 0x00100},
659                         {"firmware", 0x70000, 0xf40000},
660                         {"soft-version", 0xfb0000, 0x00100},
661                         {"support-list", 0xfb1000, 0x01000},
662                         {"user-config", 0xfc0000, 0x10000},
663                         {"default-config", 0xfd0000, 0x10000},
664                         {"log", 0xfe0000, 0x10000},
665                         {"radio", 0xff0000, 0x10000},
666                         {NULL, 0, 0}
667                 },
668 
669                 .first_sysupgrade_partition = "os-image",
670                 .last_sysupgrade_partition = "support-list",
671         },
672 
673         {
674                 .id     = "WBS210",
675                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
676                 .support_list =
677                         "SupportList:\r\n"
678                         "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
679                         "WBS210(TP-LINK|US|N300-2):1.20\r\n"
680                         "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
681                 .part_trail = 0xff,
682                 .soft_ver = SOFT_VER_DEFAULT,
683 
684                 .partitions = {
685                         {"fs-uboot", 0x00000, 0x20000},
686                         {"partition-table", 0x20000, 0x02000},
687                         {"default-mac", 0x30000, 0x00020},
688                         {"product-info", 0x31100, 0x00100},
689                         {"signature", 0x32000, 0x00400},
690                         {"firmware", 0x40000, 0x770000},
691                         {"soft-version", 0x7b0000, 0x00100},
692                         {"support-list", 0x7b1000, 0x00400},
693                         {"user-config", 0x7c0000, 0x10000},
694                         {"default-config", 0x7d0000, 0x10000},
695                         {"log", 0x7e0000, 0x10000},
696                         {"radio", 0x7f0000, 0x10000},
697                         {NULL, 0, 0}
698                 },
699 
700                 .first_sysupgrade_partition = "os-image",
701                 .last_sysupgrade_partition = "support-list",
702         },
703 
704         {
705                 .id     = "WBS210V2",
706                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
707                 .support_list =
708                         "SupportList:\r\n"
709                         "WBS210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
710                         "WBS210(TP-LINK|US|N300-2|55530000):2.0\r\n"
711                         "WBS210(TP-LINK|EU|N300-2|45550000):2.0\r\n",
712                 .part_trail = 0xff,
713                 .soft_ver = SOFT_VER_DEFAULT,
714 
715                 .partitions = {
716                         {"fs-uboot", 0x00000, 0x20000},
717                         {"partition-table", 0x20000, 0x02000},
718                         {"default-mac", 0x30000, 0x00020},
719                         {"product-info", 0x31100, 0x00100},
720                         {"signature", 0x32000, 0x00400},
721                         {"firmware", 0x40000, 0x770000},
722                         {"soft-version", 0x7b0000, 0x00100},
723                         {"support-list", 0x7b1000, 0x00400},
724                         {"user-config", 0x7c0000, 0x10000},
725                         {"default-config", 0x7d0000, 0x10000},
726                         {"log", 0x7e0000, 0x10000},
727                         {"radio", 0x7f0000, 0x10000},
728                         {NULL, 0, 0}
729                 },
730 
731                 .first_sysupgrade_partition = "os-image",
732                 .last_sysupgrade_partition = "support-list",
733         },
734 
735         {
736                 .id     = "WBS510",
737                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
738                 .support_list =
739                         "SupportList:\r\n"
740                         "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
741                         "WBS510(TP-LINK|US|N300-5):1.20\r\n"
742                         "WBS510(TP-LINK|EU|N300-5):1.20\r\n"
743                         "WBS510(TP-LINK|CA|N300-5):1.20\r\n",
744                 .part_trail = 0xff,
745                 .soft_ver = SOFT_VER_DEFAULT,
746 
747                 .partitions = {
748                         {"fs-uboot", 0x00000, 0x20000},
749                         {"partition-table", 0x20000, 0x02000},
750                         {"default-mac", 0x30000, 0x00020},
751                         {"product-info", 0x31100, 0x00100},
752                         {"signature", 0x32000, 0x00400},
753                         {"firmware", 0x40000, 0x770000},
754                         {"soft-version", 0x7b0000, 0x00100},
755                         {"support-list", 0x7b1000, 0x00400},
756                         {"user-config", 0x7c0000, 0x10000},
757                         {"default-config", 0x7d0000, 0x10000},
758                         {"log", 0x7e0000, 0x10000},
759                         {"radio", 0x7f0000, 0x10000},
760                         {NULL, 0, 0}
761                 },
762 
763                 .first_sysupgrade_partition = "os-image",
764                 .last_sysupgrade_partition = "support-list",
765         },
766 
767         {
768                 .id     = "WBS510V2",
769                 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
770                 .support_list =
771                         "SupportList:\r\n"
772                         "WBS510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
773                         "WBS510(TP-LINK|US|N300-5|55530000):2.0\r\n"
774                         "WBS510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
775                         "WBS510(TP-LINK|CA|N300-5|43410000):2.0\r\n",
776                 .part_trail = 0xff,
777                 .soft_ver = SOFT_VER_DEFAULT,
778 
779                 .partitions = {
780                         {"fs-uboot", 0x00000, 0x20000},
781                         {"partition-table", 0x20000, 0x02000},
782                         {"default-mac", 0x30000, 0x00020},
783                         {"product-info", 0x31100, 0x00100},
784                         {"signature", 0x32000, 0x00400},
785                         {"firmware", 0x40000, 0x770000},
786                         {"soft-version", 0x7b0000, 0x00100},
787                         {"support-list", 0x7b1000, 0x00400},
788                         {"user-config", 0x7c0000, 0x10000},
789                         {"default-config", 0x7d0000, 0x10000},
790                         {"log", 0x7e0000, 0x10000},
791                         {"radio", 0x7f0000, 0x10000},
792                         {NULL, 0, 0}
793                 },
794 
795                 .first_sysupgrade_partition = "os-image",
796                 .last_sysupgrade_partition = "support-list",
797         },
798 
799         /** Firmware layout for the AD7200 */
800         {
801                 .id = "AD7200",
802                 .vendor = "",
803                 .support_list =
804                         "SupportList:\r\n"
805                         "{product_name:AD7200,product_ver:1.0.0,special_id:00000000}\r\n",
806                 .part_trail = 0x00,
807                 .soft_ver = SOFT_VER_DEFAULT,
808 
809                 .partitions = {
810                         {"SBL1", 0x00000, 0x20000},
811                         {"MIBIB", 0x20000, 0x20000},
812                         {"SBL2", 0x40000, 0x20000},
813                         {"SBL3", 0x60000, 0x30000},
814                         {"DDRCONFIG", 0x90000, 0x10000},
815                         {"SSD", 0xa0000, 0x10000},
816                         {"TZ", 0xb0000, 0x30000},
817                         {"RPM", 0xe0000, 0x20000},
818                         {"fs-uboot", 0x100000, 0x70000},
819                         {"uboot-env", 0x170000, 0x40000},
820                         {"radio", 0x1b0000, 0x40000},
821                         {"os-image", 0x1f0000, 0x400000},
822                         {"file-system", 0x5f0000, 0x1900000},
823                         {"default-mac", 0x1ef0000, 0x00200},
824                         {"pin", 0x1ef0200, 0x00200},
825                         {"device-id", 0x1ef0400, 0x00200},
826                         {"product-info", 0x1ef0600, 0x0fa00},
827                         {"partition-table", 0x1f00000, 0x10000},
828                         {"soft-version", 0x1f10000, 0x10000},
829                         {"support-list", 0x1f20000, 0x10000},
830                         {"profile", 0x1f30000, 0x10000},
831                         {"default-config", 0x1f40000, 0x10000},
832                         {"user-config", 0x1f50000, 0x40000},
833                         {"qos-db", 0x1f90000, 0x40000},
834                         {"usb-config", 0x1fd0000, 0x10000},
835                         {"log", 0x1fe0000, 0x20000},
836                         {NULL, 0, 0}
837                 },
838 
839                 .first_sysupgrade_partition = "os-image",
840                 .last_sysupgrade_partition = "file-system"
841         },
842 
843         /** Firmware layout for the C2600 */
844         {
845                 .id     = "C2600",
846                 .vendor = "",
847                 .support_list =
848                         "SupportList:\r\n"
849                         "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
850                 .part_trail = 0x00,
851                 .soft_ver = SOFT_VER_DEFAULT,
852 
853                 /**
854                     We use a bigger os-image partition than the stock images (and thus
855                     smaller file-system), as our kernel doesn't fit in the stock firmware's
856                     2 MB os-image since kernel 4.14.
857                 */
858                 .partitions = {
859                         {"SBL1", 0x00000, 0x20000},
860                         {"MIBIB", 0x20000, 0x20000},
861                         {"SBL2", 0x40000, 0x20000},
862                         {"SBL3", 0x60000, 0x30000},
863                         {"DDRCONFIG", 0x90000, 0x10000},
864                         {"SSD", 0xa0000, 0x10000},
865                         {"TZ", 0xb0000, 0x30000},
866                         {"RPM", 0xe0000, 0x20000},
867                         {"fs-uboot", 0x100000, 0x70000},
868                         {"uboot-env", 0x170000, 0x40000},
869                         {"radio", 0x1b0000, 0x40000},
870                         {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
871                         {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
872                         {"default-mac", 0x1ef0000, 0x00200},
873                         {"pin", 0x1ef0200, 0x00200},
874                         {"product-info", 0x1ef0400, 0x0fc00},
875                         {"partition-table", 0x1f00000, 0x10000},
876                         {"soft-version", 0x1f10000, 0x10000},
877                         {"support-list", 0x1f20000, 0x10000},
878                         {"profile", 0x1f30000, 0x10000},
879                         {"default-config", 0x1f40000, 0x10000},
880                         {"user-config", 0x1f50000, 0x40000},
881                         {"qos-db", 0x1f90000, 0x40000},
882                         {"usb-config", 0x1fd0000, 0x10000},
883                         {"log", 0x1fe0000, 0x20000},
884                         {NULL, 0, 0}
885                 },
886 
887                 .first_sysupgrade_partition = "os-image",
888                 .last_sysupgrade_partition = "file-system"
889         },
890 
891         /** Firmware layout for the A7-V5 */
892         {
893                 .id     = "ARCHER-A7-V5",
894                 .support_list =
895                         "SupportList:\n"
896                         "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n"
897                         "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n"
898                         "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n"
899                         "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n"
900                         "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n"
901                         "{product_name:Archer A7,product_ver:5.0.0,special_id:52550000}\n",
902                 .part_trail = 0x00,
903                 .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"),
904 
905                 /* We're using a dynamic kernel/rootfs split here */
906                 .partitions = {
907                         {"factory-boot", 0x00000, 0x20000},
908                         {"fs-uboot", 0x20000, 0x20000},
909                         {"firmware", 0x40000, 0xec0000},        /* Stock: name os-image base 0x40000 size 0x120000 */
910                                                                 /* Stock: name file-system base 0x160000 size 0xda0000 */
911                         {"default-mac", 0xf40000, 0x00200},
912                         {"pin", 0xf40200, 0x00200},
913                         {"device-id", 0xf40400, 0x00100},
914                         {"product-info", 0xf40500, 0x0fb00},
915                         {"soft-version", 0xf50000, 0x00100},
916                         {"extra-para", 0xf51000, 0x01000},
917                         {"support-list", 0xf52000, 0x0a000},
918                         {"profile", 0xf5c000, 0x04000},
919                         {"default-config", 0xf60000, 0x10000},
920                         {"user-config", 0xf70000, 0x40000},
921                         {"certificate", 0xfb0000, 0x10000},
922                         {"partition-table", 0xfc0000, 0x10000},
923                         {"log", 0xfd0000, 0x20000},
924                         {"radio", 0xff0000, 0x10000},
925                         {NULL, 0, 0}
926                 },
927 
928                 .first_sysupgrade_partition = "os-image",
929                 .last_sysupgrade_partition = "file-system",
930         },
931 
932         /** Firmware layout for the Archer A9 v6 */
933         {
934                 .id     = "ARCHER-A9-V6",
935                 .support_list =
936                         "SupportList:\n"
937                         "{product_name:Archer A9,product_ver:6.0,special_id:55530000}\n"
938                         "{product_name:Archer A9,product_ver:6.0,special_id:45550000}\n"
939                         "{product_name:Archer A9,product_ver:6.0,special_id:52550000}\n"
940                         "{product_name:Archer A9,product_ver:6.0,special_id:4A500000}\n"
941                         "{product_name:Archer C90,product_ver:6.0,special_id:55530000}\n",
942                 .part_trail = 0x00,
943                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
944 
945                 /* We're using a dynamic kernel/rootfs split here */
946                 .partitions = {
947                         {"factory-boot", 0x00000, 0x20000},
948                         {"fs-uboot", 0x20000, 0x20000},
949                         {"partition-table", 0x40000, 0x10000},
950                         {"radio", 0x50000, 0x10000},
951                         {"default-mac", 0x60000, 0x00200},
952                         {"pin", 0x60200, 0x00200},
953                         {"device-id", 0x60400, 0x00100},
954                         {"product-info", 0x60500, 0x0fb00},
955                         {"soft-version", 0x70000, 0x01000},
956                         {"extra-para", 0x71000, 0x01000},
957                         {"support-list", 0x72000, 0x0a000},
958                         {"profile", 0x7c000, 0x04000},
959                         {"user-config", 0x80000, 0x10000},
960                         {"ap-config", 0x90000, 0x10000},
961                         {"apdef-config", 0xa0000, 0x10000},
962                         {"router-config", 0xb0000, 0x10000},
963                         {"firmware", 0xc0000, 0xf00000},        /* Stock: name os-image base 0xc0000 size 0x120000 */
964                                                                 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
965                         {"log", 0xfc0000, 0x20000},
966                         {"certificate", 0xfe0000, 0x10000},
967                         {"default-config", 0xff0000, 0x10000},
968                         {NULL, 0, 0}
969                 },
970 
971                 .first_sysupgrade_partition = "os-image",
972                 .last_sysupgrade_partition = "file-system",
973         },
974 
975         /** Firmware layout for the Archer AX23 v1 */
976         {
977                 .id     = "ARCHER-AX23-V1",
978                 .vendor = "",
979                 .support_list =
980                         "SupportList:\n"
981                         "{product_name:Archer AX23,product_ver:1.0,special_id:45550000}\n"
982                         "{product_name:Archer AX23,product_ver:1.0,special_id:4A500000}\n"
983                         "{product_name:Archer AX23,product_ver:1.0,special_id:4B520000}\n"
984                         "{product_name:Archer AX23,product_ver:1.0,special_id:52550000}\n"
985                         "{product_name:Archer AX23,product_ver:1.0.0,special_id:43410000}\n"
986                         "{product_name:Archer AX23,product_ver:1.0.0,special_id:54570000}\n"
987                         "{product_name:Archer AX23,product_ver:1.0.0,special_id:55530000}\n"
988                         "{product_name:Archer AX23,product_ver:1.20,special_id:45550000}\n"
989                         "{product_name:Archer AX23,product_ver:1.20,special_id:4A500000}\n"
990                         "{product_name:Archer AX23,product_ver:1.20,special_id:52550000}\n"
991                         "{product_name:Archer AX23,product_ver:1.20,special_id:55530000}\n"
992                         "{product_name:Archer AX1800,product_ver:1.20,special_id:45550000}\n"
993                         "{product_name:Archer AX1800,product_ver:1.20,special_id:52550000}\n",
994                 .part_trail = 0x00,
995                 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.3\n"),
996 
997                 .partitions = {
998                         {"fs-uboot", 0x00000, 0x40000},
999                         {"firmware", 0x40000, 0xf60000},
1000                         {"default-mac", 0xfa0000, 0x00200},
1001                         {"pin", 0xfa0200, 0x00100},
1002                         {"device-id", 0xfa0300, 0x00100},
1003                         {"product-info", 0xfa0400, 0x0fc00},
1004                         {"default-config", 0xfb0000, 0x08000},
1005                         {"ap-def-config", 0xfb8000, 0x08000},
1006                         {"user-config", 0xfc0000, 0x0a000},
1007                         {"ag-config", 0xfca000, 0x04000},
1008                         {"certificate", 0xfce000, 0x02000},
1009                         {"ap-config", 0xfd0000, 0x06000},
1010                         {"router-config", 0xfd6000, 0x06000},
1011                         {"favicon", 0xfdc000, 0x02000},
1012                         {"logo", 0xfde000, 0x02000},
1013                         {"partition-table", 0xfe0000, 0x00800},
1014                         {"soft-version", 0xfe0800, 0x00100},
1015                         {"support-list", 0xfe0900, 0x00400},
1016                         {"profile", 0xfe0d00, 0x03000},
1017                         {"extra-para", 0xfe3d00, 0x00100},
1018                         {"radio", 0xff0000, 0x10000},
1019                         {NULL, 0, 0}
1020                 },
1021                 .first_sysupgrade_partition = "os-image",
1022                 .last_sysupgrade_partition = "file-system",
1023         },
1024         /** Firmware layout for the C2v3 */
1025         {
1026                 .id     = "ARCHER-C2-V3",
1027                 .support_list =
1028                         "SupportList:\n"
1029                         "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n"
1030                         "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n"
1031                         "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n",
1032                 .part_trail = 0x00,
1033                 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.1\n"),
1034 
1035                 /** We're using a dynamic kernel/rootfs split here */
1036 
1037                 .partitions = {
1038                         {"factory-boot", 0x00000, 0x20000},
1039                         {"fs-uboot", 0x20000, 0x10000},
1040                         {"firmware", 0x30000, 0x7a0000},
1041                         {"user-config", 0x7d0000, 0x04000},
1042                         {"default-mac", 0x7e0000, 0x00100},
1043                         {"device-id", 0x7e0100, 0x00100},
1044                         {"extra-para", 0x7e0200, 0x00100},
1045                         {"pin", 0x7e0300, 0x00100},
1046                         {"support-list", 0x7e0400, 0x00400},
1047                         {"soft-version", 0x7e0800, 0x00400},
1048                         {"product-info", 0x7e0c00, 0x01400},
1049                         {"partition-table", 0x7e2000, 0x01000},
1050                         {"profile", 0x7e3000, 0x01000},
1051                         {"default-config", 0x7e4000, 0x04000},
1052                         {"merge-config", 0x7ec000, 0x02000},
1053                         {"qos-db", 0x7ee000, 0x02000},
1054                         {"radio", 0x7f0000, 0x10000},
1055                         {NULL, 0, 0}
1056                 },
1057 
1058                 .first_sysupgrade_partition = "os-image",
1059                 .last_sysupgrade_partition = "file-system",
1060         },
1061 
1062         /** Firmware layout for the C25v1 */
1063         {
1064                 .id     = "ARCHER-C25-V1",
1065                 .support_list =
1066                         "SupportList:\n"
1067                         "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
1068                         "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
1069                         "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
1070                 .part_trail = 0x00,
1071                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1072 
1073                 /* We're using a dynamic kernel/rootfs split here */
1074                 .partitions = {
1075                         {"factory-boot", 0x00000, 0x20000},
1076                         {"fs-uboot", 0x20000, 0x10000},
1077                         {"firmware", 0x30000, 0x7a0000},        /* Stock: name os-image base 0x30000 size 0x100000 */
1078                                                                 /* Stock: name file-system base 0x130000 size 0x6a0000 */
1079                         {"user-config", 0x7d0000, 0x04000},
1080                         {"default-mac", 0x7e0000, 0x00100},
1081                         {"device-id", 0x7e0100, 0x00100},
1082                         {"extra-para", 0x7e0200, 0x00100},
1083                         {"pin", 0x7e0300, 0x00100},
1084                         {"support-list", 0x7e0400, 0x00400},
1085                         {"soft-version", 0x7e0800, 0x00400},
1086                         {"product-info", 0x7e0c00, 0x01400},
1087                         {"partition-table", 0x7e2000, 0x01000},
1088                         {"profile", 0x7e3000, 0x01000},
1089                         {"default-config", 0x7e4000, 0x04000},
1090                         {"merge-config", 0x7ec000, 0x02000},
1091                         {"qos-db", 0x7ee000, 0x02000},
1092                         {"radio", 0x7f0000, 0x10000},
1093                         {NULL, 0, 0}
1094                 },
1095 
1096                 .first_sysupgrade_partition = "os-image",
1097                 .last_sysupgrade_partition = "file-system",
1098         },
1099 
1100         /** Firmware layout for the C58v1 */
1101         {
1102                 .id     = "ARCHER-C58-V1",
1103                 .vendor = "",
1104                 .support_list =
1105                         "SupportList:\r\n"
1106                         "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
1107                         "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
1108                         "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
1109                 .part_trail = 0x00,
1110                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1111 
1112                 .partitions = {
1113                         {"fs-uboot", 0x00000, 0x10000},
1114                         {"default-mac", 0x10000, 0x00200},
1115                         {"pin", 0x10200, 0x00200},
1116                         {"product-info", 0x10400, 0x00100},
1117                         {"partition-table", 0x10500, 0x00800},
1118                         {"soft-version", 0x11300, 0x00200},
1119                         {"support-list", 0x11500, 0x00100},
1120                         {"device-id", 0x11600, 0x00100},
1121                         {"profile", 0x11700, 0x03900},
1122                         {"default-config", 0x15000, 0x04000},
1123                         {"user-config", 0x19000, 0x04000},
1124                         {"firmware", 0x20000, 0x7c8000},
1125                         {"certyficate", 0x7e8000, 0x08000},
1126                         {"radio", 0x7f0000, 0x10000},
1127                         {NULL, 0, 0}
1128                 },
1129 
1130                 .first_sysupgrade_partition = "os-image",
1131                 .last_sysupgrade_partition = "file-system",
1132         },
1133 
1134         /** Firmware layout for the C59v1 */
1135         {
1136                 .id     = "ARCHER-C59-V1",
1137                 .vendor = "",
1138                 .support_list =
1139                         "SupportList:\r\n"
1140                         "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
1141                         "{product_name:Archer C59,product_ver:1.0.0,special_id:43410000}\r\n"
1142                         "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
1143                         "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
1144                         "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
1145                 .part_trail = 0x00,
1146                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1147 
1148                 /* We're using a dynamic kernel/rootfs split here */
1149                 .partitions = {
1150                         {"fs-uboot", 0x00000, 0x10000},
1151                         {"default-mac", 0x10000, 0x00200},
1152                         {"pin", 0x10200, 0x00200},
1153                         {"device-id", 0x10400, 0x00100},
1154                         {"product-info", 0x10500, 0x0fb00},
1155                         {"firmware", 0x20000, 0xe30000},
1156                         {"partition-table", 0xe50000, 0x10000},
1157                         {"soft-version", 0xe60000, 0x10000},
1158                         {"support-list", 0xe70000, 0x10000},
1159                         {"profile", 0xe80000, 0x10000},
1160                         {"default-config", 0xe90000, 0x10000},
1161                         {"user-config", 0xea0000, 0x40000},
1162                         {"usb-config", 0xee0000, 0x10000},
1163                         {"certificate", 0xef0000, 0x10000},
1164                         {"qos-db", 0xf00000, 0x40000},
1165                         {"log", 0xfe0000, 0x10000},
1166                         {"radio", 0xff0000, 0x10000},
1167                         {NULL, 0, 0}
1168                 },
1169 
1170                 .first_sysupgrade_partition = "os-image",
1171                 .last_sysupgrade_partition = "file-system",
1172         },
1173 
1174         /** Firmware layout for the C59v2 */
1175         {
1176                 .id     = "ARCHER-C59-V2",
1177                 .vendor = "",
1178                 .support_list =
1179                         "SupportList:\r\n"
1180                         "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n"
1181                         "{product_name:Archer C59,product_ver:2.0.0,special_id:43410000}\r\n"
1182                         "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n"
1183                         "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n",
1184                 .part_trail = 0x00,
1185                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0 Build 20161206 rel.7303\n"),
1186 
1187                 /** We're using a dynamic kernel/rootfs split here */
1188                 .partitions = {
1189                         {"factory-boot", 0x00000, 0x20000},
1190                         {"fs-uboot", 0x20000, 0x10000},
1191                         {"default-mac", 0x30000, 0x00200},
1192                         {"pin", 0x30200, 0x00200},
1193                         {"device-id", 0x30400, 0x00100},
1194                         {"product-info", 0x30500, 0x0fb00},
1195                         {"firmware", 0x40000, 0xe10000},
1196                         {"partition-table", 0xe50000, 0x10000},
1197                         {"soft-version", 0xe60000, 0x10000},
1198                         {"support-list", 0xe70000, 0x10000},
1199                         {"profile", 0xe80000, 0x10000},
1200                         {"default-config", 0xe90000, 0x10000},
1201                         {"user-config", 0xea0000, 0x40000},
1202                         {"usb-config", 0xee0000, 0x10000},
1203                         {"certificate", 0xef0000, 0x10000},
1204                         {"extra-para", 0xf00000, 0x10000},
1205                         {"qos-db", 0xf10000, 0x30000},
1206                         {"log", 0xfe0000, 0x10000},
1207                         {"radio", 0xff0000, 0x10000},
1208                         {NULL, 0, 0}
1209                 },
1210 
1211                 .first_sysupgrade_partition = "os-image",
1212                 .last_sysupgrade_partition = "file-system",
1213         },
1214 
1215         /** Firmware layout for the Archer C6 v2 (EU/RU/JP) */
1216         {
1217                 .id     = "ARCHER-C6-V2",
1218                 .vendor = "",
1219                 .support_list =
1220                         "SupportList:\r\n"
1221                         "{product_name:Archer A6,product_ver:2.0.0,special_id:45550000}\r\n"
1222                         "{product_name:Archer A6,product_ver:2.0.0,special_id:52550000}\r\n"
1223                         "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n"
1224                         "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n"
1225                         "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n",
1226                 .part_trail = 0x00,
1227                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"),
1228 
1229                 .partitions = {
1230                         {"fs-uboot", 0x00000, 0x20000},
1231                         {"default-mac", 0x20000, 0x00200},
1232                         {"pin", 0x20200, 0x00100},
1233                         {"product-info", 0x20300, 0x00200},
1234                         {"device-id", 0x20500, 0x0fb00},
1235                         {"firmware", 0x30000, 0x7a9400},
1236                         {"soft-version", 0x7d9400, 0x00100},
1237                         {"extra-para", 0x7d9500, 0x00100},
1238                         {"support-list", 0x7d9600, 0x00200},
1239                         {"profile", 0x7d9800, 0x03000},
1240                         {"default-config", 0x7dc800, 0x03000},
1241                         {"partition-table", 0x7df800, 0x00800},
1242                         {"user-config", 0x7e0000, 0x0c000},
1243                         {"certificate", 0x7ec000, 0x04000},
1244                         {"radio", 0x7f0000, 0x10000},
1245                         {NULL, 0, 0}
1246                 },
1247 
1248                 .first_sysupgrade_partition = "os-image",
1249                 .last_sysupgrade_partition = "file-system",
1250         },
1251 
1252         /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */
1253         {
1254                 .id     = "ARCHER-C6-V2-US",
1255                 .vendor = "",
1256                 .support_list =
1257                         "SupportList:\n"
1258                         "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n"
1259                         "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n"
1260                         "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n",
1261                 .part_trail = 0x00,
1262                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"),
1263 
1264                 .partitions = {
1265                         {"factory-boot", 0x00000, 0x20000},
1266                         {"default-mac", 0x20000, 0x00200},
1267                         {"pin", 0x20200, 0x00100},
1268                         {"product-info", 0x20300, 0x00200},
1269                         {"device-id", 0x20500, 0x0fb00},
1270                         {"fs-uboot", 0x30000, 0x20000},
1271                         {"firmware", 0x50000, 0xf89400},
1272                         {"soft-version", 0xfd9400, 0x00100},
1273                         {"extra-para", 0xfd9500, 0x00100},
1274                         {"support-list", 0xfd9600, 0x00200},
1275                         {"profile", 0xfd9800, 0x03000},
1276                         {"default-config", 0xfdc800, 0x03000},
1277                         {"partition-table", 0xfdf800, 0x00800},
1278                         {"user-config", 0xfe0000, 0x0c000},
1279                         {"certificate", 0xfec000, 0x04000},
1280                         {"radio", 0xff0000, 0x10000},
1281                         {NULL, 0, 0}
1282                 },
1283                 .first_sysupgrade_partition = "os-image",
1284                 .last_sysupgrade_partition = "file-system",
1285         },
1286         /** Firmware layout for the Archer C6 v3 */
1287         {
1288                 .id     = "ARCHER-C6-V3",
1289                 .vendor = "",
1290                 .support_list =
1291                         "SupportList:\n"
1292                         "{product_name:Archer C6,product_ver:3.20,special_id:55530000}"
1293                         "{product_name:Archer C6,product_ver:3.20,special_id:45550000}"
1294                         "{product_name:Archer C6,product_ver:3.20,special_id:52550000}"
1295                         "{product_name:Archer C6,product_ver:3.20,special_id:4A500000}"
1296                         "{product_name:Archer C6,product_ver:3.20,special_id:4B520000}"
1297                         "{product_name:Archer C6,product_ver:3.0.0,special_id:42520000}",
1298                 .part_trail = 0x00,
1299                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.9\n"),
1300 
1301                 .partitions = {
1302                         {"fs-uboot", 0x00000, 0x40000},
1303                         {"firmware", 0x40000, 0xf60000},
1304                         {"default-mac", 0xfa0000, 0x00200},
1305                         {"pin", 0xfa0200, 0x00100},
1306                         {"device-id", 0xfa0300, 0x00100},
1307                         {"product-info", 0xfa0400, 0x0fc00},
1308                         {"default-config", 0xfb0000, 0x08000},
1309                         {"ap-def-config", 0xfb8000, 0x08000},
1310                         {"user-config", 0xfc0000, 0x0a000},
1311                         {"ag-config", 0xfca000, 0x04000},
1312                         {"certificate", 0xfce000, 0x02000},
1313                         {"ap-config", 0xfd0000, 0x06000},
1314                         {"router-config", 0xfd6000, 0x06000},
1315                         {"favicon", 0xfdc000, 0x02000},
1316                         {"logo", 0xfde000, 0x02000},
1317                         {"partition-table", 0xfe0000, 0x00800},
1318                         {"soft-version", 0xfe0800, 0x00100},
1319                         {"support-list", 0xfe0900, 0x00200},
1320                         {"profile", 0xfe0b00, 0x03000},
1321                         {"extra-para", 0xfe3b00, 0x00100},
1322                         {"radio", 0xff0000, 0x10000},
1323                         {NULL, 0, 0}
1324                 },
1325                 .first_sysupgrade_partition = "os-image",
1326                 .last_sysupgrade_partition = "file-system",
1327         },
1328         /** Firmware layout for the Archer A6 v3  */
1329         {
1330                 .id     = "ARCHER-A6-V3",
1331                 .vendor = "",
1332                 .support_list =
1333                         "SupportList:\n"
1334                         "{product_name:Archer A6,product_ver:3.0.0,special_id:43410000}\n"
1335                         "{product_name:Archer A6,product_ver:3.0.0,special_id:55530000}\n"
1336                         "{product_name:Archer A6,product_ver:3.0.0,special_id:54570000}\n"
1337                         "{product_name:Archer A6,product_ver:3.0.0,special_id:4A500000}\n"
1338                         "{product_name:Archer A6,product_ver:3.20,special_id:45550000}\n"
1339                         "{product_name:Archer A6,product_ver:3.20,special_id:52550000}\n",
1340                 .part_trail = 0x00,
1341                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.5\n"),
1342 
1343                 .partitions = {
1344                         {"fs-uboot", 0x00000, 0x40000},
1345                         {"firmware", 0x40000, 0xf60000},
1346                         {"default-mac", 0xfa0000, 0x00200},
1347                         {"pin", 0xfa0200, 0x00100},
1348                         {"device-id", 0xfa0300, 0x00100},
1349                         {"product-info", 0xfa0400, 0x0fc00},
1350                         {"default-config", 0xfb0000, 0x08000},
1351                         {"ap-def-config", 0xfb8000, 0x08000},
1352                         {"user-config", 0xfc0000, 0x0a000},
1353                         {"ag-config", 0xfca000, 0x04000},
1354                         {"certificate", 0xfce000, 0x02000},
1355                         {"ap-config", 0xfd0000, 0x06000},
1356                         {"router-config", 0xfd6000, 0x06000},
1357                         {"favicon", 0xfdc000, 0x02000},
1358                         {"logo", 0xfde000, 0x02000},
1359                         {"partition-table", 0xfe0000, 0x00800},
1360                         {"soft-version", 0xfe0800, 0x00100},
1361                         {"support-list", 0xfe0900, 0x00200},
1362                         {"profile", 0xfe0b00, 0x03000},
1363                         {"extra-para", 0xfe3b00, 0x00100},
1364                         {"radio", 0xff0000, 0x10000},
1365                         {NULL, 0, 0}
1366                 },
1367                 .first_sysupgrade_partition = "os-image",
1368                 .last_sysupgrade_partition = "file-system",
1369         },
1370         /** Firmware layout for the Archer C6U v1 */
1371         {
1372                 .id     = "ARCHER-C6U-V1",
1373                 .vendor = "",
1374                 .support_list =
1375                         "SupportList:\n"
1376                         "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n"
1377                         "{product_name:Archer C6U,product_ver:1.0.0,special_id:52550000}\n",
1378                 .part_trail = 0x00,
1379                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.2\n"),
1380 
1381                 .partitions = {
1382                         {"fs-uboot", 0x00000, 0x40000},
1383                         {"firmware", 0x40000, 0xf60000},
1384                         {"default-mac", 0xfa0000, 0x00200},
1385                         {"pin", 0xfa0200, 0x00100},
1386                         {"device-id", 0xfa0300, 0x00100},
1387                         {"product-info", 0xfa0400, 0x0fc00},
1388                         {"default-config", 0xfb0000, 0x08000},
1389                         {"ap-def-config", 0xfb8000, 0x08000},
1390                         {"user-config", 0xfc0000, 0x0c000},
1391                         {"certificate", 0xfcc000, 0x04000},
1392                         {"ap-config", 0xfd0000, 0x08000},
1393                         {"router-config", 0xfd8000, 0x08000},
1394                         {"partition-table", 0xfe0000, 0x00800},
1395                         {"soft-version", 0xfe0800, 0x00100},
1396                         {"support-list", 0xfe0900, 0x00200},
1397                         {"profile", 0xfe0b00, 0x03000},
1398                         {"extra-para", 0xfe3b00, 0x00100},
1399                         {"radio", 0xff0000, 0x10000},
1400                         {NULL, 0, 0}
1401                 },
1402                 .first_sysupgrade_partition = "os-image",
1403                 .last_sysupgrade_partition = "file-system",
1404         },
1405         /** Firmware layout for the C60v1 */
1406         {
1407                 .id     = "ARCHER-C60-V1",
1408                 .vendor = "",
1409                 .support_list =
1410                         "SupportList:\r\n"
1411                         "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1412                         "{product_name:Archer C60,product_ver:1.0.0,special_id:43410000}\r\n"
1413                         "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1414                         "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1415                 .part_trail = 0x00,
1416                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1417 
1418                 .partitions = {
1419                         {"fs-uboot", 0x00000, 0x10000},
1420                         {"default-mac", 0x10000, 0x00200},
1421                         {"pin", 0x10200, 0x00200},
1422                         {"product-info", 0x10400, 0x00100},
1423                         {"partition-table", 0x10500, 0x00800},
1424                         {"soft-version", 0x11300, 0x00200},
1425                         {"support-list", 0x11500, 0x00100},
1426                         {"device-id", 0x11600, 0x00100},
1427                         {"profile", 0x11700, 0x03900},
1428                         {"default-config", 0x15000, 0x04000},
1429                         {"user-config", 0x19000, 0x04000},
1430                         {"firmware", 0x20000, 0x7c8000},
1431                         {"certyficate", 0x7e8000, 0x08000},
1432                         {"radio", 0x7f0000, 0x10000},
1433                         {NULL, 0, 0}
1434                 },
1435 
1436                 .first_sysupgrade_partition = "os-image",
1437                 .last_sysupgrade_partition = "file-system",
1438         },
1439 
1440         /** Firmware layout for the C60v2 */
1441         {
1442                 .id     = "ARCHER-C60-V2",
1443                 .vendor = "",
1444                 .support_list =
1445                         "SupportList:\r\n"
1446                         "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1447                         "{product_name:Archer C60,product_ver:2.0.0,special_id:43410000}\r\n"
1448                         "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1449                         "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1450                 .part_trail = 0x00,
1451                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
1452 
1453                 .partitions = {
1454                         {"factory-boot", 0x00000, 0x1fb00},
1455                         {"default-mac", 0x1fb00, 0x00200},
1456                         {"pin", 0x1fd00, 0x00100},
1457                         {"product-info", 0x1fe00, 0x00100},
1458                         {"device-id", 0x1ff00, 0x00100},
1459                         {"fs-uboot", 0x20000, 0x10000},
1460                         {"firmware", 0x30000, 0x7a0000},
1461                         {"soft-version", 0x7d9500, 0x00100},
1462                         {"support-list", 0x7d9600, 0x00100},
1463                         {"extra-para", 0x7d9700, 0x00100},
1464                         {"profile", 0x7d9800, 0x03000},
1465                         {"default-config", 0x7dc800, 0x03000},
1466                         {"partition-table", 0x7df800, 0x00800},
1467                         {"user-config", 0x7e0000, 0x0c000},
1468                         {"certificate", 0x7ec000, 0x04000},
1469                         {"radio", 0x7f0000, 0x10000},
1470                         {NULL, 0, 0}
1471                 },
1472 
1473                 .first_sysupgrade_partition = "os-image",
1474                 .last_sysupgrade_partition = "file-system",
1475         },
1476 
1477         /** Firmware layout for the C60v3 */
1478         {
1479                 .id     = "ARCHER-C60-V3",
1480                 .vendor = "",
1481                 .support_list =
1482                         "SupportList:\r\n"
1483                         "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1484                         "{product_name:Archer C60,product_ver:3.0.0,special_id:43410000}\r\n"
1485                         "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1486                         "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1487                 .part_trail = 0x00,
1488                 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.0\n"),
1489 
1490                 .partitions = {
1491                         {"factory-boot", 0x00000, 0x1fb00},
1492                         {"default-mac", 0x1fb00, 0x00200},
1493                         {"pin", 0x1fd00, 0x00100},
1494                         {"product-info", 0x1fe00, 0x00100},
1495                         {"device-id", 0x1ff00, 0x00100},
1496                         {"fs-uboot", 0x20000, 0x10000},
1497                         {"firmware", 0x30000, 0x7a0000},
1498                         {"soft-version", 0x7d9500, 0x00100},
1499                         {"support-list", 0x7d9600, 0x00100},
1500                         {"extra-para", 0x7d9700, 0x00100},
1501                         {"profile", 0x7d9800, 0x03000},
1502                         {"default-config", 0x7dc800, 0x03000},
1503                         {"partition-table", 0x7df800, 0x00800},
1504                         {"user-config", 0x7e0000, 0x0c000},
1505                         {"certificate", 0x7ec000, 0x04000},
1506                         {"radio", 0x7f0000, 0x10000},
1507                         {NULL, 0, 0}
1508                 },
1509 
1510                 .first_sysupgrade_partition = "os-image",
1511                 .last_sysupgrade_partition = "file-system",
1512         },
1513 
1514         /** Firmware layout for the C5 */
1515         {
1516                 .id     = "ARCHER-C5-V2",
1517                 .vendor = "",
1518                 .support_list =
1519                         "SupportList:\r\n"
1520                         "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1521                         "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1522                         "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1523                 .part_trail = 0x00,
1524                 .soft_ver = SOFT_VER_DEFAULT,
1525 
1526                 .partitions = {
1527                         {"fs-uboot", 0x00000, 0x40000},
1528                         {"os-image", 0x40000, 0x200000},
1529                         {"file-system", 0x240000, 0xc00000},
1530                         {"default-mac", 0xe40000, 0x00200},
1531                         {"pin", 0xe40200, 0x00200},
1532                         {"product-info", 0xe40400, 0x00200},
1533                         {"partition-table", 0xe50000, 0x10000},
1534                         {"soft-version", 0xe60000, 0x00200},
1535                         {"support-list", 0xe61000, 0x0f000},
1536                         {"profile", 0xe70000, 0x10000},
1537                         {"default-config", 0xe80000, 0x10000},
1538                         {"user-config", 0xe90000, 0x50000},
1539                         {"log", 0xee0000, 0x100000},
1540                         {"radio_bk", 0xfe0000, 0x10000},
1541                         {"radio", 0xff0000, 0x10000},
1542                         {NULL, 0, 0}
1543                 },
1544 
1545                 .first_sysupgrade_partition = "os-image",
1546                 .last_sysupgrade_partition = "file-system"
1547         },
1548 
1549         /** Firmware layout for the C7 */
1550         {
1551                 .id     = "ARCHER-C7-V4",
1552                 .support_list =
1553                         "SupportList:\n"
1554                         "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1555                         "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1556                         "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1557                         "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1558                         "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1559                         "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1560                         "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1561                         "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1562                         "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1563                         "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1564                 .part_trail = 0x00,
1565                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1566 
1567                 /* We're using a dynamic kernel/rootfs split here */
1568                 .partitions = {
1569                         {"factory-boot", 0x00000, 0x20000},
1570                         {"fs-uboot", 0x20000, 0x20000},
1571                         {"firmware", 0x40000, 0xEC0000},        /* Stock: name os-image base 0x40000 size 0x120000 */
1572                                                                 /* Stock: name file-system base 0x160000 size 0xda0000 */
1573                         {"default-mac", 0xf00000, 0x00200},
1574                         {"pin", 0xf00200, 0x00200},
1575                         {"device-id", 0xf00400, 0x00100},
1576                         {"product-info", 0xf00500, 0x0fb00},
1577                         {"soft-version", 0xf10000, 0x00100},
1578                         {"extra-para", 0xf11000, 0x01000},
1579                         {"support-list", 0xf12000, 0x0a000},
1580                         {"profile", 0xf1c000, 0x04000},
1581                         {"default-config", 0xf20000, 0x10000},
1582                         {"user-config", 0xf30000, 0x40000},
1583                         {"qos-db", 0xf70000, 0x40000},
1584                         {"certificate", 0xfb0000, 0x10000},
1585                         {"partition-table", 0xfc0000, 0x10000},
1586                         {"log", 0xfd0000, 0x20000},
1587                         {"radio", 0xff0000, 0x10000},
1588                         {NULL, 0, 0}
1589                 },
1590 
1591                 .first_sysupgrade_partition = "os-image",
1592                 .last_sysupgrade_partition = "file-system",
1593         },
1594 
1595         /** Firmware layout for the C7 v5*/
1596         {
1597                 .id     = "ARCHER-C7-V5",
1598                 .support_list =
1599                         "SupportList:\n"
1600                         "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1601                         "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1602                         "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1603                         "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1604                         "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1605                         "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1606                         "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1607                         "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1608 
1609                 .part_trail = 0x00,
1610                 .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"),
1611 
1612                 /* We're using a dynamic kernel/rootfs split here */
1613                 .partitions = {
1614                         {"factory-boot",    0x00000,  0x20000},
1615                         {"fs-uboot",        0x20000,  0x20000},
1616                         {"partition-table", 0x40000,  0x10000},
1617                         {"radio",           0x50000,  0x10000},
1618                         {"default-mac",     0x60000,  0x00200},
1619                         {"pin",             0x60200,  0x00200},
1620                         {"device-id",       0x60400,  0x00100},
1621                         {"product-info",    0x60500,  0x0fb00},
1622                         {"soft-version",    0x70000,  0x01000},
1623                         {"extra-para",      0x71000,  0x01000},
1624                         {"support-list",    0x72000,  0x0a000},
1625                         {"profile",         0x7c000,  0x04000},
1626                         {"user-config",     0x80000,  0x40000},
1627 
1628 
1629                         {"firmware",        0xc0000,  0xf00000},        /* Stock: name os-image base 0xc0000  size 0x120000 */
1630                                                                         /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1631 
1632                         {"log",             0xfc0000, 0x20000},
1633                         {"certificate",     0xfe0000, 0x10000},
1634                         {"default-config",  0xff0000, 0x10000},
1635                         {NULL, 0, 0}
1636 
1637                 },
1638 
1639                 .first_sysupgrade_partition = "os-image",
1640                 .last_sysupgrade_partition = "file-system",
1641         },
1642 
1643         /** Firmware layout for the C9 */
1644         {
1645                 .id     = "ARCHERC9",
1646                 .vendor = "",
1647                 .support_list =
1648                         "SupportList:\n"
1649                         "{product_name:ArcherC9,"
1650                         "product_ver:1.0.0,"
1651                         "special_id:00000000}\n",
1652                 .part_trail = 0x00,
1653                 .soft_ver = SOFT_VER_DEFAULT,
1654 
1655                 .partitions = {
1656                         {"fs-uboot", 0x00000, 0x40000},
1657                         {"os-image", 0x40000, 0x200000},
1658                         {"file-system", 0x240000, 0xc00000},
1659                         {"default-mac", 0xe40000, 0x00200},
1660                         {"pin", 0xe40200, 0x00200},
1661                         {"product-info", 0xe40400, 0x00200},
1662                         {"partition-table", 0xe50000, 0x10000},
1663                         {"soft-version", 0xe60000, 0x00200},
1664                         {"support-list", 0xe61000, 0x0f000},
1665                         {"profile", 0xe70000, 0x10000},
1666                         {"default-config", 0xe80000, 0x10000},
1667                         {"user-config", 0xe90000, 0x50000},
1668                         {"log", 0xee0000, 0x100000},
1669                         {"radio_bk", 0xfe0000, 0x10000},
1670                         {"radio", 0xff0000, 0x10000},
1671                         {NULL, 0, 0}
1672                 },
1673 
1674                 .first_sysupgrade_partition = "os-image",
1675                 .last_sysupgrade_partition = "file-system"
1676         },
1677 
1678         /** Firmware layout for the Deco M4R v1 and v2 */
1679         {
1680                 .id     = "DECO-M4R-V1",
1681                 .vendor = "",
1682                 .support_list =
1683                         "SupportList:\n"
1684                         "{product_name:M4R,product_ver:1.0.0,special_id:55530000}\n"
1685                         "{product_name:M4R,product_ver:1.0.0,special_id:45550000}\n"
1686                         "{product_name:M4R,product_ver:1.0.0,special_id:43410000}\n"
1687                         "{product_name:M4R,product_ver:1.0.0,special_id:4A500000}\n"
1688                         "{product_name:M4R,product_ver:1.0.0,special_id:41550000}\n"
1689                         "{product_name:M4R,product_ver:1.0.0,special_id:4B520000}\n"
1690                         "{product_name:M4R,product_ver:1.0.0,special_id:49440000}\n"
1691                         "{product_name:M4R,product_ver:2.0.0,special_id:55530000}\n"
1692                         "{product_name:M4R,product_ver:2.0.0,special_id:45550000}\n"
1693                         "{product_name:M4R,product_ver:2.0.0,special_id:43410000}\n"
1694                         "{product_name:M4R,product_ver:2.0.0,special_id:4A500000}\n"
1695                         "{product_name:M4R,product_ver:2.0.0,special_id:41550000}\n"
1696                         "{product_name:M4R,product_ver:2.0.0,special_id:4B520000}\n"
1697                         "{product_name:M4R,product_ver:2.0.0,special_id:54570000}\n"
1698                         "{product_name:M4R,product_ver:2.0.0,special_id:42340000}\n"
1699                         "{product_name:M4R,product_ver:2.0.0,special_id:49440000}\n",
1700                 .part_trail = 0x00,
1701                 .soft_ver = SOFT_VER_DEFAULT,
1702 
1703                 .partitions = {
1704                         {"fs-uboot", 0x00000, 0x80000},
1705                         {"firmware", 0x80000, 0xe00000},
1706                         {"product-info", 0xe80000, 0x05000},
1707                         {"default-mac", 0xe85000, 0x01000},
1708                         {"device-id", 0xe86000, 0x01000},
1709                         {"support-list", 0xe87000, 0x10000},
1710                         {"user-config", 0xea7000, 0x10000},
1711                         {"device-config", 0xeb7000, 0x10000},
1712                         {"group-info", 0xec7000, 0x10000},
1713                         {"partition-table", 0xed7000, 0x02000},
1714                         {"soft-version", 0xed9000, 0x10000},
1715                         {"profile", 0xee9000, 0x10000},
1716                         {"default-config", 0xef9000, 0x10000},
1717                         {"url-sig", 0xfe0000, 0x10000},
1718                         {"radio", 0xff0000, 0x10000},
1719                         {NULL, 0, 0}
1720                 },
1721                 .first_sysupgrade_partition = "os-image",
1722                 .last_sysupgrade_partition = "file-system",
1723         },
1724 
1725         /** Firmware layout for the Deco M4R v4 */
1726         {
1727                 .id     = "DECO-M4R-V4",
1728                 .vendor = "",
1729                 .support_list =
1730                         "SupportList:\n"
1731                         "{product_name:M4R,product_ver:4.0.0,special_id:55530000}\n"
1732                         "{product_name:M4R,product_ver:4.0.0,special_id:45550000}\n"
1733                         "{product_name:M4R,product_ver:4.0.0,special_id:4A500000}\n"
1734                         "{product_name:M4R,product_ver:4.0.0,special_id:42340000}\n"
1735                         "{product_name:M4R,product_ver:4.0.0,special_id:5A470000}\n",
1736                 .part_trail = 0x00,
1737                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1738 
1739                 .partitions = {
1740                         {"fs-uboot", 0x00000, 0x40000},
1741                         {"firmware", 0x40000, 0xf60000},
1742                         {"default-mac", 0xfa0000, 0x00300},
1743                         {"device-id", 0xfa0300, 0x00100},
1744                         {"product-info", 0xfa0400, 0x0fc00},
1745                         {"group-info", 0xfb0000, 0x04000},
1746                         {"user-config", 0xfb4000, 0x0c000},
1747                         {"device-config", 0xfc0000, 0x10000},
1748                         {"default-config", 0xfd0000, 0x10000},
1749                         {"partition-table", 0xfe0000, 0x00800},
1750                         {"soft-version", 0xfe0800, 0x00100},
1751                         {"support-list", 0xfe0900, 0x00200},
1752                         {"profile", 0xfe0b00, 0x03000},
1753                         {"extra-para", 0xfe3b00, 0x00100},
1754                         {"radio", 0xff0000, 0x10000},
1755                         {NULL, 0, 0}
1756                 },
1757                 .first_sysupgrade_partition = "os-image",
1758                 .last_sysupgrade_partition = "file-system",
1759         },
1760 
1761         /** Firmware layout for the Deco M5 */
1762         {
1763                 .id = "DECO-M5",
1764                 .vendor = "",
1765                 .support_list =
1766                         "SupportList:\n"
1767                         "{product_name:M5,product_ver:1.0.0,special_id:55530000}\n"
1768                         "{product_name:M5,product_ver:1.0.0,special_id:45550000}\n"
1769                         "{product_name:M5,product_ver:1.0.0,special_id:43410000}\n"
1770                         "{product_name:M5,product_ver:1.0.0,special_id:4A500000}\n"
1771                         "{product_name:M5,product_ver:1.0.0,special_id:41550000}\n"
1772                         "{product_name:M5,product_ver:1.0.0,special_id:4B520000}\n"
1773                         "{product_name:M5,product_ver:1.0.0,special_id:49440000}\n"
1774                         "{product_name:M5,product_ver:3.0.0,special_id:55530000}\n"
1775                         "{product_name:M5,product_ver:3.0.0,special_id:45550000}\n"
1776                         "{product_name:M5,product_ver:3.0.0,special_id:43410000}\n"
1777                         "{product_name:M5,product_ver:3.0.0,special_id:4A500000}\n"
1778                         "{product_name:M5,product_ver:3.0.0,special_id:41550000}\n"
1779                         "{product_name:M5,product_ver:3.0.0,special_id:4B520000}\n"
1780                         "{product_name:M5,product_ver:3.0.0,special_id:49440000}\n"
1781                         "{product_name:M5,product_ver:3.0.0,special_id:53570000}\n"
1782                         "{product_name:M5,product_ver:3.0.0,special_id:42340000}\n"
1783                         "{product_name:M5,product_ver:3.0.0,special_id:54570000}\n"
1784                         "{product_name:M5,product_ver:3.2.0,special_id:55530000}\n"
1785                         "{product_name:M5,product_ver:3.2.0,special_id:45550000}\n"
1786                         "{product_name:M5,product_ver:3.2.0,special_id:43410000}\n"
1787                         "{product_name:M5,product_ver:3.2.0,special_id:4A500000}\n"
1788                         "{product_name:M5,product_ver:3.2.0,special_id:41550000}\n"
1789                         "{product_name:M5,product_ver:3.2.0,special_id:4B520000}\n"
1790                         "{product_name:M5,product_ver:3.2.0,special_id:49440000}\n"
1791                         "{product_name:M5,product_ver:3.2.0,special_id:53570000}\n"
1792                         "{product_name:M5,product_ver:3.2.0,special_id:42340000}\n"
1793                         "{product_name:M5,product_ver:3.2.0,special_id:54570000}\n",
1794                 .part_trail = 0x00,
1795                 .soft_ver = SOFT_VER_DEFAULT,
1796 
1797                 .partitions = {
1798                         {"SBL1", 0x00000, 0x30000},
1799                         {"boot-config_0", 0x30000, 0x10000},
1800                         {"MIBIB", 0x40000, 0x10000},
1801                         {"boot-config_1", 0x50000, 0x10000},
1802                         {"QSEE", 0x60000, 0x60000},
1803                         {"CDT", 0xc0000, 0x10000},
1804                         {"DDRPARAMS", 0xd0000, 0x10000},
1805                         {"uboot-env", 0xe0000, 0x10000},
1806                         {"fs-uboot@0", 0xf0000, 0x80000},
1807                         {"radio", 0x170000, 0x0fff0},
1808                         {"bluetooth-XTAL", 0x17fff0, 0x00010},
1809                         {"default-mac", 0x180000, 0x01000},
1810                         {"device-id", 0x182000, 0x01000},
1811                         {"product-info", 0x183000, 0x05000},
1812                         {"support-list", 0x190000, 0x10000},
1813                         {"user-config", 0x200000, 0x10000},
1814                         {"device-config", 0x210000, 0x10000},
1815                         {"group-info", 0x220000, 0x10000},
1816                         {"partition-table@0", 0x230000, 0x02000},
1817                         {"os-image@0", 0x240000, 0x300000},
1818                         {"file-system@0", 0x540000, 0x790000},
1819                         {"soft-version@0", 0xcd0000, 0x10000},
1820                         {"profile@0", 0xce0000, 0x10000},
1821                         {"default-config@0", 0xcf0000, 0x10000},
1822                         {"partition-table@1", 0xd00000, 0x02000},
1823                         {"fs-uboot@1", 0xd10000, 0x80000},
1824                         {"os-image@1", 0xd90000, 0x400000},
1825                         {"file-system@1", 0x1190000, 0xc40000},
1826                         {"soft-version@1", 0x1dd0000, 0x10000},
1827                         {"profile@1", 0x1de0000, 0x10000},
1828                         {"default-config@1", 0x1df0000, 0x10000},
1829                         {"tm-sig", 0x1e00000, 0x200000},
1830                         {NULL, 0, 0}
1831                 },
1832 
1833                 .partition_names.partition_table = "partition-table@1",
1834                 .partition_names.soft_ver = "soft-version@1",
1835                 .partition_names.os_image = "os-image@1",
1836                 .partition_names.file_system = "file-system@1",
1837 
1838                 .first_sysupgrade_partition = "os-image@1",
1839                 .last_sysupgrade_partition = "file-system@1"
1840         },
1841 
1842         /** Firmware layout for the Deco S4 v2 */
1843         {
1844                 .id     = "DECO-S4-V2",
1845                 .vendor = "",
1846                 .support_list =
1847                         "SupportList:\n"
1848                         "{product_name:S4,product_ver:1.0.0,special_id:55530000}\n"
1849                         "{product_name:S4,product_ver:1.0.0,special_id:45550000}\n"
1850                         "{product_name:S4,product_ver:1.0.0,special_id:43410000}\n"
1851                         "{product_name:S4,product_ver:1.0.0,special_id:4A500000}\n"
1852                         "{product_name:S4,product_ver:1.0.0,special_id:41550000}\n"
1853                         "{product_name:S4,product_ver:1.0.0,special_id:4B520000}\n"
1854                         "{product_name:S4,product_ver:2.0.0,special_id:55530000}\n"
1855                         "{product_name:S4,product_ver:2.0.0,special_id:45550000}\n"
1856                         "{product_name:S4,product_ver:2.0.0,special_id:43410000}\n"
1857                         "{product_name:S4,product_ver:2.0.0,special_id:4A500000}\n"
1858                         "{product_name:S4,product_ver:2.0.0,special_id:41550000}\n"
1859                         "{product_name:S4,product_ver:2.0.0,special_id:4B520000}\n",
1860                 .part_trail = 0x00,
1861                 .soft_ver = SOFT_VER_DEFAULT,
1862 
1863                 .partitions = {
1864                         {"fs-uboot", 0x00000, 0x80000},
1865                         {"product-info", 0x80000, 0x05000},
1866                         {"default-mac", 0x85000, 0x01000},
1867                         {"device-id", 0x86000, 0x01000},
1868                         {"support-list", 0x87000, 0x10000},
1869                         {"user-config", 0xa7000, 0x10000},
1870                         {"device-config", 0xb7000, 0x10000},
1871                         {"group-info", 0xc7000, 0x10000},
1872                         {"partition-table", 0xd7000, 0x02000},
1873                         {"soft-version", 0xd9000, 0x10000},
1874                         {"profile", 0xe9000, 0x10000},
1875                         {"default-config", 0xf9000, 0x10000},
1876                         {"url-sig", 0x1e0000, 0x10000},
1877                         {"radio", 0x1f0000, 0x10000},
1878                         {"firmware", 0x200000, 0xe00000},
1879                         {NULL, 0, 0}
1880                 },
1881                 .first_sysupgrade_partition = "os-image",
1882                 .last_sysupgrade_partition = "file-system",
1883         },
1884 
1885         /** Firmware layout for the EAP120 */
1886         {
1887                 .id     = "EAP120",
1888                 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1889                 .support_list =
1890                         "SupportList:\r\n"
1891                         "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1892                 .part_trail = 0xff,
1893                 .soft_ver = SOFT_VER_DEFAULT,
1894 
1895                 .partitions = {
1896                         {"fs-uboot", 0x00000, 0x20000},
1897                         {"partition-table", 0x20000, 0x02000},
1898                         {"default-mac", 0x30000, 0x00020},
1899                         {"support-list", 0x31000, 0x00100},
1900                         {"product-info", 0x31100, 0x00100},
1901                         {"soft-version", 0x32000, 0x00100},
1902                         {"os-image", 0x40000, 0x180000},
1903                         {"file-system", 0x1c0000, 0x600000},
1904                         {"user-config", 0x7c0000, 0x10000},
1905                         {"backup-config", 0x7d0000, 0x10000},
1906                         {"log", 0x7e0000, 0x10000},
1907                         {"radio", 0x7f0000, 0x10000},
1908                         {NULL, 0, 0}
1909                 },
1910 
1911                 .first_sysupgrade_partition = "os-image",
1912                 .last_sysupgrade_partition = "file-system"
1913         },
1914 
1915         /** Firmware layout for the EAP225-Outdoor v1 */
1916         {
1917                 .id     = "EAP225-OUTDOOR-V1",
1918                 .support_list =
1919                         "SupportList:\r\n"
1920                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1921                 .part_trail = PART_TRAIL_NONE,
1922                 .soft_ver = SOFT_VER_DEFAULT,
1923                 .soft_ver_compat_level = 1,
1924 
1925                 .partitions = {
1926                         {"fs-uboot", 0x00000, 0x20000},
1927                         {"partition-table", 0x20000, 0x02000},
1928                         {"default-mac", 0x30000, 0x01000},
1929                         {"support-list", 0x31000, 0x00100},
1930                         {"product-info", 0x31100, 0x00400},
1931                         {"soft-version", 0x32000, 0x00100},
1932                         {"firmware", 0x40000, 0xd80000},
1933                         {"user-config", 0xdc0000, 0x30000},
1934                         {"mutil-log", 0xf30000, 0x80000},
1935                         {"oops", 0xfb0000, 0x40000},
1936                         {"radio", 0xff0000, 0x10000},
1937                         {NULL, 0, 0}
1938                 },
1939 
1940                 .first_sysupgrade_partition = "os-image",
1941                 .last_sysupgrade_partition = "file-system"
1942         },
1943 
1944         /** Firmware layout for the EAP225 v1 */
1945         {
1946                 .id     = "EAP225-V1",
1947                 .support_list =
1948                         "SupportList:\r\n"
1949                         "EAP225(TP-LINK|UN|AC1200-D):1.0\r\n",
1950                 .part_trail = PART_TRAIL_NONE,
1951                 .soft_ver = SOFT_VER_DEFAULT,
1952 
1953                 .partitions = {
1954                         {"fs-uboot", 0x00000, 0x20000},
1955                         {"partition-table", 0x20000, 0x02000},
1956                         {"default-mac", 0x30000, 0x01000},
1957                         {"support-list", 0x31000, 0x00100},
1958                         {"product-info", 0x31100, 0x00400},
1959                         {"soft-version", 0x32000, 0x00100},
1960                         {"firmware", 0x40000, 0xd80000},
1961                         {"user-config", 0xdc0000, 0x30000},
1962                         {"radio", 0xff0000, 0x10000},
1963                         {NULL, 0, 0}
1964                 },
1965 
1966                 .first_sysupgrade_partition = "os-image",
1967                 .last_sysupgrade_partition = "file-system"
1968         },
1969 
1970         /** Firmware layout for the EAP225 v3
1971          * Also compatible with:
1972          *   - EAP225 v3.20
1973          *   - EAP225 v4
1974          *   - EAP225-Outdoor v1
1975          *   - EAP225-Outdoor v3
1976          *   */
1977         {
1978                 .id     = "EAP225-V3",
1979                 .support_list =
1980                         "SupportList:\r\n"
1981                         "EAP225(TP-Link|UN|AC1350-D):3.0\r\n"
1982                         "EAP225(TP-Link|UN|AC1350-D):3.20\r\n"
1983                         "EAP225(TP-Link|UN|AC1350-D):4.0 CA\r\n"
1984                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n"
1985                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):3.0 CA,JP\r\n",
1986                 .part_trail = PART_TRAIL_NONE,
1987                 .soft_ver = SOFT_VER_DEFAULT,
1988                 .soft_ver_compat_level = 1,
1989 
1990                 .partitions = {
1991                         {"fs-uboot", 0x00000, 0x20000},
1992                         {"partition-table", 0x20000, 0x02000},
1993                         {"default-mac", 0x30000, 0x01000},
1994                         {"support-list", 0x31000, 0x00100},
1995                         {"product-info", 0x31100, 0x00400},
1996                         {"soft-version", 0x32000, 0x00100},
1997                         {"firmware", 0x40000, 0xd80000},
1998                         {"user-config", 0xdc0000, 0x30000},
1999                         {"mutil-log", 0xf30000, 0x80000},
2000                         {"oops", 0xfb0000, 0x40000},
2001                         {"radio", 0xff0000, 0x10000},
2002                         {NULL, 0, 0}
2003                 },
2004 
2005                 .first_sysupgrade_partition = "os-image",
2006                 .last_sysupgrade_partition = "file-system"
2007         },
2008 
2009         /** Firmware layout for the EAP225-Wall v2 */
2010         {
2011                 .id     = "EAP225-WALL-V2",
2012                 .support_list =
2013                         "SupportList:\r\n"
2014                         "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
2015                 .part_trail = PART_TRAIL_NONE,
2016                 .soft_ver = SOFT_VER_DEFAULT,
2017                 .soft_ver_compat_level = 1,
2018 
2019                 .partitions = {
2020                         {"fs-uboot", 0x00000, 0x20000},
2021                         {"partition-table", 0x20000, 0x02000},
2022                         {"default-mac", 0x30000, 0x01000},
2023                         {"support-list", 0x31000, 0x00100},
2024                         {"product-info", 0x31100, 0x00400},
2025                         {"soft-version", 0x32000, 0x00100},
2026                         {"firmware", 0x40000, 0xd80000},
2027                         {"user-config", 0xdc0000, 0x30000},
2028                         {"mutil-log", 0xf30000, 0x80000},
2029                         {"oops", 0xfb0000, 0x40000},
2030                         {"radio", 0xff0000, 0x10000},
2031                         {NULL, 0, 0}
2032                 },
2033 
2034                 .first_sysupgrade_partition = "os-image",
2035                 .last_sysupgrade_partition = "file-system"
2036         },
2037 
2038         /** Firmware layout for the EAP235-Wall v1 */
2039         {
2040                 .id     = "EAP235-WALL-V1",
2041                 .support_list =
2042                         "SupportList:\r\n"
2043                         "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
2044                 .part_trail = PART_TRAIL_NONE,
2045                 .soft_ver = SOFT_VER_NUMERIC(3, 0, 0),
2046                 .soft_ver_compat_level = 1,
2047 
2048                 .partitions = {
2049                         {"fs-uboot", 0x00000, 0x80000},
2050                         {"partition-table", 0x80000, 0x02000},
2051                         {"default-mac", 0x90000, 0x01000},
2052                         {"support-list", 0x91000, 0x00100},
2053                         {"product-info", 0x91100, 0x00400},
2054                         {"soft-version", 0x92000, 0x00100},
2055                         {"firmware", 0xa0000, 0xd20000},
2056                         {"user-config", 0xdc0000, 0x30000},
2057                         {"mutil-log", 0xf30000, 0x80000},
2058                         {"oops", 0xfb0000, 0x40000},
2059                         {"radio", 0xff0000, 0x10000},
2060                         {NULL, 0, 0}
2061                 },
2062 
2063                 .first_sysupgrade_partition = "os-image",
2064                 .last_sysupgrade_partition = "file-system"
2065         },
2066 
2067         /** Firmware layout for the EAP245 v1 */
2068         {
2069                 .id     = "EAP245-V1",
2070                 .support_list =
2071                         "SupportList:\r\n"
2072                         "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
2073                 .part_trail = PART_TRAIL_NONE,
2074                 .soft_ver = SOFT_VER_DEFAULT,
2075 
2076                 .partitions = {
2077                         {"fs-uboot", 0x00000, 0x20000},
2078                         {"partition-table", 0x20000, 0x02000},
2079                         {"default-mac", 0x30000, 0x01000},
2080                         {"support-list", 0x31000, 0x00100},
2081                         {"product-info", 0x31100, 0x00400},
2082                         {"soft-version", 0x32000, 0x00100},
2083                         {"firmware", 0x40000, 0xd80000},
2084                         {"user-config", 0xdc0000, 0x30000},
2085                         {"radio", 0xff0000, 0x10000},
2086                         {NULL, 0, 0}
2087                 },
2088 
2089                 .first_sysupgrade_partition = "os-image",
2090                 .last_sysupgrade_partition = "file-system"
2091         },
2092 
2093         /** Firmware layout for the EAP245 v3 */
2094         {
2095                 .id     = "EAP245-V3",
2096                 .support_list =
2097                         "SupportList:\r\n"
2098                         "EAP245(TP-Link|UN|AC1750-D):3.0\r\n"
2099                         "EAP265 HD(TP-Link|UN|AC1750-D):1.0",
2100                 .part_trail = PART_TRAIL_NONE,
2101                 .soft_ver = SOFT_VER_DEFAULT,
2102                 .soft_ver_compat_level = 1,
2103 
2104                 /** Firmware partition with dynamic kernel/rootfs split */
2105                 .partitions = {
2106                         {"factroy-boot", 0x00000, 0x40000},
2107                         {"fs-uboot", 0x40000, 0x40000},
2108                         {"partition-table", 0x80000, 0x10000},
2109                         {"default-mac", 0x90000, 0x01000},
2110                         {"support-list", 0x91000, 0x00100},
2111                         {"product-info", 0x91100, 0x00400},
2112                         {"soft-version", 0x92000, 0x00100},
2113                         {"radio", 0xa0000, 0x10000},
2114                         {"extra-para", 0xb0000, 0x10000},
2115                         {"firmware", 0xc0000, 0xe40000},
2116                         {"config", 0xf00000, 0x30000},
2117                         {"mutil-log", 0xf30000, 0x80000},
2118                         {"oops", 0xfb0000, 0x40000},
2119                         {NULL, 0, 0}
2120                 },
2121 
2122                 .first_sysupgrade_partition = "os-image",
2123                 .last_sysupgrade_partition = "file-system"
2124         },
2125 
2126         /** Firmware layout for the EAP610 v3/EAP613 v1 */
2127         {
2128                 .id = "EAP610-V3",
2129                 .soft_ver = SOFT_VER_DEFAULT,
2130                 .soft_ver_compat_level = 1,
2131                 .support_list =
2132                         "SupportList:\r\n"
2133                         "EAP610(TP-Link|UN|AX1800-D):3.0\r\n"
2134                         "EAP610(TP-Link|JP|AX1800-D):3.0\r\n"
2135                         "EAP610(TP-Link|EG|AX1800-D):3.0\r\n"
2136                         "EAP610(TP-Link|CA|AX1800-D):3.0\r\n"
2137                         "EAP613(TP-Link|UN|AX1800-D):1.0 JP\r\n",
2138                 .part_trail = PART_TRAIL_NONE,
2139 
2140                 .partitions = {
2141                         {"fs-uboot", 0x00000, 0x80000},
2142                         {"partition-table", 0x80000, 0x02000},
2143                         {"default-mac", 0x90000, 0x01000},
2144                         {"support-list", 0x91000, 0x00100},
2145                         {"product-info", 0x91100, 0x00400},
2146                         {"soft-version", 0x92000, 0x00100},
2147                         {"firmware", 0xa0000, 0xcf0000},
2148                         {"user-config", 0xd90000, 0x60000},
2149                         {"mutil-log", 0xf30000, 0x80000},
2150                         {"oops", 0xfb0000, 0x40000},
2151                         {"radio", 0xff0000, 0x10000},
2152                         {NULL, 0, 0}
2153                 },
2154 
2155                 .first_sysupgrade_partition = "os-image",
2156                 .last_sysupgrade_partition = "file-system"
2157         },
2158 
2159         /** Firmware layout for the EAP615-Wall v1 */
2160         {
2161                 .id = "EAP615-WALL-V1",
2162                 .soft_ver = SOFT_VER_DEFAULT,
2163                 .soft_ver_compat_level = 2,
2164                 .support_list =
2165                         "SupportList:\r\n"
2166                         "EAP615-Wall(TP-Link|UN|AX1800-D):1.0\r\n"
2167                         "EAP615-Wall(TP-Link|CA|AX1800-D):1.0\r\n"
2168                         "EAP615-Wall(TP-Link|JP|AX1800-D):1.0\r\n",
2169                 .part_trail = PART_TRAIL_NONE,
2170 
2171                 .partitions = {
2172                         {"fs-uboot", 0x00000, 0x80000},
2173                         {"partition-table", 0x80000, 0x02000},
2174                         {"default-mac", 0x90000, 0x01000},
2175                         {"support-list", 0x91000, 0x00100},
2176                         {"product-info", 0x91100, 0x00400},
2177                         {"soft-version", 0x92000, 0x00100},
2178                         {"firmware", 0xa0000, 0xcf0000},
2179                         {"user-config", 0xd90000, 0x60000},
2180                         {"mutil-log", 0xf30000, 0x80000},
2181                         {"oops", 0xfb0000, 0x40000},
2182                         {"radio", 0xff0000, 0x10000},
2183                         {NULL, 0, 0}
2184                 },
2185 
2186                 .first_sysupgrade_partition = "os-image",
2187                 .last_sysupgrade_partition = "file-system"
2188         },
2189 
2190         /** Firmware layout for the TL-WA1201 v2 */
2191         {
2192                 .id     = "TL-WA1201-V2",
2193                 .vendor = "",
2194                 .support_list =
2195                         "SupportList:\n"
2196                         "{product_name:TL-WA1201,product_ver:2.0.0,special_id:45550000}\n"
2197                         "{product_name:TL-WA1201,product_ver:2.0.0,special_id:55530000}\n",
2198                 .part_trail = 0x00,
2199                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.1 Build 20200709 rel.66244\n"),
2200 
2201                 .partitions = {
2202                         {"fs-uboot", 0x00000, 0x20000},
2203                         {"default-mac", 0x20000, 0x00200},
2204                         {"pin", 0x20200, 0x00100},
2205                         {"product-info", 0x20300, 0x00200},
2206                         {"device-id", 0x20500, 0x0fb00},
2207                         {"firmware", 0x30000, 0xce0000},
2208                         {"portal-logo", 0xd10000, 0x20000},
2209                         {"portal-back", 0xd30000, 0x200000},
2210                         {"soft-version", 0xf30000, 0x00200},
2211                         {"extra-para", 0xf30200, 0x00200},
2212                         {"support-list", 0xf30400, 0x00200},
2213                         {"profile", 0xf30600, 0x0fa00},
2214                         {"apdef-config", 0xf40000, 0x10000},
2215                         {"ap-config", 0xf50000, 0x10000},
2216                         {"redef-config", 0xf60000, 0x10000},
2217                         {"re-config", 0xf70000, 0x10000},
2218                         {"multidef-config", 0xf80000, 0x10000},
2219                         {"multi-config", 0xf90000, 0x10000},
2220                         {"clientdef-config", 0xfa0000, 0x10000},
2221                         {"client-config", 0xfb0000, 0x10000},
2222                         {"partition-table", 0xfc0000, 0x10000},
2223                         {"user-config", 0xfd0000, 0x10000},
2224                         {"certificate", 0xfe0000, 0x10000},
2225                         {"radio", 0xff0000, 0x10000},
2226                         {NULL, 0, 0}
2227                 },
2228                 .first_sysupgrade_partition = "os-image",
2229                 .last_sysupgrade_partition = "file-system",
2230         },
2231 
2232         /** Firmware layout for the TL-WA850RE v2 */
2233         {
2234                 .id     = "TLWA850REV2",
2235                 .vendor = "",
2236                 .support_list =
2237                         "SupportList:\n"
2238                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
2239                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
2240                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
2241                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
2242                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
2243                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
2244                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
2245                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
2246                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
2247                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
2248                 .part_trail = 0x00,
2249                 .soft_ver = SOFT_VER_DEFAULT,
2250 
2251                 /**
2252                    576KB were moved from file-system to os-image
2253                    in comparison to the stock image
2254                 */
2255                 .partitions = {
2256                         {"fs-uboot", 0x00000, 0x20000},
2257                         {"firmware", 0x20000, 0x390000},
2258                         {"partition-table", 0x3b0000, 0x02000},
2259                         {"default-mac", 0x3c0000, 0x00020},
2260                         {"pin", 0x3c0100, 0x00020},
2261                         {"product-info", 0x3c1000, 0x01000},
2262                         {"soft-version", 0x3c2000, 0x00100},
2263                         {"support-list", 0x3c3000, 0x01000},
2264                         {"profile", 0x3c4000, 0x08000},
2265                         {"user-config", 0x3d0000, 0x10000},
2266                         {"default-config", 0x3e0000, 0x10000},
2267                         {"radio", 0x3f0000, 0x10000},
2268                         {NULL, 0, 0}
2269                 },
2270 
2271                 .first_sysupgrade_partition = "os-image",
2272                 .last_sysupgrade_partition = "file-system"
2273         },
2274 
2275         /** Firmware layout for the TL-WA855RE v1 */
2276         {
2277                 .id     = "TLWA855REV1",
2278                 .vendor = "",
2279                 .support_list =
2280                         "SupportList:\n"
2281                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
2282                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
2283                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
2284                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
2285                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
2286                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
2287                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
2288                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
2289                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
2290                 .part_trail = 0x00,
2291                 .soft_ver = SOFT_VER_DEFAULT,
2292 
2293                 .partitions = {
2294                         {"fs-uboot", 0x00000, 0x20000},
2295                         {"os-image", 0x20000, 0x150000},
2296                         {"file-system", 0x170000, 0x240000},
2297                         {"partition-table", 0x3b0000, 0x02000},
2298                         {"default-mac", 0x3c0000, 0x00020},
2299                         {"pin", 0x3c0100, 0x00020},
2300                         {"product-info", 0x3c1000, 0x01000},
2301                         {"soft-version", 0x3c2000, 0x00100},
2302                         {"support-list", 0x3c3000, 0x01000},
2303                         {"profile", 0x3c4000, 0x08000},
2304                         {"user-config", 0x3d0000, 0x10000},
2305                         {"default-config", 0x3e0000, 0x10000},
2306                         {"radio", 0x3f0000, 0x10000},
2307                         {NULL, 0, 0}
2308                 },
2309 
2310                 .first_sysupgrade_partition = "os-image",
2311                 .last_sysupgrade_partition = "file-system"
2312         },
2313 
2314         /** Firmware layout for the TL-WPA8630P v2 (EU)*/
2315         {
2316                 .id     = "TL-WPA8630P-V2.0-EU",
2317                 .vendor = "",
2318                 .support_list =
2319                         "SupportList:\n"
2320                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
2321                 .part_trail = 0x00,
2322                 .soft_ver = SOFT_VER_DEFAULT,
2323 
2324                 .partitions = {
2325                         {"factory-uboot", 0x00000, 0x20000},
2326                         {"fs-uboot", 0x20000, 0x20000},
2327                         {"firmware", 0x40000, 0x5e0000},
2328                         {"partition-table", 0x620000, 0x02000},
2329                         {"default-mac", 0x630000, 0x00020},
2330                         {"pin", 0x630100, 0x00020},
2331                         {"device-id", 0x630200, 0x00030},
2332                         {"product-info", 0x631100, 0x01000},
2333                         {"extra-para", 0x632100, 0x01000},
2334                         {"soft-version", 0x640000, 0x01000},
2335                         {"support-list", 0x641000, 0x01000},
2336                         {"profile", 0x642000, 0x08000},
2337                         {"user-config", 0x650000, 0x10000},
2338                         {"default-config", 0x660000, 0x10000},
2339                         {"default-nvm", 0x670000, 0xc0000},
2340                         {"default-pib", 0x730000, 0x40000},
2341                         {"radio", 0x7f0000, 0x10000},
2342                         {NULL, 0, 0}
2343                 },
2344 
2345                 .first_sysupgrade_partition = "os-image",
2346                 .last_sysupgrade_partition = "file-system"
2347         },
2348 
2349         /** Firmware layout for the TL-WPA8630P v2 (INT)*/
2350         {
2351                 .id     = "TL-WPA8630P-V2-INT",
2352                 .vendor = "",
2353                 .support_list =
2354                         "SupportList:\n"
2355                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
2356                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
2357                         "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
2358                 .part_trail = 0x00,
2359                 .soft_ver = SOFT_VER_DEFAULT,
2360 
2361                 .partitions = {
2362                         {"factory-uboot", 0x00000, 0x20000},
2363                         {"fs-uboot", 0x20000, 0x20000},
2364                         {"firmware", 0x40000, 0x5e0000},
2365                         {"partition-table", 0x620000, 0x02000},
2366                         {"extra-para", 0x632100, 0x01000},
2367                         {"soft-version", 0x640000, 0x01000},
2368                         {"support-list", 0x641000, 0x01000},
2369                         {"profile", 0x642000, 0x08000},
2370                         {"user-config", 0x650000, 0x10000},
2371                         {"default-config", 0x660000, 0x10000},
2372                         {"default-nvm", 0x670000, 0xc0000},
2373                         {"default-pib", 0x730000, 0x40000},
2374                         {"default-mac", 0x7e0000, 0x00020},
2375                         {"pin", 0x7e0100, 0x00020},
2376                         {"device-id", 0x7e0200, 0x00030},
2377                         {"product-info", 0x7e1100, 0x01000},
2378                         {"radio", 0x7f0000, 0x10000},
2379                         {NULL, 0, 0}
2380                 },
2381 
2382                 .first_sysupgrade_partition = "os-image",
2383                 .last_sysupgrade_partition = "file-system"
2384         },
2385 
2386         /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
2387         {
2388                 .id     = "TL-WPA8630P-V2.1-EU",
2389                 .vendor = "",
2390                 .support_list =
2391                         "SupportList:\n"
2392                         "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
2393                 .part_trail = 0x00,
2394                 .soft_ver = SOFT_VER_DEFAULT,
2395 
2396                 .partitions = {
2397                         {"factory-uboot", 0x00000, 0x20000},
2398                         {"fs-uboot", 0x20000, 0x20000},
2399                         {"firmware", 0x40000, 0x5e0000},
2400                         {"extra-para", 0x680000, 0x01000},
2401                         {"product-info", 0x690000, 0x01000},
2402                         {"partition-table", 0x6a0000, 0x02000},
2403                         {"soft-version", 0x6b0000, 0x01000},
2404                         {"support-list", 0x6b1000, 0x01000},
2405                         {"profile", 0x6b2000, 0x08000},
2406                         {"user-config", 0x6c0000, 0x10000},
2407                         {"default-config", 0x6d0000, 0x10000},
2408                         {"default-nvm", 0x6e0000, 0xc0000},
2409                         {"default-pib", 0x7a0000, 0x40000},
2410                         {"default-mac", 0x7e0000, 0x00020},
2411                         {"pin", 0x7e0100, 0x00020},
2412                         {"device-id", 0x7e0200, 0x00030},
2413                         {"radio", 0x7f0000, 0x10000},
2414                         {NULL, 0, 0}
2415                 },
2416 
2417                 .first_sysupgrade_partition = "os-image",
2418                 .last_sysupgrade_partition = "file-system"
2419         },
2420 
2421         /** Firmware layout for the TL-WPA8631P v3 */
2422         {
2423                 .id     = "TL-WPA8631P-V3",
2424                 .vendor = "",
2425                 .support_list =
2426                         "SupportList:\n"
2427                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:41550000}\n"
2428                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:45550000}\n"
2429                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:55530000}\n"
2430                         "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:41550000}\n"
2431                         "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:45550000}\n"
2432                         "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:55530000}\n"
2433                         "{product_name:TL-WPA8635P,product_ver:3.0.0,special_id:46520000}\n",
2434                 .part_trail = 0x00,
2435                 .soft_ver = SOFT_VER_DEFAULT,
2436 
2437                 .partitions = {
2438                         {"fs-uboot", 0x00000, 0x20000},
2439                         {"firmware", 0x20000, 0x710000},
2440                         {"partition-table", 0x730000, 0x02000},
2441                         {"default-mac", 0x732000, 0x00020},
2442                         {"pin", 0x732100, 0x00020},
2443                         {"device-id", 0x732200, 0x00030},
2444                         {"default-region", 0x732300, 0x00010},
2445                         {"product-info", 0x732400, 0x00200},
2446                         {"extra-para", 0x732600, 0x00200},
2447                         {"soft-version", 0x732800, 0x00100},
2448                         {"support-list", 0x732900, 0x00200},
2449                         {"profile", 0x732b00, 0x00100},
2450                         {"default-config", 0x732c00, 0x00800},
2451                         {"plc-type", 0x733400, 0x00020},
2452                         {"default-pib", 0x733500, 0x06000},
2453                         {"user-config", 0x740000, 0x10000},
2454                         {"plc-pib", 0x750000, 0x10000},
2455                         {"plc-nvm", 0x760000, 0x90000},
2456                         {"radio", 0x7f0000, 0x10000},
2457                         {NULL, 0, 0}
2458                 },
2459 
2460                 .first_sysupgrade_partition = "os-image",
2461                 .last_sysupgrade_partition = "file-system"
2462         },
2463 
2464         /** Firmware layout for the TL-WR1043 v5 */
2465         {
2466                 .id     = "TLWR1043NV5",
2467                 .vendor = "",
2468                 .support_list =
2469                         "SupportList:\n"
2470                         "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
2471                         "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
2472                 .part_trail = 0x00,
2473                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
2474                 .partitions = {
2475                         {"factory-boot", 0x00000, 0x20000},
2476                         {"fs-uboot", 0x20000, 0x20000},
2477                         {"firmware", 0x40000, 0xec0000},
2478                         {"default-mac", 0xf00000, 0x00200},
2479                         {"pin", 0xf00200, 0x00200},
2480                         {"device-id", 0xf00400, 0x00100},
2481                         {"product-info", 0xf00500, 0x0fb00},
2482                         {"soft-version", 0xf10000, 0x01000},
2483                         {"extra-para", 0xf11000, 0x01000},
2484                         {"support-list", 0xf12000, 0x0a000},
2485                         {"profile", 0xf1c000, 0x04000},
2486                         {"default-config", 0xf20000, 0x10000},
2487                         {"user-config", 0xf30000, 0x40000},
2488                         {"qos-db", 0xf70000, 0x40000},
2489                         {"certificate", 0xfb0000, 0x10000},
2490                         {"partition-table", 0xfc0000, 0x10000},
2491                         {"log", 0xfd0000, 0x20000},
2492                         {"radio", 0xff0000, 0x10000},
2493                         {NULL, 0, 0}
2494                 },
2495                 .first_sysupgrade_partition = "os-image",
2496                 .last_sysupgrade_partition = "file-system"
2497         },
2498 
2499         /** Firmware layout for the TL-WR1043 v4 */
2500         {
2501                 .id     = "TLWR1043NDV4",
2502                 .vendor = "",
2503                 .support_list =
2504                         "SupportList:\n"
2505                         "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
2506                 .part_trail = 0x00,
2507                 .soft_ver = SOFT_VER_DEFAULT,
2508 
2509                 /* We're using a dynamic kernel/rootfs split here */
2510                 .partitions = {
2511                         {"fs-uboot", 0x00000, 0x20000},
2512                         {"firmware", 0x20000, 0xf30000},
2513                         {"default-mac", 0xf50000, 0x00200},
2514                         {"pin", 0xf50200, 0x00200},
2515                         {"product-info", 0xf50400, 0x0fc00},
2516                         {"soft-version", 0xf60000, 0x0b000},
2517                         {"support-list", 0xf6b000, 0x04000},
2518                         {"profile", 0xf70000, 0x04000},
2519                         {"default-config", 0xf74000, 0x0b000},
2520                         {"user-config", 0xf80000, 0x40000},
2521                         {"partition-table", 0xfc0000, 0x10000},
2522                         {"log", 0xfd0000, 0x20000},
2523                         {"radio", 0xff0000, 0x10000},
2524                         {NULL, 0, 0}
2525                 },
2526 
2527                 .first_sysupgrade_partition = "os-image",
2528                 .last_sysupgrade_partition = "file-system"
2529         },
2530 
2531         /** Firmware layout for the TL-WR902AC v1 */
2532         {
2533                 .id     = "TL-WR902AC-V1",
2534                 .vendor = "",
2535                 .support_list =
2536                         "SupportList:\n"
2537                         "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
2538                         "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
2539                 .part_trail = 0x00,
2540                 .soft_ver = SOFT_VER_DEFAULT,
2541 
2542                 /**
2543                    384KB were moved from file-system to os-image
2544                    in comparison to the stock image
2545                 */
2546                 .partitions = {
2547                         {"fs-uboot", 0x00000, 0x20000},
2548                         {"firmware", 0x20000, 0x730000},
2549                         {"default-mac", 0x750000, 0x00200},
2550                         {"pin", 0x750200, 0x00200},
2551                         {"product-info", 0x750400, 0x0fc00},
2552                         {"soft-version", 0x760000, 0x0b000},
2553                         {"support-list", 0x76b000, 0x04000},
2554                         {"profile", 0x770000, 0x04000},
2555                         {"default-config", 0x774000, 0x0b000},
2556                         {"user-config", 0x780000, 0x40000},
2557                         {"partition-table", 0x7c0000, 0x10000},
2558                         {"log", 0x7d0000, 0x20000},
2559                         {"radio", 0x7f0000, 0x10000},
2560                         {NULL, 0, 0}
2561                 },
2562 
2563                 .first_sysupgrade_partition = "os-image",
2564                 .last_sysupgrade_partition = "file-system",
2565         },
2566 
2567         /** Firmware layout for the TL-WR941HP v1 */
2568         {
2569                 .id     = "TL-WR941HP-V1",
2570                 .vendor = "",
2571                 .support_list =
2572                         "SupportList:\n"
2573                         "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n",
2574                 .part_trail = 0x00,
2575                 .soft_ver = SOFT_VER_DEFAULT,
2576 
2577                 .partitions = {
2578                         {"fs-uboot", 0x00000, 0x20000},
2579                         {"firmware", 0x20000, 0x730000},
2580                         {"default-mac", 0x750000, 0x00200},
2581                         {"pin", 0x750200, 0x00200},
2582                         {"product-info", 0x750400, 0x0fc00},
2583                         {"soft-version", 0x760000, 0x0b000},
2584                         {"support-list", 0x76b000, 0x04000},
2585                         {"profile", 0x770000, 0x04000},
2586                         {"default-config", 0x774000, 0x0b000},
2587                         {"user-config", 0x780000, 0x40000},
2588                         {"partition-table", 0x7c0000, 0x10000},
2589                         {"log", 0x7d0000, 0x20000},
2590                         {"radio", 0x7f0000, 0x10000},
2591                         {NULL, 0, 0}
2592                 },
2593 
2594                 .first_sysupgrade_partition = "os-image",
2595                 .last_sysupgrade_partition = "file-system",
2596         },
2597 
2598         /** Firmware layout for the TL-WR942N V1 */
2599         {
2600                 .id     = "TLWR942NV1",
2601                 .vendor = "",
2602                 .support_list =
2603                         "SupportList:\r\n"
2604                         "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
2605                         "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
2606                 .part_trail = 0x00,
2607                 .soft_ver = SOFT_VER_DEFAULT,
2608 
2609                 .partitions = {
2610                         {"fs-uboot", 0x00000, 0x20000},
2611                         {"firmware", 0x20000, 0xe20000},
2612                         {"default-mac", 0xe40000, 0x00200},
2613                         {"pin", 0xe40200, 0x00200},
2614                         {"product-info", 0xe40400, 0x0fc00},
2615                         {"partition-table", 0xe50000, 0x10000},
2616                         {"soft-version", 0xe60000, 0x10000},
2617                         {"support-list", 0xe70000, 0x10000},
2618                         {"profile", 0xe80000, 0x10000},
2619                         {"default-config", 0xe90000, 0x10000},
2620                         {"user-config", 0xea0000, 0x40000},
2621                         {"qos-db", 0xee0000, 0x40000},
2622                         {"certificate", 0xf20000, 0x10000},
2623                         {"usb-config", 0xfb0000, 0x10000},
2624                         {"log", 0xfc0000, 0x20000},
2625                         {"radio-bk", 0xfe0000, 0x10000},
2626                         {"radio", 0xff0000, 0x10000},
2627                         {NULL, 0, 0}
2628                 },
2629 
2630                 .first_sysupgrade_partition = "os-image",
2631                 .last_sysupgrade_partition = "file-system",
2632         },
2633 
2634   /** Firmware layout for the RE200 v2 */
2635         {
2636                 .id     = "RE200-V2",
2637                 .vendor = "",
2638                 .support_list =
2639                         "SupportList:\n"
2640                         "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
2641                         "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
2642                         "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
2643                         "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
2644                         "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
2645                         "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
2646                         "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
2647                         "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
2648                         "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
2649                         "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
2650                         "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
2651                         "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
2652                         "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
2653                 .part_trail = 0x00,
2654                 .soft_ver = SOFT_VER_DEFAULT,
2655 
2656                 .partitions = {
2657                         {"fs-uboot", 0x00000, 0x20000},
2658                         {"firmware", 0x20000, 0x7a0000},
2659                         {"partition-table", 0x7c0000, 0x02000},
2660                         {"default-mac", 0x7c2000, 0x00020},
2661                         {"pin", 0x7c2100, 0x00020},
2662                         {"product-info", 0x7c3100, 0x01000},
2663                         {"soft-version", 0x7c4200, 0x01000},
2664                         {"support-list", 0x7c5200, 0x01000},
2665                         {"profile", 0x7c6200, 0x08000},
2666                         {"config-info", 0x7ce200, 0x00400},
2667                         {"user-config", 0x7d0000, 0x10000},
2668                         {"default-config", 0x7e0000, 0x10000},
2669                         {"radio", 0x7f0000, 0x10000},
2670                         {NULL, 0, 0}
2671                 },
2672 
2673                 .first_sysupgrade_partition = "os-image",
2674                 .last_sysupgrade_partition = "file-system"
2675         },
2676 
2677   /** Firmware layout for the RE200 v3 */
2678         {
2679                 .id     = "RE200-V3",
2680                 .vendor = "",
2681                 .support_list =
2682                         "SupportList:\n"
2683                         "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
2684                         "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
2685                         "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
2686                         "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
2687                         "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
2688                         "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
2689                         "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
2690                         "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
2691                         "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
2692                         "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
2693                         "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
2694                         "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
2695                         "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
2696                         "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
2697                 .part_trail = 0x00,
2698                 .soft_ver = SOFT_VER_DEFAULT,
2699 
2700                 .partitions = {
2701                         {"fs-uboot", 0x00000, 0x20000},
2702                         {"firmware", 0x20000, 0x7a0000},
2703                         {"partition-table", 0x7c0000, 0x02000},
2704                         {"default-mac", 0x7c2000, 0x00020},
2705                         {"pin", 0x7c2100, 0x00020},
2706                         {"product-info", 0x7c3100, 0x01000},
2707                         {"soft-version", 0x7c4200, 0x01000},
2708                         {"support-list", 0x7c5200, 0x01000},
2709                         {"profile", 0x7c6200, 0x08000},
2710                         {"config-info", 0x7ce200, 0x00400},
2711                         {"user-config", 0x7d0000, 0x10000},
2712                         {"default-config", 0x7e0000, 0x10000},
2713                         {"radio", 0x7f0000, 0x10000},
2714                         {NULL, 0, 0}
2715                 },
2716 
2717                 .first_sysupgrade_partition = "os-image",
2718                 .last_sysupgrade_partition = "file-system"
2719         },
2720 
2721   /** Firmware layout for the RE200 v4 */
2722         {
2723                 .id     = "RE200-V4",
2724                 .vendor = "",
2725                 .support_list =
2726                         "SupportList:\n"
2727                         "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2728                         "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2729                         "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2730                         "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2731                         "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2732                         "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2733                         "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2734                         "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2735                         "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2736                         "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2737                         "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2738                         "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2739                         "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2740                         "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2741                 .part_trail = 0x00,
2742                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2743 
2744                 .partitions = {
2745                         {"fs-uboot", 0x00000, 0x20000},
2746                         {"firmware", 0x20000, 0x7a0000},
2747                         {"partition-table", 0x7c0000, 0x02000},
2748                         {"default-mac", 0x7c2000, 0x00020},
2749                         {"pin", 0x7c2100, 0x00020},
2750                         {"product-info", 0x7c3100, 0x01000},
2751                         {"soft-version", 0x7c4200, 0x01000},
2752                         {"support-list", 0x7c5200, 0x01000},
2753                         {"profile", 0x7c6200, 0x08000},
2754                         {"config-info", 0x7ce200, 0x00400},
2755                         {"user-config", 0x7d0000, 0x10000},
2756                         {"default-config", 0x7e0000, 0x10000},
2757                         {"radio", 0x7f0000, 0x10000},
2758                         {NULL, 0, 0}
2759                 },
2760 
2761                 .first_sysupgrade_partition = "os-image",
2762                 .last_sysupgrade_partition = "file-system"
2763         },
2764 
2765         /** Firmware layout for the RE220 v2 */
2766         {
2767                 .id     = "RE220-V2",
2768                 .vendor = "",
2769                 .support_list =
2770                         "SupportList:\n"
2771                         "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2772                         "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2773                         "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2774                         "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2775                         "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2776                         "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2777                         "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2778                         "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2779                         "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2780                         "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2781                         "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2782                         "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2783                         "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2784                 .part_trail = 0x00,
2785                 .soft_ver = SOFT_VER_DEFAULT,
2786 
2787                 .partitions = {
2788                         {"fs-uboot", 0x00000, 0x20000},
2789                         {"firmware", 0x20000, 0x7a0000},
2790                         {"partition-table", 0x7c0000, 0x02000},
2791                         {"default-mac", 0x7c2000, 0x00020},
2792                         {"pin", 0x7c2100, 0x00020},
2793                         {"product-info", 0x7c3100, 0x01000},
2794                         {"soft-version", 0x7c4200, 0x01000},
2795                         {"support-list", 0x7c5200, 0x01000},
2796                         {"profile", 0x7c6200, 0x08000},
2797                         {"config-info", 0x7ce200, 0x00400},
2798                         {"user-config", 0x7d0000, 0x10000},
2799                         {"default-config", 0x7e0000, 0x10000},
2800                         {"radio", 0x7f0000, 0x10000},
2801                         {NULL, 0, 0}
2802                 },
2803 
2804                 .first_sysupgrade_partition = "os-image",
2805                 .last_sysupgrade_partition = "file-system"
2806         },
2807 
2808   /** Firmware layout for the RE305 v1 */
2809         {
2810                 .id     = "RE305-V1",
2811                 .vendor = "",
2812                 .support_list =
2813                         "SupportList:\n"
2814                         "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2815                         "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2816                         "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2817                         "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2818                         "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2819                         "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2820                         "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2821                 .part_trail = 0x00,
2822                 .soft_ver = SOFT_VER_DEFAULT,
2823 
2824                 .partitions = {
2825                         {"fs-uboot", 0x00000, 0x20000},
2826                         {"firmware", 0x20000, 0x5e0000},
2827                         {"partition-table", 0x600000, 0x02000},
2828                         {"default-mac", 0x610000, 0x00020},
2829                         {"pin", 0x610100, 0x00020},
2830                         {"product-info", 0x611100, 0x01000},
2831                         {"soft-version", 0x620000, 0x01000},
2832                         {"support-list", 0x621000, 0x01000},
2833                         {"profile", 0x622000, 0x08000},
2834                         {"user-config", 0x630000, 0x10000},
2835                         {"default-config", 0x640000, 0x10000},
2836                         {"radio", 0x7f0000, 0x10000},
2837                         {NULL, 0, 0}
2838                 },
2839 
2840                 .first_sysupgrade_partition = "os-image",
2841                 .last_sysupgrade_partition = "file-system"
2842         },
2843 
2844         /** Firmware layout for the RE305 v3 */
2845         {
2846                 .id     = "RE305-V3",
2847                 .vendor = "",
2848                 .support_list =
2849                         "SupportList:\n"
2850                         "{product_name:RE305,product_ver:3.0.0,special_id:00000000}\n"
2851                         "{product_name:RE305,product_ver:3.0.0,special_id:45550000}\n"
2852                         "{product_name:RE305,product_ver:3.0.0,special_id:4A500000}\n"
2853                         "{product_name:RE305,product_ver:3.0.0,special_id:4B520000}\n"
2854                         "{product_name:RE305,product_ver:3.0.0,special_id:41550000}\n"
2855                         "{product_name:RE305,product_ver:3.0.0,special_id:42520000}\n"
2856                         "{product_name:RE305,product_ver:3.0.0,special_id:55530000}\n"
2857                         "{product_name:RE305,product_ver:3.0.0,special_id:45530000}\n"
2858                         "{product_name:RE305,product_ver:3.0.0,special_id:41530000}\n"
2859                         "{product_name:RE305,product_ver:3.0.0,special_id:43410000}\n"
2860                         "{product_name:RE305,product_ver:3.0.0,special_id:52550000}\n",
2861                 .part_trail = 0x00,
2862                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
2863 
2864                 .partitions = {
2865                         {"fs-uboot", 0x00000, 0x20000},
2866                         {"firmware", 0x20000, 0x7a0000},
2867                         {"partition-table", 0x7c0000, 0x02000},
2868                         {"default-mac", 0x7c2000, 0x00020},
2869                         {"pin", 0x7c2100, 0x00020},
2870                         {"product-info", 0x7c3100, 0x01000},
2871                         {"soft-version", 0x7c4200, 0x01000},
2872                         {"support-list", 0x7c5200, 0x01000},
2873                         {"profile", 0x7c6200, 0x08000},
2874                         {"config-info", 0x7ce200, 0x00400},
2875                         {"user-config", 0x7d0000, 0x10000},
2876                         {"default-config", 0x7e0000, 0x10000},
2877                         {"radio", 0x7f0000, 0x10000},
2878                         {NULL, 0, 0}
2879                 },
2880 
2881                 .first_sysupgrade_partition = "os-image",
2882                 .last_sysupgrade_partition = "file-system"
2883         },
2884 
2885         /** Firmware layout for the RE350 v1 */
2886         {
2887                 .id     = "RE350-V1",
2888                 .vendor = "",
2889                 .support_list =
2890                         "SupportList:\n"
2891                         "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2892                         "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2893                         "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2894                         "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2895                         "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2896                         "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2897                         "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2898                 .part_trail = 0x00,
2899                 .soft_ver = SOFT_VER_DEFAULT,
2900 
2901                 /** We're using a dynamic kernel/rootfs split here */
2902                 .partitions = {
2903                         {"fs-uboot", 0x00000, 0x20000},
2904                         {"firmware", 0x20000, 0x5e0000},
2905                         {"partition-table", 0x600000, 0x02000},
2906                         {"default-mac", 0x610000, 0x00020},
2907                         {"pin", 0x610100, 0x00020},
2908                         {"product-info", 0x611100, 0x01000},
2909                         {"soft-version", 0x620000, 0x01000},
2910                         {"support-list", 0x621000, 0x01000},
2911                         {"profile", 0x622000, 0x08000},
2912                         {"user-config", 0x630000, 0x10000},
2913                         {"default-config", 0x640000, 0x10000},
2914                         {"radio", 0x7f0000, 0x10000},
2915                         {NULL, 0, 0}
2916                 },
2917 
2918                 .first_sysupgrade_partition = "os-image",
2919                 .last_sysupgrade_partition = "file-system"
2920         },
2921 
2922         /** Firmware layout for the RE350K v1 */
2923         {
2924                 .id     = "RE350K-V1",
2925                 .vendor = "",
2926                 .support_list =
2927                         "SupportList:\n"
2928                         "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2929                 .part_trail = 0x00,
2930                 .soft_ver = SOFT_VER_DEFAULT,
2931 
2932                 /** We're using a dynamic kernel/rootfs split here */
2933                 .partitions = {
2934                         {"fs-uboot", 0x00000, 0x20000},
2935                         {"firmware", 0x20000, 0xd70000},
2936                         {"partition-table", 0xd90000, 0x02000},
2937                         {"default-mac", 0xda0000, 0x00020},
2938                         {"pin", 0xda0100, 0x00020},
2939                         {"product-info", 0xda1100, 0x01000},
2940                         {"soft-version", 0xdb0000, 0x01000},
2941                         {"support-list", 0xdb1000, 0x01000},
2942                         {"profile", 0xdb2000, 0x08000},
2943                         {"user-config", 0xdc0000, 0x10000},
2944                         {"default-config", 0xdd0000, 0x10000},
2945                         {"device-id", 0xde0000, 0x00108},
2946                         {"radio", 0xff0000, 0x10000},
2947                         {NULL, 0, 0}
2948                 },
2949 
2950                 .first_sysupgrade_partition = "os-image",
2951                 .last_sysupgrade_partition = "file-system"
2952         },
2953 
2954         /** Firmware layout for the RE355 */
2955         {
2956                 .id     = "RE355",
2957                 .vendor = "",
2958                 .support_list =
2959                         "SupportList:\r\n"
2960                         "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2961                         "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2962                         "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2963                         "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2964                         "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2965                         "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2966                         "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2967                         "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2968                 .part_trail = 0x00,
2969                 .soft_ver = SOFT_VER_DEFAULT,
2970 
2971                 /* We're using a dynamic kernel/rootfs split here */
2972                 .partitions = {
2973                         {"fs-uboot", 0x00000, 0x20000},
2974                         {"firmware", 0x20000, 0x5e0000},
2975                         {"partition-table", 0x600000, 0x02000},
2976                         {"default-mac", 0x610000, 0x00020},
2977                         {"pin", 0x610100, 0x00020},
2978                         {"product-info", 0x611100, 0x01000},
2979                         {"soft-version", 0x620000, 0x01000},
2980                         {"support-list", 0x621000, 0x01000},
2981                         {"profile", 0x622000, 0x08000},
2982                         {"user-config", 0x630000, 0x10000},
2983                         {"default-config", 0x640000, 0x10000},
2984                         {"radio", 0x7f0000, 0x10000},
2985                         {NULL, 0, 0}
2986                 },
2987 
2988                 .first_sysupgrade_partition = "os-image",
2989                 .last_sysupgrade_partition = "file-system"
2990         },
2991 
2992         /** Firmware layout for the RE450 */
2993         {
2994                 .id     = "RE450",
2995                 .vendor = "",
2996                 .support_list =
2997                         "SupportList:\r\n"
2998                         "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2999                         "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
3000                         "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
3001                         "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
3002                         "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
3003                         "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
3004                         "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
3005                         "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
3006                 .part_trail = 0x00,
3007                 .soft_ver = SOFT_VER_DEFAULT,
3008 
3009                 /** We're using a dynamic kernel/rootfs split here */
3010                 .partitions = {
3011                         {"fs-uboot", 0x00000, 0x20000},
3012                         {"firmware", 0x20000, 0x5e0000},
3013                         {"partition-table", 0x600000, 0x02000},
3014                         {"default-mac", 0x610000, 0x00020},
3015                         {"pin", 0x610100, 0x00020},
3016                         {"product-info", 0x611100, 0x01000},
3017                         {"soft-version", 0x620000, 0x01000},
3018                         {"support-list", 0x621000, 0x01000},
3019                         {"profile", 0x622000, 0x08000},
3020                         {"user-config", 0x630000, 0x10000},
3021                         {"default-config", 0x640000, 0x10000},
3022                         {"radio", 0x7f0000, 0x10000},
3023                         {NULL, 0, 0}
3024                 },
3025 
3026                 .first_sysupgrade_partition = "os-image",
3027                 .last_sysupgrade_partition = "file-system"
3028         },
3029 
3030         /** Firmware layout for the RE450 v2 */
3031         {
3032                 .id     = "RE450-V2",
3033                 .vendor = "",
3034                 .support_list =
3035                         "SupportList:\r\n"
3036                         "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
3037                         "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
3038                         "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
3039                         "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
3040                         "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
3041                         "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
3042                         "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
3043                         "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
3044                         "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
3045                 .part_trail = 0x00,
3046                 .soft_ver = SOFT_VER_DEFAULT,
3047 
3048                 /* We're using a dynamic kernel/rootfs split here */
3049                 .partitions = {
3050                         {"fs-uboot", 0x00000, 0x20000},
3051                         {"firmware", 0x20000, 0x5e0000},
3052                         {"partition-table", 0x600000, 0x02000},
3053                         {"default-mac", 0x610000, 0x00020},
3054                         {"pin", 0x610100, 0x00020},
3055                         {"product-info", 0x611100, 0x01000},
3056                         {"soft-version", 0x620000, 0x01000},
3057                         {"support-list", 0x621000, 0x01000},
3058                         {"profile", 0x622000, 0x08000},
3059                         {"user-config", 0x630000, 0x10000},
3060                         {"default-config", 0x640000, 0x10000},
3061                         {"radio", 0x7f0000, 0x10000},
3062                         {NULL, 0, 0}
3063                 },
3064 
3065                 .first_sysupgrade_partition = "os-image",
3066                 .last_sysupgrade_partition = "file-system"
3067         },
3068 
3069         /** Firmware layout for the RE450 v3 */
3070         {
3071                 .id     = "RE450-V3",
3072                 .vendor = "",
3073                 .support_list =
3074                         "SupportList:\r\n"
3075                         "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
3076                         "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
3077                         "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
3078                         "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
3079                         "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
3080                         "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
3081                         "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
3082                         "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
3083                         "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
3084                 .part_trail = 0x00,
3085                 .soft_ver = SOFT_VER_DEFAULT,
3086 
3087                 /* We're using a dynamic kernel/rootfs split here */
3088                 .partitions = {
3089                         {"fs-uboot", 0x00000, 0x20000},
3090                         {"default-mac", 0x20000, 0x00020},
3091                         {"pin", 0x20020, 0x00020},
3092                         {"product-info", 0x21000, 0x01000},
3093                         {"partition-table", 0x22000, 0x02000},
3094                         {"soft-version", 0x24000, 0x01000},
3095                         {"support-list", 0x25000, 0x01000},
3096                         {"profile", 0x26000, 0x08000},
3097                         {"user-config", 0x2e000, 0x10000},
3098                         {"default-config", 0x3e000, 0x10000},
3099                         {"config-info", 0x4e000, 0x00400},
3100                         {"firmware", 0x50000, 0x7a0000},
3101                         {"radio", 0x7f0000, 0x10000},
3102                         {NULL, 0, 0}
3103                 },
3104 
3105                 .first_sysupgrade_partition = "os-image",
3106                 .last_sysupgrade_partition = "file-system"
3107         },
3108 
3109         /** Firmware layout for the RE455 v1 */
3110         {
3111                 .id     = "RE455-V1",
3112                 .vendor = "",
3113                 .support_list =
3114                         "SupportList:\r\n"
3115                         "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
3116                         "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
3117                         "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
3118                         "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
3119                         "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
3120                         "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
3121                         "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
3122                         "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
3123                         "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
3124                 .part_trail = 0x00,
3125                 .soft_ver = SOFT_VER_DEFAULT,
3126 
3127                 /* We're using a dynamic kernel/rootfs split here */
3128                 .partitions = {
3129                         {"fs-uboot", 0x00000, 0x20000},
3130                         {"default-mac", 0x20000, 0x00020},
3131                         {"pin", 0x20020, 0x00020},
3132                         {"product-info", 0x21000, 0x01000},
3133                         {"partition-table", 0x22000, 0x02000},
3134                         {"soft-version", 0x24000, 0x01000},
3135                         {"support-list", 0x25000, 0x01000},
3136                         {"profile", 0x26000, 0x08000},
3137                         {"user-config", 0x2e000, 0x10000},
3138                         {"default-config", 0x3e000, 0x10000},
3139                         {"config-info", 0x4e000, 0x00400},
3140                         {"firmware", 0x50000, 0x7a0000},
3141                         {"radio", 0x7f0000, 0x10000},
3142                         {NULL, 0, 0}
3143                 },
3144 
3145                 .first_sysupgrade_partition = "os-image",
3146                 .last_sysupgrade_partition = "file-system"
3147         },
3148 
3149         /** Firmware layout for the RE500 */
3150         {
3151                 .id     = "RE500-V1",
3152                 .vendor = "",
3153                 .support_list =
3154                         "SupportList:\r\n"
3155                         "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
3156                         "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
3157                         "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
3158                         "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
3159                         "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
3160                         "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
3161                         "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
3162                 .part_trail = 0x00,
3163                 .soft_ver = SOFT_VER_DEFAULT,
3164 
3165                 /* We're using a dynamic kernel/rootfs split here */
3166                 .partitions = {
3167                         {"fs-uboot", 0x00000, 0x20000},
3168                         {"firmware", 0x20000, 0xde0000},
3169                         {"partition-table", 0xe00000, 0x02000},
3170                         {"default-mac", 0xe10000, 0x00020},
3171                         {"pin", 0xe10100, 0x00020},
3172                         {"product-info", 0xe11100, 0x01000},
3173                         {"soft-version", 0xe20000, 0x01000},
3174                         {"support-list", 0xe21000, 0x01000},
3175                         {"profile", 0xe22000, 0x08000},
3176                         {"user-config", 0xe30000, 0x10000},
3177                         {"default-config", 0xe40000, 0x10000},
3178                         {"radio", 0xff0000, 0x10000},
3179                         {NULL, 0, 0}
3180                 },
3181 
3182                 .first_sysupgrade_partition = "os-image",
3183                 .last_sysupgrade_partition = "file-system"
3184         },
3185 
3186         /** Firmware layout for the RE650 */
3187         {
3188                 .id     = "RE650-V1",
3189                 .vendor = "",
3190                 .support_list =
3191                         "SupportList:\r\n"
3192                         "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
3193                         "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
3194                         "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
3195                         "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
3196                         "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
3197                         "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
3198                         "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
3199                 .part_trail = 0x00,
3200                 .soft_ver = SOFT_VER_DEFAULT,
3201 
3202                 /* We're using a dynamic kernel/rootfs split here */
3203                 .partitions = {
3204                         {"fs-uboot", 0x00000, 0x20000},
3205                         {"firmware", 0x20000, 0xde0000},
3206                         {"partition-table", 0xe00000, 0x02000},
3207                         {"default-mac", 0xe10000, 0x00020},
3208                         {"pin", 0xe10100, 0x00020},
3209                         {"product-info", 0xe11100, 0x01000},
3210                         {"soft-version", 0xe20000, 0x01000},
3211                         {"support-list", 0xe21000, 0x01000},
3212                         {"profile", 0xe22000, 0x08000},
3213                         {"user-config", 0xe30000, 0x10000},
3214                         {"default-config", 0xe40000, 0x10000},
3215                         {"radio", 0xff0000, 0x10000},
3216                         {NULL, 0, 0}
3217                 },
3218 
3219                 .first_sysupgrade_partition = "os-image",
3220                 .last_sysupgrade_partition = "file-system"
3221         },
3222         /** Firmware layout for the RE650 V2 (8MB Flash)*/
3223         {
3224                 .id     = "RE650-V2",
3225                 .vendor = "",
3226                 .support_list =
3227                         "SupportList:\n"
3228                         "{product_name:RE650,product_ver:2.0.0,special_id:00000000}\n"
3229                         "{product_name:RE650,product_ver:2.0.0,special_id:45550000}\n"
3230                         "{product_name:RE650,product_ver:2.0.0,special_id:4A500000}\n"
3231                         "{product_name:RE650,product_ver:2.0.0,special_id:41550000}\n"
3232                         "{product_name:RE650,product_ver:2.0.0,special_id:43410000}\n"
3233                         "{product_name:RE650,product_ver:2.0.0,special_id:41530000}\n"
3234                         "{product_name:RE650,product_ver:2.0.0,special_id:55530000}\n",
3235                 .part_trail = 0x00,
3236                 /* For RE650 v2, soft ver is required, otherwise OEM install doesn't work */
3237                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
3238 
3239                 /* We're using a dynamic kernel/rootfs split here */
3240                 .partitions = {
3241                         {"fs-uboot", 0x00000, 0x20000},
3242                         {"firmware", 0x20000, 0x7a0000},
3243                         {"partition-table", 0x7c0000, 0x02000},
3244                         {"default-mac", 0x7c2000, 0x00020},
3245                         {"pin", 0x7c2100, 0x00020},
3246                         {"product-info", 0x7c3100, 0x01000},
3247                         {"soft-version", 0x7c4200, 0x01000},
3248                         {"support-list", 0x7c5200, 0x01000},
3249                         {"profile", 0x7c6200, 0x08000},
3250                         {"config-info", 0x7ce200, 0x00400},
3251                         {"user-config", 0x7d0000, 0x10000},
3252                         {"default-config", 0x7e0000, 0x10000},
3253                         {"radio", 0x7f0000, 0x10000},
3254                         {NULL, 0, 0}
3255                 },
3256 
3257                 .first_sysupgrade_partition = "os-image",
3258                 .last_sysupgrade_partition = "file-system"
3259         },
3260 
3261         /** Firmware layout for the Mercusys MR70X */
3262         {
3263                 .id     = "MR70X",
3264                 .vendor = "",
3265                 .support_list =
3266                         "SupportList:\n"
3267                         "{product_name:MR70X,product_ver:1.0.0,special_id:45550000}\n"
3268                         "{product_name:MR70X,product_ver:1.0.0,special_id:4A500000}\n"
3269                         "{product_name:MR70X,product_ver:1.0.0,special_id:55530000}\n",
3270                 .part_trail = 0x00,
3271                 .soft_ver = SOFT_VER_DEFAULT,
3272 
3273                 .partitions = {
3274                         {"fs-uboot", 0x00000, 0x40000},
3275                         {"firmware", 0x40000, 0xf60000},
3276                         {"default-mac", 0xfa0000, 0x00200},
3277                         {"pin", 0xfa0200, 0x00100},
3278                         {"device-id", 0xfa0300, 0x00100},
3279                         {"product-info", 0xfa0400, 0x0fc00},
3280                         {"default-config", 0xfb0000, 0x08000},
3281                         {"ap-def-config", 0xfb8000, 0x08000},
3282                         {"user-config", 0xfc0000, 0x0a000},
3283                         {"ag-config", 0xfca000, 0x04000},
3284                         {"certificate", 0xfce000, 0x02000},
3285                         {"ap-config", 0xfd0000, 0x06000},
3286                         {"router-config", 0xfd6000, 0x06000},
3287                         {"favicon", 0xfdc000, 0x02000},
3288                         {"logo", 0xfde000, 0x02000},
3289                         {"partition-table", 0xfe0000, 0x00800},
3290                         {"soft-version", 0xfe0800, 0x00100},
3291                         {"support-list", 0xfe0900, 0x00200},
3292                         {"profile", 0xfe0b00, 0x03000},
3293                         {"extra-para", 0xfe3b00, 0x00100},
3294                         {"radio", 0xff0000, 0x10000},
3295                         {NULL, 0, 0}
3296                 },
3297 
3298                 .first_sysupgrade_partition = "os-image",
3299                 .last_sysupgrade_partition = "file-system"
3300         },
3301 
3302         {}
3303 };
3304 
3305 #define error(_ret, _errno, _str, ...)                          \
3306         do {                                                    \
3307                 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__,  \
3308                         strerror(_errno));                      \
3309                 if (_ret)                                       \
3310                         exit(_ret);                             \
3311         } while (0)
3312 
3313 
3314 /** Stores a uint32 as big endian */
3315 static inline void put32(uint8_t *buf, uint32_t val) {
3316         buf[0] = val >> 24;
3317         buf[1] = val >> 16;
3318         buf[2] = val >> 8;
3319         buf[3] = val;
3320 }
3321 
3322 static inline bool meta_partition_should_pad(enum partition_trail_value pv)
3323 {
3324         return (pv >= 0) && (pv <= PART_TRAIL_MAX);
3325 }
3326 
3327 /** Allocate a padded meta partition with a correctly initialised header
3328  * If the `data` pointer is NULL, then the required space is only allocated,
3329  * otherwise `data_len` bytes will be copied from `data` into the partition
3330  * entry. */
3331 static struct image_partition_entry init_meta_partition_entry(
3332         const char *name, const void *data, uint32_t data_len,
3333         enum partition_trail_value pad_value)
3334 {
3335         uint32_t total_len = sizeof(struct meta_header) + data_len;
3336         if (meta_partition_should_pad(pad_value))
3337                 total_len += 1;
3338 
3339         struct image_partition_entry entry = {
3340                 .name = name,
3341                 .size = total_len,
3342                 .data = malloc(total_len)
3343         };
3344         if (!entry.data)
3345                 error(1, errno, "failed to allocate meta partition entry");
3346 
3347         struct meta_header *header = (struct meta_header *)entry.data;
3348         header->length = htonl(data_len);
3349         header->zero = 0;
3350 
3351         if (data)
3352                 memcpy(entry.data+sizeof(*header), data, data_len);
3353 
3354         if (meta_partition_should_pad(pad_value))
3355                 entry.data[total_len - 1] = (uint8_t) pad_value;
3356 
3357         return entry;
3358 }
3359 
3360 /** Allocates a new image partition */
3361 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
3362         struct image_partition_entry entry = {name, len, malloc(len)};
3363         if (!entry.data)
3364                 error(1, errno, "malloc");
3365 
3366         return entry;
3367 }
3368 
3369 /** Sets up default partition names whenever custom names aren't specified */
3370 static void set_partition_names(struct device_info *info)
3371 {
3372         if (!info->partition_names.partition_table)
3373                 info->partition_names.partition_table = "partition-table";
3374         if (!info->partition_names.soft_ver)
3375                 info->partition_names.soft_ver = "soft-version";
3376         if (!info->partition_names.os_image)
3377                 info->partition_names.os_image = "os-image";
3378         if (!info->partition_names.support_list)
3379                 info->partition_names.support_list = "support-list";
3380         if (!info->partition_names.file_system)
3381                 info->partition_names.file_system = "file-system";
3382         if (!info->partition_names.extra_para)
3383                 info->partition_names.extra_para = "extra-para";
3384 }
3385 
3386 /** Frees an image partition */
3387 static void free_image_partition(struct image_partition_entry *entry)
3388 {
3389         void *data = entry->data;
3390 
3391         entry->name = NULL;
3392         entry->size = 0;
3393         entry->data = NULL;
3394 
3395         free(data);
3396 }
3397 
3398 static time_t source_date_epoch = -1;
3399 static void set_source_date_epoch() {
3400         char *env = getenv("SOURCE_DATE_EPOCH");
3401         char *endptr = env;
3402         errno = 0;
3403         if (env && *env) {
3404                 source_date_epoch = strtoull(env, &endptr, 10);
3405                 if (errno || (endptr && *endptr != '\0')) {
3406                         fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
3407                         exit(1);
3408                 }
3409         }
3410 }
3411 
3412 /** Generates the partition-table partition */
3413 static struct image_partition_entry make_partition_table(const struct device_info *p)
3414 {
3415         struct image_partition_entry entry = alloc_image_partition(p->partition_names.partition_table, SAFELOADER_PAYLOAD_TABLE_SIZE);
3416 
3417         char *s = (char *)entry.data, *end = (char *)(s+entry.size);
3418 
3419         *(s++) = 0x00;
3420         *(s++) = 0x04;
3421         *(s++) = 0x00;
3422         *(s++) = 0x00;
3423 
3424         size_t i;
3425         for (i = 0; p->partitions[i].name; i++) {
3426                 size_t len = end-s;
3427                 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n",
3428                         p->partitions[i].name, p->partitions[i].base, p->partitions[i].size);
3429 
3430                 if (w > len-1)
3431                         error(1, 0, "flash partition table overflow?");
3432 
3433                 s += w;
3434         }
3435 
3436         s++;
3437 
3438         memset(s, 0xff, end-s);
3439 
3440         return entry;
3441 }
3442 
3443 
3444 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
3445 static inline uint8_t bcd(uint8_t v) {
3446         return 0x10 * (v/10) + v%10;
3447 }
3448 
3449 
3450 /** Generates the soft-version partition */
3451 static struct image_partition_entry make_soft_version(const struct device_info *info, uint32_t rev)
3452 {
3453         /** If an info string is provided, use this instead of
3454          * the structured data, and include the null-termination */
3455         if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) {
3456                 uint32_t len = strlen(info->soft_ver.text) + 1;
3457                 return init_meta_partition_entry(info->partition_names.soft_ver,
3458                         info->soft_ver.text, len, info->part_trail);
3459         }
3460 
3461         time_t t;
3462 
3463         if (source_date_epoch != -1)
3464                 t = source_date_epoch;
3465         else if (time(&t) == (time_t)(-1))
3466                 error(1, errno, "time");
3467 
3468         struct tm *tm = gmtime(&t);
3469 
3470         struct soft_version s = {
3471                 .pad1 = 0xff,
3472 
3473                 .version_major = info->soft_ver.num[0],
3474                 .version_minor = info->soft_ver.num[1],
3475                 .version_patch = info->soft_ver.num[2],
3476 
3477                 .year_hi = bcd((1900+tm->tm_year)/100),
3478                 .year_lo = bcd(tm->tm_year%100),
3479                 .month = bcd(tm->tm_mon+1),
3480                 .day = bcd(tm->tm_mday),
3481                 .rev = htonl(rev),
3482 
3483                 .compat_level = htonl(info->soft_ver_compat_level)
3484         };
3485 
3486         if (info->soft_ver_compat_level == 0)
3487                 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3488                         (uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
3489                         info->part_trail);
3490         else
3491                 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3492                         sizeof(s), info->part_trail);
3493 }
3494 
3495 /** Generates the support-list partition */
3496 static struct image_partition_entry make_support_list(
3497         const struct device_info *info)
3498 {
3499         uint32_t len = strlen(info->support_list);
3500         return init_meta_partition_entry(info->partition_names.support_list, info->support_list,
3501                 len, info->part_trail);
3502 }
3503 
3504 /** Partition with extra-para data */
3505 static struct image_partition_entry make_extra_para(
3506         const struct device_info *info, const uint8_t *extra_para, size_t len)
3507 {
3508         return init_meta_partition_entry(info->partition_names.extra_para, extra_para, len,
3509                 info->part_trail);
3510 }
3511 
3512 /** Creates a new image partition with an arbitrary name from a file */
3513 static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof, struct flash_partition_entry *file_system_partition) {
3514         struct stat statbuf;
3515 
3516         if (stat(filename, &statbuf) < 0)
3517                 error(1, errno, "unable to stat file `%s'", filename);
3518 
3519         size_t len = statbuf.st_size;
3520 
3521         if (add_jffs2_eof) {
3522                 if (file_system_partition)
3523                         len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
3524                 else
3525                         len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
3526         }
3527 
3528         struct image_partition_entry entry = alloc_image_partition(part_name, len);
3529 
3530         FILE *file = fopen(filename, "rb");
3531         if (!file)
3532                 error(1, errno, "unable to open file `%s'", filename);
3533 
3534         if (fread(entry.data, statbuf.st_size, 1, file) != 1)
3535                 error(1, errno, "unable to read file `%s'", filename);
3536 
3537         if (add_jffs2_eof) {
3538                 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
3539 
3540                 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
3541                 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
3542         }
3543 
3544         fclose(file);
3545 
3546         return entry;
3547 }
3548 
3549 /**
3550    Copies a list of image partitions into an image buffer and generates the image partition table while doing so
3551 
3552    Example image partition table:
3553 
3554      fwup-ptn partition-table base 0x00800 size 0x00800
3555      fwup-ptn os-image base 0x01000 size 0x113b45
3556      fwup-ptn file-system base 0x114b45 size 0x1d0004
3557      fwup-ptn support-list base 0x2e4b49 size 0x000d1
3558 
3559    Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
3560    the end of the partition table is marked with a zero byte.
3561 
3562    The firmware image must contain at least the partition-table and support-list partitions
3563    to be accepted. There aren't any alignment constraints for the image partitions.
3564 
3565    The partition-table partition contains the actual flash layout; partitions
3566    from the image partition table are mapped to the corresponding flash partitions during
3567    the firmware upgrade. The support-list partition contains a list of devices supported by
3568    the firmware image.
3569 
3570    The base offsets in the firmware partition table are relative to the end
3571    of the vendor information block, so the partition-table partition will
3572    actually start at offset 0x1814 of the image.
3573 
3574    I think partition-table must be the first partition in the firmware image.
3575 */
3576 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
3577         size_t i, j;
3578         char *image_pt = (char *)buffer, *end = image_pt + SAFELOADER_PAYLOAD_TABLE_SIZE;
3579 
3580         size_t base = SAFELOADER_PAYLOAD_TABLE_SIZE;
3581         for (i = 0; parts[i].name; i++) {
3582                 for (j = 0; flash_parts[j].name; j++) {
3583                         if (!strcmp(flash_parts[j].name, parts[i].name)) {
3584                                 if (parts[i].size > flash_parts[j].size)
3585                                         error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
3586                                 break;
3587                         }
3588                 }
3589 
3590                 assert(flash_parts[j].name);
3591 
3592                 memcpy(buffer + base, parts[i].data, parts[i].size);
3593 
3594                 size_t len = end-image_pt;
3595                 size_t w = snprintf(image_pt, len, "fwup-ptn %s base 0x%05x size 0x%05x\t\r\n", parts[i].name, (unsigned)base, (unsigned)parts[i].size);
3596 
3597                 if (w > len-1)
3598                         error(1, 0, "image partition table overflow?");
3599 
3600                 image_pt += w;
3601 
3602                 base += parts[i].size;
3603         }
3604 }
3605 
3606 /** Generates and writes the image MD5 checksum */
3607 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
3608         MD5_CTX ctx;
3609 
3610         MD5_Init(&ctx);
3611         MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
3612         MD5_Update(&ctx, buffer, len);
3613         MD5_Final(md5, &ctx);
3614 }
3615 
3616 
3617 /**
3618    Generates the firmware image in factory format
3619 
3620    Image format:
3621 
3622      Bytes (hex)  Usage
3623      -----------  -----
3624      0000-0003    Image size (4 bytes, big endian)
3625      0004-0013    MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
3626      0014-0017    Vendor information length (without padding) (4 bytes, big endian)
3627      0018-1013    Vendor information (4092 bytes, padded with 0xff; there seem to be older
3628                   (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
3629      1014-1813    Image partition table (2048 bytes, padded with 0xff)
3630      1814-xxxx    Firmware partitions
3631 */
3632 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
3633         *len = SAFELOADER_PAYLOAD_OFFSET + SAFELOADER_PAYLOAD_TABLE_SIZE;
3634 
3635         size_t i;
3636         for (i = 0; parts[i].name; i++)
3637                 *len += parts[i].size;
3638 
3639         uint8_t *image = malloc(*len);
3640         if (!image)
3641                 error(1, errno, "malloc");
3642 
3643         memset(image, 0xff, *len);
3644         put32(image, *len);
3645 
3646         if (info->vendor) {
3647                 size_t vendor_len = strlen(info->vendor);
3648                 put32(image + SAFELOADER_PREAMBLE_SIZE, vendor_len);
3649                 memcpy(image + SAFELOADER_PREAMBLE_SIZE + 0x4, info->vendor, vendor_len);
3650         }
3651 
3652         put_partitions(image + SAFELOADER_PAYLOAD_OFFSET, info->partitions, parts);
3653         put_md5(image + 0x04, image + SAFELOADER_PREAMBLE_SIZE, *len - SAFELOADER_PREAMBLE_SIZE);
3654 
3655         return image;
3656 }
3657 
3658 /**
3659    Generates the firmware image in sysupgrade format
3660 
3661    This makes some assumptions about the provided flash and image partition tables and
3662    should be generalized when TP-LINK starts building its safeloader into hardware with
3663    different flash layouts.
3664 */
3665 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
3666         size_t i, j;
3667         size_t flash_first_partition_index = 0;
3668         size_t flash_last_partition_index = 0;
3669         const struct flash_partition_entry *flash_first_partition = NULL;
3670         const struct flash_partition_entry *flash_last_partition = NULL;
3671         const struct image_partition_entry *image_last_partition = NULL;
3672 
3673         /** Find first and last partitions */
3674         for (i = 0; info->partitions[i].name; i++) {
3675                 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
3676                         flash_first_partition = &info->partitions[i];
3677                         flash_first_partition_index = i;
3678                 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
3679                         flash_last_partition = &info->partitions[i];
3680                         flash_last_partition_index = i;
3681                 }
3682         }
3683 
3684         assert(flash_first_partition && flash_last_partition);
3685         assert(flash_first_partition_index < flash_last_partition_index);
3686 
3687         /** Find last partition from image to calculate needed size */
3688         for (i = 0; image_parts[i].name; i++) {
3689                 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
3690                         image_last_partition = &image_parts[i];
3691                         break;
3692                 }
3693         }
3694 
3695         assert(image_last_partition);
3696 
3697         *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
3698 
3699         uint8_t *image = malloc(*len);
3700         if (!image)
3701                 error(1, errno, "malloc");
3702 
3703         memset(image, 0xff, *len);
3704 
3705         for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
3706                 for (j = 0; image_parts[j].name; j++) {
3707                         if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
3708                                 if (image_parts[j].size > info->partitions[i].size)
3709                                         error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
3710                                 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
3711                                 break;
3712                         }
3713 
3714                         assert(image_parts[j].name);
3715                 }
3716         }
3717 
3718         return image;
3719 }
3720 
3721 /** Generates an image according to a given layout and writes it to a file */
3722 static void build_image(const char *output,
3723                 const char *kernel_image,
3724                 const char *rootfs_image,
3725                 uint32_t rev,
3726                 bool add_jffs2_eof,
3727                 bool sysupgrade,
3728                 struct device_info *info) {
3729 
3730         size_t i;
3731 
3732         struct image_partition_entry parts[7] = {};
3733 
3734         struct flash_partition_entry *firmware_partition = NULL;
3735         struct flash_partition_entry *os_image_partition = NULL;
3736         struct flash_partition_entry *file_system_partition = NULL;
3737         size_t firmware_partition_index = 0;
3738 
3739         set_partition_names(info);
3740 
3741         for (i = 0; info->partitions[i].name; i++) {
3742                 if (!strcmp(info->partitions[i].name, "firmware"))
3743                 {
3744                         firmware_partition = &info->partitions[i];
3745                         firmware_partition_index = i;
3746                 }
3747         }
3748 
3749         if (firmware_partition)
3750         {
3751                 os_image_partition = &info->partitions[firmware_partition_index];
3752                 file_system_partition = &info->partitions[firmware_partition_index + 1];
3753 
3754                 struct stat kernel;
3755                 if (stat(kernel_image, &kernel) < 0)
3756                         error(1, errno, "unable to stat file `%s'", kernel_image);
3757 
3758                 if (kernel.st_size > firmware_partition->size)
3759                         error(1, 0, "kernel overflowed firmware partition\n");
3760 
3761                 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
3762                         info->partitions[i+1] = info->partitions[i];
3763 
3764                 file_system_partition->name = info->partition_names.file_system;
3765 
3766                 file_system_partition->base = firmware_partition->base + kernel.st_size;
3767 
3768                 /* Align partition start to erase blocks for factory images only */
3769                 if (!sysupgrade)
3770                         file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
3771 
3772                 file_system_partition->size = firmware_partition->size - file_system_partition->base;
3773 
3774                 os_image_partition->name = info->partition_names.os_image;
3775 
3776                 os_image_partition->size = kernel.st_size;
3777         }
3778 
3779         parts[0] = make_partition_table(info);
3780         parts[1] = make_soft_version(info, rev);
3781         parts[2] = make_support_list(info);
3782         parts[3] = read_file(info->partition_names.os_image, kernel_image, false, NULL);
3783         parts[4] = read_file(info->partition_names.file_system, rootfs_image, add_jffs2_eof, file_system_partition);
3784 
3785 
3786         /* Some devices need the extra-para partition to accept the firmware */
3787         if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 ||
3788             strcasecmp(info->id, "ARCHER-A7-V5") == 0 ||
3789             strcasecmp(info->id, "ARCHER-A9-V6") == 0 ||
3790             strcasecmp(info->id, "ARCHER-AX23-V1") == 0 ||
3791             strcasecmp(info->id, "ARCHER-C2-V3") == 0 ||
3792             strcasecmp(info->id, "ARCHER-C7-V4") == 0 ||
3793             strcasecmp(info->id, "ARCHER-C7-V5") == 0 ||
3794             strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
3795             strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
3796             strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
3797             strcasecmp(info->id, "ARCHER-C60-V3") == 0 ||
3798             strcasecmp(info->id, "ARCHER-C6U-V1") == 0 ||
3799             strcasecmp(info->id, "ARCHER-C6-V3") == 0 ||
3800             strcasecmp(info->id, "DECO-M4R-V4") == 0 ||
3801             strcasecmp(info->id, "MR70X") == 0 ||
3802             strcasecmp(info->id, "TLWR1043NV5") == 0) {
3803                 const uint8_t extra_para[2] = {0x01, 0x00};
3804                 parts[5] = make_extra_para(info, extra_para,
3805                         sizeof(extra_para));
3806         } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 ||
3807                    strcasecmp(info->id, "TL-WA1201-V2") == 0) {
3808                 const uint8_t extra_para[2] = {0x00, 0x01};
3809                 parts[5] = make_extra_para(info, extra_para,
3810                         sizeof(extra_para));
3811         } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 ||
3812                    strcasecmp(info->id, "EAP245-V3") == 0) {
3813                 const uint8_t extra_para[2] = {0x01, 0x01};
3814                 parts[5] = make_extra_para(info, extra_para,
3815                         sizeof(extra_para));
3816         }
3817 
3818         size_t len;
3819         void *image;
3820         if (sysupgrade)
3821                 image = generate_sysupgrade_image(info, parts, &len);
3822         else
3823                 image = generate_factory_image(info, parts, &len);
3824 
3825         FILE *file = fopen(output, "wb");
3826         if (!file)
3827                 error(1, errno, "unable to open output file");
3828 
3829         if (fwrite(image, len, 1, file) != 1)
3830                 error(1, 0, "unable to write output file");
3831 
3832         fclose(file);
3833 
3834         free(image);
3835 
3836         for (i = 0; parts[i].name; i++)
3837                 free_image_partition(&parts[i]);
3838 }
3839 
3840 /** Usage output */
3841 static void usage(const char *argv0) {
3842         fprintf(stderr,
3843                 "Usage: %s [OPTIONS...]\n"
3844                 "\n"
3845                 "Options:\n"
3846                 "  -h              show this help\n"
3847                 "\n"
3848                 "Info about an image:\n"
3849                 "  -i <file>       input file to read from\n"
3850                 "Create a new image:\n"
3851                 "  -B <board>      create image for the board specified with <board>\n"
3852                 "  -k <file>       read kernel image from the file <file>\n"
3853                 "  -r <file>       read rootfs image from the file <file>\n"
3854                 "  -o <file>       write output to the file <file>\n"
3855                 "  -V <rev>        sets the revision number to <rev>\n"
3856                 "  -j              add jffs2 end-of-filesystem markers\n"
3857                 "  -S              create sysupgrade instead of factory image\n"
3858                 "Extract an old image:\n"
3859                 "  -x <file>       extract all oem firmware partition\n"
3860                 "  -d <dir>        destination to extract the firmware partition\n"
3861                 "  -z <file>       convert an oem firmware into a sysupgade file. Use -o for output file\n",
3862                 argv0
3863         );
3864 };
3865 
3866 
3867 static struct device_info *find_board(const char *id)
3868 {
3869         struct device_info *board = NULL;
3870 
3871         for (board = boards; board->id != NULL; board++)
3872                 if (strcasecmp(id, board->id) == 0)
3873                         return board;
3874 
3875         return NULL;
3876 }
3877 
3878 static int add_flash_partition(
3879                 struct flash_partition_entry *part_list,
3880                 size_t max_entries,
3881                 const char *name,
3882                 unsigned long base,
3883                 unsigned long size)
3884 {
3885         size_t ptr;
3886         /* check if the list has a free entry */
3887         for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
3888                 if (part_list->name == NULL &&
3889                                 part_list->base == 0 &&
3890                                 part_list->size == 0)
3891                         break;
3892         }
3893 
3894         if (ptr == max_entries) {
3895                 error(1, 0, "No free flash part entry available.");
3896         }
3897 
3898         part_list->name = calloc(1, strlen(name) + 1);
3899         if (!part_list->name) {
3900                 error(1, 0, "Unable to allocate memory");
3901         }
3902 
3903         memcpy((char *)part_list->name, name, strlen(name));
3904         part_list->base = base;
3905         part_list->size = size;
3906 
3907         return 0;
3908 }
3909 
3910 /** read the partition table into struct flash_partition_entry */
3911 enum PARTITION_TABLE_TYPE {
3912         PARTITION_TABLE_FWUP,
3913         PARTITION_TABLE_FLASH,
3914 };
3915 
3916 static int read_partition_table(
3917                 FILE *file, long offset,
3918                 struct flash_partition_entry *entries, size_t max_entries,
3919                 int type)
3920 {
3921         char buf[SAFELOADER_PAYLOAD_TABLE_SIZE];
3922         char *ptr, *end;
3923         const char *parthdr = NULL;
3924         const char *fwuphdr = "fwup-ptn";
3925         const char *flashhdr = "partition";
3926 
3927         /* TODO: search for the partition table */
3928 
3929         switch(type) {
3930         case PARTITION_TABLE_FWUP:
3931                 parthdr = fwuphdr;
3932                 break;
3933         case PARTITION_TABLE_FLASH:
3934                 parthdr = flashhdr;
3935                 break;
3936         default:
3937                 error(1, 0, "Invalid partition table");
3938         }
3939 
3940         if (fseek(file, offset, SEEK_SET) < 0)
3941                 error(1, errno, "Can not seek in the firmware");
3942 
3943         if (fread(buf, sizeof(buf), 1, file) != 1)
3944                 error(1, errno, "Can not read fwup-ptn from the firmware");
3945 
3946         buf[sizeof(buf) - 1] = '\0';
3947 
3948         /* look for the partition header */
3949         if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
3950                 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
3951                 return 1;
3952         }
3953 
3954         ptr = buf;
3955         end = buf + sizeof(buf);
3956         while ((ptr + strlen(parthdr)) < end &&
3957                         memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
3958                 char *end_part;
3959                 char *end_element;
3960 
3961                 char name[32] = { 0 };
3962                 int name_len = 0;
3963                 unsigned long base = 0;
3964                 unsigned long size = 0;
3965 
3966                 end_part = memchr(ptr, '\n', (end - ptr));
3967                 if (end_part == NULL) {
3968                         /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
3969                         break;
3970                 }
3971 
3972                 for (int i = 0; i <= 4; i++) {
3973                         if (end_part <= ptr)
3974                                 break;
3975 
3976                         end_element = memchr(ptr, 0x20, (end_part - ptr));
3977                         if (end_element == NULL) {
3978                                 error(1, errno, "Ignoring the rest of the partition entries.");
3979                                 break;
3980                         }
3981 
3982                         switch (i) {
3983                                 /* partition header */
3984                                 case 0:
3985                                         ptr = end_element + 1;
3986                                         continue;
3987                                 /* name */
3988                                 case 1:
3989                                         name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
3990                                         strncpy(name, ptr, name_len);
3991                                         name[name_len] = '\0';
3992                                         ptr = end_element + 1;
3993                                         continue;
3994 
3995                                 /* string "base" */
3996                                 case 2:
3997                                         ptr = end_element + 1;
3998                                         continue;
3999 
4000                                 /* actual base */
4001                                 case 3:
4002                                         base = strtoul(ptr, NULL, 16);
4003                                         ptr = end_element + 1;
4004                                         continue;
4005 
4006                                 /* string "size" */
4007                                 case 4:
4008                                         ptr = end_element + 1;
4009                                         /* actual size. The last element doesn't have a sepeartor */
4010                                         size = strtoul(ptr, NULL, 16);
4011                                         /* the part ends with 0x09, 0x0d, 0x0a */
4012                                         ptr = end_part + 1;
4013                                         add_flash_partition(entries, max_entries, name, base, size);
4014                                         continue;
4015                         }
4016                 }
4017         }
4018 
4019         return 0;
4020 }
4021 
4022 static void safeloader_read_partition(FILE *input_file, size_t payload_offset,
4023                                       struct flash_partition_entry *entry,
4024                                       struct image_partition_entry *part)
4025 {
4026         size_t part_size = entry->size;
4027         void *part_data = malloc(part_size);
4028 
4029         if (fseek(input_file, payload_offset, SEEK_SET))
4030                 error(1, errno, "Failed to seek to partition data");
4031 
4032         if (!part_data)
4033                 error(1, ENOMEM, "Failed to allocate partition data");
4034 
4035         if (fread(part_data, 1, part_size, input_file) < part_size)
4036                 error(1, errno, "Failed to read partition data");
4037 
4038         part->data = part_data;
4039         part->size = part_size;
4040         part->name = entry->name;
4041 }
4042 
4043 static void safeloader_parse_image(FILE *input_file, struct safeloader_image_info *image)
4044 {
4045         static const char *HEADER_ID_CLOUD = "fw-type:Cloud";
4046         static const char *HEADER_ID_QNEW = "?NEW";
4047 
4048         char buf[64];
4049 
4050         if (!input_file)
4051                 return;
4052 
4053         fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET);
4054 
4055         if (fread(buf, sizeof(buf), 1, input_file) != 1)
4056                 error(1, errno, "Can not read image header");
4057 
4058         if (memcmp(HEADER_ID_QNEW, &buf[0], strlen(HEADER_ID_QNEW)) == 0)
4059                 image->type = SAFELOADER_TYPE_QNEW;
4060         else if (memcmp(HEADER_ID_CLOUD, &buf[0], strlen(HEADER_ID_CLOUD)) == 0)
4061                 image->type = SAFELOADER_TYPE_CLOUD;
4062         else if (ntohl(*((uint32_t *) &buf[0])) <= SAFELOADER_HEADER_SIZE)
4063                 image->type = SAFELOADER_TYPE_VENDOR;
4064         else
4065                 image->type = SAFELOADER_TYPE_DEFAULT;
4066 
4067         switch (image->type) {
4068         case SAFELOADER_TYPE_DEFAULT:
4069         case SAFELOADER_TYPE_VENDOR:
4070         case SAFELOADER_TYPE_CLOUD:
4071                 image->payload_offset = SAFELOADER_PAYLOAD_OFFSET;
4072                 break;
4073         case SAFELOADER_TYPE_QNEW:
4074                 image->payload_offset = SAFELOADER_QNEW_PAYLOAD_OFFSET;
4075                 break;
4076         }
4077 
4078         /* Parse image partition table */
4079         read_partition_table(input_file, image->payload_offset, &image->entries[0],
4080                              MAX_PARTITIONS, PARTITION_TABLE_FWUP);
4081 }
4082 
4083 static void write_partition(
4084                 FILE *input_file,
4085                 size_t firmware_offset,
4086                 struct flash_partition_entry *entry,
4087                 FILE *output_file)
4088 {
4089         char buf[4096];
4090         size_t offset;
4091 
4092         fseek(input_file, entry->base + firmware_offset, SEEK_SET);
4093 
4094         for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
4095                 if (fread(buf, sizeof(buf), 1, input_file) != 1)
4096                         error(1, errno, "Can not read partition from input_file");
4097 
4098                 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
4099                         error(1, errno, "Can not write partition to output_file");
4100         }
4101         /* write last chunk smaller than buffer */
4102         if (offset < entry->size) {
4103                 offset = entry->size - offset;
4104                 if (fread(buf, offset, 1, input_file) != 1)
4105                         error(1, errno, "Can not read partition from input_file");
4106                 if (fwrite(buf, offset, 1, output_file) != 1)
4107                         error(1, errno, "Can not write partition to output_file");
4108         }
4109 }
4110 
4111 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
4112 {
4113         FILE *output_file;
4114         char output[PATH_MAX];
4115 
4116         snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
4117         output_file = fopen(output, "wb+");
4118         if (output_file == NULL) {
4119                 error(1, errno, "Can not open output file %s", output);
4120         }
4121 
4122         write_partition(input_file, firmware_offset, entry, output_file);
4123 
4124         fclose(output_file);
4125 
4126         return 0;
4127 }
4128 
4129 /** extract all partitions from the firmware file */
4130 static int extract_firmware(const char *input, const char *output_directory)
4131 {
4132         struct safeloader_image_info info = {};
4133         struct stat statbuf;
4134         FILE *input_file;
4135 
4136         /* check input file */
4137         if (stat(input, &statbuf)) {
4138                 error(1, errno, "Can not read input firmware %s", input);
4139         }
4140 
4141         /* check if output directory exists */
4142         if (stat(output_directory, &statbuf)) {
4143                 error(1, errno, "Failed to stat output directory %s", output_directory);
4144         }
4145 
4146         if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
4147                 error(1, errno, "Given output directory is not a directory %s", output_directory);
4148         }
4149 
4150         input_file = fopen(input, "rb");
4151         safeloader_parse_image(input_file, &info);
4152 
4153         for (size_t i = 0; i < MAX_PARTITIONS && info.entries[i].name; i++)
4154                 extract_firmware_partition(input_file, info.payload_offset, &info.entries[i], output_directory);
4155 
4156         return 0;
4157 }
4158 
4159 static struct flash_partition_entry *find_partition(
4160                 struct flash_partition_entry *entries, size_t max_entries,
4161                 const char *name, const char *error_msg)
4162 {
4163         for (size_t i = 0; i < max_entries; i++, entries++) {
4164                 if (strcmp(entries->name, name) == 0)
4165                         return entries;
4166         }
4167 
4168         if (error_msg) {
4169                 error(1, 0, "%s", error_msg);
4170         }
4171 
4172         return NULL;
4173 }
4174 
4175 static int firmware_info(const char *input)
4176 {
4177         struct safeloader_image_info info = {};
4178         struct image_partition_entry part = {};
4179         struct flash_partition_entry *e;
4180         FILE *input_file;
4181 
4182         input_file = fopen(input, "rb");
4183 
4184         safeloader_parse_image(input_file, &info);
4185 
4186         if (info.type == SAFELOADER_TYPE_VENDOR) {
4187                 char buf[SAFELOADER_HEADER_SIZE] = {};
4188                 uint32_t vendor_size;
4189 
4190                 fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET);
4191                 fread(&vendor_size, sizeof(uint32_t), 1, input_file);
4192 
4193                 vendor_size = ntohl(vendor_size);
4194                 fread(buf, vendor_size, 1, input_file);
4195 
4196                 printf("Firmware vendor string:\n");
4197                 fwrite(buf, strnlen(buf, vendor_size), 1, stdout);
4198                 printf("\n");
4199         }
4200 
4201         printf("Firmware image partitions:\n");
4202         printf("%-8s %-8s %s\n", "base", "size", "name");
4203 
4204         e = &info.entries[0];
4205         for (unsigned int i = 0; i < MAX_PARTITIONS && e->name; i++, e++)
4206                 printf("%08x %08x %s\n", e->base, e->size, e->name);
4207 
4208         e = find_partition(&info.entries[0], MAX_PARTITIONS, "soft-version", NULL);
4209         if (e) {
4210                 struct soft_version *s;
4211                 unsigned int ascii_len;
4212                 const uint8_t *buf;
4213                 size_t data_len;
4214                 bool isstr;
4215 
4216                 safeloader_read_partition(input_file, info.payload_offset + e->base, e, &part);
4217                 data_len = ntohl(((struct meta_header *) part.data)->length);
4218                 buf = part.data + sizeof(struct meta_header);
4219 
4220                 /* Check for (null-terminated) string */
4221                 ascii_len = 0;
4222                 while (ascii_len < data_len && isascii(buf[ascii_len]))
4223                         ascii_len++;
4224 
4225                 isstr = ascii_len == data_len;
4226 
4227                 printf("\n[Software version]\n");
4228                 if (isstr) {
4229                         fwrite(buf, strnlen((const char *) buf, data_len), 1, stdout);
4230                         putchar('\n');
4231                 } else if (data_len >= offsetof(struct soft_version, rev)) {
4232                         s = (struct soft_version *) buf;
4233 
4234                         printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch);
4235                         printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day);
4236                         printf("Revision: %d\n", ntohl(s->rev));
4237                 } else {
4238                         printf("Failed to parse data\n");
4239                 }
4240 
4241                 free_image_partition(&part);
4242         }
4243 
4244         e = find_partition(&info.entries[0], MAX_PARTITIONS, "support-list", NULL);
4245         if (e) {
4246                 size_t data_len;
4247 
4248                 safeloader_read_partition(input_file, info.payload_offset + e->base, e, &part);
4249                 data_len = ntohl(((struct meta_header *) part.data)->length);
4250 
4251                 printf("\n[Support list]\n");
4252                 fwrite(part.data + sizeof(struct meta_header), data_len, 1, stdout);
4253                 printf("\n");
4254 
4255                 free_image_partition(&part);
4256         }
4257 
4258         e = find_partition(&info.entries[0], MAX_PARTITIONS, "partition-table", NULL);
4259         if (e) {
4260                 size_t flash_table_offset = info.payload_offset + e->base + 4;
4261                 struct flash_partition_entry parts[MAX_PARTITIONS] = {};
4262 
4263                 if (read_partition_table(input_file, flash_table_offset, parts, MAX_PARTITIONS, PARTITION_TABLE_FLASH))
4264                         error(1, 0, "Error can not read the partition table (partition)");
4265 
4266                 printf("\n[Partition table]\n");
4267                 printf("%-8s %-8s %s\n", "base", "size", "name");
4268 
4269                 e = &parts[0];
4270                 for (unsigned int i = 0; i < MAX_PARTITIONS && e->name; i++, e++)
4271                         printf("%08x %08x %s\n", e->base, e->size, e->name);
4272         }
4273 
4274         fclose(input_file);
4275 
4276         return 0;
4277 }
4278 
4279 static void write_ff(FILE *output_file, size_t size)
4280 {
4281         char buf[4096];
4282         size_t offset;
4283 
4284         memset(buf, 0xff, sizeof(buf));
4285 
4286         for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
4287                 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
4288                         error(1, errno, "Can not write 0xff to output_file");
4289         }
4290 
4291         /* write last chunk smaller than buffer */
4292         if (offset < size) {
4293                 offset = size - offset;
4294                 if (fwrite(buf, offset, 1, output_file) != 1)
4295                         error(1, errno, "Can not write partition to output_file");
4296         }
4297 }
4298 
4299 static void convert_firmware(const char *input, const char *output)
4300 {
4301         struct flash_partition_entry flash[MAX_PARTITIONS] = {};
4302         struct flash_partition_entry *fwup_partition_table;
4303         struct flash_partition_entry *flash_file_system;
4304         struct flash_partition_entry *fwup_file_system;
4305         struct flash_partition_entry *flash_os_image;
4306         struct flash_partition_entry *fwup_os_image;
4307         struct safeloader_image_info info = {};
4308         size_t flash_table_offset;
4309         struct stat statbuf;
4310         FILE *output_file;
4311         FILE *input_file;
4312 
4313         /* check input file */
4314         if (stat(input, &statbuf)) {
4315                 error(1, errno, "Can not read input firmware %s", input);
4316         }
4317 
4318         input_file = fopen(input, "rb");
4319         if (!input_file)
4320                 error(1, 0, "Can not open input firmware %s", input);
4321 
4322         output_file = fopen(output, "wb");
4323         if (!output_file)
4324                 error(1, 0, "Can not open output firmware %s", output);
4325 
4326         input_file = fopen(input, "rb");
4327         safeloader_parse_image(input_file, &info);
4328 
4329         fwup_os_image = find_partition(info.entries, MAX_PARTITIONS,
4330                         "os-image", "Error can not find os-image partition (fwup)");
4331         fwup_file_system = find_partition(info.entries, MAX_PARTITIONS,
4332                         "file-system", "Error can not find file-system partition (fwup)");
4333         fwup_partition_table = find_partition(info.entries, MAX_PARTITIONS,
4334                         "partition-table", "Error can not find partition-table partition");
4335 
4336         /* the flash partition table has a 0x00000004 magic haeder */
4337         flash_table_offset = info.payload_offset + fwup_partition_table->base + 4;
4338         if (read_partition_table(input_file, flash_table_offset, flash, MAX_PARTITIONS, PARTITION_TABLE_FLASH) != 0)
4339                 error(1, 0, "Error can not read the partition table (flash)");
4340 
4341         flash_os_image = find_partition(flash, MAX_PARTITIONS,
4342                         "os-image", "Error can not find os-image partition (flash)");
4343         flash_file_system = find_partition(flash, MAX_PARTITIONS,
4344                         "file-system", "Error can not find file-system partition (flash)");
4345 
4346         /* write os_image to 0x0 */
4347         write_partition(input_file, info.payload_offset, fwup_os_image, output_file);
4348         write_ff(output_file, flash_os_image->size - fwup_os_image->size);
4349 
4350         /* write file-system behind os_image */
4351         fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
4352         write_partition(input_file, info.payload_offset, fwup_file_system, output_file);
4353 
4354         fclose(output_file);
4355         fclose(input_file);
4356 }
4357 
4358 int main(int argc, char *argv[]) {
4359         const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
4360         const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
4361         bool add_jffs2_eof = false, sysupgrade = false;
4362         unsigned rev = 0;
4363         struct device_info *info;
4364         set_source_date_epoch();
4365 
4366         while (true) {
4367                 int c;
4368 
4369                 c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:");
4370                 if (c == -1)
4371                         break;
4372 
4373                 switch (c) {
4374                 case 'i':
4375                         info_image = optarg;
4376                         break;
4377 
4378                 case 'B':
4379                         board = optarg;
4380                         break;
4381 
4382                 case 'k':
4383                         kernel_image = optarg;
4384                         break;
4385 
4386                 case 'r':
4387                         rootfs_image = optarg;
4388                         break;
4389 
4390                 case 'o':
4391                         output = optarg;
4392                         break;
4393 
4394                 case 'V':
4395                         sscanf(optarg, "r%u", &rev);
4396                         break;
4397 
4398                 case 'j':
4399                         add_jffs2_eof = true;
4400                         break;
4401 
4402                 case 'S':
4403                         sysupgrade = true;
4404                         break;
4405 
4406                 case 'h':
4407                         usage(argv[0]);
4408                         return 0;
4409 
4410                 case 'd':
4411                         output_directory = optarg;
4412                         break;
4413 
4414                 case 'x':
4415                         extract_image = optarg;
4416                         break;
4417 
4418                 case 'z':
4419                         convert_image = optarg;
4420                         break;
4421 
4422                 default:
4423                         usage(argv[0]);
4424                         return 1;
4425                 }
4426         }
4427 
4428         if (info_image) {
4429                 firmware_info(info_image);
4430         } else if (extract_image || output_directory) {
4431                 if (!extract_image)
4432                         error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
4433                 if (!output_directory)
4434                         error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
4435                 extract_firmware(extract_image, output_directory);
4436         } else if (convert_image) {
4437                 if (!output)
4438                         error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
4439                 convert_firmware(convert_image, output);
4440         } else {
4441                 if (!board)
4442                         error(1, 0, "no board has been specified");
4443                 if (!kernel_image)
4444                         error(1, 0, "no kernel image has been specified");
4445                 if (!rootfs_image)
4446                         error(1, 0, "no rootfs image has been specified");
4447                 if (!output)
4448                         error(1, 0, "no output filename has been specified");
4449 
4450                 info = find_board(board);
4451 
4452                 if (info == NULL)
4453                         error(1, 0, "unsupported board %s", board);
4454 
4455                 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
4456         }
4457 
4458         return 0;
4459 }
4460 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt