• 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 EAP120 */
1581         {
1582                 .id     = "EAP120",
1583                 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1584                 .support_list =
1585                         "SupportList:\r\n"
1586                         "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1587                 .part_trail = 0xff,
1588                 .soft_ver = SOFT_VER_DEFAULT,
1589 
1590                 .partitions = {
1591                         {"fs-uboot", 0x00000, 0x20000},
1592                         {"partition-table", 0x20000, 0x02000},
1593                         {"default-mac", 0x30000, 0x00020},
1594                         {"support-list", 0x31000, 0x00100},
1595                         {"product-info", 0x31100, 0x00100},
1596                         {"soft-version", 0x32000, 0x00100},
1597                         {"os-image", 0x40000, 0x180000},
1598                         {"file-system", 0x1c0000, 0x600000},
1599                         {"user-config", 0x7c0000, 0x10000},
1600                         {"backup-config", 0x7d0000, 0x10000},
1601                         {"log", 0x7e0000, 0x10000},
1602                         {"radio", 0x7f0000, 0x10000},
1603                         {NULL, 0, 0}
1604                 },
1605 
1606                 .first_sysupgrade_partition = "os-image",
1607                 .last_sysupgrade_partition = "file-system"
1608         },
1609 
1610         /** Firmware layout for the EAP225-Outdoor v1 */
1611         {
1612                 .id     = "EAP225-OUTDOOR-V1",
1613                 .support_list =
1614                         "SupportList:\r\n"
1615                         "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1616                 .part_trail = PART_TRAIL_NONE,
1617                 .soft_ver = SOFT_VER_DEFAULT,
1618                 .soft_ver_compat_level = 1,
1619 
1620                 .partitions = {
1621                         {"fs-uboot", 0x00000, 0x20000},
1622                         {"partition-table", 0x20000, 0x02000},
1623                         {"default-mac", 0x30000, 0x01000},
1624                         {"support-list", 0x31000, 0x00100},
1625                         {"product-info", 0x31100, 0x00400},
1626                         {"soft-version", 0x32000, 0x00100},
1627                         {"firmware", 0x40000, 0xd80000},
1628                         {"user-config", 0xdc0000, 0x30000},
1629                         {"mutil-log", 0xf30000, 0x80000},
1630                         {"oops", 0xfb0000, 0x40000},
1631                         {"radio", 0xff0000, 0x10000},
1632                         {NULL, 0, 0}
1633                 },
1634 
1635                 .first_sysupgrade_partition = "os-image",
1636                 .last_sysupgrade_partition = "file-system"
1637         },
1638 
1639         /** Firmware layout for the EAP225 v1 */
1640         {
1641                 .id     = "EAP225-V1",
1642                 .support_list =
1643                         "SupportList:\r\n"
1644                         "EAP225(TP-LINK|UN|AC1200-D):1.0\r\n",
1645                 .part_trail = PART_TRAIL_NONE,
1646                 .soft_ver = SOFT_VER_DEFAULT,
1647 
1648                 .partitions = {
1649                         {"fs-uboot", 0x00000, 0x20000},
1650                         {"partition-table", 0x20000, 0x02000},
1651                         {"default-mac", 0x30000, 0x01000},
1652                         {"support-list", 0x31000, 0x00100},
1653                         {"product-info", 0x31100, 0x00400},
1654                         {"soft-version", 0x32000, 0x00100},
1655                         {"firmware", 0x40000, 0xd80000},
1656                         {"user-config", 0xdc0000, 0x30000},
1657                         {"radio", 0xff0000, 0x10000},
1658                         {NULL, 0, 0}
1659                 },
1660 
1661                 .first_sysupgrade_partition = "os-image",
1662                 .last_sysupgrade_partition = "file-system"
1663         },
1664 
1665         /** Firmware layout for the EAP225 v3
1666          * Also compatible with:
1667          *   - EAP225 v3.20
1668          *   - EAP225 v4
1669          *   - EAP225-Outdoor v1
1670          *   - EAP225-Outdoor v3
1671          *   */
1672         {
1673                 .id     = "EAP225-V3",
1674                 .support_list =
1675                         "SupportList:\r\n"
1676                         "EAP225(TP-Link|UN|AC1350-D):3.0\r\n"
1677                         "EAP225(TP-Link|UN|AC1350-D):3.20\r\n"
1678                         "EAP225(TP-Link|UN|AC1350-D):4.0 CA\r\n"
1679                         "EAP225-Outdoor(TP-Link|UN|AC1350-D):1.0\r\n"
1680                         "EAP225-Outdoor(TP-Link|UN|AC1350-D):3.0 CA,JP\r\n",
1681                 .part_trail = PART_TRAIL_NONE,
1682                 .soft_ver = SOFT_VER_DEFAULT,
1683                 .soft_ver_compat_level = 1,
1684 
1685                 .partitions = {
1686                         {"fs-uboot", 0x00000, 0x20000},
1687                         {"partition-table", 0x20000, 0x02000},
1688                         {"default-mac", 0x30000, 0x01000},
1689                         {"support-list", 0x31000, 0x00100},
1690                         {"product-info", 0x31100, 0x00400},
1691                         {"soft-version", 0x32000, 0x00100},
1692                         {"firmware", 0x40000, 0xd80000},
1693                         {"user-config", 0xdc0000, 0x30000},
1694                         {"mutil-log", 0xf30000, 0x80000},
1695                         {"oops", 0xfb0000, 0x40000},
1696                         {"radio", 0xff0000, 0x10000},
1697                         {NULL, 0, 0}
1698                 },
1699 
1700                 .first_sysupgrade_partition = "os-image",
1701                 .last_sysupgrade_partition = "file-system"
1702         },
1703 
1704         /** Firmware layout for the EAP225-Wall v2 */
1705         {
1706                 .id     = "EAP225-WALL-V2",
1707                 .support_list =
1708                         "SupportList:\r\n"
1709                         "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
1710                 .part_trail = PART_TRAIL_NONE,
1711                 .soft_ver = SOFT_VER_DEFAULT,
1712                 .soft_ver_compat_level = 1,
1713 
1714                 .partitions = {
1715                         {"fs-uboot", 0x00000, 0x20000},
1716                         {"partition-table", 0x20000, 0x02000},
1717                         {"default-mac", 0x30000, 0x01000},
1718                         {"support-list", 0x31000, 0x00100},
1719                         {"product-info", 0x31100, 0x00400},
1720                         {"soft-version", 0x32000, 0x00100},
1721                         {"firmware", 0x40000, 0xd80000},
1722                         {"user-config", 0xdc0000, 0x30000},
1723                         {"mutil-log", 0xf30000, 0x80000},
1724                         {"oops", 0xfb0000, 0x40000},
1725                         {"radio", 0xff0000, 0x10000},
1726                         {NULL, 0, 0}
1727                 },
1728 
1729                 .first_sysupgrade_partition = "os-image",
1730                 .last_sysupgrade_partition = "file-system"
1731         },
1732 
1733         /** Firmware layout for the EAP235-Wall v1 */
1734         {
1735                 .id     = "EAP235-WALL-V1",
1736                 .support_list =
1737                         "SupportList:\r\n"
1738                         "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
1739                 .part_trail = PART_TRAIL_NONE,
1740                 .soft_ver = SOFT_VER_NUMERIC(3, 0, 0),
1741                 .soft_ver_compat_level = 1,
1742 
1743                 .partitions = {
1744                         {"fs-uboot", 0x00000, 0x80000},
1745                         {"partition-table", 0x80000, 0x02000},
1746                         {"default-mac", 0x90000, 0x01000},
1747                         {"support-list", 0x91000, 0x00100},
1748                         {"product-info", 0x91100, 0x00400},
1749                         {"soft-version", 0x92000, 0x00100},
1750                         {"firmware", 0xa0000, 0xd20000},
1751                         {"user-config", 0xdc0000, 0x30000},
1752                         {"mutil-log", 0xf30000, 0x80000},
1753                         {"oops", 0xfb0000, 0x40000},
1754                         {"radio", 0xff0000, 0x10000},
1755                         {NULL, 0, 0}
1756                 },
1757 
1758                 .first_sysupgrade_partition = "os-image",
1759                 .last_sysupgrade_partition = "file-system"
1760         },
1761 
1762         /** Firmware layout for the EAP245 v1 */
1763         {
1764                 .id     = "EAP245-V1",
1765                 .support_list =
1766                         "SupportList:\r\n"
1767                         "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
1768                 .part_trail = PART_TRAIL_NONE,
1769                 .soft_ver = SOFT_VER_DEFAULT,
1770 
1771                 .partitions = {
1772                         {"fs-uboot", 0x00000, 0x20000},
1773                         {"partition-table", 0x20000, 0x02000},
1774                         {"default-mac", 0x30000, 0x01000},
1775                         {"support-list", 0x31000, 0x00100},
1776                         {"product-info", 0x31100, 0x00400},
1777                         {"soft-version", 0x32000, 0x00100},
1778                         {"firmware", 0x40000, 0xd80000},
1779                         {"user-config", 0xdc0000, 0x30000},
1780                         {"radio", 0xff0000, 0x10000},
1781                         {NULL, 0, 0}
1782                 },
1783 
1784                 .first_sysupgrade_partition = "os-image",
1785                 .last_sysupgrade_partition = "file-system"
1786         },
1787 
1788         /** Firmware layout for the EAP245 v3 */
1789         {
1790                 .id     = "EAP245-V3",
1791                 .support_list =
1792                         "SupportList:\r\n"
1793                         "EAP245(TP-Link|UN|AC1750-D):3.0\r\n"
1794                         "EAP265 HD(TP-Link|UN|AC1750-D):1.0",
1795                 .part_trail = PART_TRAIL_NONE,
1796                 .soft_ver = SOFT_VER_DEFAULT,
1797                 .soft_ver_compat_level = 1,
1798 
1799                 /** Firmware partition with dynamic kernel/rootfs split */
1800                 .partitions = {
1801                         {"factroy-boot", 0x00000, 0x40000},
1802                         {"fs-uboot", 0x40000, 0x40000},
1803                         {"partition-table", 0x80000, 0x10000},
1804                         {"default-mac", 0x90000, 0x01000},
1805                         {"support-list", 0x91000, 0x00100},
1806                         {"product-info", 0x91100, 0x00400},
1807                         {"soft-version", 0x92000, 0x00100},
1808                         {"radio", 0xa0000, 0x10000},
1809                         {"extra-para", 0xb0000, 0x10000},
1810                         {"firmware", 0xc0000, 0xe40000},
1811                         {"config", 0xf00000, 0x30000},
1812                         {"mutil-log", 0xf30000, 0x80000},
1813                         {"oops", 0xfb0000, 0x40000},
1814                         {NULL, 0, 0}
1815                 },
1816 
1817                 .first_sysupgrade_partition = "os-image",
1818                 .last_sysupgrade_partition = "file-system"
1819         },
1820 
1821         /** Firmware layout for the EAP615-Wall v1 */
1822         {
1823                 .id = "EAP615-WALL-V1",
1824                 .soft_ver = SOFT_VER_DEFAULT,
1825                 .soft_ver_compat_level = 1,
1826                 .support_list =
1827                         "SupportList:\r\n"
1828                         "EAP615-Wall(TP-Link|UN|AX1800-D):1.0\r\n"
1829                         "EAP615-Wall(TP-Link|CA|AX1800-D):1.0\r\n"
1830                         "EAP615-Wall(TP-Link|JP|AX1800-D):1.0\r\n",
1831                 .part_trail = PART_TRAIL_NONE,
1832 
1833                 .partitions = {
1834                         {"fs-uboot", 0x00000, 0x80000},
1835                         {"partition-table", 0x80000, 0x02000},
1836                         {"default-mac", 0x90000, 0x01000},
1837                         {"support-list", 0x91000, 0x00100},
1838                         {"product-info", 0x91100, 0x00400},
1839                         {"soft-version", 0x92000, 0x00100},
1840                         {"firmware", 0xa0000, 0xcf0000},
1841                         {"user-config", 0xd90000, 0x60000},
1842                         {"mutil-log", 0xf30000, 0x80000},
1843                         {"oops", 0xfb0000, 0x40000},
1844                         {"radio", 0xff0000, 0x10000},
1845                         {NULL, 0, 0}
1846                 },
1847 
1848                 .first_sysupgrade_partition = "os-image",
1849                 .last_sysupgrade_partition = "file-system"
1850         },
1851 
1852         /** Firmware layout for the TL-WA1201 v2 */
1853         {
1854                 .id     = "TL-WA1201-V2",
1855                 .vendor = "",
1856                 .support_list =
1857                         "SupportList:\n"
1858                         "{product_name:TL-WA1201,product_ver:2.0.0,special_id:45550000}\n"
1859                         "{product_name:TL-WA1201,product_ver:2.0.0,special_id:55530000}\n",
1860                 .part_trail = 0x00,
1861                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.1 Build 20200709 rel.66244\n"),
1862 
1863                 .partitions = {
1864                         {"fs-uboot", 0x00000, 0x20000},
1865                         {"default-mac", 0x20000, 0x00200},
1866                         {"pin", 0x20200, 0x00100},
1867                         {"product-info", 0x20300, 0x00200},
1868                         {"device-id", 0x20500, 0x0fb00},
1869                         {"firmware", 0x30000, 0xce0000},
1870                         {"portal-logo", 0xd10000, 0x20000},
1871                         {"portal-back", 0xd30000, 0x200000},
1872                         {"soft-version", 0xf30000, 0x00200},
1873                         {"extra-para", 0xf30200, 0x00200},
1874                         {"support-list", 0xf30400, 0x00200},
1875                         {"profile", 0xf30600, 0x0fa00},
1876                         {"apdef-config", 0xf40000, 0x10000},
1877                         {"ap-config", 0xf50000, 0x10000},
1878                         {"redef-config", 0xf60000, 0x10000},
1879                         {"re-config", 0xf70000, 0x10000},
1880                         {"multidef-config", 0xf80000, 0x10000},
1881                         {"multi-config", 0xf90000, 0x10000},
1882                         {"clientdef-config", 0xfa0000, 0x10000},
1883                         {"client-config", 0xfb0000, 0x10000},
1884                         {"partition-table", 0xfc0000, 0x10000},
1885                         {"user-config", 0xfd0000, 0x10000},
1886                         {"certificate", 0xfe0000, 0x10000},
1887                         {"radio", 0xff0000, 0x10000},
1888                         {NULL, 0, 0}
1889                 },
1890                 .first_sysupgrade_partition = "os-image",
1891                 .last_sysupgrade_partition = "file-system",
1892         },
1893 
1894         /** Firmware layout for the TL-WA850RE v2 */
1895         {
1896                 .id     = "TLWA850REV2",
1897                 .vendor = "",
1898                 .support_list =
1899                         "SupportList:\n"
1900                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
1901                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
1902                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
1903                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
1904                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
1905                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
1906                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
1907                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
1908                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
1909                         "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
1910                 .part_trail = 0x00,
1911                 .soft_ver = SOFT_VER_DEFAULT,
1912 
1913                 /**
1914                    576KB were moved from file-system to os-image
1915                    in comparison to the stock image
1916                 */
1917                 .partitions = {
1918                         {"fs-uboot", 0x00000, 0x20000},
1919                         {"firmware", 0x20000, 0x390000},
1920                         {"partition-table", 0x3b0000, 0x02000},
1921                         {"default-mac", 0x3c0000, 0x00020},
1922                         {"pin", 0x3c0100, 0x00020},
1923                         {"product-info", 0x3c1000, 0x01000},
1924                         {"soft-version", 0x3c2000, 0x00100},
1925                         {"support-list", 0x3c3000, 0x01000},
1926                         {"profile", 0x3c4000, 0x08000},
1927                         {"user-config", 0x3d0000, 0x10000},
1928                         {"default-config", 0x3e0000, 0x10000},
1929                         {"radio", 0x3f0000, 0x10000},
1930                         {NULL, 0, 0}
1931                 },
1932 
1933                 .first_sysupgrade_partition = "os-image",
1934                 .last_sysupgrade_partition = "file-system"
1935         },
1936 
1937         /** Firmware layout for the TL-WA855RE v1 */
1938         {
1939                 .id     = "TLWA855REV1",
1940                 .vendor = "",
1941                 .support_list =
1942                         "SupportList:\n"
1943                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
1944                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
1945                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
1946                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
1947                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
1948                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
1949                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
1950                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
1951                         "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
1952                 .part_trail = 0x00,
1953                 .soft_ver = SOFT_VER_DEFAULT,
1954 
1955                 .partitions = {
1956                         {"fs-uboot", 0x00000, 0x20000},
1957                         {"os-image", 0x20000, 0x150000},
1958                         {"file-system", 0x170000, 0x240000},
1959                         {"partition-table", 0x3b0000, 0x02000},
1960                         {"default-mac", 0x3c0000, 0x00020},
1961                         {"pin", 0x3c0100, 0x00020},
1962                         {"product-info", 0x3c1000, 0x01000},
1963                         {"soft-version", 0x3c2000, 0x00100},
1964                         {"support-list", 0x3c3000, 0x01000},
1965                         {"profile", 0x3c4000, 0x08000},
1966                         {"user-config", 0x3d0000, 0x10000},
1967                         {"default-config", 0x3e0000, 0x10000},
1968                         {"radio", 0x3f0000, 0x10000},
1969                         {NULL, 0, 0}
1970                 },
1971 
1972                 .first_sysupgrade_partition = "os-image",
1973                 .last_sysupgrade_partition = "file-system"
1974         },
1975 
1976         /** Firmware layout for the TL-WPA8630P v2 (EU)*/
1977         {
1978                 .id     = "TL-WPA8630P-V2.0-EU",
1979                 .vendor = "",
1980                 .support_list =
1981                         "SupportList:\n"
1982                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
1983                 .part_trail = 0x00,
1984                 .soft_ver = SOFT_VER_DEFAULT,
1985 
1986                 .partitions = {
1987                         {"factory-uboot", 0x00000, 0x20000},
1988                         {"fs-uboot", 0x20000, 0x20000},
1989                         {"firmware", 0x40000, 0x5e0000},
1990                         {"partition-table", 0x620000, 0x02000},
1991                         {"default-mac", 0x630000, 0x00020},
1992                         {"pin", 0x630100, 0x00020},
1993                         {"device-id", 0x630200, 0x00030},
1994                         {"product-info", 0x631100, 0x01000},
1995                         {"extra-para", 0x632100, 0x01000},
1996                         {"soft-version", 0x640000, 0x01000},
1997                         {"support-list", 0x641000, 0x01000},
1998                         {"profile", 0x642000, 0x08000},
1999                         {"user-config", 0x650000, 0x10000},
2000                         {"default-config", 0x660000, 0x10000},
2001                         {"default-nvm", 0x670000, 0xc0000},
2002                         {"default-pib", 0x730000, 0x40000},
2003                         {"radio", 0x7f0000, 0x10000},
2004                         {NULL, 0, 0}
2005                 },
2006 
2007                 .first_sysupgrade_partition = "os-image",
2008                 .last_sysupgrade_partition = "file-system"
2009         },
2010 
2011         /** Firmware layout for the TL-WPA8630P v2 (INT)*/
2012         {
2013                 .id     = "TL-WPA8630P-V2-INT",
2014                 .vendor = "",
2015                 .support_list =
2016                         "SupportList:\n"
2017                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
2018                         "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
2019                         "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
2020                 .part_trail = 0x00,
2021                 .soft_ver = SOFT_VER_DEFAULT,
2022 
2023                 .partitions = {
2024                         {"factory-uboot", 0x00000, 0x20000},
2025                         {"fs-uboot", 0x20000, 0x20000},
2026                         {"firmware", 0x40000, 0x5e0000},
2027                         {"partition-table", 0x620000, 0x02000},
2028                         {"extra-para", 0x632100, 0x01000},
2029                         {"soft-version", 0x640000, 0x01000},
2030                         {"support-list", 0x641000, 0x01000},
2031                         {"profile", 0x642000, 0x08000},
2032                         {"user-config", 0x650000, 0x10000},
2033                         {"default-config", 0x660000, 0x10000},
2034                         {"default-nvm", 0x670000, 0xc0000},
2035                         {"default-pib", 0x730000, 0x40000},
2036                         {"default-mac", 0x7e0000, 0x00020},
2037                         {"pin", 0x7e0100, 0x00020},
2038                         {"device-id", 0x7e0200, 0x00030},
2039                         {"product-info", 0x7e1100, 0x01000},
2040                         {"radio", 0x7f0000, 0x10000},
2041                         {NULL, 0, 0}
2042                 },
2043 
2044                 .first_sysupgrade_partition = "os-image",
2045                 .last_sysupgrade_partition = "file-system"
2046         },
2047 
2048         /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
2049         {
2050                 .id     = "TL-WPA8630P-V2.1-EU",
2051                 .vendor = "",
2052                 .support_list =
2053                         "SupportList:\n"
2054                         "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
2055                 .part_trail = 0x00,
2056                 .soft_ver = SOFT_VER_DEFAULT,
2057 
2058                 .partitions = {
2059                         {"factory-uboot", 0x00000, 0x20000},
2060                         {"fs-uboot", 0x20000, 0x20000},
2061                         {"firmware", 0x40000, 0x5e0000},
2062                         {"extra-para", 0x680000, 0x01000},
2063                         {"product-info", 0x690000, 0x01000},
2064                         {"partition-table", 0x6a0000, 0x02000},
2065                         {"soft-version", 0x6b0000, 0x01000},
2066                         {"support-list", 0x6b1000, 0x01000},
2067                         {"profile", 0x6b2000, 0x08000},
2068                         {"user-config", 0x6c0000, 0x10000},
2069                         {"default-config", 0x6d0000, 0x10000},
2070                         {"default-nvm", 0x6e0000, 0xc0000},
2071                         {"default-pib", 0x7a0000, 0x40000},
2072                         {"default-mac", 0x7e0000, 0x00020},
2073                         {"pin", 0x7e0100, 0x00020},
2074                         {"device-id", 0x7e0200, 0x00030},
2075                         {"radio", 0x7f0000, 0x10000},
2076                         {NULL, 0, 0}
2077                 },
2078 
2079                 .first_sysupgrade_partition = "os-image",
2080                 .last_sysupgrade_partition = "file-system"
2081         },
2082 
2083         /** Firmware layout for the TL-WPA8631P v3 */
2084         {
2085                 .id     = "TL-WPA8631P-V3",
2086                 .vendor = "",
2087                 .support_list =
2088                         "SupportList:\n"
2089                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:41550000}\n"
2090                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:45550000}\n"
2091                         "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:55530000}\n",
2092                 .part_trail = 0x00,
2093                 .soft_ver = SOFT_VER_DEFAULT,
2094 
2095                 .partitions = {
2096                         {"fs-uboot", 0x00000, 0x20000},
2097                         {"firmware", 0x20000, 0x710000},
2098                         {"partition-table", 0x730000, 0x02000},
2099                         {"default-mac", 0x732000, 0x00020},
2100                         {"pin", 0x732100, 0x00020},
2101                         {"device-id", 0x732200, 0x00030},
2102                         {"default-region", 0x732300, 0x00010},
2103                         {"product-info", 0x732400, 0x00200},
2104                         {"extra-para", 0x732600, 0x00200},
2105                         {"soft-version", 0x732800, 0x00200},
2106                         {"support-list", 0x732a00, 0x00100},
2107                         {"profile", 0x732b00, 0x00100},
2108                         {"default-config", 0x732c00, 0x00800},
2109                         {"plc-type", 0x733400, 0x00020},
2110                         {"default-pib", 0x733500, 0x06000},
2111                         {"user-config", 0x740000, 0x10000},
2112                         {"plc-pib", 0x750000, 0x10000},
2113                         {"plc-nvm", 0x760000, 0x90000},
2114                         {"radio", 0x7f0000, 0x10000},
2115                         {NULL, 0, 0}
2116                 },
2117 
2118                 .first_sysupgrade_partition = "os-image",
2119                 .last_sysupgrade_partition = "file-system"
2120         },
2121 
2122         /** Firmware layout for the TL-WR1043 v5 */
2123         {
2124                 .id     = "TLWR1043NV5",
2125                 .vendor = "",
2126                 .support_list =
2127                         "SupportList:\n"
2128                         "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
2129                         "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
2130                 .part_trail = 0x00,
2131                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
2132                 .partitions = {
2133                         {"factory-boot", 0x00000, 0x20000},
2134                         {"fs-uboot", 0x20000, 0x20000},
2135                         {"firmware", 0x40000, 0xec0000},
2136                         {"default-mac", 0xf00000, 0x00200},
2137                         {"pin", 0xf00200, 0x00200},
2138                         {"device-id", 0xf00400, 0x00100},
2139                         {"product-info", 0xf00500, 0x0fb00},
2140                         {"soft-version", 0xf10000, 0x01000},
2141                         {"extra-para", 0xf11000, 0x01000},
2142                         {"support-list", 0xf12000, 0x0a000},
2143                         {"profile", 0xf1c000, 0x04000},
2144                         {"default-config", 0xf20000, 0x10000},
2145                         {"user-config", 0xf30000, 0x40000},
2146                         {"qos-db", 0xf70000, 0x40000},
2147                         {"certificate", 0xfb0000, 0x10000},
2148                         {"partition-table", 0xfc0000, 0x10000},
2149                         {"log", 0xfd0000, 0x20000},
2150                         {"radio", 0xff0000, 0x10000},
2151                         {NULL, 0, 0}
2152                 },
2153                 .first_sysupgrade_partition = "os-image",
2154                 .last_sysupgrade_partition = "file-system"
2155         },
2156 
2157         /** Firmware layout for the TL-WR1043 v4 */
2158         {
2159                 .id     = "TLWR1043NDV4",
2160                 .vendor = "",
2161                 .support_list =
2162                         "SupportList:\n"
2163                         "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
2164                 .part_trail = 0x00,
2165                 .soft_ver = SOFT_VER_DEFAULT,
2166 
2167                 /* We're using a dynamic kernel/rootfs split here */
2168                 .partitions = {
2169                         {"fs-uboot", 0x00000, 0x20000},
2170                         {"firmware", 0x20000, 0xf30000},
2171                         {"default-mac", 0xf50000, 0x00200},
2172                         {"pin", 0xf50200, 0x00200},
2173                         {"product-info", 0xf50400, 0x0fc00},
2174                         {"soft-version", 0xf60000, 0x0b000},
2175                         {"support-list", 0xf6b000, 0x04000},
2176                         {"profile", 0xf70000, 0x04000},
2177                         {"default-config", 0xf74000, 0x0b000},
2178                         {"user-config", 0xf80000, 0x40000},
2179                         {"partition-table", 0xfc0000, 0x10000},
2180                         {"log", 0xfd0000, 0x20000},
2181                         {"radio", 0xff0000, 0x10000},
2182                         {NULL, 0, 0}
2183                 },
2184 
2185                 .first_sysupgrade_partition = "os-image",
2186                 .last_sysupgrade_partition = "file-system"
2187         },
2188 
2189         /** Firmware layout for the TL-WR902AC v1 */
2190         {
2191                 .id     = "TL-WR902AC-V1",
2192                 .vendor = "",
2193                 .support_list =
2194                         "SupportList:\n"
2195                         "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
2196                         "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
2197                 .part_trail = 0x00,
2198                 .soft_ver = SOFT_VER_DEFAULT,
2199 
2200                 /**
2201                    384KB were moved from file-system to os-image
2202                    in comparison to the stock image
2203                 */
2204                 .partitions = {
2205                         {"fs-uboot", 0x00000, 0x20000},
2206                         {"firmware", 0x20000, 0x730000},
2207                         {"default-mac", 0x750000, 0x00200},
2208                         {"pin", 0x750200, 0x00200},
2209                         {"product-info", 0x750400, 0x0fc00},
2210                         {"soft-version", 0x760000, 0x0b000},
2211                         {"support-list", 0x76b000, 0x04000},
2212                         {"profile", 0x770000, 0x04000},
2213                         {"default-config", 0x774000, 0x0b000},
2214                         {"user-config", 0x780000, 0x40000},
2215                         {"partition-table", 0x7c0000, 0x10000},
2216                         {"log", 0x7d0000, 0x20000},
2217                         {"radio", 0x7f0000, 0x10000},
2218                         {NULL, 0, 0}
2219                 },
2220 
2221                 .first_sysupgrade_partition = "os-image",
2222                 .last_sysupgrade_partition = "file-system",
2223         },
2224 
2225         /** Firmware layout for the TL-WR941HP v1 */
2226         {
2227                 .id     = "TL-WR941HP-V1",
2228                 .vendor = "",
2229                 .support_list =
2230                         "SupportList:\n"
2231                         "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n",
2232                 .part_trail = 0x00,
2233                 .soft_ver = SOFT_VER_DEFAULT,
2234 
2235                 .partitions = {
2236                         {"fs-uboot", 0x00000, 0x20000},
2237                         {"firmware", 0x20000, 0x730000},
2238                         {"default-mac", 0x750000, 0x00200},
2239                         {"pin", 0x750200, 0x00200},
2240                         {"product-info", 0x750400, 0x0fc00},
2241                         {"soft-version", 0x760000, 0x0b000},
2242                         {"support-list", 0x76b000, 0x04000},
2243                         {"profile", 0x770000, 0x04000},
2244                         {"default-config", 0x774000, 0x0b000},
2245                         {"user-config", 0x780000, 0x40000},
2246                         {"partition-table", 0x7c0000, 0x10000},
2247                         {"log", 0x7d0000, 0x20000},
2248                         {"radio", 0x7f0000, 0x10000},
2249                         {NULL, 0, 0}
2250                 },
2251 
2252                 .first_sysupgrade_partition = "os-image",
2253                 .last_sysupgrade_partition = "file-system",
2254         },
2255 
2256         /** Firmware layout for the TL-WR942N V1 */
2257         {
2258                 .id     = "TLWR942NV1",
2259                 .vendor = "",
2260                 .support_list =
2261                         "SupportList:\r\n"
2262                         "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
2263                         "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
2264                 .part_trail = 0x00,
2265                 .soft_ver = SOFT_VER_DEFAULT,
2266 
2267                 .partitions = {
2268                         {"fs-uboot", 0x00000, 0x20000},
2269                         {"firmware", 0x20000, 0xe20000},
2270                         {"default-mac", 0xe40000, 0x00200},
2271                         {"pin", 0xe40200, 0x00200},
2272                         {"product-info", 0xe40400, 0x0fc00},
2273                         {"partition-table", 0xe50000, 0x10000},
2274                         {"soft-version", 0xe60000, 0x10000},
2275                         {"support-list", 0xe70000, 0x10000},
2276                         {"profile", 0xe80000, 0x10000},
2277                         {"default-config", 0xe90000, 0x10000},
2278                         {"user-config", 0xea0000, 0x40000},
2279                         {"qos-db", 0xee0000, 0x40000},
2280                         {"certificate", 0xf20000, 0x10000},
2281                         {"usb-config", 0xfb0000, 0x10000},
2282                         {"log", 0xfc0000, 0x20000},
2283                         {"radio-bk", 0xfe0000, 0x10000},
2284                         {"radio", 0xff0000, 0x10000},
2285                         {NULL, 0, 0}
2286                 },
2287 
2288                 .first_sysupgrade_partition = "os-image",
2289                 .last_sysupgrade_partition = "file-system",
2290         },
2291 
2292   /** Firmware layout for the RE200 v2 */
2293         {
2294                 .id     = "RE200-V2",
2295                 .vendor = "",
2296                 .support_list =
2297                         "SupportList:\n"
2298                         "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
2299                         "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
2300                         "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
2301                         "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
2302                         "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
2303                         "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
2304                         "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
2305                         "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
2306                         "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
2307                         "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
2308                         "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
2309                         "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
2310                         "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
2311                 .part_trail = 0x00,
2312                 .soft_ver = SOFT_VER_DEFAULT,
2313 
2314                 .partitions = {
2315                         {"fs-uboot", 0x00000, 0x20000},
2316                         {"firmware", 0x20000, 0x7a0000},
2317                         {"partition-table", 0x7c0000, 0x02000},
2318                         {"default-mac", 0x7c2000, 0x00020},
2319                         {"pin", 0x7c2100, 0x00020},
2320                         {"product-info", 0x7c3100, 0x01000},
2321                         {"soft-version", 0x7c4200, 0x01000},
2322                         {"support-list", 0x7c5200, 0x01000},
2323                         {"profile", 0x7c6200, 0x08000},
2324                         {"config-info", 0x7ce200, 0x00400},
2325                         {"user-config", 0x7d0000, 0x10000},
2326                         {"default-config", 0x7e0000, 0x10000},
2327                         {"radio", 0x7f0000, 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 v3 */
2336         {
2337                 .id     = "RE200-V3",
2338                 .vendor = "",
2339                 .support_list =
2340                         "SupportList:\n"
2341                         "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
2342                         "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
2343                         "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
2344                         "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
2345                         "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
2346                         "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
2347                         "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
2348                         "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
2349                         "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
2350                         "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
2351                         "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
2352                         "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
2353                         "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
2354                         "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
2355                 .part_trail = 0x00,
2356                 .soft_ver = SOFT_VER_DEFAULT,
2357 
2358                 .partitions = {
2359                         {"fs-uboot", 0x00000, 0x20000},
2360                         {"firmware", 0x20000, 0x7a0000},
2361                         {"partition-table", 0x7c0000, 0x02000},
2362                         {"default-mac", 0x7c2000, 0x00020},
2363                         {"pin", 0x7c2100, 0x00020},
2364                         {"product-info", 0x7c3100, 0x01000},
2365                         {"soft-version", 0x7c4200, 0x01000},
2366                         {"support-list", 0x7c5200, 0x01000},
2367                         {"profile", 0x7c6200, 0x08000},
2368                         {"config-info", 0x7ce200, 0x00400},
2369                         {"user-config", 0x7d0000, 0x10000},
2370                         {"default-config", 0x7e0000, 0x10000},
2371                         {"radio", 0x7f0000, 0x10000},
2372                         {NULL, 0, 0}
2373                 },
2374 
2375                 .first_sysupgrade_partition = "os-image",
2376                 .last_sysupgrade_partition = "file-system"
2377         },
2378 
2379   /** Firmware layout for the RE200 v4 */
2380         {
2381                 .id     = "RE200-V4",
2382                 .vendor = "",
2383                 .support_list =
2384                         "SupportList:\n"
2385                         "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2386                         "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2387                         "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2388                         "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2389                         "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2390                         "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2391                         "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2392                         "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2393                         "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2394                         "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2395                         "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2396                         "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2397                         "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2398                         "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2399                 .part_trail = 0x00,
2400                 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2401 
2402                 .partitions = {
2403                         {"fs-uboot", 0x00000, 0x20000},
2404                         {"firmware", 0x20000, 0x7a0000},
2405                         {"partition-table", 0x7c0000, 0x02000},
2406                         {"default-mac", 0x7c2000, 0x00020},
2407                         {"pin", 0x7c2100, 0x00020},
2408                         {"product-info", 0x7c3100, 0x01000},
2409                         {"soft-version", 0x7c4200, 0x01000},
2410                         {"support-list", 0x7c5200, 0x01000},
2411                         {"profile", 0x7c6200, 0x08000},
2412                         {"config-info", 0x7ce200, 0x00400},
2413                         {"user-config", 0x7d0000, 0x10000},
2414                         {"default-config", 0x7e0000, 0x10000},
2415                         {"radio", 0x7f0000, 0x10000},
2416                         {NULL, 0, 0}
2417                 },
2418 
2419                 .first_sysupgrade_partition = "os-image",
2420                 .last_sysupgrade_partition = "file-system"
2421         },
2422 
2423         /** Firmware layout for the RE220 v2 */
2424         {
2425                 .id     = "RE220-V2",
2426                 .vendor = "",
2427                 .support_list =
2428                         "SupportList:\n"
2429                         "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2430                         "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2431                         "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2432                         "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2433                         "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2434                         "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2435                         "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2436                         "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2437                         "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2438                         "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2439                         "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2440                         "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2441                         "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2442                 .part_trail = 0x00,
2443                 .soft_ver = SOFT_VER_DEFAULT,
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 RE305 v1 */
2467         {
2468                 .id     = "RE305-V1",
2469                 .vendor = "",
2470                 .support_list =
2471                         "SupportList:\n"
2472                         "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2473                         "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2474                         "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2475                         "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2476                         "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2477                         "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2478                         "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2479                 .part_trail = 0x00,
2480                 .soft_ver = SOFT_VER_DEFAULT,
2481 
2482                 .partitions = {
2483                         {"fs-uboot", 0x00000, 0x20000},
2484                         {"firmware", 0x20000, 0x5e0000},
2485                         {"partition-table", 0x600000, 0x02000},
2486                         {"default-mac", 0x610000, 0x00020},
2487                         {"pin", 0x610100, 0x00020},
2488                         {"product-info", 0x611100, 0x01000},
2489                         {"soft-version", 0x620000, 0x01000},
2490                         {"support-list", 0x621000, 0x01000},
2491                         {"profile", 0x622000, 0x08000},
2492                         {"user-config", 0x630000, 0x10000},
2493                         {"default-config", 0x640000, 0x10000},
2494                         {"radio", 0x7f0000, 0x10000},
2495                         {NULL, 0, 0}
2496                 },
2497 
2498                 .first_sysupgrade_partition = "os-image",
2499                 .last_sysupgrade_partition = "file-system"
2500         },
2501 
2502         /** Firmware layout for the RE305 v3 */
2503         {
2504                 .id     = "RE305-V3",
2505                 .vendor = "",
2506                 .support_list =
2507                         "SupportList:\n"
2508                         "{product_name:RE305,product_ver:3.0.0,special_id:00000000}\n"
2509                         "{product_name:RE305,product_ver:3.0.0,special_id:45550000}\n"
2510                         "{product_name:RE305,product_ver:3.0.0,special_id:4A500000}\n"
2511                         "{product_name:RE305,product_ver:3.0.0,special_id:4B520000}\n"
2512                         "{product_name:RE305,product_ver:3.0.0,special_id:41550000}\n"
2513                         "{product_name:RE305,product_ver:3.0.0,special_id:42520000}\n"
2514                         "{product_name:RE305,product_ver:3.0.0,special_id:55530000}\n"
2515                         "{product_name:RE305,product_ver:3.0.0,special_id:45530000}\n"
2516                         "{product_name:RE305,product_ver:3.0.0,special_id:41530000}\n"
2517                         "{product_name:RE305,product_ver:3.0.0,special_id:43410000}\n"
2518                         "{product_name:RE305,product_ver:3.0.0,special_id:52550000}\n",
2519                 .part_trail = 0x00,
2520                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
2521 
2522                 .partitions = {
2523                         {"fs-uboot", 0x00000, 0x20000},
2524                         {"firmware", 0x20000, 0x7a0000},
2525                         {"partition-table", 0x7c0000, 0x02000},
2526                         {"default-mac", 0x7c2000, 0x00020},
2527                         {"pin", 0x7c2100, 0x00020},
2528                         {"product-info", 0x7c3100, 0x01000},
2529                         {"soft-version", 0x7c4200, 0x01000},
2530                         {"support-list", 0x7c5200, 0x01000},
2531                         {"profile", 0x7c6200, 0x08000},
2532                         {"config-info", 0x7ce200, 0x00400},
2533                         {"user-config", 0x7d0000, 0x10000},
2534                         {"default-config", 0x7e0000, 0x10000},
2535                         {"radio", 0x7f0000, 0x10000},
2536                         {NULL, 0, 0}
2537                 },
2538 
2539                 .first_sysupgrade_partition = "os-image",
2540                 .last_sysupgrade_partition = "file-system"
2541         },
2542 
2543         /** Firmware layout for the RE350 v1 */
2544         {
2545                 .id     = "RE350-V1",
2546                 .vendor = "",
2547                 .support_list =
2548                         "SupportList:\n"
2549                         "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2550                         "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2551                         "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2552                         "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2553                         "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2554                         "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2555                         "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2556                 .part_trail = 0x00,
2557                 .soft_ver = SOFT_VER_DEFAULT,
2558 
2559                 /** We're using a dynamic kernel/rootfs split here */
2560                 .partitions = {
2561                         {"fs-uboot", 0x00000, 0x20000},
2562                         {"firmware", 0x20000, 0x5e0000},
2563                         {"partition-table", 0x600000, 0x02000},
2564                         {"default-mac", 0x610000, 0x00020},
2565                         {"pin", 0x610100, 0x00020},
2566                         {"product-info", 0x611100, 0x01000},
2567                         {"soft-version", 0x620000, 0x01000},
2568                         {"support-list", 0x621000, 0x01000},
2569                         {"profile", 0x622000, 0x08000},
2570                         {"user-config", 0x630000, 0x10000},
2571                         {"default-config", 0x640000, 0x10000},
2572                         {"radio", 0x7f0000, 0x10000},
2573                         {NULL, 0, 0}
2574                 },
2575 
2576                 .first_sysupgrade_partition = "os-image",
2577                 .last_sysupgrade_partition = "file-system"
2578         },
2579 
2580         /** Firmware layout for the RE350K v1 */
2581         {
2582                 .id     = "RE350K-V1",
2583                 .vendor = "",
2584                 .support_list =
2585                         "SupportList:\n"
2586                         "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2587                 .part_trail = 0x00,
2588                 .soft_ver = SOFT_VER_DEFAULT,
2589 
2590                 /** We're using a dynamic kernel/rootfs split here */
2591                 .partitions = {
2592                         {"fs-uboot", 0x00000, 0x20000},
2593                         {"firmware", 0x20000, 0xd70000},
2594                         {"partition-table", 0xd90000, 0x02000},
2595                         {"default-mac", 0xda0000, 0x00020},
2596                         {"pin", 0xda0100, 0x00020},
2597                         {"product-info", 0xda1100, 0x01000},
2598                         {"soft-version", 0xdb0000, 0x01000},
2599                         {"support-list", 0xdb1000, 0x01000},
2600                         {"profile", 0xdb2000, 0x08000},
2601                         {"user-config", 0xdc0000, 0x10000},
2602                         {"default-config", 0xdd0000, 0x10000},
2603                         {"device-id", 0xde0000, 0x00108},
2604                         {"radio", 0xff0000, 0x10000},
2605                         {NULL, 0, 0}
2606                 },
2607 
2608                 .first_sysupgrade_partition = "os-image",
2609                 .last_sysupgrade_partition = "file-system"
2610         },
2611 
2612         /** Firmware layout for the RE355 */
2613         {
2614                 .id     = "RE355",
2615                 .vendor = "",
2616                 .support_list =
2617                         "SupportList:\r\n"
2618                         "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2619                         "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2620                         "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2621                         "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2622                         "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2623                         "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2624                         "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2625                         "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2626                 .part_trail = 0x00,
2627                 .soft_ver = SOFT_VER_DEFAULT,
2628 
2629                 /* We're using a dynamic kernel/rootfs split here */
2630                 .partitions = {
2631                         {"fs-uboot", 0x00000, 0x20000},
2632                         {"firmware", 0x20000, 0x5e0000},
2633                         {"partition-table", 0x600000, 0x02000},
2634                         {"default-mac", 0x610000, 0x00020},
2635                         {"pin", 0x610100, 0x00020},
2636                         {"product-info", 0x611100, 0x01000},
2637                         {"soft-version", 0x620000, 0x01000},
2638                         {"support-list", 0x621000, 0x01000},
2639                         {"profile", 0x622000, 0x08000},
2640                         {"user-config", 0x630000, 0x10000},
2641                         {"default-config", 0x640000, 0x10000},
2642                         {"radio", 0x7f0000, 0x10000},
2643                         {NULL, 0, 0}
2644                 },
2645 
2646                 .first_sysupgrade_partition = "os-image",
2647                 .last_sysupgrade_partition = "file-system"
2648         },
2649 
2650         /** Firmware layout for the RE450 */
2651         {
2652                 .id     = "RE450",
2653                 .vendor = "",
2654                 .support_list =
2655                         "SupportList:\r\n"
2656                         "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2657                         "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
2658                         "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
2659                         "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
2660                         "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
2661                         "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
2662                         "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
2663                         "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
2664                 .part_trail = 0x00,
2665                 .soft_ver = SOFT_VER_DEFAULT,
2666 
2667                 /** We're using a dynamic kernel/rootfs split here */
2668                 .partitions = {
2669                         {"fs-uboot", 0x00000, 0x20000},
2670                         {"firmware", 0x20000, 0x5e0000},
2671                         {"partition-table", 0x600000, 0x02000},
2672                         {"default-mac", 0x610000, 0x00020},
2673                         {"pin", 0x610100, 0x00020},
2674                         {"product-info", 0x611100, 0x01000},
2675                         {"soft-version", 0x620000, 0x01000},
2676                         {"support-list", 0x621000, 0x01000},
2677                         {"profile", 0x622000, 0x08000},
2678                         {"user-config", 0x630000, 0x10000},
2679                         {"default-config", 0x640000, 0x10000},
2680                         {"radio", 0x7f0000, 0x10000},
2681                         {NULL, 0, 0}
2682                 },
2683 
2684                 .first_sysupgrade_partition = "os-image",
2685                 .last_sysupgrade_partition = "file-system"
2686         },
2687 
2688         /** Firmware layout for the RE450 v2 */
2689         {
2690                 .id     = "RE450-V2",
2691                 .vendor = "",
2692                 .support_list =
2693                         "SupportList:\r\n"
2694                         "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
2695                         "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
2696                         "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
2697                         "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
2698                         "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
2699                         "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
2700                         "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
2701                         "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
2702                         "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
2703                 .part_trail = 0x00,
2704                 .soft_ver = SOFT_VER_DEFAULT,
2705 
2706                 /* We're using a dynamic kernel/rootfs split here */
2707                 .partitions = {
2708                         {"fs-uboot", 0x00000, 0x20000},
2709                         {"firmware", 0x20000, 0x5e0000},
2710                         {"partition-table", 0x600000, 0x02000},
2711                         {"default-mac", 0x610000, 0x00020},
2712                         {"pin", 0x610100, 0x00020},
2713                         {"product-info", 0x611100, 0x01000},
2714                         {"soft-version", 0x620000, 0x01000},
2715                         {"support-list", 0x621000, 0x01000},
2716                         {"profile", 0x622000, 0x08000},
2717                         {"user-config", 0x630000, 0x10000},
2718                         {"default-config", 0x640000, 0x10000},
2719                         {"radio", 0x7f0000, 0x10000},
2720                         {NULL, 0, 0}
2721                 },
2722 
2723                 .first_sysupgrade_partition = "os-image",
2724                 .last_sysupgrade_partition = "file-system"
2725         },
2726 
2727         /** Firmware layout for the RE450 v3 */
2728         {
2729                 .id     = "RE450-V3",
2730                 .vendor = "",
2731                 .support_list =
2732                         "SupportList:\r\n"
2733                         "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
2734                         "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
2735                         "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
2736                         "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
2737                         "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
2738                         "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
2739                         "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
2740                         "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
2741                         "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
2742                 .part_trail = 0x00,
2743                 .soft_ver = SOFT_VER_DEFAULT,
2744 
2745                 /* We're using a dynamic kernel/rootfs split here */
2746                 .partitions = {
2747                         {"fs-uboot", 0x00000, 0x20000},
2748                         {"default-mac", 0x20000, 0x00020},
2749                         {"pin", 0x20020, 0x00020},
2750                         {"product-info", 0x21000, 0x01000},
2751                         {"partition-table", 0x22000, 0x02000},
2752                         {"soft-version", 0x24000, 0x01000},
2753                         {"support-list", 0x25000, 0x01000},
2754                         {"profile", 0x26000, 0x08000},
2755                         {"user-config", 0x2e000, 0x10000},
2756                         {"default-config", 0x3e000, 0x10000},
2757                         {"config-info", 0x4e000, 0x00400},
2758                         {"firmware", 0x50000, 0x7a0000},
2759                         {"radio", 0x7f0000, 0x10000},
2760                         {NULL, 0, 0}
2761                 },
2762 
2763                 .first_sysupgrade_partition = "os-image",
2764                 .last_sysupgrade_partition = "file-system"
2765         },
2766 
2767         /** Firmware layout for the RE455 v1 */
2768         {
2769                 .id     = "RE455-V1",
2770                 .vendor = "",
2771                 .support_list =
2772                         "SupportList:\r\n"
2773                         "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
2774                         "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
2775                         "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
2776                         "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
2777                         "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
2778                         "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
2779                         "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
2780                         "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
2781                         "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
2782                 .part_trail = 0x00,
2783                 .soft_ver = SOFT_VER_DEFAULT,
2784 
2785                 /* We're using a dynamic kernel/rootfs split here */
2786                 .partitions = {
2787                         {"fs-uboot", 0x00000, 0x20000},
2788                         {"default-mac", 0x20000, 0x00020},
2789                         {"pin", 0x20020, 0x00020},
2790                         {"product-info", 0x21000, 0x01000},
2791                         {"partition-table", 0x22000, 0x02000},
2792                         {"soft-version", 0x24000, 0x01000},
2793                         {"support-list", 0x25000, 0x01000},
2794                         {"profile", 0x26000, 0x08000},
2795                         {"user-config", 0x2e000, 0x10000},
2796                         {"default-config", 0x3e000, 0x10000},
2797                         {"config-info", 0x4e000, 0x00400},
2798                         {"firmware", 0x50000, 0x7a0000},
2799                         {"radio", 0x7f0000, 0x10000},
2800                         {NULL, 0, 0}
2801                 },
2802 
2803                 .first_sysupgrade_partition = "os-image",
2804                 .last_sysupgrade_partition = "file-system"
2805         },
2806 
2807         /** Firmware layout for the RE500 */
2808         {
2809                 .id     = "RE500-V1",
2810                 .vendor = "",
2811                 .support_list =
2812                         "SupportList:\r\n"
2813                         "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
2814                         "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
2815                         "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
2816                         "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
2817                         "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
2818                         "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
2819                         "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
2820                 .part_trail = 0x00,
2821                 .soft_ver = SOFT_VER_DEFAULT,
2822 
2823                 /* We're using a dynamic kernel/rootfs split here */
2824                 .partitions = {
2825                         {"fs-uboot", 0x00000, 0x20000},
2826                         {"firmware", 0x20000, 0xde0000},
2827                         {"partition-table", 0xe00000, 0x02000},
2828                         {"default-mac", 0xe10000, 0x00020},
2829                         {"pin", 0xe10100, 0x00020},
2830                         {"product-info", 0xe11100, 0x01000},
2831                         {"soft-version", 0xe20000, 0x01000},
2832                         {"support-list", 0xe21000, 0x01000},
2833                         {"profile", 0xe22000, 0x08000},
2834                         {"user-config", 0xe30000, 0x10000},
2835                         {"default-config", 0xe40000, 0x10000},
2836                         {"radio", 0xff0000, 0x10000},
2837                         {NULL, 0, 0}
2838                 },
2839 
2840                 .first_sysupgrade_partition = "os-image",
2841                 .last_sysupgrade_partition = "file-system"
2842         },
2843 
2844         /** Firmware layout for the RE650 */
2845         {
2846                 .id     = "RE650-V1",
2847                 .vendor = "",
2848                 .support_list =
2849                         "SupportList:\r\n"
2850                         "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
2851                         "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
2852                         "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
2853                         "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
2854                         "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
2855                         "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
2856                         "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
2857                 .part_trail = 0x00,
2858                 .soft_ver = SOFT_VER_DEFAULT,
2859 
2860                 /* We're using a dynamic kernel/rootfs split here */
2861                 .partitions = {
2862                         {"fs-uboot", 0x00000, 0x20000},
2863                         {"firmware", 0x20000, 0xde0000},
2864                         {"partition-table", 0xe00000, 0x02000},
2865                         {"default-mac", 0xe10000, 0x00020},
2866                         {"pin", 0xe10100, 0x00020},
2867                         {"product-info", 0xe11100, 0x01000},
2868                         {"soft-version", 0xe20000, 0x01000},
2869                         {"support-list", 0xe21000, 0x01000},
2870                         {"profile", 0xe22000, 0x08000},
2871                         {"user-config", 0xe30000, 0x10000},
2872                         {"default-config", 0xe40000, 0x10000},
2873                         {"radio", 0xff0000, 0x10000},
2874                         {NULL, 0, 0}
2875                 },
2876 
2877                 .first_sysupgrade_partition = "os-image",
2878                 .last_sysupgrade_partition = "file-system"
2879         },
2880         /** Firmware layout for the RE650 V2 (8MB Flash)*/
2881         {
2882                 .id     = "RE650-V2",
2883                 .vendor = "",
2884                 .support_list =
2885                         "SupportList:\n"
2886                         "{product_name:RE650,product_ver:2.0.0,special_id:00000000}\n"
2887                         "{product_name:RE650,product_ver:2.0.0,special_id:45550000}\n"
2888                         "{product_name:RE650,product_ver:2.0.0,special_id:4A500000}\n"
2889                         "{product_name:RE650,product_ver:2.0.0,special_id:41550000}\n"
2890                         "{product_name:RE650,product_ver:2.0.0,special_id:43410000}\n"
2891                         "{product_name:RE650,product_ver:2.0.0,special_id:41530000}\n"
2892                         "{product_name:RE650,product_ver:2.0.0,special_id:55530000}\n",
2893                 .part_trail = 0x00,
2894                 /* For RE650 v2, soft ver is required, otherwise OEM install doesn't work */
2895                 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
2896 
2897                 /* We're using a dynamic kernel/rootfs split here */
2898                 .partitions = {
2899                         {"fs-uboot", 0x00000, 0x20000},
2900                         {"firmware", 0x20000, 0x7a0000},
2901                         {"partition-table", 0x7c0000, 0x02000},
2902                         {"default-mac", 0x7c2000, 0x00020},
2903                         {"pin", 0x7c2100, 0x00020},
2904                         {"product-info", 0x7c3100, 0x01000},
2905                         {"soft-version", 0x7c4200, 0x01000},
2906                         {"support-list", 0x7c5200, 0x01000},
2907                         {"profile", 0x7c6200, 0x08000},
2908                         {"config-info", 0x7ce200, 0x00400},
2909                         {"user-config", 0x7d0000, 0x10000},
2910                         {"default-config", 0x7e0000, 0x10000},
2911                         {"radio", 0x7f0000, 0x10000},
2912                         {NULL, 0, 0}
2913                 },
2914 
2915                 .first_sysupgrade_partition = "os-image",
2916                 .last_sysupgrade_partition = "file-system"
2917         },
2918 
2919         /** Firmware layout for the Mercusys MR70X */
2920         {
2921                 .id     = "MR70X",
2922                 .vendor = "",
2923                 .support_list =
2924                         "SupportList:\n"
2925                         "{product_name:MR70X,product_ver:1.0.0,special_id:45550000}\n"
2926                         "{product_name:MR70X,product_ver:1.0.0,special_id:4A500000}\n"
2927                         "{product_name:MR70X,product_ver:1.0.0,special_id:55530000}\n",
2928                 .part_trail = 0x00,
2929                 .soft_ver = SOFT_VER_DEFAULT,
2930 
2931                 .partitions = {
2932                         {"fs-uboot", 0x00000, 0x40000},
2933                         {"firmware", 0x40000, 0xf60000},
2934                         {"default-mac", 0xfa0000, 0x00200},
2935                         {"pin", 0xfa0200, 0x00100},
2936                         {"device-id", 0xfa0300, 0x00100},
2937                         {"product-info", 0xfa0400, 0x0fc00},
2938                         {"default-config", 0xfb0000, 0x08000},
2939                         {"ap-def-config", 0xfb8000, 0x08000},
2940                         {"user-config", 0xfc0000, 0x0a000},
2941                         {"ag-config", 0xfca000, 0x04000},
2942                         {"certificate", 0xfce000, 0x02000},
2943                         {"ap-config", 0xfd0000, 0x06000},
2944                         {"router-config", 0xfd6000, 0x06000},
2945                         {"favicon", 0xfdc000, 0x02000},
2946                         {"logo", 0xfde000, 0x02000},
2947                         {"partition-table", 0xfe0000, 0x00800},
2948                         {"soft-version", 0xfe0800, 0x00100},
2949                         {"support-list", 0xfe0900, 0x00200},
2950                         {"profile", 0xfe0b00, 0x03000},
2951                         {"extra-para", 0xfe3b00, 0x00100},
2952                         {"radio", 0xff0000, 0x10000},
2953                         {NULL, 0, 0}
2954                 },
2955 
2956                 .first_sysupgrade_partition = "os-image",
2957                 .last_sysupgrade_partition = "file-system"
2958         },
2959 
2960         {}
2961 };
2962 
2963 #define error(_ret, _errno, _str, ...)                          \
2964         do {                                                    \
2965                 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__,  \
2966                         strerror(_errno));                      \
2967                 if (_ret)                                       \
2968                         exit(_ret);                             \
2969         } while (0)
2970 
2971 
2972 /** Stores a uint32 as big endian */
2973 static inline void put32(uint8_t *buf, uint32_t val) {
2974         buf[0] = val >> 24;
2975         buf[1] = val >> 16;
2976         buf[2] = val >> 8;
2977         buf[3] = val;
2978 }
2979 
2980 static inline bool meta_partition_should_pad(enum partition_trail_value pv)
2981 {
2982         return (pv >= 0) && (pv <= PART_TRAIL_MAX);
2983 }
2984 
2985 /** Allocate a padded meta partition with a correctly initialised header
2986  * If the `data` pointer is NULL, then the required space is only allocated,
2987  * otherwise `data_len` bytes will be copied from `data` into the partition
2988  * entry. */
2989 static struct image_partition_entry init_meta_partition_entry(
2990         const char *name, const void *data, uint32_t data_len,
2991         enum partition_trail_value pad_value)
2992 {
2993         uint32_t total_len = sizeof(struct meta_header) + data_len;
2994         if (meta_partition_should_pad(pad_value))
2995                 total_len += 1;
2996 
2997         struct image_partition_entry entry = {
2998                 .name = name,
2999                 .size = total_len,
3000                 .data = malloc(total_len)
3001         };
3002         if (!entry.data)
3003                 error(1, errno, "failed to allocate meta partition entry");
3004 
3005         struct meta_header *header = (struct meta_header *)entry.data;
3006         header->length = htonl(data_len);
3007         header->zero = 0;
3008 
3009         if (data)
3010                 memcpy(entry.data+sizeof(*header), data, data_len);
3011 
3012         if (meta_partition_should_pad(pad_value))
3013                 entry.data[total_len - 1] = (uint8_t) pad_value;
3014 
3015         return entry;
3016 }
3017 
3018 /** Allocates a new image partition */
3019 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
3020         struct image_partition_entry entry = {name, len, malloc(len)};
3021         if (!entry.data)
3022                 error(1, errno, "malloc");
3023 
3024         return entry;
3025 }
3026 
3027 /** Sets up default partition names whenever custom names aren't specified */
3028 static void set_partition_names(struct device_info *info)
3029 {
3030         if (!info->partition_names.partition_table)
3031                 info->partition_names.partition_table = "partition-table";
3032         if (!info->partition_names.soft_ver)
3033                 info->partition_names.soft_ver = "soft-version";
3034         if (!info->partition_names.os_image)
3035                 info->partition_names.os_image = "os-image";
3036         if (!info->partition_names.support_list)
3037                 info->partition_names.support_list = "support-list";
3038         if (!info->partition_names.file_system)
3039                 info->partition_names.file_system = "file-system";
3040         if (!info->partition_names.extra_para)
3041                 info->partition_names.extra_para = "extra-para";
3042 }
3043 
3044 /** Frees an image partition */
3045 static void free_image_partition(struct image_partition_entry entry) {
3046         free(entry.data);
3047 }
3048 
3049 static time_t source_date_epoch = -1;
3050 static void set_source_date_epoch() {
3051         char *env = getenv("SOURCE_DATE_EPOCH");
3052         char *endptr = env;
3053         errno = 0;
3054         if (env && *env) {
3055                 source_date_epoch = strtoull(env, &endptr, 10);
3056                 if (errno || (endptr && *endptr != '\0')) {
3057                         fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
3058                         exit(1);
3059                 }
3060         }
3061 }
3062 
3063 /** Generates the partition-table partition */
3064 static struct image_partition_entry make_partition_table(const struct device_info *p)
3065 {
3066         struct image_partition_entry entry = alloc_image_partition(p->partition_names.partition_table, 0x800);
3067 
3068         char *s = (char *)entry.data, *end = (char *)(s+entry.size);
3069 
3070         *(s++) = 0x00;
3071         *(s++) = 0x04;
3072         *(s++) = 0x00;
3073         *(s++) = 0x00;
3074 
3075         size_t i;
3076         for (i = 0; p->partitions[i].name; i++) {
3077                 size_t len = end-s;
3078                 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n",
3079                         p->partitions[i].name, p->partitions[i].base, p->partitions[i].size);
3080 
3081                 if (w > len-1)
3082                         error(1, 0, "flash partition table overflow?");
3083 
3084                 s += w;
3085         }
3086 
3087         s++;
3088 
3089         memset(s, 0xff, end-s);
3090 
3091         return entry;
3092 }
3093 
3094 
3095 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
3096 static inline uint8_t bcd(uint8_t v) {
3097         return 0x10 * (v/10) + v%10;
3098 }
3099 
3100 
3101 /** Generates the soft-version partition */
3102 static struct image_partition_entry make_soft_version(const struct device_info *info, uint32_t rev)
3103 {
3104         /** If an info string is provided, use this instead of
3105          * the structured data, and include the null-termination */
3106         if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) {
3107                 uint32_t len = strlen(info->soft_ver.text) + 1;
3108                 return init_meta_partition_entry(info->partition_names.soft_ver,
3109                         info->soft_ver.text, len, info->part_trail);
3110         }
3111 
3112         time_t t;
3113 
3114         if (source_date_epoch != -1)
3115                 t = source_date_epoch;
3116         else if (time(&t) == (time_t)(-1))
3117                 error(1, errno, "time");
3118 
3119         struct tm *tm = gmtime(&t);
3120 
3121         struct soft_version s = {
3122                 .pad1 = 0xff,
3123 
3124                 .version_major = info->soft_ver.num[0],
3125                 .version_minor = info->soft_ver.num[1],
3126                 .version_patch = info->soft_ver.num[2],
3127 
3128                 .year_hi = bcd((1900+tm->tm_year)/100),
3129                 .year_lo = bcd(tm->tm_year%100),
3130                 .month = bcd(tm->tm_mon+1),
3131                 .day = bcd(tm->tm_mday),
3132                 .rev = htonl(rev),
3133 
3134                 .compat_level = htonl(info->soft_ver_compat_level)
3135         };
3136 
3137         if (info->soft_ver_compat_level == 0)
3138                 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3139                         (uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
3140                         info->part_trail);
3141         else
3142                 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3143                         sizeof(s), info->part_trail);
3144 }
3145 
3146 /** Generates the support-list partition */
3147 static struct image_partition_entry make_support_list(
3148         const struct device_info *info)
3149 {
3150         uint32_t len = strlen(info->support_list);
3151         return init_meta_partition_entry(info->partition_names.support_list, info->support_list,
3152                 len, info->part_trail);
3153 }
3154 
3155 /** Partition with extra-para data */
3156 static struct image_partition_entry make_extra_para(
3157         const struct device_info *info, const uint8_t *extra_para, size_t len)
3158 {
3159         return init_meta_partition_entry(info->partition_names.extra_para, extra_para, len,
3160                 info->part_trail);
3161 }
3162 
3163 /** Creates a new image partition with an arbitrary name from a file */
3164 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) {
3165         struct stat statbuf;
3166 
3167         if (stat(filename, &statbuf) < 0)
3168                 error(1, errno, "unable to stat file `%s'", filename);
3169 
3170         size_t len = statbuf.st_size;
3171 
3172         if (add_jffs2_eof) {
3173                 if (file_system_partition)
3174                         len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
3175                 else
3176                         len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
3177         }
3178 
3179         struct image_partition_entry entry = alloc_image_partition(part_name, len);
3180 
3181         FILE *file = fopen(filename, "rb");
3182         if (!file)
3183                 error(1, errno, "unable to open file `%s'", filename);
3184 
3185         if (fread(entry.data, statbuf.st_size, 1, file) != 1)
3186                 error(1, errno, "unable to read file `%s'", filename);
3187 
3188         if (add_jffs2_eof) {
3189                 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
3190 
3191                 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
3192                 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
3193         }
3194 
3195         fclose(file);
3196 
3197         return entry;
3198 }
3199 
3200 /**
3201    Copies a list of image partitions into an image buffer and generates the image partition table while doing so
3202 
3203    Example image partition table:
3204 
3205      fwup-ptn partition-table base 0x00800 size 0x00800
3206      fwup-ptn os-image base 0x01000 size 0x113b45
3207      fwup-ptn file-system base 0x114b45 size 0x1d0004
3208      fwup-ptn support-list base 0x2e4b49 size 0x000d1
3209 
3210    Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
3211    the end of the partition table is marked with a zero byte.
3212 
3213    The firmware image must contain at least the partition-table and support-list partitions
3214    to be accepted. There aren't any alignment constraints for the image partitions.
3215 
3216    The partition-table partition contains the actual flash layout; partitions
3217    from the image partition table are mapped to the corresponding flash partitions during
3218    the firmware upgrade. The support-list partition contains a list of devices supported by
3219    the firmware image.
3220 
3221    The base offsets in the firmware partition table are relative to the end
3222    of the vendor information block, so the partition-table partition will
3223    actually start at offset 0x1814 of the image.
3224 
3225    I think partition-table must be the first partition in the firmware image.
3226 */
3227 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
3228         size_t i, j;
3229         char *image_pt = (char *)buffer, *end = image_pt + 0x800;
3230 
3231         size_t base = 0x800;
3232         for (i = 0; parts[i].name; i++) {
3233                 for (j = 0; flash_parts[j].name; j++) {
3234                         if (!strcmp(flash_parts[j].name, parts[i].name)) {
3235                                 if (parts[i].size > flash_parts[j].size)
3236                                         error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
3237                                 break;
3238                         }
3239                 }
3240 
3241                 assert(flash_parts[j].name);
3242 
3243                 memcpy(buffer + base, parts[i].data, parts[i].size);
3244 
3245                 size_t len = end-image_pt;
3246                 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);
3247 
3248                 if (w > len-1)
3249                         error(1, 0, "image partition table overflow?");
3250 
3251                 image_pt += w;
3252 
3253                 base += parts[i].size;
3254         }
3255 }
3256 
3257 /** Generates and writes the image MD5 checksum */
3258 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
3259         MD5_CTX ctx;
3260 
3261         MD5_Init(&ctx);
3262         MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
3263         MD5_Update(&ctx, buffer, len);
3264         MD5_Final(md5, &ctx);
3265 }
3266 
3267 
3268 /**
3269    Generates the firmware image in factory format
3270 
3271    Image format:
3272 
3273      Bytes (hex)  Usage
3274      -----------  -----
3275      0000-0003    Image size (4 bytes, big endian)
3276      0004-0013    MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
3277      0014-0017    Vendor information length (without padding) (4 bytes, big endian)
3278      0018-1013    Vendor information (4092 bytes, padded with 0xff; there seem to be older
3279                   (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
3280      1014-1813    Image partition table (2048 bytes, padded with 0xff)
3281      1814-xxxx    Firmware partitions
3282 */
3283 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
3284         *len = 0x1814;
3285 
3286         size_t i;
3287         for (i = 0; parts[i].name; i++)
3288                 *len += parts[i].size;
3289 
3290         uint8_t *image = malloc(*len);
3291         if (!image)
3292                 error(1, errno, "malloc");
3293 
3294         memset(image, 0xff, *len);
3295         put32(image, *len);
3296 
3297         if (info->vendor) {
3298                 size_t vendor_len = strlen(info->vendor);
3299                 put32(image+0x14, vendor_len);
3300                 memcpy(image+0x18, info->vendor, vendor_len);
3301         }
3302 
3303         put_partitions(image + 0x1014, info->partitions, parts);
3304         put_md5(image+0x04, image+0x14, *len-0x14);
3305 
3306         return image;
3307 }
3308 
3309 /**
3310    Generates the firmware image in sysupgrade format
3311 
3312    This makes some assumptions about the provided flash and image partition tables and
3313    should be generalized when TP-LINK starts building its safeloader into hardware with
3314    different flash layouts.
3315 */
3316 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
3317         size_t i, j;
3318         size_t flash_first_partition_index = 0;
3319         size_t flash_last_partition_index = 0;
3320         const struct flash_partition_entry *flash_first_partition = NULL;
3321         const struct flash_partition_entry *flash_last_partition = NULL;
3322         const struct image_partition_entry *image_last_partition = NULL;
3323 
3324         /** Find first and last partitions */
3325         for (i = 0; info->partitions[i].name; i++) {
3326                 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
3327                         flash_first_partition = &info->partitions[i];
3328                         flash_first_partition_index = i;
3329                 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
3330                         flash_last_partition = &info->partitions[i];
3331                         flash_last_partition_index = i;
3332                 }
3333         }
3334 
3335         assert(flash_first_partition && flash_last_partition);
3336         assert(flash_first_partition_index < flash_last_partition_index);
3337 
3338         /** Find last partition from image to calculate needed size */
3339         for (i = 0; image_parts[i].name; i++) {
3340                 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
3341                         image_last_partition = &image_parts[i];
3342                         break;
3343                 }
3344         }
3345 
3346         assert(image_last_partition);
3347 
3348         *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
3349 
3350         uint8_t *image = malloc(*len);
3351         if (!image)
3352                 error(1, errno, "malloc");
3353 
3354         memset(image, 0xff, *len);
3355 
3356         for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
3357                 for (j = 0; image_parts[j].name; j++) {
3358                         if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
3359                                 if (image_parts[j].size > info->partitions[i].size)
3360                                         error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
3361                                 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
3362                                 break;
3363                         }
3364 
3365                         assert(image_parts[j].name);
3366                 }
3367         }
3368 
3369         return image;
3370 }
3371 
3372 /** Generates an image according to a given layout and writes it to a file */
3373 static void build_image(const char *output,
3374                 const char *kernel_image,
3375                 const char *rootfs_image,
3376                 uint32_t rev,
3377                 bool add_jffs2_eof,
3378                 bool sysupgrade,
3379                 struct device_info *info) {
3380 
3381         size_t i;
3382 
3383         struct image_partition_entry parts[7] = {};
3384 
3385         struct flash_partition_entry *firmware_partition = NULL;
3386         struct flash_partition_entry *os_image_partition = NULL;
3387         struct flash_partition_entry *file_system_partition = NULL;
3388         size_t firmware_partition_index = 0;
3389 
3390         set_partition_names(info);
3391 
3392         for (i = 0; info->partitions[i].name; i++) {
3393                 if (!strcmp(info->partitions[i].name, "firmware"))
3394                 {
3395                         firmware_partition = &info->partitions[i];
3396                         firmware_partition_index = i;
3397                 }
3398         }
3399 
3400         if (firmware_partition)
3401         {
3402                 os_image_partition = &info->partitions[firmware_partition_index];
3403                 file_system_partition = &info->partitions[firmware_partition_index + 1];
3404 
3405                 struct stat kernel;
3406                 if (stat(kernel_image, &kernel) < 0)
3407                         error(1, errno, "unable to stat file `%s'", kernel_image);
3408 
3409                 if (kernel.st_size > firmware_partition->size)
3410                         error(1, 0, "kernel overflowed firmware partition\n");
3411 
3412                 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
3413                         info->partitions[i+1] = info->partitions[i];
3414 
3415                 file_system_partition->name = info->partition_names.file_system;
3416 
3417                 file_system_partition->base = firmware_partition->base + kernel.st_size;
3418 
3419                 /* Align partition start to erase blocks for factory images only */
3420                 if (!sysupgrade)
3421                         file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
3422 
3423                 file_system_partition->size = firmware_partition->size - file_system_partition->base;
3424 
3425                 os_image_partition->name = info->partition_names.os_image;
3426 
3427                 os_image_partition->size = kernel.st_size;
3428         }
3429 
3430         parts[0] = make_partition_table(info);
3431         parts[1] = make_soft_version(info, rev);
3432         parts[2] = make_support_list(info);
3433         parts[3] = read_file(info->partition_names.os_image, kernel_image, false, NULL);
3434         parts[4] = read_file(info->partition_names.file_system, rootfs_image, add_jffs2_eof, file_system_partition);
3435 
3436 
3437         /* Some devices need the extra-para partition to accept the firmware */
3438         if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 ||
3439             strcasecmp(info->id, "ARCHER-A7-V5") == 0 ||
3440             strcasecmp(info->id, "ARCHER-A9-V6") == 0 ||
3441             strcasecmp(info->id, "ARCHER-C2-V3") == 0 ||
3442             strcasecmp(info->id, "ARCHER-C7-V4") == 0 ||
3443             strcasecmp(info->id, "ARCHER-C7-V5") == 0 ||
3444             strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
3445             strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
3446             strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
3447             strcasecmp(info->id, "ARCHER-C60-V3") == 0 ||
3448             strcasecmp(info->id, "ARCHER-C6U-V1") == 0 ||
3449             strcasecmp(info->id, "ARCHER-C6-V3") == 0 ||
3450             strcasecmp(info->id, "MR70X") == 0 ||
3451             strcasecmp(info->id, "TLWR1043NV5") == 0) {
3452                 const uint8_t extra_para[2] = {0x01, 0x00};
3453                 parts[5] = make_extra_para(info, extra_para,
3454                         sizeof(extra_para));
3455         } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 ||
3456                    strcasecmp(info->id, "TL-WA1201-V2") == 0) {
3457                 const uint8_t extra_para[2] = {0x00, 0x01};
3458                 parts[5] = make_extra_para(info, extra_para,
3459                         sizeof(extra_para));
3460         } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 ||
3461                    strcasecmp(info->id, "EAP245-V3") == 0) {
3462                 const uint8_t extra_para[2] = {0x01, 0x01};
3463                 parts[5] = make_extra_para(info, extra_para,
3464                         sizeof(extra_para));
3465         }
3466 
3467         size_t len;
3468         void *image;
3469         if (sysupgrade)
3470                 image = generate_sysupgrade_image(info, parts, &len);
3471         else
3472                 image = generate_factory_image(info, parts, &len);
3473 
3474         FILE *file = fopen(output, "wb");
3475         if (!file)
3476                 error(1, errno, "unable to open output file");
3477 
3478         if (fwrite(image, len, 1, file) != 1)
3479                 error(1, 0, "unable to write output file");
3480 
3481         fclose(file);
3482 
3483         free(image);
3484 
3485         for (i = 0; parts[i].name; i++)
3486                 free_image_partition(parts[i]);
3487 }
3488 
3489 /** Usage output */
3490 static void usage(const char *argv0) {
3491         fprintf(stderr,
3492                 "Usage: %s [OPTIONS...]\n"
3493                 "\n"
3494                 "Options:\n"
3495                 "  -h              show this help\n"
3496                 "\n"
3497                 "Info about an image:\n"
3498                 "  -i <file>       input file to read from\n"
3499                 "Create a new image:\n"
3500                 "  -B <board>      create image for the board specified with <board>\n"
3501                 "  -k <file>       read kernel image from the file <file>\n"
3502                 "  -r <file>       read rootfs image from the file <file>\n"
3503                 "  -o <file>       write output to the file <file>\n"
3504                 "  -V <rev>        sets the revision number to <rev>\n"
3505                 "  -j              add jffs2 end-of-filesystem markers\n"
3506                 "  -S              create sysupgrade instead of factory image\n"
3507                 "Extract an old image:\n"
3508                 "  -x <file>       extract all oem firmware partition\n"
3509                 "  -d <dir>        destination to extract the firmware partition\n"
3510                 "  -z <file>       convert an oem firmware into a sysupgade file. Use -o for output file\n",
3511                 argv0
3512         );
3513 };
3514 
3515 
3516 static struct device_info *find_board(const char *id)
3517 {
3518         struct device_info *board = NULL;
3519 
3520         for (board = boards; board->id != NULL; board++)
3521                 if (strcasecmp(id, board->id) == 0)
3522                         return board;
3523 
3524         return NULL;
3525 }
3526 
3527 static int add_flash_partition(
3528                 struct flash_partition_entry *part_list,
3529                 size_t max_entries,
3530                 const char *name,
3531                 unsigned long base,
3532                 unsigned long size)
3533 {
3534         size_t ptr;
3535         /* check if the list has a free entry */
3536         for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
3537                 if (part_list->name == NULL &&
3538                                 part_list->base == 0 &&
3539                                 part_list->size == 0)
3540                         break;
3541         }
3542 
3543         if (ptr == max_entries) {
3544                 error(1, 0, "No free flash part entry available.");
3545         }
3546 
3547         part_list->name = calloc(1, strlen(name) + 1);
3548         if (!part_list->name) {
3549                 error(1, 0, "Unable to allocate memory");
3550         }
3551 
3552         memcpy((char *)part_list->name, name, strlen(name));
3553         part_list->base = base;
3554         part_list->size = size;
3555 
3556         return 0;
3557 }
3558 
3559 /** read the partition table into struct flash_partition_entry */
3560 static int read_partition_table(
3561                 FILE *file, long offset,
3562                 struct flash_partition_entry *entries, size_t max_entries,
3563                 int type)
3564 {
3565         char buf[2048];
3566         char *ptr, *end;
3567         const char *parthdr = NULL;
3568         const char *fwuphdr = "fwup-ptn";
3569         const char *flashhdr = "partition";
3570 
3571         /* TODO: search for the partition table */
3572 
3573         switch(type) {
3574                 case 0:
3575                         parthdr = fwuphdr;
3576                         break;
3577                 case 1:
3578                         parthdr = flashhdr;
3579                         break;
3580                 default:
3581                         error(1, 0, "Invalid partition table");
3582         }
3583 
3584         if (fseek(file, offset, SEEK_SET) < 0)
3585                 error(1, errno, "Can not seek in the firmware");
3586 
3587         if (fread(buf, 2048, 1, file) != 1)
3588                 error(1, errno, "Can not read fwup-ptn from the firmware");
3589 
3590         buf[2047] = '\0';
3591 
3592         /* look for the partition header */
3593         if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
3594                 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
3595                 return 1;
3596         }
3597 
3598         ptr = buf;
3599         end = buf + sizeof(buf);
3600         while ((ptr + strlen(parthdr)) < end &&
3601                         memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
3602                 char *end_part;
3603                 char *end_element;
3604 
3605                 char name[32] = { 0 };
3606                 int name_len = 0;
3607                 unsigned long base = 0;
3608                 unsigned long size = 0;
3609 
3610                 end_part = memchr(ptr, '\n', (end - ptr));
3611                 if (end_part == NULL) {
3612                         /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
3613                         break;
3614                 }
3615 
3616                 for (int i = 0; i <= 4; i++) {
3617                         if (end_part <= ptr)
3618                                 break;
3619 
3620                         end_element = memchr(ptr, 0x20, (end_part - ptr));
3621                         if (end_element == NULL) {
3622                                 error(1, errno, "Ignoring the rest of the partition entries.");
3623                                 break;
3624                         }
3625 
3626                         switch (i) {
3627                                 /* partition header */
3628                                 case 0:
3629                                         ptr = end_element + 1;
3630                                         continue;
3631                                 /* name */
3632                                 case 1:
3633                                         name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
3634                                         strncpy(name, ptr, name_len);
3635                                         name[name_len] = '\0';
3636                                         ptr = end_element + 1;
3637                                         continue;
3638 
3639                                 /* string "base" */
3640                                 case 2:
3641                                         ptr = end_element + 1;
3642                                         continue;
3643 
3644                                 /* actual base */
3645                                 case 3:
3646                                         base = strtoul(ptr, NULL, 16);
3647                                         ptr = end_element + 1;
3648                                         continue;
3649 
3650                                 /* string "size" */
3651                                 case 4:
3652                                         ptr = end_element + 1;
3653                                         /* actual size. The last element doesn't have a sepeartor */
3654                                         size = strtoul(ptr, NULL, 16);
3655                                         /* the part ends with 0x09, 0x0d, 0x0a */
3656                                         ptr = end_part + 1;
3657                                         add_flash_partition(entries, max_entries, name, base, size);
3658                                         continue;
3659                         }
3660                 }
3661         }
3662 
3663         return 0;
3664 }
3665 
3666 static void write_partition(
3667                 FILE *input_file,
3668                 size_t firmware_offset,
3669                 struct flash_partition_entry *entry,
3670                 FILE *output_file)
3671 {
3672         char buf[4096];
3673         size_t offset;
3674 
3675         fseek(input_file, entry->base + firmware_offset, SEEK_SET);
3676 
3677         for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
3678                 if (fread(buf, sizeof(buf), 1, input_file) != 1)
3679                         error(1, errno, "Can not read partition from input_file");
3680 
3681                 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
3682                         error(1, errno, "Can not write partition to output_file");
3683         }
3684         /* write last chunk smaller than buffer */
3685         if (offset < entry->size) {
3686                 offset = entry->size - offset;
3687                 if (fread(buf, offset, 1, input_file) != 1)
3688                         error(1, errno, "Can not read partition from input_file");
3689                 if (fwrite(buf, offset, 1, output_file) != 1)
3690                         error(1, errno, "Can not write partition to output_file");
3691         }
3692 }
3693 
3694 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
3695 {
3696         FILE *output_file;
3697         char output[PATH_MAX];
3698 
3699         snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
3700         output_file = fopen(output, "wb+");
3701         if (output_file == NULL) {
3702                 error(1, errno, "Can not open output file %s", output);
3703         }
3704 
3705         write_partition(input_file, firmware_offset, entry, output_file);
3706 
3707         fclose(output_file);
3708 
3709         return 0;
3710 }
3711 
3712 /** extract all partitions from the firmware file */
3713 static int extract_firmware(const char *input, const char *output_directory)
3714 {
3715         struct flash_partition_entry entries[16] = { 0 };
3716         size_t max_entries = 16;
3717         size_t firmware_offset = 0x1014;
3718         FILE *input_file;
3719 
3720         struct stat statbuf;
3721 
3722         /* check input file */
3723         if (stat(input, &statbuf)) {
3724                 error(1, errno, "Can not read input firmware %s", input);
3725         }
3726 
3727         /* check if output directory exists */
3728         if (stat(output_directory, &statbuf)) {
3729                 error(1, errno, "Failed to stat output directory %s", output_directory);
3730         }
3731 
3732         if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
3733                 error(1, errno, "Given output directory is not a directory %s", output_directory);
3734         }
3735 
3736         input_file = fopen(input, "rb");
3737 
3738         if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) {
3739                 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3740         }
3741 
3742         for (size_t i = 0; i < max_entries; i++) {
3743                 if (entries[i].name == NULL &&
3744                                 entries[i].base == 0 &&
3745                                 entries[i].size == 0)
3746                         continue;
3747 
3748                 extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory);
3749         }
3750 
3751         return 0;
3752 }
3753 
3754 static struct flash_partition_entry *find_partition(
3755                 struct flash_partition_entry *entries, size_t max_entries,
3756                 const char *name, const char *error_msg)
3757 {
3758         for (size_t i = 0; i < max_entries; i++, entries++) {
3759                 if (strcmp(entries->name, name) == 0)
3760                         return entries;
3761         }
3762 
3763         if (error_msg) {
3764                 error(1, 0, "%s", error_msg);
3765         }
3766 
3767         return NULL;
3768 }
3769 
3770 static int firmware_info(const char *input)
3771 {
3772         struct flash_partition_entry pointers[MAX_PARTITIONS] = { };
3773         struct flash_partition_entry *e;
3774         FILE *fp;
3775         int i;
3776 
3777         fp = fopen(input, "r");
3778 
3779         if (read_partition_table(fp, 0x1014, pointers, MAX_PARTITIONS, 0)) {
3780                 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3781         }
3782 
3783         printf("Firmware image partitions:\n");
3784         printf("%-8s %-8s %s\n", "base", "size", "name");
3785         for (i = 0; i < MAX_PARTITIONS; i++) {
3786                 e = &pointers[i];
3787 
3788                 if (!e->name && !e->base && !e->size)
3789                         continue;
3790 
3791                 printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : "");
3792         }
3793 
3794         e = find_partition(pointers, MAX_PARTITIONS, "soft-version", NULL);
3795         if (e) {
3796                 size_t data_len = e->size - sizeof(struct meta_header);
3797                 char *buf = malloc(data_len);
3798                 struct soft_version *s;
3799                 bool isstr;
3800                 int i;
3801 
3802                 if (!buf)
3803                         error(1, errno, "Failed to alloc buffer");
3804 
3805                 if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET))
3806                         error(1, errno, "Can not seek in the firmware");
3807 
3808                 if (fread(buf, data_len, 1, fp) != 1)
3809                         error(1, errno, "Can not read fwup-ptn data from the firmware");
3810 
3811                 /* Check for string ignoring padding character */
3812                 isstr = true;
3813                 for (i = 0; i < data_len - 1; i++) {
3814                         if (!isascii(buf[i])) {
3815                                 isstr = false;
3816                                 break;
3817                         }
3818                 }
3819 
3820                 printf("\n[Software version]\n");
3821                 if (isstr) {
3822                         fwrite(buf, data_len, 1, stdout);
3823                         putchar('\n');
3824                 } else if (data_len >= offsetof(struct soft_version, rev)) {
3825                         s = (struct soft_version *)buf;
3826 
3827                         printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch);
3828                         printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day);
3829                         printf("Revision: %d\n", ntohl(s->rev));
3830                 } else {
3831                         printf("Failed to parse data\n");
3832                 }
3833 
3834                 free(buf);
3835         }
3836 
3837         e = find_partition(pointers, MAX_PARTITIONS, "support-list", NULL);
3838         if (e) {
3839                 char buf[128];
3840                 size_t length;
3841                 size_t bytes;
3842                 size_t max_length = sizeof(buf) - 1;
3843 
3844                 if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET))
3845                         error(1, errno, "Can not seek in the firmware");
3846 
3847                 printf("\n[Support list]\n");
3848                 for (length = e->size - sizeof(struct meta_header); length; length -= bytes) {
3849                         bytes = fread(buf, 1, length > max_length ? max_length: length, fp);
3850                         if (bytes <= 0)
3851                                 error(1, errno, "Can not read fwup-ptn data from the firmware");
3852 
3853                         buf[bytes] = '\0';
3854                         printf(buf);
3855                 }
3856         printf("\n");
3857         }
3858 
3859         e = find_partition(pointers, MAX_PARTITIONS, "partition-table", NULL);
3860         if (e) {
3861                 struct flash_partition_entry parts[MAX_PARTITIONS] = { };
3862 
3863                 if (read_partition_table(fp, 0x1014 + e->base + 4, parts, MAX_PARTITIONS, 1)) {
3864                         error(1, 0, "Error can not read the partition table (partition)");
3865                 }
3866 
3867                 printf("\n[Partition table]\n");
3868                 printf("%-8s %-8s %s\n", "base", "size", "name");
3869                 for (i = 0; i < MAX_PARTITIONS; i++) {
3870                         e = &parts[i];
3871 
3872                         if (!e->name && !e->base && !e->size)
3873                                 continue;
3874 
3875                         printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : "");
3876                 }
3877         }
3878 
3879         fclose(fp);
3880 
3881         return 0;
3882 }
3883 
3884 static void write_ff(FILE *output_file, size_t size)
3885 {
3886         char buf[4096];
3887         size_t offset;
3888 
3889         memset(buf, 0xff, sizeof(buf));
3890 
3891         for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
3892                 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
3893                         error(1, errno, "Can not write 0xff to output_file");
3894         }
3895 
3896         /* write last chunk smaller than buffer */
3897         if (offset < size) {
3898                 offset = size - offset;
3899                 if (fwrite(buf, offset, 1, output_file) != 1)
3900                         error(1, errno, "Can not write partition to output_file");
3901         }
3902 }
3903 
3904 static void convert_firmware(const char *input, const char *output)
3905 {
3906         struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 };
3907         struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 };
3908         struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL;
3909         struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL;
3910         struct flash_partition_entry *fwup_partition_table = NULL;
3911         size_t firmware_offset = 0x1014;
3912         FILE *input_file, *output_file;
3913 
3914         struct stat statbuf;
3915 
3916         /* check input file */
3917         if (stat(input, &statbuf)) {
3918                 error(1, errno, "Can not read input firmware %s", input);
3919         }
3920 
3921         input_file = fopen(input, "rb");
3922         if (!input_file)
3923                 error(1, 0, "Can not open input firmware %s", input);
3924 
3925         output_file = fopen(output, "wb");
3926         if (!output_file)
3927                 error(1, 0, "Can not open output firmware %s", output);
3928 
3929         if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) {
3930                 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3931         }
3932 
3933         fwup_os_image = find_partition(fwup, MAX_PARTITIONS,
3934                         "os-image", "Error can not find os-image partition (fwup)");
3935         fwup_file_system = find_partition(fwup, MAX_PARTITIONS,
3936                         "file-system", "Error can not find file-system partition (fwup)");
3937         fwup_partition_table = find_partition(fwup, MAX_PARTITIONS,
3938                         "partition-table", "Error can not find partition-table partition");
3939 
3940         /* the flash partition table has a 0x00000004 magic haeder */
3941         if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0)
3942                 error(1, 0, "Error can not read the partition table (flash)");
3943 
3944         flash_os_image = find_partition(flash, MAX_PARTITIONS,
3945                         "os-image", "Error can not find os-image partition (flash)");
3946         flash_file_system = find_partition(flash, MAX_PARTITIONS,
3947                         "file-system", "Error can not find file-system partition (flash)");
3948 
3949         /* write os_image to 0x0 */
3950         write_partition(input_file, firmware_offset, fwup_os_image, output_file);
3951         write_ff(output_file, flash_os_image->size - fwup_os_image->size);
3952 
3953         /* write file-system behind os_image */
3954         fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
3955         write_partition(input_file, firmware_offset, fwup_file_system, output_file);
3956         write_ff(output_file, flash_file_system->size - fwup_file_system->size);
3957 
3958         fclose(output_file);
3959         fclose(input_file);
3960 }
3961 
3962 int main(int argc, char *argv[]) {
3963         const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
3964         const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
3965         bool add_jffs2_eof = false, sysupgrade = false;
3966         unsigned rev = 0;
3967         struct device_info *info;
3968         set_source_date_epoch();
3969 
3970         while (true) {
3971                 int c;
3972 
3973                 c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:");
3974                 if (c == -1)
3975                         break;
3976 
3977                 switch (c) {
3978                 case 'i':
3979                         info_image = optarg;
3980                         break;
3981 
3982                 case 'B':
3983                         board = optarg;
3984                         break;
3985 
3986                 case 'k':
3987                         kernel_image = optarg;
3988                         break;
3989 
3990                 case 'r':
3991                         rootfs_image = optarg;
3992                         break;
3993 
3994                 case 'o':
3995                         output = optarg;
3996                         break;
3997 
3998                 case 'V':
3999                         sscanf(optarg, "r%u", &rev);
4000                         break;
4001 
4002                 case 'j':
4003                         add_jffs2_eof = true;
4004                         break;
4005 
4006                 case 'S':
4007                         sysupgrade = true;
4008                         break;
4009 
4010                 case 'h':
4011                         usage(argv[0]);
4012                         return 0;
4013 
4014                 case 'd':
4015                         output_directory = optarg;
4016                         break;
4017 
4018                 case 'x':
4019                         extract_image = optarg;
4020                         break;
4021 
4022                 case 'z':
4023                         convert_image = optarg;
4024                         break;
4025 
4026                 default:
4027                         usage(argv[0]);
4028                         return 1;
4029                 }
4030         }
4031 
4032         if (info_image) {
4033                 firmware_info(info_image);
4034         } else if (extract_image || output_directory) {
4035                 if (!extract_image)
4036                         error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
4037                 if (!output_directory)
4038                         error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
4039                 extract_firmware(extract_image, output_directory);
4040         } else if (convert_image) {
4041                 if (!output)
4042                         error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
4043                 convert_firmware(convert_image, output);
4044         } else {
4045                 if (!board)
4046                         error(1, 0, "no board has been specified");
4047                 if (!kernel_image)
4048                         error(1, 0, "no kernel image has been specified");
4049                 if (!rootfs_image)
4050                         error(1, 0, "no rootfs image has been specified");
4051                 if (!output)
4052                         error(1, 0, "no output filename has been specified");
4053 
4054                 info = find_board(board);
4055 
4056                 if (info == NULL)
4057                         error(1, 0, "unsupported board %s", board);
4058 
4059                 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
4060         }
4061 
4062         return 0;
4063 }
4064 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt