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