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