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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt