pc1crypt: make decrypt/encrypt functions take void * as argument
[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 A6,product_ver:2.0.0,special_id:52550000}\r\n"
1223 "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n"
1224 "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n"
1225 "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n",
1226 .part_trail = 0x00,
1227 .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"),
1228
1229 .partitions = {
1230 {"fs-uboot", 0x00000, 0x20000},
1231 {"default-mac", 0x20000, 0x00200},
1232 {"pin", 0x20200, 0x00100},
1233 {"product-info", 0x20300, 0x00200},
1234 {"device-id", 0x20500, 0x0fb00},
1235 {"firmware", 0x30000, 0x7a9400},
1236 {"soft-version", 0x7d9400, 0x00100},
1237 {"extra-para", 0x7d9500, 0x00100},
1238 {"support-list", 0x7d9600, 0x00200},
1239 {"profile", 0x7d9800, 0x03000},
1240 {"default-config", 0x7dc800, 0x03000},
1241 {"partition-table", 0x7df800, 0x00800},
1242 {"user-config", 0x7e0000, 0x0c000},
1243 {"certificate", 0x7ec000, 0x04000},
1244 {"radio", 0x7f0000, 0x10000},
1245 {NULL, 0, 0}
1246 },
1247
1248 .first_sysupgrade_partition = "os-image",
1249 .last_sysupgrade_partition = "file-system",
1250 },
1251
1252 /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */
1253 {
1254 .id = "ARCHER-C6-V2-US",
1255 .vendor = "",
1256 .support_list =
1257 "SupportList:\n"
1258 "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n"
1259 "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n"
1260 "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n",
1261 .part_trail = 0x00,
1262 .soft_ver = SOFT_VER_TEXT("soft_ver:1.9.1\n"),
1263
1264 .partitions = {
1265 {"factory-boot", 0x00000, 0x20000},
1266 {"default-mac", 0x20000, 0x00200},
1267 {"pin", 0x20200, 0x00100},
1268 {"product-info", 0x20300, 0x00200},
1269 {"device-id", 0x20500, 0x0fb00},
1270 {"fs-uboot", 0x30000, 0x20000},
1271 {"firmware", 0x50000, 0xf89400},
1272 {"soft-version", 0xfd9400, 0x00100},
1273 {"extra-para", 0xfd9500, 0x00100},
1274 {"support-list", 0xfd9600, 0x00200},
1275 {"profile", 0xfd9800, 0x03000},
1276 {"default-config", 0xfdc800, 0x03000},
1277 {"partition-table", 0xfdf800, 0x00800},
1278 {"user-config", 0xfe0000, 0x0c000},
1279 {"certificate", 0xfec000, 0x04000},
1280 {"radio", 0xff0000, 0x10000},
1281 {NULL, 0, 0}
1282 },
1283 .first_sysupgrade_partition = "os-image",
1284 .last_sysupgrade_partition = "file-system",
1285 },
1286 /** Firmware layout for the Archer C6 v3 */
1287 {
1288 .id = "ARCHER-C6-V3",
1289 .vendor = "",
1290 .support_list =
1291 "SupportList:\n"
1292 "{product_name:Archer C6,product_ver:3.20,special_id:55530000}"
1293 "{product_name:Archer C6,product_ver:3.20,special_id:45550000}"
1294 "{product_name:Archer C6,product_ver:3.20,special_id:52550000}"
1295 "{product_name:Archer C6,product_ver:3.20,special_id:4A500000}"
1296 "{product_name:Archer C6,product_ver:3.20,special_id:4B520000}"
1297 "{product_name:Archer C6,product_ver:3.0.0,special_id:42520000}",
1298 .part_trail = 0x00,
1299 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.9\n"),
1300
1301 .partitions = {
1302 {"fs-uboot", 0x00000, 0x40000},
1303 {"firmware", 0x40000, 0xf60000},
1304 {"default-mac", 0xfa0000, 0x00200},
1305 {"pin", 0xfa0200, 0x00100},
1306 {"device-id", 0xfa0300, 0x00100},
1307 {"product-info", 0xfa0400, 0x0fc00},
1308 {"default-config", 0xfb0000, 0x08000},
1309 {"ap-def-config", 0xfb8000, 0x08000},
1310 {"user-config", 0xfc0000, 0x0a000},
1311 {"ag-config", 0xfca000, 0x04000},
1312 {"certificate", 0xfce000, 0x02000},
1313 {"ap-config", 0xfd0000, 0x06000},
1314 {"router-config", 0xfd6000, 0x06000},
1315 {"favicon", 0xfdc000, 0x02000},
1316 {"logo", 0xfde000, 0x02000},
1317 {"partition-table", 0xfe0000, 0x00800},
1318 {"soft-version", 0xfe0800, 0x00100},
1319 {"support-list", 0xfe0900, 0x00200},
1320 {"profile", 0xfe0b00, 0x03000},
1321 {"extra-para", 0xfe3b00, 0x00100},
1322 {"radio", 0xff0000, 0x10000},
1323 {NULL, 0, 0}
1324 },
1325 .first_sysupgrade_partition = "os-image",
1326 .last_sysupgrade_partition = "file-system",
1327 },
1328 /** Firmware layout for the Archer A6 v3 */
1329 {
1330 .id = "ARCHER-A6-V3",
1331 .vendor = "",
1332 .support_list =
1333 "SupportList:\n"
1334 "{product_name:Archer A6,product_ver:3.0.0,special_id:43410000}\n"
1335 "{product_name:Archer A6,product_ver:3.0.0,special_id:55530000}\n"
1336 "{product_name:Archer A6,product_ver:3.0.0,special_id:54570000}\n"
1337 "{product_name:Archer A6,product_ver:3.0.0,special_id:4A500000}\n"
1338 "{product_name:Archer A6,product_ver:3.20,special_id:45550000}\n"
1339 "{product_name:Archer A6,product_ver:3.20,special_id:52550000}\n",
1340 .part_trail = 0x00,
1341 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.5\n"),
1342
1343 .partitions = {
1344 {"fs-uboot", 0x00000, 0x40000},
1345 {"firmware", 0x40000, 0xf60000},
1346 {"default-mac", 0xfa0000, 0x00200},
1347 {"pin", 0xfa0200, 0x00100},
1348 {"device-id", 0xfa0300, 0x00100},
1349 {"product-info", 0xfa0400, 0x0fc00},
1350 {"default-config", 0xfb0000, 0x08000},
1351 {"ap-def-config", 0xfb8000, 0x08000},
1352 {"user-config", 0xfc0000, 0x0a000},
1353 {"ag-config", 0xfca000, 0x04000},
1354 {"certificate", 0xfce000, 0x02000},
1355 {"ap-config", 0xfd0000, 0x06000},
1356 {"router-config", 0xfd6000, 0x06000},
1357 {"favicon", 0xfdc000, 0x02000},
1358 {"logo", 0xfde000, 0x02000},
1359 {"partition-table", 0xfe0000, 0x00800},
1360 {"soft-version", 0xfe0800, 0x00100},
1361 {"support-list", 0xfe0900, 0x00200},
1362 {"profile", 0xfe0b00, 0x03000},
1363 {"extra-para", 0xfe3b00, 0x00100},
1364 {"radio", 0xff0000, 0x10000},
1365 {NULL, 0, 0}
1366 },
1367 .first_sysupgrade_partition = "os-image",
1368 .last_sysupgrade_partition = "file-system",
1369 },
1370 /** Firmware layout for the Archer C6U v1 */
1371 {
1372 .id = "ARCHER-C6U-V1",
1373 .vendor = "",
1374 .support_list =
1375 "SupportList:\n"
1376 "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n"
1377 "{product_name:Archer C6U,product_ver:1.0.0,special_id:52550000}\n",
1378 .part_trail = 0x00,
1379 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.2\n"),
1380
1381 .partitions = {
1382 {"fs-uboot", 0x00000, 0x40000},
1383 {"firmware", 0x40000, 0xf60000},
1384 {"default-mac", 0xfa0000, 0x00200},
1385 {"pin", 0xfa0200, 0x00100},
1386 {"device-id", 0xfa0300, 0x00100},
1387 {"product-info", 0xfa0400, 0x0fc00},
1388 {"default-config", 0xfb0000, 0x08000},
1389 {"ap-def-config", 0xfb8000, 0x08000},
1390 {"user-config", 0xfc0000, 0x0c000},
1391 {"certificate", 0xfcc000, 0x04000},
1392 {"ap-config", 0xfd0000, 0x08000},
1393 {"router-config", 0xfd8000, 0x08000},
1394 {"partition-table", 0xfe0000, 0x00800},
1395 {"soft-version", 0xfe0800, 0x00100},
1396 {"support-list", 0xfe0900, 0x00200},
1397 {"profile", 0xfe0b00, 0x03000},
1398 {"extra-para", 0xfe3b00, 0x00100},
1399 {"radio", 0xff0000, 0x10000},
1400 {NULL, 0, 0}
1401 },
1402 .first_sysupgrade_partition = "os-image",
1403 .last_sysupgrade_partition = "file-system",
1404 },
1405 /** Firmware layout for the C60v1 */
1406 {
1407 .id = "ARCHER-C60-V1",
1408 .vendor = "",
1409 .support_list =
1410 "SupportList:\r\n"
1411 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1412 "{product_name:Archer C60,product_ver:1.0.0,special_id:43410000}\r\n"
1413 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1414 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1415 .part_trail = 0x00,
1416 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1417
1418 .partitions = {
1419 {"fs-uboot", 0x00000, 0x10000},
1420 {"default-mac", 0x10000, 0x00200},
1421 {"pin", 0x10200, 0x00200},
1422 {"product-info", 0x10400, 0x00100},
1423 {"partition-table", 0x10500, 0x00800},
1424 {"soft-version", 0x11300, 0x00200},
1425 {"support-list", 0x11500, 0x00100},
1426 {"device-id", 0x11600, 0x00100},
1427 {"profile", 0x11700, 0x03900},
1428 {"default-config", 0x15000, 0x04000},
1429 {"user-config", 0x19000, 0x04000},
1430 {"firmware", 0x20000, 0x7c8000},
1431 {"certyficate", 0x7e8000, 0x08000},
1432 {"radio", 0x7f0000, 0x10000},
1433 {NULL, 0, 0}
1434 },
1435
1436 .first_sysupgrade_partition = "os-image",
1437 .last_sysupgrade_partition = "file-system",
1438 },
1439
1440 /** Firmware layout for the C60v2 */
1441 {
1442 .id = "ARCHER-C60-V2",
1443 .vendor = "",
1444 .support_list =
1445 "SupportList:\r\n"
1446 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1447 "{product_name:Archer C60,product_ver:2.0.0,special_id:43410000}\r\n"
1448 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1449 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1450 .part_trail = 0x00,
1451 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
1452
1453 .partitions = {
1454 {"factory-boot", 0x00000, 0x1fb00},
1455 {"default-mac", 0x1fb00, 0x00200},
1456 {"pin", 0x1fd00, 0x00100},
1457 {"product-info", 0x1fe00, 0x00100},
1458 {"device-id", 0x1ff00, 0x00100},
1459 {"fs-uboot", 0x20000, 0x10000},
1460 {"firmware", 0x30000, 0x7a0000},
1461 {"soft-version", 0x7d9500, 0x00100},
1462 {"support-list", 0x7d9600, 0x00100},
1463 {"extra-para", 0x7d9700, 0x00100},
1464 {"profile", 0x7d9800, 0x03000},
1465 {"default-config", 0x7dc800, 0x03000},
1466 {"partition-table", 0x7df800, 0x00800},
1467 {"user-config", 0x7e0000, 0x0c000},
1468 {"certificate", 0x7ec000, 0x04000},
1469 {"radio", 0x7f0000, 0x10000},
1470 {NULL, 0, 0}
1471 },
1472
1473 .first_sysupgrade_partition = "os-image",
1474 .last_sysupgrade_partition = "file-system",
1475 },
1476
1477 /** Firmware layout for the C60v3 */
1478 {
1479 .id = "ARCHER-C60-V3",
1480 .vendor = "",
1481 .support_list =
1482 "SupportList:\r\n"
1483 "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1484 "{product_name:Archer C60,product_ver:3.0.0,special_id:43410000}\r\n"
1485 "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1486 "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1487 .part_trail = 0x00,
1488 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.0\n"),
1489
1490 .partitions = {
1491 {"factory-boot", 0x00000, 0x1fb00},
1492 {"default-mac", 0x1fb00, 0x00200},
1493 {"pin", 0x1fd00, 0x00100},
1494 {"product-info", 0x1fe00, 0x00100},
1495 {"device-id", 0x1ff00, 0x00100},
1496 {"fs-uboot", 0x20000, 0x10000},
1497 {"firmware", 0x30000, 0x7a0000},
1498 {"soft-version", 0x7d9500, 0x00100},
1499 {"support-list", 0x7d9600, 0x00100},
1500 {"extra-para", 0x7d9700, 0x00100},
1501 {"profile", 0x7d9800, 0x03000},
1502 {"default-config", 0x7dc800, 0x03000},
1503 {"partition-table", 0x7df800, 0x00800},
1504 {"user-config", 0x7e0000, 0x0c000},
1505 {"certificate", 0x7ec000, 0x04000},
1506 {"radio", 0x7f0000, 0x10000},
1507 {NULL, 0, 0}
1508 },
1509
1510 .first_sysupgrade_partition = "os-image",
1511 .last_sysupgrade_partition = "file-system",
1512 },
1513
1514 /** Firmware layout for the C5 */
1515 {
1516 .id = "ARCHER-C5-V2",
1517 .vendor = "",
1518 .support_list =
1519 "SupportList:\r\n"
1520 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1521 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1522 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1523 .part_trail = 0x00,
1524 .soft_ver = SOFT_VER_DEFAULT,
1525
1526 .partitions = {
1527 {"fs-uboot", 0x00000, 0x40000},
1528 {"os-image", 0x40000, 0x200000},
1529 {"file-system", 0x240000, 0xc00000},
1530 {"default-mac", 0xe40000, 0x00200},
1531 {"pin", 0xe40200, 0x00200},
1532 {"product-info", 0xe40400, 0x00200},
1533 {"partition-table", 0xe50000, 0x10000},
1534 {"soft-version", 0xe60000, 0x00200},
1535 {"support-list", 0xe61000, 0x0f000},
1536 {"profile", 0xe70000, 0x10000},
1537 {"default-config", 0xe80000, 0x10000},
1538 {"user-config", 0xe90000, 0x50000},
1539 {"log", 0xee0000, 0x100000},
1540 {"radio_bk", 0xfe0000, 0x10000},
1541 {"radio", 0xff0000, 0x10000},
1542 {NULL, 0, 0}
1543 },
1544
1545 .first_sysupgrade_partition = "os-image",
1546 .last_sysupgrade_partition = "file-system"
1547 },
1548
1549 /** Firmware layout for the C7 */
1550 {
1551 .id = "ARCHER-C7-V4",
1552 .support_list =
1553 "SupportList:\n"
1554 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1555 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1556 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1557 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1558 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1559 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1560 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1561 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1562 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1563 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1564 .part_trail = 0x00,
1565 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1566
1567 /* We're using a dynamic kernel/rootfs split here */
1568 .partitions = {
1569 {"factory-boot", 0x00000, 0x20000},
1570 {"fs-uboot", 0x20000, 0x20000},
1571 {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
1572 /* Stock: name file-system base 0x160000 size 0xda0000 */
1573 {"default-mac", 0xf00000, 0x00200},
1574 {"pin", 0xf00200, 0x00200},
1575 {"device-id", 0xf00400, 0x00100},
1576 {"product-info", 0xf00500, 0x0fb00},
1577 {"soft-version", 0xf10000, 0x00100},
1578 {"extra-para", 0xf11000, 0x01000},
1579 {"support-list", 0xf12000, 0x0a000},
1580 {"profile", 0xf1c000, 0x04000},
1581 {"default-config", 0xf20000, 0x10000},
1582 {"user-config", 0xf30000, 0x40000},
1583 {"qos-db", 0xf70000, 0x40000},
1584 {"certificate", 0xfb0000, 0x10000},
1585 {"partition-table", 0xfc0000, 0x10000},
1586 {"log", 0xfd0000, 0x20000},
1587 {"radio", 0xff0000, 0x10000},
1588 {NULL, 0, 0}
1589 },
1590
1591 .first_sysupgrade_partition = "os-image",
1592 .last_sysupgrade_partition = "file-system",
1593 },
1594
1595 /** Firmware layout for the C7 v5*/
1596 {
1597 .id = "ARCHER-C7-V5",
1598 .support_list =
1599 "SupportList:\n"
1600 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1601 "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1602 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1603 "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1604 "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1605 "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1606 "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1607 "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1608
1609 .part_trail = 0x00,
1610 .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"),
1611
1612 /* We're using a dynamic kernel/rootfs split here */
1613 .partitions = {
1614 {"factory-boot", 0x00000, 0x20000},
1615 {"fs-uboot", 0x20000, 0x20000},
1616 {"partition-table", 0x40000, 0x10000},
1617 {"radio", 0x50000, 0x10000},
1618 {"default-mac", 0x60000, 0x00200},
1619 {"pin", 0x60200, 0x00200},
1620 {"device-id", 0x60400, 0x00100},
1621 {"product-info", 0x60500, 0x0fb00},
1622 {"soft-version", 0x70000, 0x01000},
1623 {"extra-para", 0x71000, 0x01000},
1624 {"support-list", 0x72000, 0x0a000},
1625 {"profile", 0x7c000, 0x04000},
1626 {"user-config", 0x80000, 0x40000},
1627
1628
1629 {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */
1630 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1631
1632 {"log", 0xfc0000, 0x20000},
1633 {"certificate", 0xfe0000, 0x10000},
1634 {"default-config", 0xff0000, 0x10000},
1635 {NULL, 0, 0}
1636
1637 },
1638
1639 .first_sysupgrade_partition = "os-image",
1640 .last_sysupgrade_partition = "file-system",
1641 },
1642
1643 /** Firmware layout for the C9 */
1644 {
1645 .id = "ARCHERC9",
1646 .vendor = "",
1647 .support_list =
1648 "SupportList:\n"
1649 "{product_name:ArcherC9,"
1650 "product_ver:1.0.0,"
1651 "special_id:00000000}\n",
1652 .part_trail = 0x00,
1653 .soft_ver = SOFT_VER_DEFAULT,
1654
1655 .partitions = {
1656 {"fs-uboot", 0x00000, 0x40000},
1657 {"os-image", 0x40000, 0x200000},
1658 {"file-system", 0x240000, 0xc00000},
1659 {"default-mac", 0xe40000, 0x00200},
1660 {"pin", 0xe40200, 0x00200},
1661 {"product-info", 0xe40400, 0x00200},
1662 {"partition-table", 0xe50000, 0x10000},
1663 {"soft-version", 0xe60000, 0x00200},
1664 {"support-list", 0xe61000, 0x0f000},
1665 {"profile", 0xe70000, 0x10000},
1666 {"default-config", 0xe80000, 0x10000},
1667 {"user-config", 0xe90000, 0x50000},
1668 {"log", 0xee0000, 0x100000},
1669 {"radio_bk", 0xfe0000, 0x10000},
1670 {"radio", 0xff0000, 0x10000},
1671 {NULL, 0, 0}
1672 },
1673
1674 .first_sysupgrade_partition = "os-image",
1675 .last_sysupgrade_partition = "file-system"
1676 },
1677
1678 /** Firmware layout for the Deco M4R v1 and v2 */
1679 {
1680 .id = "DECO-M4R-V1",
1681 .vendor = "",
1682 .support_list =
1683 "SupportList:\n"
1684 "{product_name:M4R,product_ver:1.0.0,special_id:55530000}\n"
1685 "{product_name:M4R,product_ver:1.0.0,special_id:45550000}\n"
1686 "{product_name:M4R,product_ver:1.0.0,special_id:43410000}\n"
1687 "{product_name:M4R,product_ver:1.0.0,special_id:4A500000}\n"
1688 "{product_name:M4R,product_ver:1.0.0,special_id:41550000}\n"
1689 "{product_name:M4R,product_ver:1.0.0,special_id:4B520000}\n"
1690 "{product_name:M4R,product_ver:1.0.0,special_id:49440000}\n"
1691 "{product_name:M4R,product_ver:2.0.0,special_id:55530000}\n"
1692 "{product_name:M4R,product_ver:2.0.0,special_id:45550000}\n"
1693 "{product_name:M4R,product_ver:2.0.0,special_id:43410000}\n"
1694 "{product_name:M4R,product_ver:2.0.0,special_id:4A500000}\n"
1695 "{product_name:M4R,product_ver:2.0.0,special_id:41550000}\n"
1696 "{product_name:M4R,product_ver:2.0.0,special_id:4B520000}\n"
1697 "{product_name:M4R,product_ver:2.0.0,special_id:54570000}\n"
1698 "{product_name:M4R,product_ver:2.0.0,special_id:42340000}\n"
1699 "{product_name:M4R,product_ver:2.0.0,special_id:49440000}\n",
1700 .part_trail = 0x00,
1701 .soft_ver = SOFT_VER_DEFAULT,
1702
1703 .partitions = {
1704 {"fs-uboot", 0x00000, 0x80000},
1705 {"firmware", 0x80000, 0xe00000},
1706 {"product-info", 0xe80000, 0x05000},
1707 {"default-mac", 0xe85000, 0x01000},
1708 {"device-id", 0xe86000, 0x01000},
1709 {"support-list", 0xe87000, 0x10000},
1710 {"user-config", 0xea7000, 0x10000},
1711 {"device-config", 0xeb7000, 0x10000},
1712 {"group-info", 0xec7000, 0x10000},
1713 {"partition-table", 0xed7000, 0x02000},
1714 {"soft-version", 0xed9000, 0x10000},
1715 {"profile", 0xee9000, 0x10000},
1716 {"default-config", 0xef9000, 0x10000},
1717 {"url-sig", 0xfe0000, 0x10000},
1718 {"radio", 0xff0000, 0x10000},
1719 {NULL, 0, 0}
1720 },
1721 .first_sysupgrade_partition = "os-image",
1722 .last_sysupgrade_partition = "file-system",
1723 },
1724
1725 /** Firmware layout for the Deco M4R v4 */
1726 {
1727 .id = "DECO-M4R-V4",
1728 .vendor = "",
1729 .support_list =
1730 "SupportList:\n"
1731 "{product_name:M4R,product_ver:4.0.0,special_id:55530000}\n"
1732 "{product_name:M4R,product_ver:4.0.0,special_id:45550000}\n"
1733 "{product_name:M4R,product_ver:4.0.0,special_id:4A500000}\n"
1734 "{product_name:M4R,product_ver:4.0.0,special_id:42340000}\n"
1735 "{product_name:M4R,product_ver:4.0.0,special_id:5A470000}\n",
1736 .part_trail = 0x00,
1737 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1738
1739 .partitions = {
1740 {"fs-uboot", 0x00000, 0x40000},
1741 {"firmware", 0x40000, 0xf60000},
1742 {"default-mac", 0xfa0000, 0x00300},
1743 {"device-id", 0xfa0300, 0x00100},
1744 {"product-info", 0xfa0400, 0x0fc00},
1745 {"group-info", 0xfb0000, 0x04000},
1746 {"user-config", 0xfb4000, 0x0c000},
1747 {"device-config", 0xfc0000, 0x10000},
1748 {"default-config", 0xfd0000, 0x10000},
1749 {"partition-table", 0xfe0000, 0x00800},
1750 {"soft-version", 0xfe0800, 0x00100},
1751 {"support-list", 0xfe0900, 0x00200},
1752 {"profile", 0xfe0b00, 0x03000},
1753 {"extra-para", 0xfe3b00, 0x00100},
1754 {"radio", 0xff0000, 0x10000},
1755 {NULL, 0, 0}
1756 },
1757 .first_sysupgrade_partition = "os-image",
1758 .last_sysupgrade_partition = "file-system",
1759 },
1760
1761 /** Firmware layout for the Deco M5 */
1762 {
1763 .id = "DECO-M5",
1764 .vendor = "",
1765 .support_list =
1766 "SupportList:\n"
1767 "{product_name:M5,product_ver:1.0.0,special_id:55530000}\n"
1768 "{product_name:M5,product_ver:1.0.0,special_id:45550000}\n"
1769 "{product_name:M5,product_ver:1.0.0,special_id:43410000}\n"
1770 "{product_name:M5,product_ver:1.0.0,special_id:4A500000}\n"
1771 "{product_name:M5,product_ver:1.0.0,special_id:41550000}\n"
1772 "{product_name:M5,product_ver:1.0.0,special_id:4B520000}\n"
1773 "{product_name:M5,product_ver:1.0.0,special_id:49440000}\n"
1774 "{product_name:M5,product_ver:3.0.0,special_id:55530000}\n"
1775 "{product_name:M5,product_ver:3.0.0,special_id:45550000}\n"
1776 "{product_name:M5,product_ver:3.0.0,special_id:43410000}\n"
1777 "{product_name:M5,product_ver:3.0.0,special_id:4A500000}\n"
1778 "{product_name:M5,product_ver:3.0.0,special_id:41550000}\n"
1779 "{product_name:M5,product_ver:3.0.0,special_id:4B520000}\n"
1780 "{product_name:M5,product_ver:3.0.0,special_id:49440000}\n"
1781 "{product_name:M5,product_ver:3.0.0,special_id:53570000}\n"
1782 "{product_name:M5,product_ver:3.0.0,special_id:42340000}\n"
1783 "{product_name:M5,product_ver:3.0.0,special_id:54570000}\n"
1784 "{product_name:M5,product_ver:3.2.0,special_id:55530000}\n"
1785 "{product_name:M5,product_ver:3.2.0,special_id:45550000}\n"
1786 "{product_name:M5,product_ver:3.2.0,special_id:43410000}\n"
1787 "{product_name:M5,product_ver:3.2.0,special_id:4A500000}\n"
1788 "{product_name:M5,product_ver:3.2.0,special_id:41550000}\n"
1789 "{product_name:M5,product_ver:3.2.0,special_id:4B520000}\n"
1790 "{product_name:M5,product_ver:3.2.0,special_id:49440000}\n"
1791 "{product_name:M5,product_ver:3.2.0,special_id:53570000}\n"
1792 "{product_name:M5,product_ver:3.2.0,special_id:42340000}\n"
1793 "{product_name:M5,product_ver:3.2.0,special_id:54570000}\n",
1794 .part_trail = 0x00,
1795 .soft_ver = SOFT_VER_DEFAULT,
1796
1797 .partitions = {
1798 {"SBL1", 0x00000, 0x30000},
1799 {"boot-config_0", 0x30000, 0x10000},
1800 {"MIBIB", 0x40000, 0x10000},
1801 {"boot-config_1", 0x50000, 0x10000},
1802 {"QSEE", 0x60000, 0x60000},
1803 {"CDT", 0xc0000, 0x10000},
1804 {"DDRPARAMS", 0xd0000, 0x10000},
1805 {"uboot-env", 0xe0000, 0x10000},
1806 {"fs-uboot@0", 0xf0000, 0x80000},
1807 {"radio", 0x170000, 0x0fff0},
1808 {"bluetooth-XTAL", 0x17fff0, 0x00010},
1809 {"default-mac", 0x180000, 0x01000},
1810 {"device-id", 0x182000, 0x01000},
1811 {"product-info", 0x183000, 0x05000},
1812 {"support-list", 0x190000, 0x10000},
1813 {"user-config", 0x200000, 0x10000},
1814 {"device-config", 0x210000, 0x10000},
1815 {"group-info", 0x220000, 0x10000},
1816 {"partition-table@0", 0x230000, 0x02000},
1817 {"os-image@0", 0x240000, 0x300000},
1818 {"file-system@0", 0x540000, 0x790000},
1819 {"soft-version@0", 0xcd0000, 0x10000},
1820 {"profile@0", 0xce0000, 0x10000},
1821 {"default-config@0", 0xcf0000, 0x10000},
1822 {"partition-table@1", 0xd00000, 0x02000},
1823 {"fs-uboot@1", 0xd10000, 0x80000},
1824 {"os-image@1", 0xd90000, 0x400000},
1825 {"file-system@1", 0x1190000, 0xc40000},
1826 {"soft-version@1", 0x1dd0000, 0x10000},
1827 {"profile@1", 0x1de0000, 0x10000},
1828 {"default-config@1", 0x1df0000, 0x10000},
1829 {"tm-sig", 0x1e00000, 0x200000},
1830 {NULL, 0, 0}
1831 },
1832
1833 .partition_names.partition_table = "partition-table@1",
1834 .partition_names.soft_ver = "soft-version@1",
1835 .partition_names.os_image = "os-image@1",
1836 .partition_names.file_system = "file-system@1",
1837
1838 .first_sysupgrade_partition = "os-image@1",
1839 .last_sysupgrade_partition = "file-system@1"
1840 },
1841
1842 /** Firmware layout for the Deco S4 v2 */
1843 {
1844 .id = "DECO-S4-V2",
1845 .vendor = "",
1846 .support_list =
1847 "SupportList:\n"
1848 "{product_name:S4,product_ver:1.0.0,special_id:55530000}\n"
1849 "{product_name:S4,product_ver:1.0.0,special_id:45550000}\n"
1850 "{product_name:S4,product_ver:1.0.0,special_id:43410000}\n"
1851 "{product_name:S4,product_ver:1.0.0,special_id:4A500000}\n"
1852 "{product_name:S4,product_ver:1.0.0,special_id:41550000}\n"
1853 "{product_name:S4,product_ver:1.0.0,special_id:4B520000}\n"
1854 "{product_name:S4,product_ver:2.0.0,special_id:55530000}\n"
1855 "{product_name:S4,product_ver:2.0.0,special_id:45550000}\n"
1856 "{product_name:S4,product_ver:2.0.0,special_id:43410000}\n"
1857 "{product_name:S4,product_ver:2.0.0,special_id:4A500000}\n"
1858 "{product_name:S4,product_ver:2.0.0,special_id:41550000}\n"
1859 "{product_name:S4,product_ver:2.0.0,special_id:4B520000}\n",
1860 .part_trail = 0x00,
1861 .soft_ver = SOFT_VER_DEFAULT,
1862
1863 .partitions = {
1864 {"fs-uboot", 0x00000, 0x80000},
1865 {"product-info", 0x80000, 0x05000},
1866 {"default-mac", 0x85000, 0x01000},
1867 {"device-id", 0x86000, 0x01000},
1868 {"support-list", 0x87000, 0x10000},
1869 {"user-config", 0xa7000, 0x10000},
1870 {"device-config", 0xb7000, 0x10000},
1871 {"group-info", 0xc7000, 0x10000},
1872 {"partition-table", 0xd7000, 0x02000},
1873 {"soft-version", 0xd9000, 0x10000},
1874 {"profile", 0xe9000, 0x10000},
1875 {"default-config", 0xf9000, 0x10000},
1876 {"url-sig", 0x1e0000, 0x10000},
1877 {"radio", 0x1f0000, 0x10000},
1878 {"firmware", 0x200000, 0xe00000},
1879 {NULL, 0, 0}
1880 },
1881 .first_sysupgrade_partition = "os-image",
1882 .last_sysupgrade_partition = "file-system",
1883 },
1884
1885 /** Firmware layout for the EAP120 */
1886 {
1887 .id = "EAP120",
1888 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1889 .support_list =
1890 "SupportList:\r\n"
1891 "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1892 .part_trail = 0xff,
1893 .soft_ver = SOFT_VER_DEFAULT,
1894
1895 .partitions = {
1896 {"fs-uboot", 0x00000, 0x20000},
1897 {"partition-table", 0x20000, 0x02000},
1898 {"default-mac", 0x30000, 0x00020},
1899 {"support-list", 0x31000, 0x00100},
1900 {"product-info", 0x31100, 0x00100},
1901 {"soft-version", 0x32000, 0x00100},
1902 {"os-image", 0x40000, 0x180000},
1903 {"file-system", 0x1c0000, 0x600000},
1904 {"user-config", 0x7c0000, 0x10000},
1905 {"backup-config", 0x7d0000, 0x10000},
1906 {"log", 0x7e0000, 0x10000},
1907 {"radio", 0x7f0000, 0x10000},
1908 {NULL, 0, 0}
1909 },
1910
1911 .first_sysupgrade_partition = "os-image",
1912 .last_sysupgrade_partition = "file-system"
1913 },
1914
1915 /** Firmware layout for the EAP225-Outdoor v1 */
1916 {
1917 .id = "EAP225-OUTDOOR-V1",
1918 .support_list =
1919 "SupportList:\r\n"
1920 "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1921 .part_trail = PART_TRAIL_NONE,
1922 .soft_ver = SOFT_VER_DEFAULT,
1923 .soft_ver_compat_level = 2,
1924
1925 .partitions = {
1926 {"fs-uboot", 0x00000, 0x20000},
1927 {"partition-table", 0x20000, 0x02000},
1928 {"default-mac", 0x30000, 0x01000},
1929 {"support-list", 0x31000, 0x00100},
1930 {"product-info", 0x31100, 0x00400},
1931 {"soft-version", 0x32000, 0x00100},
1932 {"firmware", 0x40000, 0xd80000},
1933 {"user-config", 0xdc0000, 0x30000},
1934 {"mutil-log", 0xf30000, 0x80000},
1935 {"oops", 0xfb0000, 0x40000},
1936 {"radio", 0xff0000, 0x10000},
1937 {NULL, 0, 0}
1938 },
1939
1940 .first_sysupgrade_partition = "os-image",
1941 .last_sysupgrade_partition = "file-system"
1942 },
1943
1944 /** Firmware layout for the EAP225 v1 */
1945 {
1946 .id = "EAP225-V1",
1947 .support_list =
1948 "SupportList:\r\n"
1949 "EAP225(TP-LINK|UN|AC1200-D):1.0\r\n",
1950 .part_trail = PART_TRAIL_NONE,
1951 .soft_ver = SOFT_VER_DEFAULT,
1952
1953 .partitions = {
1954 {"fs-uboot", 0x00000, 0x20000},
1955 {"partition-table", 0x20000, 0x02000},
1956 {"default-mac", 0x30000, 0x01000},
1957 {"support-list", 0x31000, 0x00100},
1958 {"product-info", 0x31100, 0x00400},
1959 {"soft-version", 0x32000, 0x00100},
1960 {"firmware", 0x40000, 0xd80000},
1961 {"user-config", 0xdc0000, 0x30000},
1962 {"radio", 0xff0000, 0x10000},
1963 {NULL, 0, 0}
1964 },
1965
1966 .first_sysupgrade_partition = "os-image",
1967 .last_sysupgrade_partition = "file-system"
1968 },
1969
1970 /** Firmware layout for the EAP225 v3
1971 * Also compatible with:
1972 * - EAP225 v3.20
1973 * - EAP225 v4
1974 * - EAP225-Outdoor v1
1975 * - EAP225-Outdoor v3
1976 * */
1977 {
1978 .id = "EAP225-V3",
1979 .support_list =
1980 "SupportList:\r\n"
1981 "EAP225(TP-Link|UN|AC1350-D):3.0\r\n"
1982 "EAP225(TP-Link|UN|AC1350-D):3.20\r\n"
1983 "EAP225(TP-Link|UN|AC1350-D):4.0 CA\r\n"
1984 "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n"
1985 "EAP225-Outdoor(TP-Link|UN|AC1200-D):3.0 CA,JP\r\n",
1986 .part_trail = PART_TRAIL_NONE,
1987 .soft_ver = SOFT_VER_DEFAULT,
1988 .soft_ver_compat_level = 2,
1989
1990 .partitions = {
1991 {"fs-uboot", 0x00000, 0x20000},
1992 {"partition-table", 0x20000, 0x02000},
1993 {"default-mac", 0x30000, 0x01000},
1994 {"support-list", 0x31000, 0x00100},
1995 {"product-info", 0x31100, 0x00400},
1996 {"soft-version", 0x32000, 0x00100},
1997 {"firmware", 0x40000, 0xd80000},
1998 {"user-config", 0xdc0000, 0x30000},
1999 {"mutil-log", 0xf30000, 0x80000},
2000 {"oops", 0xfb0000, 0x40000},
2001 {"radio", 0xff0000, 0x10000},
2002 {NULL, 0, 0}
2003 },
2004
2005 .first_sysupgrade_partition = "os-image",
2006 .last_sysupgrade_partition = "file-system"
2007 },
2008
2009 /** Firmware layout for the EAP225-Wall v2 */
2010 {
2011 .id = "EAP225-WALL-V2",
2012 .support_list =
2013 "SupportList:\r\n"
2014 "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
2015 .part_trail = PART_TRAIL_NONE,
2016 .soft_ver = SOFT_VER_DEFAULT,
2017 .soft_ver_compat_level = 1,
2018
2019 .partitions = {
2020 {"fs-uboot", 0x00000, 0x20000},
2021 {"partition-table", 0x20000, 0x02000},
2022 {"default-mac", 0x30000, 0x01000},
2023 {"support-list", 0x31000, 0x00100},
2024 {"product-info", 0x31100, 0x00400},
2025 {"soft-version", 0x32000, 0x00100},
2026 {"firmware", 0x40000, 0xd80000},
2027 {"user-config", 0xdc0000, 0x30000},
2028 {"mutil-log", 0xf30000, 0x80000},
2029 {"oops", 0xfb0000, 0x40000},
2030 {"radio", 0xff0000, 0x10000},
2031 {NULL, 0, 0}
2032 },
2033
2034 .first_sysupgrade_partition = "os-image",
2035 .last_sysupgrade_partition = "file-system"
2036 },
2037
2038 /** Firmware layout for the EAP235-Wall v1 */
2039 {
2040 .id = "EAP235-WALL-V1",
2041 .support_list =
2042 "SupportList:\r\n"
2043 "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
2044 .part_trail = PART_TRAIL_NONE,
2045 .soft_ver = SOFT_VER_NUMERIC(3, 0, 0),
2046 .soft_ver_compat_level = 1,
2047
2048 .partitions = {
2049 {"fs-uboot", 0x00000, 0x80000},
2050 {"partition-table", 0x80000, 0x02000},
2051 {"default-mac", 0x90000, 0x01000},
2052 {"support-list", 0x91000, 0x00100},
2053 {"product-info", 0x91100, 0x00400},
2054 {"soft-version", 0x92000, 0x00100},
2055 {"firmware", 0xa0000, 0xd20000},
2056 {"user-config", 0xdc0000, 0x30000},
2057 {"mutil-log", 0xf30000, 0x80000},
2058 {"oops", 0xfb0000, 0x40000},
2059 {"radio", 0xff0000, 0x10000},
2060 {NULL, 0, 0}
2061 },
2062
2063 .first_sysupgrade_partition = "os-image",
2064 .last_sysupgrade_partition = "file-system"
2065 },
2066
2067 /** Firmware layout for the EAP245 v1 */
2068 {
2069 .id = "EAP245-V1",
2070 .support_list =
2071 "SupportList:\r\n"
2072 "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
2073 .part_trail = PART_TRAIL_NONE,
2074 .soft_ver = SOFT_VER_DEFAULT,
2075
2076 .partitions = {
2077 {"fs-uboot", 0x00000, 0x20000},
2078 {"partition-table", 0x20000, 0x02000},
2079 {"default-mac", 0x30000, 0x01000},
2080 {"support-list", 0x31000, 0x00100},
2081 {"product-info", 0x31100, 0x00400},
2082 {"soft-version", 0x32000, 0x00100},
2083 {"firmware", 0x40000, 0xd80000},
2084 {"user-config", 0xdc0000, 0x30000},
2085 {"radio", 0xff0000, 0x10000},
2086 {NULL, 0, 0}
2087 },
2088
2089 .first_sysupgrade_partition = "os-image",
2090 .last_sysupgrade_partition = "file-system"
2091 },
2092
2093 /** Firmware layout for the EAP245 v3 */
2094 {
2095 .id = "EAP245-V3",
2096 .support_list =
2097 "SupportList:\r\n"
2098 "EAP245(TP-Link|UN|AC1750-D):3.0\r\n"
2099 "EAP265 HD(TP-Link|UN|AC1750-D):1.0",
2100 .part_trail = PART_TRAIL_NONE,
2101 .soft_ver = SOFT_VER_DEFAULT,
2102 .soft_ver_compat_level = 1,
2103
2104 /** Firmware partition with dynamic kernel/rootfs split */
2105 .partitions = {
2106 {"factroy-boot", 0x00000, 0x40000},
2107 {"fs-uboot", 0x40000, 0x40000},
2108 {"partition-table", 0x80000, 0x10000},
2109 {"default-mac", 0x90000, 0x01000},
2110 {"support-list", 0x91000, 0x00100},
2111 {"product-info", 0x91100, 0x00400},
2112 {"soft-version", 0x92000, 0x00100},
2113 {"radio", 0xa0000, 0x10000},
2114 {"extra-para", 0xb0000, 0x10000},
2115 {"firmware", 0xc0000, 0xe40000},
2116 {"config", 0xf00000, 0x30000},
2117 {"mutil-log", 0xf30000, 0x80000},
2118 {"oops", 0xfb0000, 0x40000},
2119 {NULL, 0, 0}
2120 },
2121
2122 .first_sysupgrade_partition = "os-image",
2123 .last_sysupgrade_partition = "file-system"
2124 },
2125
2126 /** Firmware layout for the EAP610 v3/EAP613 v1 */
2127 {
2128 .id = "EAP610-V3",
2129 .soft_ver = SOFT_VER_DEFAULT,
2130 .soft_ver_compat_level = 1,
2131 .support_list =
2132 "SupportList:\r\n"
2133 "EAP610(TP-Link|UN|AX1800-D):3.0\r\n"
2134 "EAP610(TP-Link|JP|AX1800-D):3.0\r\n"
2135 "EAP610(TP-Link|EG|AX1800-D):3.0\r\n"
2136 "EAP610(TP-Link|CA|AX1800-D):3.0\r\n"
2137 "EAP613(TP-Link|UN|AX1800-D):1.0 JP\r\n",
2138 .part_trail = PART_TRAIL_NONE,
2139
2140 .partitions = {
2141 {"fs-uboot", 0x00000, 0x80000},
2142 {"partition-table", 0x80000, 0x02000},
2143 {"default-mac", 0x90000, 0x01000},
2144 {"support-list", 0x91000, 0x00100},
2145 {"product-info", 0x91100, 0x00400},
2146 {"soft-version", 0x92000, 0x00100},
2147 {"firmware", 0xa0000, 0xcf0000},
2148 {"user-config", 0xd90000, 0x60000},
2149 {"mutil-log", 0xf30000, 0x80000},
2150 {"oops", 0xfb0000, 0x40000},
2151 {"radio", 0xff0000, 0x10000},
2152 {NULL, 0, 0}
2153 },
2154
2155 .first_sysupgrade_partition = "os-image",
2156 .last_sysupgrade_partition = "file-system"
2157 },
2158
2159 /** Firmware layout for the EAP615-Wall v1 */
2160 {
2161 .id = "EAP615-WALL-V1",
2162 .soft_ver = SOFT_VER_DEFAULT,
2163 .soft_ver_compat_level = 2,
2164 .support_list =
2165 "SupportList:\r\n"
2166 "EAP615-Wall(TP-Link|UN|AX1800-D):1.0\r\n"
2167 "EAP615-Wall(TP-Link|CA|AX1800-D):1.0\r\n"
2168 "EAP615-Wall(TP-Link|JP|AX1800-D):1.0\r\n",
2169 .part_trail = PART_TRAIL_NONE,
2170
2171 .partitions = {
2172 {"fs-uboot", 0x00000, 0x80000},
2173 {"partition-table", 0x80000, 0x02000},
2174 {"default-mac", 0x90000, 0x01000},
2175 {"support-list", 0x91000, 0x00100},
2176 {"product-info", 0x91100, 0x00400},
2177 {"soft-version", 0x92000, 0x00100},
2178 {"firmware", 0xa0000, 0xcf0000},
2179 {"user-config", 0xd90000, 0x60000},
2180 {"mutil-log", 0xf30000, 0x80000},
2181 {"oops", 0xfb0000, 0x40000},
2182 {"radio", 0xff0000, 0x10000},
2183 {NULL, 0, 0}
2184 },
2185
2186 .first_sysupgrade_partition = "os-image",
2187 .last_sysupgrade_partition = "file-system"
2188 },
2189
2190 /** Firmware layout for the TL-WA1201 v2 */
2191 {
2192 .id = "TL-WA1201-V2",
2193 .vendor = "",
2194 .support_list =
2195 "SupportList:\n"
2196 "{product_name:TL-WA1201,product_ver:2.0.0,special_id:45550000}\n"
2197 "{product_name:TL-WA1201,product_ver:2.0.0,special_id:55530000}\n",
2198 .part_trail = 0x00,
2199 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.1 Build 20200709 rel.66244\n"),
2200
2201 .partitions = {
2202 {"fs-uboot", 0x00000, 0x20000},
2203 {"default-mac", 0x20000, 0x00200},
2204 {"pin", 0x20200, 0x00100},
2205 {"product-info", 0x20300, 0x00200},
2206 {"device-id", 0x20500, 0x0fb00},
2207 {"firmware", 0x30000, 0xce0000},
2208 {"portal-logo", 0xd10000, 0x20000},
2209 {"portal-back", 0xd30000, 0x200000},
2210 {"soft-version", 0xf30000, 0x00200},
2211 {"extra-para", 0xf30200, 0x00200},
2212 {"support-list", 0xf30400, 0x00200},
2213 {"profile", 0xf30600, 0x0fa00},
2214 {"apdef-config", 0xf40000, 0x10000},
2215 {"ap-config", 0xf50000, 0x10000},
2216 {"redef-config", 0xf60000, 0x10000},
2217 {"re-config", 0xf70000, 0x10000},
2218 {"multidef-config", 0xf80000, 0x10000},
2219 {"multi-config", 0xf90000, 0x10000},
2220 {"clientdef-config", 0xfa0000, 0x10000},
2221 {"client-config", 0xfb0000, 0x10000},
2222 {"partition-table", 0xfc0000, 0x10000},
2223 {"user-config", 0xfd0000, 0x10000},
2224 {"certificate", 0xfe0000, 0x10000},
2225 {"radio", 0xff0000, 0x10000},
2226 {NULL, 0, 0}
2227 },
2228 .first_sysupgrade_partition = "os-image",
2229 .last_sysupgrade_partition = "file-system",
2230 },
2231
2232 /** Firmware layout for the TL-WA850RE v2 */
2233 {
2234 .id = "TLWA850REV2",
2235 .vendor = "",
2236 .support_list =
2237 "SupportList:\n"
2238 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
2239 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
2240 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
2241 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
2242 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
2243 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
2244 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
2245 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
2246 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
2247 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
2248 .part_trail = 0x00,
2249 .soft_ver = SOFT_VER_DEFAULT,
2250
2251 /**
2252 576KB were moved from file-system to os-image
2253 in comparison to the stock image
2254 */
2255 .partitions = {
2256 {"fs-uboot", 0x00000, 0x20000},
2257 {"firmware", 0x20000, 0x390000},
2258 {"partition-table", 0x3b0000, 0x02000},
2259 {"default-mac", 0x3c0000, 0x00020},
2260 {"pin", 0x3c0100, 0x00020},
2261 {"product-info", 0x3c1000, 0x01000},
2262 {"soft-version", 0x3c2000, 0x00100},
2263 {"support-list", 0x3c3000, 0x01000},
2264 {"profile", 0x3c4000, 0x08000},
2265 {"user-config", 0x3d0000, 0x10000},
2266 {"default-config", 0x3e0000, 0x10000},
2267 {"radio", 0x3f0000, 0x10000},
2268 {NULL, 0, 0}
2269 },
2270
2271 .first_sysupgrade_partition = "os-image",
2272 .last_sysupgrade_partition = "file-system"
2273 },
2274
2275 /** Firmware layout for the TL-WA855RE v1 */
2276 {
2277 .id = "TLWA855REV1",
2278 .vendor = "",
2279 .support_list =
2280 "SupportList:\n"
2281 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
2282 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
2283 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
2284 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
2285 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
2286 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
2287 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
2288 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
2289 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
2290 .part_trail = 0x00,
2291 .soft_ver = SOFT_VER_DEFAULT,
2292
2293 .partitions = {
2294 {"fs-uboot", 0x00000, 0x20000},
2295 {"os-image", 0x20000, 0x150000},
2296 {"file-system", 0x170000, 0x240000},
2297 {"partition-table", 0x3b0000, 0x02000},
2298 {"default-mac", 0x3c0000, 0x00020},
2299 {"pin", 0x3c0100, 0x00020},
2300 {"product-info", 0x3c1000, 0x01000},
2301 {"soft-version", 0x3c2000, 0x00100},
2302 {"support-list", 0x3c3000, 0x01000},
2303 {"profile", 0x3c4000, 0x08000},
2304 {"user-config", 0x3d0000, 0x10000},
2305 {"default-config", 0x3e0000, 0x10000},
2306 {"radio", 0x3f0000, 0x10000},
2307 {NULL, 0, 0}
2308 },
2309
2310 .first_sysupgrade_partition = "os-image",
2311 .last_sysupgrade_partition = "file-system"
2312 },
2313
2314 /** Firmware layout for the TL-WPA8630P v2 (EU)*/
2315 {
2316 .id = "TL-WPA8630P-V2.0-EU",
2317 .vendor = "",
2318 .support_list =
2319 "SupportList:\n"
2320 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
2321 .part_trail = 0x00,
2322 .soft_ver = SOFT_VER_DEFAULT,
2323
2324 .partitions = {
2325 {"factory-uboot", 0x00000, 0x20000},
2326 {"fs-uboot", 0x20000, 0x20000},
2327 {"firmware", 0x40000, 0x5e0000},
2328 {"partition-table", 0x620000, 0x02000},
2329 {"default-mac", 0x630000, 0x00020},
2330 {"pin", 0x630100, 0x00020},
2331 {"device-id", 0x630200, 0x00030},
2332 {"product-info", 0x631100, 0x01000},
2333 {"extra-para", 0x632100, 0x01000},
2334 {"soft-version", 0x640000, 0x01000},
2335 {"support-list", 0x641000, 0x01000},
2336 {"profile", 0x642000, 0x08000},
2337 {"user-config", 0x650000, 0x10000},
2338 {"default-config", 0x660000, 0x10000},
2339 {"default-nvm", 0x670000, 0xc0000},
2340 {"default-pib", 0x730000, 0x40000},
2341 {"radio", 0x7f0000, 0x10000},
2342 {NULL, 0, 0}
2343 },
2344
2345 .first_sysupgrade_partition = "os-image",
2346 .last_sysupgrade_partition = "file-system"
2347 },
2348
2349 /** Firmware layout for the TL-WPA8630P v2 (INT)*/
2350 {
2351 .id = "TL-WPA8630P-V2-INT",
2352 .vendor = "",
2353 .support_list =
2354 "SupportList:\n"
2355 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
2356 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
2357 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
2358 .part_trail = 0x00,
2359 .soft_ver = SOFT_VER_DEFAULT,
2360
2361 .partitions = {
2362 {"factory-uboot", 0x00000, 0x20000},
2363 {"fs-uboot", 0x20000, 0x20000},
2364 {"firmware", 0x40000, 0x5e0000},
2365 {"partition-table", 0x620000, 0x02000},
2366 {"extra-para", 0x632100, 0x01000},
2367 {"soft-version", 0x640000, 0x01000},
2368 {"support-list", 0x641000, 0x01000},
2369 {"profile", 0x642000, 0x08000},
2370 {"user-config", 0x650000, 0x10000},
2371 {"default-config", 0x660000, 0x10000},
2372 {"default-nvm", 0x670000, 0xc0000},
2373 {"default-pib", 0x730000, 0x40000},
2374 {"default-mac", 0x7e0000, 0x00020},
2375 {"pin", 0x7e0100, 0x00020},
2376 {"device-id", 0x7e0200, 0x00030},
2377 {"product-info", 0x7e1100, 0x01000},
2378 {"radio", 0x7f0000, 0x10000},
2379 {NULL, 0, 0}
2380 },
2381
2382 .first_sysupgrade_partition = "os-image",
2383 .last_sysupgrade_partition = "file-system"
2384 },
2385
2386 /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
2387 {
2388 .id = "TL-WPA8630P-V2.1-EU",
2389 .vendor = "",
2390 .support_list =
2391 "SupportList:\n"
2392 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
2393 .part_trail = 0x00,
2394 .soft_ver = SOFT_VER_DEFAULT,
2395
2396 .partitions = {
2397 {"factory-uboot", 0x00000, 0x20000},
2398 {"fs-uboot", 0x20000, 0x20000},
2399 {"firmware", 0x40000, 0x5e0000},
2400 {"extra-para", 0x680000, 0x01000},
2401 {"product-info", 0x690000, 0x01000},
2402 {"partition-table", 0x6a0000, 0x02000},
2403 {"soft-version", 0x6b0000, 0x01000},
2404 {"support-list", 0x6b1000, 0x01000},
2405 {"profile", 0x6b2000, 0x08000},
2406 {"user-config", 0x6c0000, 0x10000},
2407 {"default-config", 0x6d0000, 0x10000},
2408 {"default-nvm", 0x6e0000, 0xc0000},
2409 {"default-pib", 0x7a0000, 0x40000},
2410 {"default-mac", 0x7e0000, 0x00020},
2411 {"pin", 0x7e0100, 0x00020},
2412 {"device-id", 0x7e0200, 0x00030},
2413 {"radio", 0x7f0000, 0x10000},
2414 {NULL, 0, 0}
2415 },
2416
2417 .first_sysupgrade_partition = "os-image",
2418 .last_sysupgrade_partition = "file-system"
2419 },
2420
2421 /** Firmware layout for the TL-WPA8631P v3 */
2422 {
2423 .id = "TL-WPA8631P-V3",
2424 .vendor = "",
2425 .support_list =
2426 "SupportList:\n"
2427 "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:41550000}\n"
2428 "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:45550000}\n"
2429 "{product_name:TL-WPA8631P,product_ver:3.0.0,special_id:55530000}\n"
2430 "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:41550000}\n"
2431 "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:45550000}\n"
2432 "{product_name:TL-WPA8631P,product_ver:4.0.0,special_id:55530000}\n"
2433 "{product_name:TL-WPA8635P,product_ver:3.0.0,special_id:46520000}\n",
2434 .part_trail = 0x00,
2435 .soft_ver = SOFT_VER_DEFAULT,
2436
2437 .partitions = {
2438 {"fs-uboot", 0x00000, 0x20000},
2439 {"firmware", 0x20000, 0x710000},
2440 {"partition-table", 0x730000, 0x02000},
2441 {"default-mac", 0x732000, 0x00020},
2442 {"pin", 0x732100, 0x00020},
2443 {"device-id", 0x732200, 0x00030},
2444 {"default-region", 0x732300, 0x00010},
2445 {"product-info", 0x732400, 0x00200},
2446 {"extra-para", 0x732600, 0x00200},
2447 {"soft-version", 0x732800, 0x00100},
2448 {"support-list", 0x732900, 0x00200},
2449 {"profile", 0x732b00, 0x00100},
2450 {"default-config", 0x732c00, 0x00800},
2451 {"plc-type", 0x733400, 0x00020},
2452 {"default-pib", 0x733500, 0x06000},
2453 {"user-config", 0x740000, 0x10000},
2454 {"plc-pib", 0x750000, 0x10000},
2455 {"plc-nvm", 0x760000, 0x90000},
2456 {"radio", 0x7f0000, 0x10000},
2457 {NULL, 0, 0}
2458 },
2459
2460 .first_sysupgrade_partition = "os-image",
2461 .last_sysupgrade_partition = "file-system"
2462 },
2463
2464 /** Firmware layout for the TL-WR1043 v5 */
2465 {
2466 .id = "TLWR1043NV5",
2467 .vendor = "",
2468 .support_list =
2469 "SupportList:\n"
2470 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
2471 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
2472 .part_trail = 0x00,
2473 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
2474 .partitions = {
2475 {"factory-boot", 0x00000, 0x20000},
2476 {"fs-uboot", 0x20000, 0x20000},
2477 {"firmware", 0x40000, 0xec0000},
2478 {"default-mac", 0xf00000, 0x00200},
2479 {"pin", 0xf00200, 0x00200},
2480 {"device-id", 0xf00400, 0x00100},
2481 {"product-info", 0xf00500, 0x0fb00},
2482 {"soft-version", 0xf10000, 0x01000},
2483 {"extra-para", 0xf11000, 0x01000},
2484 {"support-list", 0xf12000, 0x0a000},
2485 {"profile", 0xf1c000, 0x04000},
2486 {"default-config", 0xf20000, 0x10000},
2487 {"user-config", 0xf30000, 0x40000},
2488 {"qos-db", 0xf70000, 0x40000},
2489 {"certificate", 0xfb0000, 0x10000},
2490 {"partition-table", 0xfc0000, 0x10000},
2491 {"log", 0xfd0000, 0x20000},
2492 {"radio", 0xff0000, 0x10000},
2493 {NULL, 0, 0}
2494 },
2495 .first_sysupgrade_partition = "os-image",
2496 .last_sysupgrade_partition = "file-system"
2497 },
2498
2499 /** Firmware layout for the TL-WR1043 v4 */
2500 {
2501 .id = "TLWR1043NDV4",
2502 .vendor = "",
2503 .support_list =
2504 "SupportList:\n"
2505 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
2506 .part_trail = 0x00,
2507 .soft_ver = SOFT_VER_DEFAULT,
2508
2509 /* We're using a dynamic kernel/rootfs split here */
2510 .partitions = {
2511 {"fs-uboot", 0x00000, 0x20000},
2512 {"firmware", 0x20000, 0xf30000},
2513 {"default-mac", 0xf50000, 0x00200},
2514 {"pin", 0xf50200, 0x00200},
2515 {"product-info", 0xf50400, 0x0fc00},
2516 {"soft-version", 0xf60000, 0x0b000},
2517 {"support-list", 0xf6b000, 0x04000},
2518 {"profile", 0xf70000, 0x04000},
2519 {"default-config", 0xf74000, 0x0b000},
2520 {"user-config", 0xf80000, 0x40000},
2521 {"partition-table", 0xfc0000, 0x10000},
2522 {"log", 0xfd0000, 0x20000},
2523 {"radio", 0xff0000, 0x10000},
2524 {NULL, 0, 0}
2525 },
2526
2527 .first_sysupgrade_partition = "os-image",
2528 .last_sysupgrade_partition = "file-system"
2529 },
2530
2531 /** Firmware layout for the TL-WR902AC v1 */
2532 {
2533 .id = "TL-WR902AC-V1",
2534 .vendor = "",
2535 .support_list =
2536 "SupportList:\n"
2537 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
2538 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
2539 .part_trail = 0x00,
2540 .soft_ver = SOFT_VER_DEFAULT,
2541
2542 /**
2543 384KB were moved from file-system to os-image
2544 in comparison to the stock image
2545 */
2546 .partitions = {
2547 {"fs-uboot", 0x00000, 0x20000},
2548 {"firmware", 0x20000, 0x730000},
2549 {"default-mac", 0x750000, 0x00200},
2550 {"pin", 0x750200, 0x00200},
2551 {"product-info", 0x750400, 0x0fc00},
2552 {"soft-version", 0x760000, 0x0b000},
2553 {"support-list", 0x76b000, 0x04000},
2554 {"profile", 0x770000, 0x04000},
2555 {"default-config", 0x774000, 0x0b000},
2556 {"user-config", 0x780000, 0x40000},
2557 {"partition-table", 0x7c0000, 0x10000},
2558 {"log", 0x7d0000, 0x20000},
2559 {"radio", 0x7f0000, 0x10000},
2560 {NULL, 0, 0}
2561 },
2562
2563 .first_sysupgrade_partition = "os-image",
2564 .last_sysupgrade_partition = "file-system",
2565 },
2566
2567 /** Firmware layout for the TL-WR941HP v1 */
2568 {
2569 .id = "TL-WR941HP-V1",
2570 .vendor = "",
2571 .support_list =
2572 "SupportList:\n"
2573 "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n",
2574 .part_trail = 0x00,
2575 .soft_ver = SOFT_VER_DEFAULT,
2576
2577 .partitions = {
2578 {"fs-uboot", 0x00000, 0x20000},
2579 {"firmware", 0x20000, 0x730000},
2580 {"default-mac", 0x750000, 0x00200},
2581 {"pin", 0x750200, 0x00200},
2582 {"product-info", 0x750400, 0x0fc00},
2583 {"soft-version", 0x760000, 0x0b000},
2584 {"support-list", 0x76b000, 0x04000},
2585 {"profile", 0x770000, 0x04000},
2586 {"default-config", 0x774000, 0x0b000},
2587 {"user-config", 0x780000, 0x40000},
2588 {"partition-table", 0x7c0000, 0x10000},
2589 {"log", 0x7d0000, 0x20000},
2590 {"radio", 0x7f0000, 0x10000},
2591 {NULL, 0, 0}
2592 },
2593
2594 .first_sysupgrade_partition = "os-image",
2595 .last_sysupgrade_partition = "file-system",
2596 },
2597
2598 /** Firmware layout for the TL-WR942N V1 */
2599 {
2600 .id = "TLWR942NV1",
2601 .vendor = "",
2602 .support_list =
2603 "SupportList:\r\n"
2604 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
2605 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
2606 .part_trail = 0x00,
2607 .soft_ver = SOFT_VER_DEFAULT,
2608
2609 .partitions = {
2610 {"fs-uboot", 0x00000, 0x20000},
2611 {"firmware", 0x20000, 0xe20000},
2612 {"default-mac", 0xe40000, 0x00200},
2613 {"pin", 0xe40200, 0x00200},
2614 {"product-info", 0xe40400, 0x0fc00},
2615 {"partition-table", 0xe50000, 0x10000},
2616 {"soft-version", 0xe60000, 0x10000},
2617 {"support-list", 0xe70000, 0x10000},
2618 {"profile", 0xe80000, 0x10000},
2619 {"default-config", 0xe90000, 0x10000},
2620 {"user-config", 0xea0000, 0x40000},
2621 {"qos-db", 0xee0000, 0x40000},
2622 {"certificate", 0xf20000, 0x10000},
2623 {"usb-config", 0xfb0000, 0x10000},
2624 {"log", 0xfc0000, 0x20000},
2625 {"radio-bk", 0xfe0000, 0x10000},
2626 {"radio", 0xff0000, 0x10000},
2627 {NULL, 0, 0}
2628 },
2629
2630 .first_sysupgrade_partition = "os-image",
2631 .last_sysupgrade_partition = "file-system",
2632 },
2633
2634 /** Firmware layout for the RE200 v2 */
2635 {
2636 .id = "RE200-V2",
2637 .vendor = "",
2638 .support_list =
2639 "SupportList:\n"
2640 "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
2641 "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
2642 "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
2643 "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
2644 "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
2645 "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
2646 "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
2647 "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
2648 "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
2649 "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
2650 "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
2651 "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
2652 "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
2653 .part_trail = 0x00,
2654 .soft_ver = SOFT_VER_DEFAULT,
2655
2656 .partitions = {
2657 {"fs-uboot", 0x00000, 0x20000},
2658 {"firmware", 0x20000, 0x7a0000},
2659 {"partition-table", 0x7c0000, 0x02000},
2660 {"default-mac", 0x7c2000, 0x00020},
2661 {"pin", 0x7c2100, 0x00020},
2662 {"product-info", 0x7c3100, 0x01000},
2663 {"soft-version", 0x7c4200, 0x01000},
2664 {"support-list", 0x7c5200, 0x01000},
2665 {"profile", 0x7c6200, 0x08000},
2666 {"config-info", 0x7ce200, 0x00400},
2667 {"user-config", 0x7d0000, 0x10000},
2668 {"default-config", 0x7e0000, 0x10000},
2669 {"radio", 0x7f0000, 0x10000},
2670 {NULL, 0, 0}
2671 },
2672
2673 .first_sysupgrade_partition = "os-image",
2674 .last_sysupgrade_partition = "file-system"
2675 },
2676
2677 /** Firmware layout for the RE200 v3 */
2678 {
2679 .id = "RE200-V3",
2680 .vendor = "",
2681 .support_list =
2682 "SupportList:\n"
2683 "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
2684 "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
2685 "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
2686 "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
2687 "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
2688 "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
2689 "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
2690 "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
2691 "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
2692 "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
2693 "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
2694 "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
2695 "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
2696 "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
2697 .part_trail = 0x00,
2698 .soft_ver = SOFT_VER_DEFAULT,
2699
2700 .partitions = {
2701 {"fs-uboot", 0x00000, 0x20000},
2702 {"firmware", 0x20000, 0x7a0000},
2703 {"partition-table", 0x7c0000, 0x02000},
2704 {"default-mac", 0x7c2000, 0x00020},
2705 {"pin", 0x7c2100, 0x00020},
2706 {"product-info", 0x7c3100, 0x01000},
2707 {"soft-version", 0x7c4200, 0x01000},
2708 {"support-list", 0x7c5200, 0x01000},
2709 {"profile", 0x7c6200, 0x08000},
2710 {"config-info", 0x7ce200, 0x00400},
2711 {"user-config", 0x7d0000, 0x10000},
2712 {"default-config", 0x7e0000, 0x10000},
2713 {"radio", 0x7f0000, 0x10000},
2714 {NULL, 0, 0}
2715 },
2716
2717 .first_sysupgrade_partition = "os-image",
2718 .last_sysupgrade_partition = "file-system"
2719 },
2720
2721 /** Firmware layout for the RE200 v4 */
2722 {
2723 .id = "RE200-V4",
2724 .vendor = "",
2725 .support_list =
2726 "SupportList:\n"
2727 "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2728 "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2729 "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2730 "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2731 "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2732 "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2733 "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2734 "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2735 "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2736 "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2737 "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2738 "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2739 "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2740 "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2741 .part_trail = 0x00,
2742 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2743
2744 .partitions = {
2745 {"fs-uboot", 0x00000, 0x20000},
2746 {"firmware", 0x20000, 0x7a0000},
2747 {"partition-table", 0x7c0000, 0x02000},
2748 {"default-mac", 0x7c2000, 0x00020},
2749 {"pin", 0x7c2100, 0x00020},
2750 {"product-info", 0x7c3100, 0x01000},
2751 {"soft-version", 0x7c4200, 0x01000},
2752 {"support-list", 0x7c5200, 0x01000},
2753 {"profile", 0x7c6200, 0x08000},
2754 {"config-info", 0x7ce200, 0x00400},
2755 {"user-config", 0x7d0000, 0x10000},
2756 {"default-config", 0x7e0000, 0x10000},
2757 {"radio", 0x7f0000, 0x10000},
2758 {NULL, 0, 0}
2759 },
2760
2761 .first_sysupgrade_partition = "os-image",
2762 .last_sysupgrade_partition = "file-system"
2763 },
2764
2765 /** Firmware layout for the RE205 v3 */
2766 {
2767 .id = "RE205-V3",
2768 .vendor = "",
2769 .support_list =
2770 "SupportList:\n"
2771 "{product_name:RE205,product_ver:3.0.0,special_id:00000000}\n"
2772 "{product_name:RE205,product_ver:3.0.0,special_id:45550000}\n"
2773 "{product_name:RE205,product_ver:3.0.0,special_id:4A500000}\n"
2774 "{product_name:RE205,product_ver:3.0.0,special_id:4B520000}\n"
2775 "{product_name:RE205,product_ver:3.0.0,special_id:43410000}\n"
2776 "{product_name:RE205,product_ver:3.0.0,special_id:41550000}\n"
2777 "{product_name:RE205,product_ver:3.0.0,special_id:42520000}\n"
2778 "{product_name:RE205,product_ver:3.0.0,special_id:55530000}\n"
2779 "{product_name:RE205,product_ver:3.0.0,special_id:41520000}\n"
2780 "{product_name:RE205,product_ver:3.0.0,special_id:52550000}\n"
2781 "{product_name:RE205,product_ver:3.0.0,special_id:54570000}\n"
2782 "{product_name:RE205,product_ver:3.0.0,special_id:45530000}\n"
2783 "{product_name:RE205,product_ver:3.0.0,special_id:45470000}\n",
2784 .part_trail = 0x00,
2785 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2786
2787 .partitions = {
2788 {"fs-uboot", 0x00000, 0x20000},
2789 {"firmware", 0x20000, 0x7a0000},
2790 {"partition-table", 0x7c0000, 0x02000},
2791 {"default-mac", 0x7c2000, 0x00020},
2792 {"pin", 0x7c2100, 0x00020},
2793 {"product-info", 0x7c3100, 0x01000},
2794 {"soft-version", 0x7c4200, 0x01000},
2795 {"support-list", 0x7c5200, 0x01000},
2796 {"profile", 0x7c6200, 0x08000},
2797 {"config-info", 0x7ce200, 0x00400},
2798 {"user-config", 0x7d0000, 0x10000},
2799 {"default-config", 0x7e0000, 0x10000},
2800 {"radio", 0x7f0000, 0x10000},
2801 {NULL, 0, 0}
2802 },
2803
2804 .first_sysupgrade_partition = "os-image",
2805 .last_sysupgrade_partition = "file-system"
2806 },
2807
2808 /** Firmware layout for the RE220 v2 */
2809 {
2810 .id = "RE220-V2",
2811 .vendor = "",
2812 .support_list =
2813 "SupportList:\n"
2814 "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2815 "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2816 "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2817 "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2818 "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2819 "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2820 "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2821 "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2822 "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2823 "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2824 "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2825 "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2826 "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2827 .part_trail = 0x00,
2828 .soft_ver = SOFT_VER_DEFAULT,
2829
2830 .partitions = {
2831 {"fs-uboot", 0x00000, 0x20000},
2832 {"firmware", 0x20000, 0x7a0000},
2833 {"partition-table", 0x7c0000, 0x02000},
2834 {"default-mac", 0x7c2000, 0x00020},
2835 {"pin", 0x7c2100, 0x00020},
2836 {"product-info", 0x7c3100, 0x01000},
2837 {"soft-version", 0x7c4200, 0x01000},
2838 {"support-list", 0x7c5200, 0x01000},
2839 {"profile", 0x7c6200, 0x08000},
2840 {"config-info", 0x7ce200, 0x00400},
2841 {"user-config", 0x7d0000, 0x10000},
2842 {"default-config", 0x7e0000, 0x10000},
2843 {"radio", 0x7f0000, 0x10000},
2844 {NULL, 0, 0}
2845 },
2846
2847 .first_sysupgrade_partition = "os-image",
2848 .last_sysupgrade_partition = "file-system"
2849 },
2850
2851 /** Firmware layout for the RE305 v1 */
2852 {
2853 .id = "RE305-V1",
2854 .vendor = "",
2855 .support_list =
2856 "SupportList:\n"
2857 "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2858 "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2859 "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2860 "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2861 "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2862 "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2863 "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2864 .part_trail = 0x00,
2865 .soft_ver = SOFT_VER_DEFAULT,
2866
2867 .partitions = {
2868 {"fs-uboot", 0x00000, 0x20000},
2869 {"firmware", 0x20000, 0x5e0000},
2870 {"partition-table", 0x600000, 0x02000},
2871 {"default-mac", 0x610000, 0x00020},
2872 {"pin", 0x610100, 0x00020},
2873 {"product-info", 0x611100, 0x01000},
2874 {"soft-version", 0x620000, 0x01000},
2875 {"support-list", 0x621000, 0x01000},
2876 {"profile", 0x622000, 0x08000},
2877 {"user-config", 0x630000, 0x10000},
2878 {"default-config", 0x640000, 0x10000},
2879 {"radio", 0x7f0000, 0x10000},
2880 {NULL, 0, 0}
2881 },
2882
2883 .first_sysupgrade_partition = "os-image",
2884 .last_sysupgrade_partition = "file-system"
2885 },
2886
2887 /** Firmware layout for the RE305 v3 */
2888 {
2889 .id = "RE305-V3",
2890 .vendor = "",
2891 .support_list =
2892 "SupportList:\n"
2893 "{product_name:RE305,product_ver:3.0.0,special_id:00000000}\n"
2894 "{product_name:RE305,product_ver:3.0.0,special_id:45550000}\n"
2895 "{product_name:RE305,product_ver:3.0.0,special_id:4A500000}\n"
2896 "{product_name:RE305,product_ver:3.0.0,special_id:4B520000}\n"
2897 "{product_name:RE305,product_ver:3.0.0,special_id:41550000}\n"
2898 "{product_name:RE305,product_ver:3.0.0,special_id:42520000}\n"
2899 "{product_name:RE305,product_ver:3.0.0,special_id:55530000}\n"
2900 "{product_name:RE305,product_ver:3.0.0,special_id:45530000}\n"
2901 "{product_name:RE305,product_ver:3.0.0,special_id:41530000}\n"
2902 "{product_name:RE305,product_ver:3.0.0,special_id:43410000}\n"
2903 "{product_name:RE305,product_ver:3.0.0,special_id:52550000}\n",
2904 .part_trail = 0x00,
2905 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
2906
2907 .partitions = {
2908 {"fs-uboot", 0x00000, 0x20000},
2909 {"firmware", 0x20000, 0x7a0000},
2910 {"partition-table", 0x7c0000, 0x02000},
2911 {"default-mac", 0x7c2000, 0x00020},
2912 {"pin", 0x7c2100, 0x00020},
2913 {"product-info", 0x7c3100, 0x01000},
2914 {"soft-version", 0x7c4200, 0x01000},
2915 {"support-list", 0x7c5200, 0x01000},
2916 {"profile", 0x7c6200, 0x08000},
2917 {"config-info", 0x7ce200, 0x00400},
2918 {"user-config", 0x7d0000, 0x10000},
2919 {"default-config", 0x7e0000, 0x10000},
2920 {"radio", 0x7f0000, 0x10000},
2921 {NULL, 0, 0}
2922 },
2923
2924 .first_sysupgrade_partition = "os-image",
2925 .last_sysupgrade_partition = "file-system"
2926 },
2927
2928 /** Firmware layout for the RE350 v1 */
2929 {
2930 .id = "RE350-V1",
2931 .vendor = "",
2932 .support_list =
2933 "SupportList:\n"
2934 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2935 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2936 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2937 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2938 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2939 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2940 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2941 .part_trail = 0x00,
2942 .soft_ver = SOFT_VER_DEFAULT,
2943
2944 /** We're using a dynamic kernel/rootfs split here */
2945 .partitions = {
2946 {"fs-uboot", 0x00000, 0x20000},
2947 {"firmware", 0x20000, 0x5e0000},
2948 {"partition-table", 0x600000, 0x02000},
2949 {"default-mac", 0x610000, 0x00020},
2950 {"pin", 0x610100, 0x00020},
2951 {"product-info", 0x611100, 0x01000},
2952 {"soft-version", 0x620000, 0x01000},
2953 {"support-list", 0x621000, 0x01000},
2954 {"profile", 0x622000, 0x08000},
2955 {"user-config", 0x630000, 0x10000},
2956 {"default-config", 0x640000, 0x10000},
2957 {"radio", 0x7f0000, 0x10000},
2958 {NULL, 0, 0}
2959 },
2960
2961 .first_sysupgrade_partition = "os-image",
2962 .last_sysupgrade_partition = "file-system"
2963 },
2964
2965 /** Firmware layout for the RE350K v1 */
2966 {
2967 .id = "RE350K-V1",
2968 .vendor = "",
2969 .support_list =
2970 "SupportList:\n"
2971 "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2972 .part_trail = 0x00,
2973 .soft_ver = SOFT_VER_DEFAULT,
2974
2975 /** We're using a dynamic kernel/rootfs split here */
2976 .partitions = {
2977 {"fs-uboot", 0x00000, 0x20000},
2978 {"firmware", 0x20000, 0xd70000},
2979 {"partition-table", 0xd90000, 0x02000},
2980 {"default-mac", 0xda0000, 0x00020},
2981 {"pin", 0xda0100, 0x00020},
2982 {"product-info", 0xda1100, 0x01000},
2983 {"soft-version", 0xdb0000, 0x01000},
2984 {"support-list", 0xdb1000, 0x01000},
2985 {"profile", 0xdb2000, 0x08000},
2986 {"user-config", 0xdc0000, 0x10000},
2987 {"default-config", 0xdd0000, 0x10000},
2988 {"device-id", 0xde0000, 0x00108},
2989 {"radio", 0xff0000, 0x10000},
2990 {NULL, 0, 0}
2991 },
2992
2993 .first_sysupgrade_partition = "os-image",
2994 .last_sysupgrade_partition = "file-system"
2995 },
2996
2997 /** Firmware layout for the RE355 */
2998 {
2999 .id = "RE355",
3000 .vendor = "",
3001 .support_list =
3002 "SupportList:\r\n"
3003 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
3004 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
3005 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
3006 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
3007 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
3008 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
3009 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
3010 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
3011 .part_trail = 0x00,
3012 .soft_ver = SOFT_VER_DEFAULT,
3013
3014 /* We're using a dynamic kernel/rootfs split here */
3015 .partitions = {
3016 {"fs-uboot", 0x00000, 0x20000},
3017 {"firmware", 0x20000, 0x5e0000},
3018 {"partition-table", 0x600000, 0x02000},
3019 {"default-mac", 0x610000, 0x00020},
3020 {"pin", 0x610100, 0x00020},
3021 {"product-info", 0x611100, 0x01000},
3022 {"soft-version", 0x620000, 0x01000},
3023 {"support-list", 0x621000, 0x01000},
3024 {"profile", 0x622000, 0x08000},
3025 {"user-config", 0x630000, 0x10000},
3026 {"default-config", 0x640000, 0x10000},
3027 {"radio", 0x7f0000, 0x10000},
3028 {NULL, 0, 0}
3029 },
3030
3031 .first_sysupgrade_partition = "os-image",
3032 .last_sysupgrade_partition = "file-system"
3033 },
3034
3035 /** Firmware layout for the RE365 v1 */
3036 {
3037 .id = "RE365",
3038 .vendor = "",
3039 .support_list =
3040 "SupportList:\r\n"
3041 "{product_name:RE365,product_ver:1.0.0,special_id:45550000}\r\n"
3042 "{product_name:RE365,product_ver:1.0.0,special_id:55530000}\r\n"
3043 "{product_name:RE365,product_ver:1.0.0,special_id:4a500000}\r\n"
3044 "{product_name:RE365,product_ver:1.0.0,special_id:42520000}\r\n"
3045 "{product_name:RE365,product_ver:1.0.0,special_id:4b520000}\r\n"
3046 "{product_name:RE365,product_ver:1.0.0,special_id:41550000}\r\n"
3047 "{product_name:RE365,product_ver:1.0.0,special_id:43410000}\r\n"
3048 "{product_name:RE365,product_ver:1.0.0,special_id:54570000}\r\n"
3049 "{product_name:RE365,product_ver:1.0.0,special_id:41530000}\r\n",
3050 .part_trail = 0x00,
3051 .soft_ver = SOFT_VER_DEFAULT,
3052
3053 .partitions = {
3054 {"fs-uboot", 0x00000, 0x20000},
3055 {"firmware", 0x20000, 0x5e0000},
3056 {"partition-table", 0x600000, 0x02000},
3057 {"default-mac", 0x610000, 0x00020},
3058 {"pin", 0x610100, 0x00020},
3059 {"product-info", 0x611100, 0x01000},
3060 {"soft-version", 0x620000, 0x01000},
3061 {"support-list", 0x621000, 0x01000},
3062 {"profile", 0x622000, 0x08000},
3063 {"user-config", 0x630000, 0x10000},
3064 {"default-config", 0x640000, 0x10000},
3065 {"radio", 0x7f0000, 0x10000},
3066 {NULL, 0, 0}
3067 },
3068
3069 .first_sysupgrade_partition = "os-image",
3070 .last_sysupgrade_partition = "file-system"
3071 },
3072
3073 /** Firmware layout for the RE450 */
3074 {
3075 .id = "RE450",
3076 .vendor = "",
3077 .support_list =
3078 "SupportList:\r\n"
3079 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
3080 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
3081 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
3082 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
3083 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
3084 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
3085 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
3086 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
3087 .part_trail = 0x00,
3088 .soft_ver = SOFT_VER_DEFAULT,
3089
3090 /** We're using a dynamic kernel/rootfs split here */
3091 .partitions = {
3092 {"fs-uboot", 0x00000, 0x20000},
3093 {"firmware", 0x20000, 0x5e0000},
3094 {"partition-table", 0x600000, 0x02000},
3095 {"default-mac", 0x610000, 0x00020},
3096 {"pin", 0x610100, 0x00020},
3097 {"product-info", 0x611100, 0x01000},
3098 {"soft-version", 0x620000, 0x01000},
3099 {"support-list", 0x621000, 0x01000},
3100 {"profile", 0x622000, 0x08000},
3101 {"user-config", 0x630000, 0x10000},
3102 {"default-config", 0x640000, 0x10000},
3103 {"radio", 0x7f0000, 0x10000},
3104 {NULL, 0, 0}
3105 },
3106
3107 .first_sysupgrade_partition = "os-image",
3108 .last_sysupgrade_partition = "file-system"
3109 },
3110
3111 /** Firmware layout for the RE450 v2 */
3112 {
3113 .id = "RE450-V2",
3114 .vendor = "",
3115 .support_list =
3116 "SupportList:\r\n"
3117 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
3118 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
3119 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
3120 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
3121 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
3122 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
3123 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
3124 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
3125 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
3126 .part_trail = 0x00,
3127 .soft_ver = SOFT_VER_DEFAULT,
3128
3129 /* We're using a dynamic kernel/rootfs split here */
3130 .partitions = {
3131 {"fs-uboot", 0x00000, 0x20000},
3132 {"firmware", 0x20000, 0x5e0000},
3133 {"partition-table", 0x600000, 0x02000},
3134 {"default-mac", 0x610000, 0x00020},
3135 {"pin", 0x610100, 0x00020},
3136 {"product-info", 0x611100, 0x01000},
3137 {"soft-version", 0x620000, 0x01000},
3138 {"support-list", 0x621000, 0x01000},
3139 {"profile", 0x622000, 0x08000},
3140 {"user-config", 0x630000, 0x10000},
3141 {"default-config", 0x640000, 0x10000},
3142 {"radio", 0x7f0000, 0x10000},
3143 {NULL, 0, 0}
3144 },
3145
3146 .first_sysupgrade_partition = "os-image",
3147 .last_sysupgrade_partition = "file-system"
3148 },
3149
3150 /** Firmware layout for the RE450 v3 */
3151 {
3152 .id = "RE450-V3",
3153 .vendor = "",
3154 .support_list =
3155 "SupportList:\r\n"
3156 "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
3157 "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
3158 "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
3159 "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
3160 "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
3161 "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
3162 "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
3163 "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
3164 "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
3165 .part_trail = 0x00,
3166 .soft_ver = SOFT_VER_DEFAULT,
3167
3168 /* We're using a dynamic kernel/rootfs split here */
3169 .partitions = {
3170 {"fs-uboot", 0x00000, 0x20000},
3171 {"default-mac", 0x20000, 0x00020},
3172 {"pin", 0x20020, 0x00020},
3173 {"product-info", 0x21000, 0x01000},
3174 {"partition-table", 0x22000, 0x02000},
3175 {"soft-version", 0x24000, 0x01000},
3176 {"support-list", 0x25000, 0x01000},
3177 {"profile", 0x26000, 0x08000},
3178 {"user-config", 0x2e000, 0x10000},
3179 {"default-config", 0x3e000, 0x10000},
3180 {"config-info", 0x4e000, 0x00400},
3181 {"firmware", 0x50000, 0x7a0000},
3182 {"radio", 0x7f0000, 0x10000},
3183 {NULL, 0, 0}
3184 },
3185
3186 .first_sysupgrade_partition = "os-image",
3187 .last_sysupgrade_partition = "file-system"
3188 },
3189
3190 /** Firmware layout for the RE455 v1 */
3191 {
3192 .id = "RE455-V1",
3193 .vendor = "",
3194 .support_list =
3195 "SupportList:\r\n"
3196 "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
3197 "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
3198 "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
3199 "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
3200 "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
3201 "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
3202 "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
3203 "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
3204 "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
3205 .part_trail = 0x00,
3206 .soft_ver = SOFT_VER_DEFAULT,
3207
3208 /* We're using a dynamic kernel/rootfs split here */
3209 .partitions = {
3210 {"fs-uboot", 0x00000, 0x20000},
3211 {"default-mac", 0x20000, 0x00020},
3212 {"pin", 0x20020, 0x00020},
3213 {"product-info", 0x21000, 0x01000},
3214 {"partition-table", 0x22000, 0x02000},
3215 {"soft-version", 0x24000, 0x01000},
3216 {"support-list", 0x25000, 0x01000},
3217 {"profile", 0x26000, 0x08000},
3218 {"user-config", 0x2e000, 0x10000},
3219 {"default-config", 0x3e000, 0x10000},
3220 {"config-info", 0x4e000, 0x00400},
3221 {"firmware", 0x50000, 0x7a0000},
3222 {"radio", 0x7f0000, 0x10000},
3223 {NULL, 0, 0}
3224 },
3225
3226 .first_sysupgrade_partition = "os-image",
3227 .last_sysupgrade_partition = "file-system"
3228 },
3229
3230 /** Firmware layout for the RE500 */
3231 {
3232 .id = "RE500-V1",
3233 .vendor = "",
3234 .support_list =
3235 "SupportList:\r\n"
3236 "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
3237 "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
3238 "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
3239 "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
3240 "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
3241 "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
3242 "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
3243 .part_trail = 0x00,
3244 .soft_ver = SOFT_VER_DEFAULT,
3245
3246 /* We're using a dynamic kernel/rootfs split here */
3247 .partitions = {
3248 {"fs-uboot", 0x00000, 0x20000},
3249 {"firmware", 0x20000, 0xde0000},
3250 {"partition-table", 0xe00000, 0x02000},
3251 {"default-mac", 0xe10000, 0x00020},
3252 {"pin", 0xe10100, 0x00020},
3253 {"product-info", 0xe11100, 0x01000},
3254 {"soft-version", 0xe20000, 0x01000},
3255 {"support-list", 0xe21000, 0x01000},
3256 {"profile", 0xe22000, 0x08000},
3257 {"user-config", 0xe30000, 0x10000},
3258 {"default-config", 0xe40000, 0x10000},
3259 {"radio", 0xff0000, 0x10000},
3260 {NULL, 0, 0}
3261 },
3262
3263 .first_sysupgrade_partition = "os-image",
3264 .last_sysupgrade_partition = "file-system"
3265 },
3266
3267 /** Firmware layout for the RE650 */
3268 {
3269 .id = "RE650-V1",
3270 .vendor = "",
3271 .support_list =
3272 "SupportList:\r\n"
3273 "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
3274 "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
3275 "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
3276 "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
3277 "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
3278 "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
3279 "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
3280 .part_trail = 0x00,
3281 .soft_ver = SOFT_VER_DEFAULT,
3282
3283 /* We're using a dynamic kernel/rootfs split here */
3284 .partitions = {
3285 {"fs-uboot", 0x00000, 0x20000},
3286 {"firmware", 0x20000, 0xde0000},
3287 {"partition-table", 0xe00000, 0x02000},
3288 {"default-mac", 0xe10000, 0x00020},
3289 {"pin", 0xe10100, 0x00020},
3290 {"product-info", 0xe11100, 0x01000},
3291 {"soft-version", 0xe20000, 0x01000},
3292 {"support-list", 0xe21000, 0x01000},
3293 {"profile", 0xe22000, 0x08000},
3294 {"user-config", 0xe30000, 0x10000},
3295 {"default-config", 0xe40000, 0x10000},
3296 {"radio", 0xff0000, 0x10000},
3297 {NULL, 0, 0}
3298 },
3299
3300 .first_sysupgrade_partition = "os-image",
3301 .last_sysupgrade_partition = "file-system"
3302 },
3303 /** Firmware layout for the RE650 V2 (8MB Flash)*/
3304 {
3305 .id = "RE650-V2",
3306 .vendor = "",
3307 .support_list =
3308 "SupportList:\n"
3309 "{product_name:RE650,product_ver:2.0.0,special_id:00000000}\n"
3310 "{product_name:RE650,product_ver:2.0.0,special_id:45550000}\n"
3311 "{product_name:RE650,product_ver:2.0.0,special_id:4A500000}\n"
3312 "{product_name:RE650,product_ver:2.0.0,special_id:41550000}\n"
3313 "{product_name:RE650,product_ver:2.0.0,special_id:43410000}\n"
3314 "{product_name:RE650,product_ver:2.0.0,special_id:41530000}\n"
3315 "{product_name:RE650,product_ver:2.0.0,special_id:55530000}\n",
3316 .part_trail = 0x00,
3317 /* For RE650 v2, soft ver is required, otherwise OEM install doesn't work */
3318 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
3319
3320 /* We're using a dynamic kernel/rootfs split here */
3321 .partitions = {
3322 {"fs-uboot", 0x00000, 0x20000},
3323 {"firmware", 0x20000, 0x7a0000},
3324 {"partition-table", 0x7c0000, 0x02000},
3325 {"default-mac", 0x7c2000, 0x00020},
3326 {"pin", 0x7c2100, 0x00020},
3327 {"product-info", 0x7c3100, 0x01000},
3328 {"soft-version", 0x7c4200, 0x01000},
3329 {"support-list", 0x7c5200, 0x01000},
3330 {"profile", 0x7c6200, 0x08000},
3331 {"config-info", 0x7ce200, 0x00400},
3332 {"user-config", 0x7d0000, 0x10000},
3333 {"default-config", 0x7e0000, 0x10000},
3334 {"radio", 0x7f0000, 0x10000},
3335 {NULL, 0, 0}
3336 },
3337
3338 .first_sysupgrade_partition = "os-image",
3339 .last_sysupgrade_partition = "file-system"
3340 },
3341
3342 /** Firmware layout for the Mercusys MR70X */
3343 {
3344 .id = "MR70X",
3345 .vendor = "",
3346 .support_list =
3347 "SupportList:\n"
3348 "{product_name:MR70X,product_ver:1.0.0,special_id:45550000}\n"
3349 "{product_name:MR70X,product_ver:1.0.0,special_id:4A500000}\n"
3350 "{product_name:MR70X,product_ver:1.0.0,special_id:55530000}\n",
3351 .part_trail = 0x00,
3352 .soft_ver = SOFT_VER_DEFAULT,
3353
3354 .partitions = {
3355 {"fs-uboot", 0x00000, 0x40000},
3356 {"firmware", 0x40000, 0xf60000},
3357 {"default-mac", 0xfa0000, 0x00200},
3358 {"pin", 0xfa0200, 0x00100},
3359 {"device-id", 0xfa0300, 0x00100},
3360 {"product-info", 0xfa0400, 0x0fc00},
3361 {"default-config", 0xfb0000, 0x08000},
3362 {"ap-def-config", 0xfb8000, 0x08000},
3363 {"user-config", 0xfc0000, 0x0a000},
3364 {"ag-config", 0xfca000, 0x04000},
3365 {"certificate", 0xfce000, 0x02000},
3366 {"ap-config", 0xfd0000, 0x06000},
3367 {"router-config", 0xfd6000, 0x06000},
3368 {"favicon", 0xfdc000, 0x02000},
3369 {"logo", 0xfde000, 0x02000},
3370 {"partition-table", 0xfe0000, 0x00800},
3371 {"soft-version", 0xfe0800, 0x00100},
3372 {"support-list", 0xfe0900, 0x00200},
3373 {"profile", 0xfe0b00, 0x03000},
3374 {"extra-para", 0xfe3b00, 0x00100},
3375 {"radio", 0xff0000, 0x10000},
3376 {NULL, 0, 0}
3377 },
3378
3379 .first_sysupgrade_partition = "os-image",
3380 .last_sysupgrade_partition = "file-system"
3381 },
3382
3383 {}
3384 };
3385
3386 #define error(_ret, _errno, _str, ...) \
3387 do { \
3388 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
3389 strerror(_errno)); \
3390 if (_ret) \
3391 exit(_ret); \
3392 } while (0)
3393
3394
3395 /** Stores a uint32 as big endian */
3396 static inline void put32(uint8_t *buf, uint32_t val) {
3397 buf[0] = val >> 24;
3398 buf[1] = val >> 16;
3399 buf[2] = val >> 8;
3400 buf[3] = val;
3401 }
3402
3403 static inline bool meta_partition_should_pad(enum partition_trail_value pv)
3404 {
3405 return (pv >= 0) && (pv <= PART_TRAIL_MAX);
3406 }
3407
3408 /** Allocate a padded meta partition with a correctly initialised header
3409 * If the `data` pointer is NULL, then the required space is only allocated,
3410 * otherwise `data_len` bytes will be copied from `data` into the partition
3411 * entry. */
3412 static struct image_partition_entry init_meta_partition_entry(
3413 const char *name, const void *data, uint32_t data_len,
3414 enum partition_trail_value pad_value)
3415 {
3416 uint32_t total_len = sizeof(struct meta_header) + data_len;
3417 if (meta_partition_should_pad(pad_value))
3418 total_len += 1;
3419
3420 struct image_partition_entry entry = {
3421 .name = name,
3422 .size = total_len,
3423 .data = malloc(total_len)
3424 };
3425 if (!entry.data)
3426 error(1, errno, "failed to allocate meta partition entry");
3427
3428 struct meta_header *header = (struct meta_header *)entry.data;
3429 header->length = htonl(data_len);
3430 header->zero = 0;
3431
3432 if (data)
3433 memcpy(entry.data+sizeof(*header), data, data_len);
3434
3435 if (meta_partition_should_pad(pad_value))
3436 entry.data[total_len - 1] = (uint8_t) pad_value;
3437
3438 return entry;
3439 }
3440
3441 /** Allocates a new image partition */
3442 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
3443 struct image_partition_entry entry = {name, len, malloc(len)};
3444 if (!entry.data)
3445 error(1, errno, "malloc");
3446
3447 return entry;
3448 }
3449
3450 /** Sets up default partition names whenever custom names aren't specified */
3451 static void set_partition_names(struct device_info *info)
3452 {
3453 if (!info->partition_names.partition_table)
3454 info->partition_names.partition_table = "partition-table";
3455 if (!info->partition_names.soft_ver)
3456 info->partition_names.soft_ver = "soft-version";
3457 if (!info->partition_names.os_image)
3458 info->partition_names.os_image = "os-image";
3459 if (!info->partition_names.support_list)
3460 info->partition_names.support_list = "support-list";
3461 if (!info->partition_names.file_system)
3462 info->partition_names.file_system = "file-system";
3463 if (!info->partition_names.extra_para)
3464 info->partition_names.extra_para = "extra-para";
3465 }
3466
3467 /** Frees an image partition */
3468 static void free_image_partition(struct image_partition_entry *entry)
3469 {
3470 void *data = entry->data;
3471
3472 entry->name = NULL;
3473 entry->size = 0;
3474 entry->data = NULL;
3475
3476 free(data);
3477 }
3478
3479 static time_t source_date_epoch = -1;
3480 static void set_source_date_epoch() {
3481 char *env = getenv("SOURCE_DATE_EPOCH");
3482 char *endptr = env;
3483 errno = 0;
3484 if (env && *env) {
3485 source_date_epoch = strtoull(env, &endptr, 10);
3486 if (errno || (endptr && *endptr != '\0')) {
3487 fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
3488 exit(1);
3489 }
3490 }
3491 }
3492
3493 /** Generates the partition-table partition */
3494 static struct image_partition_entry make_partition_table(const struct device_info *p)
3495 {
3496 struct image_partition_entry entry = alloc_image_partition(p->partition_names.partition_table, SAFELOADER_PAYLOAD_TABLE_SIZE);
3497
3498 char *s = (char *)entry.data, *end = (char *)(s+entry.size);
3499
3500 *(s++) = 0x00;
3501 *(s++) = 0x04;
3502 *(s++) = 0x00;
3503 *(s++) = 0x00;
3504
3505 size_t i;
3506 for (i = 0; p->partitions[i].name; i++) {
3507 size_t len = end-s;
3508 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n",
3509 p->partitions[i].name, p->partitions[i].base, p->partitions[i].size);
3510
3511 if (w > len-1)
3512 error(1, 0, "flash partition table overflow?");
3513
3514 s += w;
3515 }
3516
3517 s++;
3518
3519 memset(s, 0xff, end-s);
3520
3521 return entry;
3522 }
3523
3524
3525 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
3526 static inline uint8_t bcd(uint8_t v) {
3527 return 0x10 * (v/10) + v%10;
3528 }
3529
3530
3531 /** Generates the soft-version partition */
3532 static struct image_partition_entry make_soft_version(const struct device_info *info, uint32_t rev)
3533 {
3534 /** If an info string is provided, use this instead of
3535 * the structured data, and include the null-termination */
3536 if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) {
3537 uint32_t len = strlen(info->soft_ver.text) + 1;
3538 return init_meta_partition_entry(info->partition_names.soft_ver,
3539 info->soft_ver.text, len, info->part_trail);
3540 }
3541
3542 time_t t;
3543
3544 if (source_date_epoch != -1)
3545 t = source_date_epoch;
3546 else if (time(&t) == (time_t)(-1))
3547 error(1, errno, "time");
3548
3549 struct tm *tm = gmtime(&t);
3550
3551 struct soft_version s = {
3552 .pad1 = 0xff,
3553
3554 .version_major = info->soft_ver.num[0],
3555 .version_minor = info->soft_ver.num[1],
3556 .version_patch = info->soft_ver.num[2],
3557
3558 .year_hi = bcd((1900+tm->tm_year)/100),
3559 .year_lo = bcd(tm->tm_year%100),
3560 .month = bcd(tm->tm_mon+1),
3561 .day = bcd(tm->tm_mday),
3562 .rev = htonl(rev),
3563
3564 .compat_level = htonl(info->soft_ver_compat_level)
3565 };
3566
3567 if (info->soft_ver_compat_level == 0)
3568 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3569 (uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
3570 info->part_trail);
3571 else
3572 return init_meta_partition_entry(info->partition_names.soft_ver, &s,
3573 sizeof(s), info->part_trail);
3574 }
3575
3576 /** Generates the support-list partition */
3577 static struct image_partition_entry make_support_list(
3578 const struct device_info *info)
3579 {
3580 uint32_t len = strlen(info->support_list);
3581 return init_meta_partition_entry(info->partition_names.support_list, info->support_list,
3582 len, info->part_trail);
3583 }
3584
3585 /** Partition with extra-para data */
3586 static struct image_partition_entry make_extra_para(
3587 const struct device_info *info, const uint8_t *extra_para, size_t len)
3588 {
3589 return init_meta_partition_entry(info->partition_names.extra_para, extra_para, len,
3590 info->part_trail);
3591 }
3592
3593 /** Creates a new image partition with an arbitrary name from a file */
3594 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) {
3595 struct stat statbuf;
3596
3597 if (stat(filename, &statbuf) < 0)
3598 error(1, errno, "unable to stat file `%s'", filename);
3599
3600 size_t len = statbuf.st_size;
3601
3602 if (add_jffs2_eof) {
3603 if (file_system_partition)
3604 len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
3605 else
3606 len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
3607 }
3608
3609 struct image_partition_entry entry = alloc_image_partition(part_name, len);
3610
3611 FILE *file = fopen(filename, "rb");
3612 if (!file)
3613 error(1, errno, "unable to open file `%s'", filename);
3614
3615 if (fread(entry.data, statbuf.st_size, 1, file) != 1)
3616 error(1, errno, "unable to read file `%s'", filename);
3617
3618 if (add_jffs2_eof) {
3619 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
3620
3621 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
3622 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
3623 }
3624
3625 fclose(file);
3626
3627 return entry;
3628 }
3629
3630 /**
3631 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
3632
3633 Example image partition table:
3634
3635 fwup-ptn partition-table base 0x00800 size 0x00800
3636 fwup-ptn os-image base 0x01000 size 0x113b45
3637 fwup-ptn file-system base 0x114b45 size 0x1d0004
3638 fwup-ptn support-list base 0x2e4b49 size 0x000d1
3639
3640 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
3641 the end of the partition table is marked with a zero byte.
3642
3643 The firmware image must contain at least the partition-table and support-list partitions
3644 to be accepted. There aren't any alignment constraints for the image partitions.
3645
3646 The partition-table partition contains the actual flash layout; partitions
3647 from the image partition table are mapped to the corresponding flash partitions during
3648 the firmware upgrade. The support-list partition contains a list of devices supported by
3649 the firmware image.
3650
3651 The base offsets in the firmware partition table are relative to the end
3652 of the vendor information block, so the partition-table partition will
3653 actually start at offset 0x1814 of the image.
3654
3655 I think partition-table must be the first partition in the firmware image.
3656 */
3657 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
3658 size_t i, j;
3659 char *image_pt = (char *)buffer, *end = image_pt + SAFELOADER_PAYLOAD_TABLE_SIZE;
3660
3661 size_t base = SAFELOADER_PAYLOAD_TABLE_SIZE;
3662 for (i = 0; parts[i].name; i++) {
3663 for (j = 0; flash_parts[j].name; j++) {
3664 if (!strcmp(flash_parts[j].name, parts[i].name)) {
3665 if (parts[i].size > flash_parts[j].size)
3666 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
3667 break;
3668 }
3669 }
3670
3671 assert(flash_parts[j].name);
3672
3673 memcpy(buffer + base, parts[i].data, parts[i].size);
3674
3675 size_t len = end-image_pt;
3676 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);
3677
3678 if (w > len-1)
3679 error(1, 0, "image partition table overflow?");
3680
3681 image_pt += w;
3682
3683 base += parts[i].size;
3684 }
3685 }
3686
3687 /** Generates and writes the image MD5 checksum */
3688 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
3689 MD5_CTX ctx;
3690
3691 MD5_Init(&ctx);
3692 MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
3693 MD5_Update(&ctx, buffer, len);
3694 MD5_Final(md5, &ctx);
3695 }
3696
3697
3698 /**
3699 Generates the firmware image in factory format
3700
3701 Image format:
3702
3703 Bytes (hex) Usage
3704 ----------- -----
3705 0000-0003 Image size (4 bytes, big endian)
3706 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
3707 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
3708 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
3709 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
3710 1014-1813 Image partition table (2048 bytes, padded with 0xff)
3711 1814-xxxx Firmware partitions
3712 */
3713 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
3714 *len = SAFELOADER_PAYLOAD_OFFSET + SAFELOADER_PAYLOAD_TABLE_SIZE;
3715
3716 size_t i;
3717 for (i = 0; parts[i].name; i++)
3718 *len += parts[i].size;
3719
3720 uint8_t *image = malloc(*len);
3721 if (!image)
3722 error(1, errno, "malloc");
3723
3724 memset(image, 0xff, *len);
3725 put32(image, *len);
3726
3727 if (info->vendor) {
3728 size_t vendor_len = strlen(info->vendor);
3729 put32(image + SAFELOADER_PREAMBLE_SIZE, vendor_len);
3730 memcpy(image + SAFELOADER_PREAMBLE_SIZE + 0x4, info->vendor, vendor_len);
3731 }
3732
3733 put_partitions(image + SAFELOADER_PAYLOAD_OFFSET, info->partitions, parts);
3734 put_md5(image + 0x04, image + SAFELOADER_PREAMBLE_SIZE, *len - SAFELOADER_PREAMBLE_SIZE);
3735
3736 return image;
3737 }
3738
3739 /**
3740 Generates the firmware image in sysupgrade format
3741
3742 This makes some assumptions about the provided flash and image partition tables and
3743 should be generalized when TP-LINK starts building its safeloader into hardware with
3744 different flash layouts.
3745 */
3746 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
3747 size_t i, j;
3748 size_t flash_first_partition_index = 0;
3749 size_t flash_last_partition_index = 0;
3750 const struct flash_partition_entry *flash_first_partition = NULL;
3751 const struct flash_partition_entry *flash_last_partition = NULL;
3752 const struct image_partition_entry *image_last_partition = NULL;
3753
3754 /** Find first and last partitions */
3755 for (i = 0; info->partitions[i].name; i++) {
3756 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
3757 flash_first_partition = &info->partitions[i];
3758 flash_first_partition_index = i;
3759 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
3760 flash_last_partition = &info->partitions[i];
3761 flash_last_partition_index = i;
3762 }
3763 }
3764
3765 assert(flash_first_partition && flash_last_partition);
3766 assert(flash_first_partition_index < flash_last_partition_index);
3767
3768 /** Find last partition from image to calculate needed size */
3769 for (i = 0; image_parts[i].name; i++) {
3770 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
3771 image_last_partition = &image_parts[i];
3772 break;
3773 }
3774 }
3775
3776 assert(image_last_partition);
3777
3778 *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
3779
3780 uint8_t *image = malloc(*len);
3781 if (!image)
3782 error(1, errno, "malloc");
3783
3784 memset(image, 0xff, *len);
3785
3786 for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
3787 for (j = 0; image_parts[j].name; j++) {
3788 if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
3789 if (image_parts[j].size > info->partitions[i].size)
3790 error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
3791 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
3792 break;
3793 }
3794
3795 assert(image_parts[j].name);
3796 }
3797 }
3798
3799 return image;
3800 }
3801
3802 /** Generates an image according to a given layout and writes it to a file */
3803 static void build_image(const char *output,
3804 const char *kernel_image,
3805 const char *rootfs_image,
3806 uint32_t rev,
3807 bool add_jffs2_eof,
3808 bool sysupgrade,
3809 struct device_info *info) {
3810
3811 size_t i;
3812
3813 struct image_partition_entry parts[7] = {};
3814
3815 struct flash_partition_entry *firmware_partition = NULL;
3816 struct flash_partition_entry *os_image_partition = NULL;
3817 struct flash_partition_entry *file_system_partition = NULL;
3818 size_t firmware_partition_index = 0;
3819
3820 set_partition_names(info);
3821
3822 for (i = 0; info->partitions[i].name; i++) {
3823 if (!strcmp(info->partitions[i].name, "firmware"))
3824 {
3825 firmware_partition = &info->partitions[i];
3826 firmware_partition_index = i;
3827 }
3828 }
3829
3830 if (firmware_partition)
3831 {
3832 os_image_partition = &info->partitions[firmware_partition_index];
3833 file_system_partition = &info->partitions[firmware_partition_index + 1];
3834
3835 struct stat kernel;
3836 if (stat(kernel_image, &kernel) < 0)
3837 error(1, errno, "unable to stat file `%s'", kernel_image);
3838
3839 if (kernel.st_size > firmware_partition->size)
3840 error(1, 0, "kernel overflowed firmware partition\n");
3841
3842 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
3843 info->partitions[i+1] = info->partitions[i];
3844
3845 file_system_partition->name = info->partition_names.file_system;
3846
3847 file_system_partition->base = firmware_partition->base + kernel.st_size;
3848
3849 /* Align partition start to erase blocks for factory images only */
3850 if (!sysupgrade)
3851 file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
3852
3853 file_system_partition->size = firmware_partition->size - file_system_partition->base;
3854
3855 os_image_partition->name = info->partition_names.os_image;
3856
3857 os_image_partition->size = kernel.st_size;
3858 }
3859
3860 parts[0] = make_partition_table(info);
3861 parts[1] = make_soft_version(info, rev);
3862 parts[2] = make_support_list(info);
3863 parts[3] = read_file(info->partition_names.os_image, kernel_image, false, NULL);
3864 parts[4] = read_file(info->partition_names.file_system, rootfs_image, add_jffs2_eof, file_system_partition);
3865
3866
3867 /* Some devices need the extra-para partition to accept the firmware */
3868 if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 ||
3869 strcasecmp(info->id, "ARCHER-A7-V5") == 0 ||
3870 strcasecmp(info->id, "ARCHER-A9-V6") == 0 ||
3871 strcasecmp(info->id, "ARCHER-AX23-V1") == 0 ||
3872 strcasecmp(info->id, "ARCHER-C2-V3") == 0 ||
3873 strcasecmp(info->id, "ARCHER-C7-V4") == 0 ||
3874 strcasecmp(info->id, "ARCHER-C7-V5") == 0 ||
3875 strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
3876 strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
3877 strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
3878 strcasecmp(info->id, "ARCHER-C60-V3") == 0 ||
3879 strcasecmp(info->id, "ARCHER-C6U-V1") == 0 ||
3880 strcasecmp(info->id, "ARCHER-C6-V3") == 0 ||
3881 strcasecmp(info->id, "DECO-M4R-V4") == 0 ||
3882 strcasecmp(info->id, "MR70X") == 0 ||
3883 strcasecmp(info->id, "TLWR1043NV5") == 0) {
3884 const uint8_t extra_para[2] = {0x01, 0x00};
3885 parts[5] = make_extra_para(info, extra_para,
3886 sizeof(extra_para));
3887 } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 ||
3888 strcasecmp(info->id, "TL-WA1201-V2") == 0) {
3889 const uint8_t extra_para[2] = {0x00, 0x01};
3890 parts[5] = make_extra_para(info, extra_para,
3891 sizeof(extra_para));
3892 } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 ||
3893 strcasecmp(info->id, "EAP245-V3") == 0) {
3894 const uint8_t extra_para[2] = {0x01, 0x01};
3895 parts[5] = make_extra_para(info, extra_para,
3896 sizeof(extra_para));
3897 }
3898
3899 size_t len;
3900 void *image;
3901 if (sysupgrade)
3902 image = generate_sysupgrade_image(info, parts, &len);
3903 else
3904 image = generate_factory_image(info, parts, &len);
3905
3906 FILE *file = fopen(output, "wb");
3907 if (!file)
3908 error(1, errno, "unable to open output file");
3909
3910 if (fwrite(image, len, 1, file) != 1)
3911 error(1, 0, "unable to write output file");
3912
3913 fclose(file);
3914
3915 free(image);
3916
3917 for (i = 0; parts[i].name; i++)
3918 free_image_partition(&parts[i]);
3919 }
3920
3921 /** Usage output */
3922 static void usage(const char *argv0) {
3923 fprintf(stderr,
3924 "Usage: %s [OPTIONS...]\n"
3925 "\n"
3926 "Options:\n"
3927 " -h show this help\n"
3928 "\n"
3929 "Info about an image:\n"
3930 " -i <file> input file to read from\n"
3931 "Create a new image:\n"
3932 " -B <board> create image for the board specified with <board>\n"
3933 " -k <file> read kernel image from the file <file>\n"
3934 " -r <file> read rootfs image from the file <file>\n"
3935 " -o <file> write output to the file <file>\n"
3936 " -V <rev> sets the revision number to <rev>\n"
3937 " -j add jffs2 end-of-filesystem markers\n"
3938 " -S create sysupgrade instead of factory image\n"
3939 "Extract an old image:\n"
3940 " -x <file> extract all oem firmware partition\n"
3941 " -d <dir> destination to extract the firmware partition\n"
3942 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
3943 argv0
3944 );
3945 };
3946
3947
3948 static struct device_info *find_board(const char *id)
3949 {
3950 struct device_info *board = NULL;
3951
3952 for (board = boards; board->id != NULL; board++)
3953 if (strcasecmp(id, board->id) == 0)
3954 return board;
3955
3956 return NULL;
3957 }
3958
3959 static int add_flash_partition(
3960 struct flash_partition_entry *part_list,
3961 size_t max_entries,
3962 const char *name,
3963 unsigned long base,
3964 unsigned long size)
3965 {
3966 size_t ptr;
3967 /* check if the list has a free entry */
3968 for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
3969 if (part_list->name == NULL &&
3970 part_list->base == 0 &&
3971 part_list->size == 0)
3972 break;
3973 }
3974
3975 if (ptr == max_entries) {
3976 error(1, 0, "No free flash part entry available.");
3977 }
3978
3979 part_list->name = calloc(1, strlen(name) + 1);
3980 if (!part_list->name) {
3981 error(1, 0, "Unable to allocate memory");
3982 }
3983
3984 memcpy((char *)part_list->name, name, strlen(name));
3985 part_list->base = base;
3986 part_list->size = size;
3987
3988 return 0;
3989 }
3990
3991 /** read the partition table into struct flash_partition_entry */
3992 enum PARTITION_TABLE_TYPE {
3993 PARTITION_TABLE_FWUP,
3994 PARTITION_TABLE_FLASH,
3995 };
3996
3997 static int read_partition_table(
3998 FILE *file, long offset,
3999 struct flash_partition_entry *entries, size_t max_entries,
4000 int type)
4001 {
4002 char buf[SAFELOADER_PAYLOAD_TABLE_SIZE];
4003 char *ptr, *end;
4004 const char *parthdr = NULL;
4005 const char *fwuphdr = "fwup-ptn";
4006 const char *flashhdr = "partition";
4007
4008 /* TODO: search for the partition table */
4009
4010 switch(type) {
4011 case PARTITION_TABLE_FWUP:
4012 parthdr = fwuphdr;
4013 break;
4014 case PARTITION_TABLE_FLASH:
4015 parthdr = flashhdr;
4016 break;
4017 default:
4018 error(1, 0, "Invalid partition table");
4019 }
4020
4021 if (fseek(file, offset, SEEK_SET) < 0)
4022 error(1, errno, "Can not seek in the firmware");
4023
4024 if (fread(buf, sizeof(buf), 1, file) != 1)
4025 error(1, errno, "Can not read fwup-ptn from the firmware");
4026
4027 buf[sizeof(buf) - 1] = '\0';
4028
4029 /* look for the partition header */
4030 if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
4031 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
4032 return 1;
4033 }
4034
4035 ptr = buf;
4036 end = buf + sizeof(buf);
4037 while ((ptr + strlen(parthdr)) < end &&
4038 memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
4039 char *end_part;
4040 char *end_element;
4041
4042 char name[32] = { 0 };
4043 int name_len = 0;
4044 unsigned long base = 0;
4045 unsigned long size = 0;
4046
4047 end_part = memchr(ptr, '\n', (end - ptr));
4048 if (end_part == NULL) {
4049 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
4050 break;
4051 }
4052
4053 for (int i = 0; i <= 4; i++) {
4054 if (end_part <= ptr)
4055 break;
4056
4057 end_element = memchr(ptr, 0x20, (end_part - ptr));
4058 if (end_element == NULL) {
4059 error(1, errno, "Ignoring the rest of the partition entries.");
4060 break;
4061 }
4062
4063 switch (i) {
4064 /* partition header */
4065 case 0:
4066 ptr = end_element + 1;
4067 continue;
4068 /* name */
4069 case 1:
4070 name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
4071 strncpy(name, ptr, name_len);
4072 name[name_len] = '\0';
4073 ptr = end_element + 1;
4074 continue;
4075
4076 /* string "base" */
4077 case 2:
4078 ptr = end_element + 1;
4079 continue;
4080
4081 /* actual base */
4082 case 3:
4083 base = strtoul(ptr, NULL, 16);
4084 ptr = end_element + 1;
4085 continue;
4086
4087 /* string "size" */
4088 case 4:
4089 ptr = end_element + 1;
4090 /* actual size. The last element doesn't have a sepeartor */
4091 size = strtoul(ptr, NULL, 16);
4092 /* the part ends with 0x09, 0x0d, 0x0a */
4093 ptr = end_part + 1;
4094 add_flash_partition(entries, max_entries, name, base, size);
4095 continue;
4096 }
4097 }
4098 }
4099
4100 return 0;
4101 }
4102
4103 static void safeloader_read_partition(FILE *input_file, size_t payload_offset,
4104 struct flash_partition_entry *entry,
4105 struct image_partition_entry *part)
4106 {
4107 size_t part_size = entry->size;
4108 void *part_data = malloc(part_size);
4109
4110 if (fseek(input_file, payload_offset, SEEK_SET))
4111 error(1, errno, "Failed to seek to partition data");
4112
4113 if (!part_data)
4114 error(1, ENOMEM, "Failed to allocate partition data");
4115
4116 if (fread(part_data, 1, part_size, input_file) < part_size)
4117 error(1, errno, "Failed to read partition data");
4118
4119 part->data = part_data;
4120 part->size = part_size;
4121 part->name = entry->name;
4122 }
4123
4124 static void safeloader_parse_image(FILE *input_file, struct safeloader_image_info *image)
4125 {
4126 static const char *HEADER_ID_CLOUD = "fw-type:Cloud";
4127 static const char *HEADER_ID_QNEW = "?NEW";
4128
4129 char buf[64];
4130
4131 if (!input_file)
4132 return;
4133
4134 fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET);
4135
4136 if (fread(buf, sizeof(buf), 1, input_file) != 1)
4137 error(1, errno, "Can not read image header");
4138
4139 if (memcmp(HEADER_ID_QNEW, &buf[0], strlen(HEADER_ID_QNEW)) == 0)
4140 image->type = SAFELOADER_TYPE_QNEW;
4141 else if (memcmp(HEADER_ID_CLOUD, &buf[0], strlen(HEADER_ID_CLOUD)) == 0)
4142 image->type = SAFELOADER_TYPE_CLOUD;
4143 else if (ntohl(*((uint32_t *) &buf[0])) <= SAFELOADER_HEADER_SIZE)
4144 image->type = SAFELOADER_TYPE_VENDOR;
4145 else
4146 image->type = SAFELOADER_TYPE_DEFAULT;
4147
4148 switch (image->type) {
4149 case SAFELOADER_TYPE_DEFAULT:
4150 case SAFELOADER_TYPE_VENDOR:
4151 case SAFELOADER_TYPE_CLOUD:
4152 image->payload_offset = SAFELOADER_PAYLOAD_OFFSET;
4153 break;
4154 case SAFELOADER_TYPE_QNEW:
4155 image->payload_offset = SAFELOADER_QNEW_PAYLOAD_OFFSET;
4156 break;
4157 }
4158
4159 /* Parse image partition table */
4160 read_partition_table(input_file, image->payload_offset, &image->entries[0],
4161 MAX_PARTITIONS, PARTITION_TABLE_FWUP);
4162 }
4163
4164 static void write_partition(
4165 FILE *input_file,
4166 size_t firmware_offset,
4167 struct flash_partition_entry *entry,
4168 FILE *output_file)
4169 {
4170 char buf[4096];
4171 size_t offset;
4172
4173 fseek(input_file, entry->base + firmware_offset, SEEK_SET);
4174
4175 for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
4176 if (fread(buf, sizeof(buf), 1, input_file) != 1)
4177 error(1, errno, "Can not read partition from input_file");
4178
4179 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
4180 error(1, errno, "Can not write partition to output_file");
4181 }
4182 /* write last chunk smaller than buffer */
4183 if (offset < entry->size) {
4184 offset = entry->size - offset;
4185 if (fread(buf, offset, 1, input_file) != 1)
4186 error(1, errno, "Can not read partition from input_file");
4187 if (fwrite(buf, offset, 1, output_file) != 1)
4188 error(1, errno, "Can not write partition to output_file");
4189 }
4190 }
4191
4192 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
4193 {
4194 FILE *output_file;
4195 char output[PATH_MAX];
4196
4197 snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
4198 output_file = fopen(output, "wb+");
4199 if (output_file == NULL) {
4200 error(1, errno, "Can not open output file %s", output);
4201 }
4202
4203 write_partition(input_file, firmware_offset, entry, output_file);
4204
4205 fclose(output_file);
4206
4207 return 0;
4208 }
4209
4210 /** extract all partitions from the firmware file */
4211 static int extract_firmware(const char *input, const char *output_directory)
4212 {
4213 struct safeloader_image_info info = {};
4214 struct stat statbuf;
4215 FILE *input_file;
4216
4217 /* check input file */
4218 if (stat(input, &statbuf)) {
4219 error(1, errno, "Can not read input firmware %s", input);
4220 }
4221
4222 /* check if output directory exists */
4223 if (stat(output_directory, &statbuf)) {
4224 error(1, errno, "Failed to stat output directory %s", output_directory);
4225 }
4226
4227 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
4228 error(1, errno, "Given output directory is not a directory %s", output_directory);
4229 }
4230
4231 input_file = fopen(input, "rb");
4232 safeloader_parse_image(input_file, &info);
4233
4234 for (size_t i = 0; i < MAX_PARTITIONS && info.entries[i].name; i++)
4235 extract_firmware_partition(input_file, info.payload_offset, &info.entries[i], output_directory);
4236
4237 return 0;
4238 }
4239
4240 static struct flash_partition_entry *find_partition(
4241 struct flash_partition_entry *entries, size_t max_entries,
4242 const char *name, const char *error_msg)
4243 {
4244 for (size_t i = 0; i < max_entries; i++, entries++) {
4245 if (strcmp(entries->name, name) == 0)
4246 return entries;
4247 }
4248
4249 if (error_msg) {
4250 error(1, 0, "%s", error_msg);
4251 }
4252
4253 return NULL;
4254 }
4255
4256 static int firmware_info(const char *input)
4257 {
4258 struct safeloader_image_info info = {};
4259 struct image_partition_entry part = {};
4260 struct flash_partition_entry *e;
4261 FILE *input_file;
4262
4263 input_file = fopen(input, "rb");
4264
4265 safeloader_parse_image(input_file, &info);
4266
4267 if (info.type == SAFELOADER_TYPE_VENDOR) {
4268 char buf[SAFELOADER_HEADER_SIZE] = {};
4269 uint32_t vendor_size;
4270
4271 fseek(input_file, SAFELOADER_PREAMBLE_SIZE, SEEK_SET);
4272 fread(&vendor_size, sizeof(uint32_t), 1, input_file);
4273
4274 vendor_size = ntohl(vendor_size);
4275 fread(buf, vendor_size, 1, input_file);
4276
4277 printf("Firmware vendor string:\n");
4278 fwrite(buf, strnlen(buf, vendor_size), 1, stdout);
4279 printf("\n");
4280 }
4281
4282 printf("Firmware image partitions:\n");
4283 printf("%-8s %-8s %s\n", "base", "size", "name");
4284
4285 e = &info.entries[0];
4286 for (unsigned int i = 0; i < MAX_PARTITIONS && e->name; i++, e++)
4287 printf("%08x %08x %s\n", e->base, e->size, e->name);
4288
4289 e = find_partition(&info.entries[0], MAX_PARTITIONS, "soft-version", NULL);
4290 if (e) {
4291 struct soft_version *s;
4292 unsigned int ascii_len;
4293 const uint8_t *buf;
4294 size_t data_len;
4295 bool isstr;
4296
4297 safeloader_read_partition(input_file, info.payload_offset + e->base, e, &part);
4298 data_len = ntohl(((struct meta_header *) part.data)->length);
4299 buf = part.data + sizeof(struct meta_header);
4300
4301 /* Check for (null-terminated) string */
4302 ascii_len = 0;
4303 while (ascii_len < data_len && isascii(buf[ascii_len]))
4304 ascii_len++;
4305
4306 isstr = ascii_len == data_len;
4307
4308 printf("\n[Software version]\n");
4309 if (isstr) {
4310 fwrite(buf, strnlen((const char *) buf, data_len), 1, stdout);
4311 putchar('\n');
4312 } else if (data_len >= offsetof(struct soft_version, rev)) {
4313 s = (struct soft_version *) buf;
4314
4315 printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch);
4316 printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day);
4317 printf("Revision: %d\n", ntohl(s->rev));
4318
4319 if (data_len >= offsetof(struct soft_version, compat_level)) {
4320 printf("Compatibility level: %d\n", ntohl(s->compat_level));
4321 }
4322 } else {
4323 printf("Failed to parse data\n");
4324 }
4325
4326 free_image_partition(&part);
4327 }
4328
4329 e = find_partition(&info.entries[0], MAX_PARTITIONS, "support-list", NULL);
4330 if (e) {
4331 size_t data_len;
4332
4333 safeloader_read_partition(input_file, info.payload_offset + e->base, e, &part);
4334 data_len = ntohl(((struct meta_header *) part.data)->length);
4335
4336 printf("\n[Support list]\n");
4337 fwrite(part.data + sizeof(struct meta_header), data_len, 1, stdout);
4338 printf("\n");
4339
4340 free_image_partition(&part);
4341 }
4342
4343 e = find_partition(&info.entries[0], MAX_PARTITIONS, "partition-table", NULL);
4344 if (e) {
4345 size_t flash_table_offset = info.payload_offset + e->base + 4;
4346 struct flash_partition_entry parts[MAX_PARTITIONS] = {};
4347
4348 if (read_partition_table(input_file, flash_table_offset, parts, MAX_PARTITIONS, PARTITION_TABLE_FLASH))
4349 error(1, 0, "Error can not read the partition table (partition)");
4350
4351 printf("\n[Partition table]\n");
4352 printf("%-8s %-8s %s\n", "base", "size", "name");
4353
4354 e = &parts[0];
4355 for (unsigned int i = 0; i < MAX_PARTITIONS && e->name; i++, e++)
4356 printf("%08x %08x %s\n", e->base, e->size, e->name);
4357 }
4358
4359 fclose(input_file);
4360
4361 return 0;
4362 }
4363
4364 static void write_ff(FILE *output_file, size_t size)
4365 {
4366 char buf[4096];
4367 size_t offset;
4368
4369 memset(buf, 0xff, sizeof(buf));
4370
4371 for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
4372 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
4373 error(1, errno, "Can not write 0xff to output_file");
4374 }
4375
4376 /* write last chunk smaller than buffer */
4377 if (offset < size) {
4378 offset = size - offset;
4379 if (fwrite(buf, offset, 1, output_file) != 1)
4380 error(1, errno, "Can not write partition to output_file");
4381 }
4382 }
4383
4384 static void convert_firmware(const char *input, const char *output)
4385 {
4386 struct flash_partition_entry flash[MAX_PARTITIONS] = {};
4387 struct flash_partition_entry *fwup_partition_table;
4388 struct flash_partition_entry *flash_file_system;
4389 struct flash_partition_entry *fwup_file_system;
4390 struct flash_partition_entry *flash_os_image;
4391 struct flash_partition_entry *fwup_os_image;
4392 struct safeloader_image_info info = {};
4393 size_t flash_table_offset;
4394 struct stat statbuf;
4395 FILE *output_file;
4396 FILE *input_file;
4397
4398 /* check input file */
4399 if (stat(input, &statbuf)) {
4400 error(1, errno, "Can not read input firmware %s", input);
4401 }
4402
4403 input_file = fopen(input, "rb");
4404 if (!input_file)
4405 error(1, 0, "Can not open input firmware %s", input);
4406
4407 output_file = fopen(output, "wb");
4408 if (!output_file)
4409 error(1, 0, "Can not open output firmware %s", output);
4410
4411 input_file = fopen(input, "rb");
4412 safeloader_parse_image(input_file, &info);
4413
4414 fwup_os_image = find_partition(info.entries, MAX_PARTITIONS,
4415 "os-image", "Error can not find os-image partition (fwup)");
4416 fwup_file_system = find_partition(info.entries, MAX_PARTITIONS,
4417 "file-system", "Error can not find file-system partition (fwup)");
4418 fwup_partition_table = find_partition(info.entries, MAX_PARTITIONS,
4419 "partition-table", "Error can not find partition-table partition");
4420
4421 /* the flash partition table has a 0x00000004 magic haeder */
4422 flash_table_offset = info.payload_offset + fwup_partition_table->base + 4;
4423 if (read_partition_table(input_file, flash_table_offset, flash, MAX_PARTITIONS, PARTITION_TABLE_FLASH) != 0)
4424 error(1, 0, "Error can not read the partition table (flash)");
4425
4426 flash_os_image = find_partition(flash, MAX_PARTITIONS,
4427 "os-image", "Error can not find os-image partition (flash)");
4428 flash_file_system = find_partition(flash, MAX_PARTITIONS,
4429 "file-system", "Error can not find file-system partition (flash)");
4430
4431 /* write os_image to 0x0 */
4432 write_partition(input_file, info.payload_offset, fwup_os_image, output_file);
4433 write_ff(output_file, flash_os_image->size - fwup_os_image->size);
4434
4435 /* write file-system behind os_image */
4436 fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
4437 write_partition(input_file, info.payload_offset, fwup_file_system, output_file);
4438
4439 fclose(output_file);
4440 fclose(input_file);
4441 }
4442
4443 int main(int argc, char *argv[]) {
4444 const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
4445 const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
4446 bool add_jffs2_eof = false, sysupgrade = false;
4447 unsigned rev = 0;
4448 struct device_info *info;
4449 set_source_date_epoch();
4450
4451 while (true) {
4452 int c;
4453
4454 c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:");
4455 if (c == -1)
4456 break;
4457
4458 switch (c) {
4459 case 'i':
4460 info_image = optarg;
4461 break;
4462
4463 case 'B':
4464 board = optarg;
4465 break;
4466
4467 case 'k':
4468 kernel_image = optarg;
4469 break;
4470
4471 case 'r':
4472 rootfs_image = optarg;
4473 break;
4474
4475 case 'o':
4476 output = optarg;
4477 break;
4478
4479 case 'V':
4480 sscanf(optarg, "r%u", &rev);
4481 break;
4482
4483 case 'j':
4484 add_jffs2_eof = true;
4485 break;
4486
4487 case 'S':
4488 sysupgrade = true;
4489 break;
4490
4491 case 'h':
4492 usage(argv[0]);
4493 return 0;
4494
4495 case 'd':
4496 output_directory = optarg;
4497 break;
4498
4499 case 'x':
4500 extract_image = optarg;
4501 break;
4502
4503 case 'z':
4504 convert_image = optarg;
4505 break;
4506
4507 default:
4508 usage(argv[0]);
4509 return 1;
4510 }
4511 }
4512
4513 if (info_image) {
4514 firmware_info(info_image);
4515 } else if (extract_image || output_directory) {
4516 if (!extract_image)
4517 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
4518 if (!output_directory)
4519 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
4520 extract_firmware(extract_image, output_directory);
4521 } else if (convert_image) {
4522 if (!output)
4523 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
4524 convert_firmware(convert_image, output);
4525 } else {
4526 if (!board)
4527 error(1, 0, "no board has been specified");
4528 if (!kernel_image)
4529 error(1, 0, "no kernel image has been specified");
4530 if (!rootfs_image)
4531 error(1, 0, "no rootfs image has been specified");
4532 if (!output)
4533 error(1, 0, "no output filename has been specified");
4534
4535 info = find_board(board);
4536
4537 if (info == NULL)
4538 error(1, 0, "unsupported board %s", board);
4539
4540 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
4541 }
4542
4543 return 0;
4544 }