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