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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt