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