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