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