tplink-safeloader: support for Archer A6 v3 JP
[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 "{product_name:Archer A6,product_ver:3.0.0,special_id:4A500000}\n",
1144 .part_trail = 0x00,
1145 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.5\n"),
1146
1147 .partitions = {
1148 {"fs-uboot", 0x00000, 0x40000},
1149 {"firmware", 0x40000, 0xf60000},
1150 {"default-mac", 0xfa0000, 0x00200},
1151 {"pin", 0xfa0200, 0x00100},
1152 {"device-id", 0xfa0300, 0x00100},
1153 {"product-info", 0xfa0400, 0x0fc00},
1154 {"default-config", 0xfb0000, 0x08000},
1155 {"ap-def-config", 0xfb8000, 0x08000},
1156 {"user-config", 0xfc0000, 0x0a000},
1157 {"ag-config", 0xfca000, 0x04000},
1158 {"certificate", 0xfce000, 0x02000},
1159 {"ap-config", 0xfd0000, 0x06000},
1160 {"router-config", 0xfd6000, 0x06000},
1161 {"favicon", 0xfdc000, 0x02000},
1162 {"logo", 0xfde000, 0x02000},
1163 {"partition-table", 0xfe0000, 0x00800},
1164 {"soft-version", 0xfe0800, 0x00100},
1165 {"support-list", 0xfe0900, 0x00200},
1166 {"profile", 0xfe0b00, 0x03000},
1167 {"extra-para", 0xfe3b00, 0x00100},
1168 {"radio", 0xff0000, 0x10000},
1169 {NULL, 0, 0}
1170 },
1171 .first_sysupgrade_partition = "os-image",
1172 .last_sysupgrade_partition = "file-system",
1173 },
1174 /** Firmware layout for the Archer C6U v1 */
1175 {
1176 .id = "ARCHER-C6U-V1",
1177 .vendor = "",
1178 .support_list =
1179 "SupportList:\n"
1180 "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n",
1181 .part_trail = 0x00,
1182 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.2\n"),
1183
1184 .partitions = {
1185 {"fs-uboot", 0x00000, 0x40000},
1186 {"firmware", 0x40000, 0xf60000},
1187 {"default-mac", 0xfa0000, 0x00200},
1188 {"pin", 0xfa0200, 0x00100},
1189 {"device-id", 0xfa0300, 0x00100},
1190 {"product-info", 0xfa0400, 0x0fc00},
1191 {"default-config", 0xfb0000, 0x08000},
1192 {"ap-def-config", 0xfb8000, 0x08000},
1193 {"user-config", 0xfc0000, 0x0c000},
1194 {"certificate", 0xfcc000, 0x04000},
1195 {"ap-config", 0xfd0000, 0x08000},
1196 {"router-config", 0xfd8000, 0x08000},
1197 {"partition-table", 0xfe0000, 0x00800},
1198 {"soft-version", 0xfe0800, 0x00100},
1199 {"support-list", 0xfe0900, 0x00200},
1200 {"profile", 0xfe0b00, 0x03000},
1201 {"extra-para", 0xfe3b00, 0x00100},
1202 {"radio", 0xff0000, 0x10000},
1203 {NULL, 0, 0}
1204 },
1205 .first_sysupgrade_partition = "os-image",
1206 .last_sysupgrade_partition = "file-system",
1207 },
1208 /** Firmware layout for the C60v1 */
1209 {
1210 .id = "ARCHER-C60-V1",
1211 .vendor = "",
1212 .support_list =
1213 "SupportList:\r\n"
1214 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1215 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1216 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1217 .part_trail = 0x00,
1218 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1219
1220 .partitions = {
1221 {"fs-uboot", 0x00000, 0x10000},
1222 {"default-mac", 0x10000, 0x00200},
1223 {"pin", 0x10200, 0x00200},
1224 {"product-info", 0x10400, 0x00100},
1225 {"partition-table", 0x10500, 0x00800},
1226 {"soft-version", 0x11300, 0x00200},
1227 {"support-list", 0x11500, 0x00100},
1228 {"device-id", 0x11600, 0x00100},
1229 {"profile", 0x11700, 0x03900},
1230 {"default-config", 0x15000, 0x04000},
1231 {"user-config", 0x19000, 0x04000},
1232 {"firmware", 0x20000, 0x7c8000},
1233 {"certyficate", 0x7e8000, 0x08000},
1234 {"radio", 0x7f0000, 0x10000},
1235 {NULL, 0, 0}
1236 },
1237
1238 .first_sysupgrade_partition = "os-image",
1239 .last_sysupgrade_partition = "file-system",
1240 },
1241
1242 /** Firmware layout for the C60v2 */
1243 {
1244 .id = "ARCHER-C60-V2",
1245 .vendor = "",
1246 .support_list =
1247 "SupportList:\r\n"
1248 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1249 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1250 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1251 .part_trail = 0x00,
1252 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
1253
1254 .partitions = {
1255 {"factory-boot", 0x00000, 0x1fb00},
1256 {"default-mac", 0x1fb00, 0x00200},
1257 {"pin", 0x1fd00, 0x00100},
1258 {"product-info", 0x1fe00, 0x00100},
1259 {"device-id", 0x1ff00, 0x00100},
1260 {"fs-uboot", 0x20000, 0x10000},
1261 {"firmware", 0x30000, 0x7a0000},
1262 {"soft-version", 0x7d9500, 0x00100},
1263 {"support-list", 0x7d9600, 0x00100},
1264 {"extra-para", 0x7d9700, 0x00100},
1265 {"profile", 0x7d9800, 0x03000},
1266 {"default-config", 0x7dc800, 0x03000},
1267 {"partition-table", 0x7df800, 0x00800},
1268 {"user-config", 0x7e0000, 0x0c000},
1269 {"certificate", 0x7ec000, 0x04000},
1270 {"radio", 0x7f0000, 0x10000},
1271 {NULL, 0, 0}
1272 },
1273
1274 .first_sysupgrade_partition = "os-image",
1275 .last_sysupgrade_partition = "file-system",
1276 },
1277
1278 /** Firmware layout for the C60v3 */
1279 {
1280 .id = "ARCHER-C60-V3",
1281 .vendor = "",
1282 .support_list =
1283 "SupportList:\r\n"
1284 "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1285 "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1286 "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1287 .part_trail = 0x00,
1288 .soft_ver = SOFT_VER_TEXT("soft_ver:3.0.0\n"),
1289
1290 .partitions = {
1291 {"factory-boot", 0x00000, 0x1fb00},
1292 {"default-mac", 0x1fb00, 0x00200},
1293 {"pin", 0x1fd00, 0x00100},
1294 {"product-info", 0x1fe00, 0x00100},
1295 {"device-id", 0x1ff00, 0x00100},
1296 {"fs-uboot", 0x20000, 0x10000},
1297 {"firmware", 0x30000, 0x7a0000},
1298 {"soft-version", 0x7d9500, 0x00100},
1299 {"support-list", 0x7d9600, 0x00100},
1300 {"extra-para", 0x7d9700, 0x00100},
1301 {"profile", 0x7d9800, 0x03000},
1302 {"default-config", 0x7dc800, 0x03000},
1303 {"partition-table", 0x7df800, 0x00800},
1304 {"user-config", 0x7e0000, 0x0c000},
1305 {"certificate", 0x7ec000, 0x04000},
1306 {"radio", 0x7f0000, 0x10000},
1307 {NULL, 0, 0}
1308 },
1309
1310 .first_sysupgrade_partition = "os-image",
1311 .last_sysupgrade_partition = "file-system",
1312 },
1313
1314 /** Firmware layout for the C5 */
1315 {
1316 .id = "ARCHER-C5-V2",
1317 .vendor = "",
1318 .support_list =
1319 "SupportList:\r\n"
1320 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1321 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1322 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1323 .part_trail = 0x00,
1324 .soft_ver = SOFT_VER_DEFAULT,
1325
1326 .partitions = {
1327 {"fs-uboot", 0x00000, 0x40000},
1328 {"os-image", 0x40000, 0x200000},
1329 {"file-system", 0x240000, 0xc00000},
1330 {"default-mac", 0xe40000, 0x00200},
1331 {"pin", 0xe40200, 0x00200},
1332 {"product-info", 0xe40400, 0x00200},
1333 {"partition-table", 0xe50000, 0x10000},
1334 {"soft-version", 0xe60000, 0x00200},
1335 {"support-list", 0xe61000, 0x0f000},
1336 {"profile", 0xe70000, 0x10000},
1337 {"default-config", 0xe80000, 0x10000},
1338 {"user-config", 0xe90000, 0x50000},
1339 {"log", 0xee0000, 0x100000},
1340 {"radio_bk", 0xfe0000, 0x10000},
1341 {"radio", 0xff0000, 0x10000},
1342 {NULL, 0, 0}
1343 },
1344
1345 .first_sysupgrade_partition = "os-image",
1346 .last_sysupgrade_partition = "file-system"
1347 },
1348
1349 /** Firmware layout for the C7 */
1350 {
1351 .id = "ARCHER-C7-V4",
1352 .support_list =
1353 "SupportList:\n"
1354 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1355 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1356 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1357 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1358 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1359 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1360 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1361 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1362 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1363 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1364 .part_trail = 0x00,
1365 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1366
1367 /* We're using a dynamic kernel/rootfs split here */
1368 .partitions = {
1369 {"factory-boot", 0x00000, 0x20000},
1370 {"fs-uboot", 0x20000, 0x20000},
1371 {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
1372 /* Stock: name file-system base 0x160000 size 0xda0000 */
1373 {"default-mac", 0xf00000, 0x00200},
1374 {"pin", 0xf00200, 0x00200},
1375 {"device-id", 0xf00400, 0x00100},
1376 {"product-info", 0xf00500, 0x0fb00},
1377 {"soft-version", 0xf10000, 0x00100},
1378 {"extra-para", 0xf11000, 0x01000},
1379 {"support-list", 0xf12000, 0x0a000},
1380 {"profile", 0xf1c000, 0x04000},
1381 {"default-config", 0xf20000, 0x10000},
1382 {"user-config", 0xf30000, 0x40000},
1383 {"qos-db", 0xf70000, 0x40000},
1384 {"certificate", 0xfb0000, 0x10000},
1385 {"partition-table", 0xfc0000, 0x10000},
1386 {"log", 0xfd0000, 0x20000},
1387 {"radio", 0xff0000, 0x10000},
1388 {NULL, 0, 0}
1389 },
1390
1391 .first_sysupgrade_partition = "os-image",
1392 .last_sysupgrade_partition = "file-system",
1393 },
1394
1395 /** Firmware layout for the C7 v5*/
1396 {
1397 .id = "ARCHER-C7-V5",
1398 .support_list =
1399 "SupportList:\n"
1400 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1401 "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1402 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1403 "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1404 "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1405 "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1406 "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1407 "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1408
1409 .part_trail = 0x00,
1410 .soft_ver = SOFT_VER_TEXT("soft_ver:7.0.0\n"),
1411
1412 /* We're using a dynamic kernel/rootfs split here */
1413 .partitions = {
1414 {"factory-boot", 0x00000, 0x20000},
1415 {"fs-uboot", 0x20000, 0x20000},
1416 {"partition-table", 0x40000, 0x10000},
1417 {"radio", 0x50000, 0x10000},
1418 {"default-mac", 0x60000, 0x00200},
1419 {"pin", 0x60200, 0x00200},
1420 {"device-id", 0x60400, 0x00100},
1421 {"product-info", 0x60500, 0x0fb00},
1422 {"soft-version", 0x70000, 0x01000},
1423 {"extra-para", 0x71000, 0x01000},
1424 {"support-list", 0x72000, 0x0a000},
1425 {"profile", 0x7c000, 0x04000},
1426 {"user-config", 0x80000, 0x40000},
1427
1428
1429 {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */
1430 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1431
1432 {"log", 0xfc0000, 0x20000},
1433 {"certificate", 0xfe0000, 0x10000},
1434 {"default-config", 0xff0000, 0x10000},
1435 {NULL, 0, 0}
1436
1437 },
1438
1439 .first_sysupgrade_partition = "os-image",
1440 .last_sysupgrade_partition = "file-system",
1441 },
1442
1443 /** Firmware layout for the C9 */
1444 {
1445 .id = "ARCHERC9",
1446 .vendor = "",
1447 .support_list =
1448 "SupportList:\n"
1449 "{product_name:ArcherC9,"
1450 "product_ver:1.0.0,"
1451 "special_id:00000000}\n",
1452 .part_trail = 0x00,
1453 .soft_ver = SOFT_VER_DEFAULT,
1454
1455 .partitions = {
1456 {"fs-uboot", 0x00000, 0x40000},
1457 {"os-image", 0x40000, 0x200000},
1458 {"file-system", 0x240000, 0xc00000},
1459 {"default-mac", 0xe40000, 0x00200},
1460 {"pin", 0xe40200, 0x00200},
1461 {"product-info", 0xe40400, 0x00200},
1462 {"partition-table", 0xe50000, 0x10000},
1463 {"soft-version", 0xe60000, 0x00200},
1464 {"support-list", 0xe61000, 0x0f000},
1465 {"profile", 0xe70000, 0x10000},
1466 {"default-config", 0xe80000, 0x10000},
1467 {"user-config", 0xe90000, 0x50000},
1468 {"log", 0xee0000, 0x100000},
1469 {"radio_bk", 0xfe0000, 0x10000},
1470 {"radio", 0xff0000, 0x10000},
1471 {NULL, 0, 0}
1472 },
1473
1474 .first_sysupgrade_partition = "os-image",
1475 .last_sysupgrade_partition = "file-system"
1476 },
1477
1478 /** Firmware layout for the EAP120 */
1479 {
1480 .id = "EAP120",
1481 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1482 .support_list =
1483 "SupportList:\r\n"
1484 "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1485 .part_trail = 0xff,
1486 .soft_ver = SOFT_VER_DEFAULT,
1487
1488 .partitions = {
1489 {"fs-uboot", 0x00000, 0x20000},
1490 {"partition-table", 0x20000, 0x02000},
1491 {"default-mac", 0x30000, 0x00020},
1492 {"support-list", 0x31000, 0x00100},
1493 {"product-info", 0x31100, 0x00100},
1494 {"soft-version", 0x32000, 0x00100},
1495 {"os-image", 0x40000, 0x180000},
1496 {"file-system", 0x1c0000, 0x600000},
1497 {"user-config", 0x7c0000, 0x10000},
1498 {"backup-config", 0x7d0000, 0x10000},
1499 {"log", 0x7e0000, 0x10000},
1500 {"radio", 0x7f0000, 0x10000},
1501 {NULL, 0, 0}
1502 },
1503
1504 .first_sysupgrade_partition = "os-image",
1505 .last_sysupgrade_partition = "file-system"
1506 },
1507
1508 /** Firmware layout for the EAP225-Outdoor v1 */
1509 {
1510 .id = "EAP225-OUTDOOR-V1",
1511 .support_list =
1512 "SupportList:\r\n"
1513 "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1514 .part_trail = PART_TRAIL_NONE,
1515 .soft_ver = SOFT_VER_DEFAULT,
1516 .soft_ver_compat_level = 1,
1517
1518 .partitions = {
1519 {"fs-uboot", 0x00000, 0x20000},
1520 {"partition-table", 0x20000, 0x02000},
1521 {"default-mac", 0x30000, 0x01000},
1522 {"support-list", 0x31000, 0x00100},
1523 {"product-info", 0x31100, 0x00400},
1524 {"soft-version", 0x32000, 0x00100},
1525 {"firmware", 0x40000, 0xd80000},
1526 {"user-config", 0xdc0000, 0x30000},
1527 {"mutil-log", 0xf30000, 0x80000},
1528 {"oops", 0xfb0000, 0x40000},
1529 {"radio", 0xff0000, 0x10000},
1530 {NULL, 0, 0}
1531 },
1532
1533 .first_sysupgrade_partition = "os-image",
1534 .last_sysupgrade_partition = "file-system"
1535 },
1536
1537 /** Firmware layout for the EAP225 v1 */
1538 {
1539 .id = "EAP225-V1",
1540 .support_list =
1541 "SupportList:\r\n"
1542 "EAP225(TP-LINK|UN|AC1200-D):1.0\r\n",
1543 .part_trail = PART_TRAIL_NONE,
1544 .soft_ver = SOFT_VER_DEFAULT,
1545
1546 .partitions = {
1547 {"fs-uboot", 0x00000, 0x20000},
1548 {"partition-table", 0x20000, 0x02000},
1549 {"default-mac", 0x30000, 0x01000},
1550 {"support-list", 0x31000, 0x00100},
1551 {"product-info", 0x31100, 0x00400},
1552 {"soft-version", 0x32000, 0x00100},
1553 {"firmware", 0x40000, 0xd80000},
1554 {"user-config", 0xdc0000, 0x30000},
1555 {"radio", 0xff0000, 0x10000},
1556 {NULL, 0, 0}
1557 },
1558
1559 .first_sysupgrade_partition = "os-image",
1560 .last_sysupgrade_partition = "file-system"
1561 },
1562
1563 /** Firmware layout for the EAP225 v3 */
1564 {
1565 .id = "EAP225-V3",
1566 .support_list =
1567 "SupportList:\r\n"
1568 "EAP225(TP-Link|UN|AC1350-D):3.0\r\n",
1569 .part_trail = PART_TRAIL_NONE,
1570 .soft_ver = SOFT_VER_DEFAULT,
1571 .soft_ver_compat_level = 1,
1572
1573 .partitions = {
1574 {"fs-uboot", 0x00000, 0x20000},
1575 {"partition-table", 0x20000, 0x02000},
1576 {"default-mac", 0x30000, 0x01000},
1577 {"support-list", 0x31000, 0x00100},
1578 {"product-info", 0x31100, 0x00400},
1579 {"soft-version", 0x32000, 0x00100},
1580 {"firmware", 0x40000, 0xd80000},
1581 {"user-config", 0xdc0000, 0x30000},
1582 {"mutil-log", 0xf30000, 0x80000},
1583 {"oops", 0xfb0000, 0x40000},
1584 {"radio", 0xff0000, 0x10000},
1585 {NULL, 0, 0}
1586 },
1587
1588 .first_sysupgrade_partition = "os-image",
1589 .last_sysupgrade_partition = "file-system"
1590 },
1591
1592 /** Firmware layout for the EAP225-Wall v2 */
1593 {
1594 .id = "EAP225-WALL-V2",
1595 .support_list =
1596 "SupportList:\r\n"
1597 "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
1598 .part_trail = PART_TRAIL_NONE,
1599 .soft_ver = SOFT_VER_DEFAULT,
1600 .soft_ver_compat_level = 1,
1601
1602 .partitions = {
1603 {"fs-uboot", 0x00000, 0x20000},
1604 {"partition-table", 0x20000, 0x02000},
1605 {"default-mac", 0x30000, 0x01000},
1606 {"support-list", 0x31000, 0x00100},
1607 {"product-info", 0x31100, 0x00400},
1608 {"soft-version", 0x32000, 0x00100},
1609 {"firmware", 0x40000, 0xd80000},
1610 {"user-config", 0xdc0000, 0x30000},
1611 {"mutil-log", 0xf30000, 0x80000},
1612 {"oops", 0xfb0000, 0x40000},
1613 {"radio", 0xff0000, 0x10000},
1614 {NULL, 0, 0}
1615 },
1616
1617 .first_sysupgrade_partition = "os-image",
1618 .last_sysupgrade_partition = "file-system"
1619 },
1620
1621 /** Firmware layout for the EAP235-Wall v1 */
1622 {
1623 .id = "EAP235-WALL-V1",
1624 .support_list =
1625 "SupportList:\r\n"
1626 "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
1627 .part_trail = PART_TRAIL_NONE,
1628 .soft_ver = SOFT_VER_NUMERIC(3, 0, 0),
1629 .soft_ver_compat_level = 1,
1630
1631 .partitions = {
1632 {"fs-uboot", 0x00000, 0x80000},
1633 {"partition-table", 0x80000, 0x02000},
1634 {"default-mac", 0x90000, 0x01000},
1635 {"support-list", 0x91000, 0x00100},
1636 {"product-info", 0x91100, 0x00400},
1637 {"soft-version", 0x92000, 0x00100},
1638 {"firmware", 0xa0000, 0xd20000},
1639 {"user-config", 0xdc0000, 0x30000},
1640 {"mutil-log", 0xf30000, 0x80000},
1641 {"oops", 0xfb0000, 0x40000},
1642 {"radio", 0xff0000, 0x10000},
1643 {NULL, 0, 0}
1644 },
1645
1646 .first_sysupgrade_partition = "os-image",
1647 .last_sysupgrade_partition = "file-system"
1648 },
1649
1650 /** Firmware layout for the EAP245 v1 */
1651 {
1652 .id = "EAP245-V1",
1653 .support_list =
1654 "SupportList:\r\n"
1655 "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
1656 .part_trail = PART_TRAIL_NONE,
1657 .soft_ver = SOFT_VER_DEFAULT,
1658
1659 .partitions = {
1660 {"fs-uboot", 0x00000, 0x20000},
1661 {"partition-table", 0x20000, 0x02000},
1662 {"default-mac", 0x30000, 0x01000},
1663 {"support-list", 0x31000, 0x00100},
1664 {"product-info", 0x31100, 0x00400},
1665 {"soft-version", 0x32000, 0x00100},
1666 {"firmware", 0x40000, 0xd80000},
1667 {"user-config", 0xdc0000, 0x30000},
1668 {"radio", 0xff0000, 0x10000},
1669 {NULL, 0, 0}
1670 },
1671
1672 .first_sysupgrade_partition = "os-image",
1673 .last_sysupgrade_partition = "file-system"
1674 },
1675
1676 /** Firmware layout for the EAP245 v3 */
1677 {
1678 .id = "EAP245-V3",
1679 .support_list =
1680 "SupportList:\r\n"
1681 "EAP245(TP-Link|UN|AC1750-D):3.0\r\n",
1682 .part_trail = PART_TRAIL_NONE,
1683 .soft_ver = SOFT_VER_DEFAULT,
1684 .soft_ver_compat_level = 1,
1685
1686 /** Firmware partition with dynamic kernel/rootfs split */
1687 .partitions = {
1688 {"factroy-boot", 0x00000, 0x40000},
1689 {"fs-uboot", 0x40000, 0x40000},
1690 {"partition-table", 0x80000, 0x10000},
1691 {"default-mac", 0x90000, 0x01000},
1692 {"support-list", 0x91000, 0x00100},
1693 {"product-info", 0x91100, 0x00400},
1694 {"soft-version", 0x92000, 0x00100},
1695 {"radio", 0xa0000, 0x10000},
1696 {"extra-para", 0xb0000, 0x10000},
1697 {"firmware", 0xc0000, 0xe40000},
1698 {"config", 0xf00000, 0x30000},
1699 {"mutil-log", 0xf30000, 0x80000},
1700 {"oops", 0xfb0000, 0x40000},
1701 {NULL, 0, 0}
1702 },
1703
1704 .first_sysupgrade_partition = "os-image",
1705 .last_sysupgrade_partition = "file-system"
1706 },
1707
1708 /** Firmware layout for the TL-WA1201 v2 */
1709 {
1710 .id = "TL-WA1201-V2",
1711 .vendor = "",
1712 .support_list =
1713 "SupportList:\n"
1714 "{product_name:TL-WA1201,product_ver:2.0.0,special_id:45550000}\n"
1715 "{product_name:TL-WA1201,product_ver:2.0.0,special_id:55530000}\n",
1716 .part_trail = 0x00,
1717 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.1 Build 20200709 rel.66244\n"),
1718
1719 .partitions = {
1720 {"fs-uboot", 0x00000, 0x20000},
1721 {"default-mac", 0x20000, 0x00200},
1722 {"pin", 0x20200, 0x00100},
1723 {"product-info", 0x20300, 0x00200},
1724 {"device-id", 0x20500, 0x0fb00},
1725 {"firmware", 0x30000, 0xce0000},
1726 {"portal-logo", 0xd10000, 0x20000},
1727 {"portal-back", 0xd30000, 0x200000},
1728 {"soft-version", 0xf30000, 0x00200},
1729 {"extra-para", 0xf30200, 0x00200},
1730 {"support-list", 0xf30400, 0x00200},
1731 {"profile", 0xf30600, 0x0fa00},
1732 {"apdef-config", 0xf40000, 0x10000},
1733 {"ap-config", 0xf50000, 0x10000},
1734 {"redef-config", 0xf60000, 0x10000},
1735 {"re-config", 0xf70000, 0x10000},
1736 {"multidef-config", 0xf80000, 0x10000},
1737 {"multi-config", 0xf90000, 0x10000},
1738 {"clientdef-config", 0xfa0000, 0x10000},
1739 {"client-config", 0xfb0000, 0x10000},
1740 {"partition-table", 0xfc0000, 0x10000},
1741 {"user-config", 0xfd0000, 0x10000},
1742 {"certificate", 0xfe0000, 0x10000},
1743 {"radio", 0xff0000, 0x10000},
1744 {NULL, 0, 0}
1745 },
1746 .first_sysupgrade_partition = "os-image",
1747 .last_sysupgrade_partition = "file-system",
1748 },
1749
1750 /** Firmware layout for the TL-WA850RE v2 */
1751 {
1752 .id = "TLWA850REV2",
1753 .vendor = "",
1754 .support_list =
1755 "SupportList:\n"
1756 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
1757 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
1758 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
1759 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
1760 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
1761 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
1762 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
1763 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
1764 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
1765 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
1766 .part_trail = 0x00,
1767 .soft_ver = SOFT_VER_DEFAULT,
1768
1769 /**
1770 576KB were moved from file-system to os-image
1771 in comparison to the stock image
1772 */
1773 .partitions = {
1774 {"fs-uboot", 0x00000, 0x20000},
1775 {"firmware", 0x20000, 0x390000},
1776 {"partition-table", 0x3b0000, 0x02000},
1777 {"default-mac", 0x3c0000, 0x00020},
1778 {"pin", 0x3c0100, 0x00020},
1779 {"product-info", 0x3c1000, 0x01000},
1780 {"soft-version", 0x3c2000, 0x00100},
1781 {"support-list", 0x3c3000, 0x01000},
1782 {"profile", 0x3c4000, 0x08000},
1783 {"user-config", 0x3d0000, 0x10000},
1784 {"default-config", 0x3e0000, 0x10000},
1785 {"radio", 0x3f0000, 0x10000},
1786 {NULL, 0, 0}
1787 },
1788
1789 .first_sysupgrade_partition = "os-image",
1790 .last_sysupgrade_partition = "file-system"
1791 },
1792
1793 /** Firmware layout for the TL-WA855RE v1 */
1794 {
1795 .id = "TLWA855REV1",
1796 .vendor = "",
1797 .support_list =
1798 "SupportList:\n"
1799 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
1800 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
1801 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
1802 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
1803 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
1804 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
1805 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
1806 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
1807 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
1808 .part_trail = 0x00,
1809 .soft_ver = SOFT_VER_DEFAULT,
1810
1811 .partitions = {
1812 {"fs-uboot", 0x00000, 0x20000},
1813 {"os-image", 0x20000, 0x150000},
1814 {"file-system", 0x170000, 0x240000},
1815 {"partition-table", 0x3b0000, 0x02000},
1816 {"default-mac", 0x3c0000, 0x00020},
1817 {"pin", 0x3c0100, 0x00020},
1818 {"product-info", 0x3c1000, 0x01000},
1819 {"soft-version", 0x3c2000, 0x00100},
1820 {"support-list", 0x3c3000, 0x01000},
1821 {"profile", 0x3c4000, 0x08000},
1822 {"user-config", 0x3d0000, 0x10000},
1823 {"default-config", 0x3e0000, 0x10000},
1824 {"radio", 0x3f0000, 0x10000},
1825 {NULL, 0, 0}
1826 },
1827
1828 .first_sysupgrade_partition = "os-image",
1829 .last_sysupgrade_partition = "file-system"
1830 },
1831
1832 /** Firmware layout for the TL-WPA8630P v2 (EU)*/
1833 {
1834 .id = "TL-WPA8630P-V2.0-EU",
1835 .vendor = "",
1836 .support_list =
1837 "SupportList:\n"
1838 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
1839 .part_trail = 0x00,
1840 .soft_ver = SOFT_VER_DEFAULT,
1841
1842 .partitions = {
1843 {"factory-uboot", 0x00000, 0x20000},
1844 {"fs-uboot", 0x20000, 0x20000},
1845 {"firmware", 0x40000, 0x5e0000},
1846 {"partition-table", 0x620000, 0x02000},
1847 {"default-mac", 0x630000, 0x00020},
1848 {"pin", 0x630100, 0x00020},
1849 {"device-id", 0x630200, 0x00030},
1850 {"product-info", 0x631100, 0x01000},
1851 {"extra-para", 0x632100, 0x01000},
1852 {"soft-version", 0x640000, 0x01000},
1853 {"support-list", 0x641000, 0x01000},
1854 {"profile", 0x642000, 0x08000},
1855 {"user-config", 0x650000, 0x10000},
1856 {"default-config", 0x660000, 0x10000},
1857 {"default-nvm", 0x670000, 0xc0000},
1858 {"default-pib", 0x730000, 0x40000},
1859 {"radio", 0x7f0000, 0x10000},
1860 {NULL, 0, 0}
1861 },
1862
1863 .first_sysupgrade_partition = "os-image",
1864 .last_sysupgrade_partition = "file-system"
1865 },
1866
1867 /** Firmware layout for the TL-WPA8630P v2 (INT)*/
1868 {
1869 .id = "TL-WPA8630P-V2-INT",
1870 .vendor = "",
1871 .support_list =
1872 "SupportList:\n"
1873 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
1874 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
1875 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
1876 .part_trail = 0x00,
1877 .soft_ver = SOFT_VER_DEFAULT,
1878
1879 .partitions = {
1880 {"factory-uboot", 0x00000, 0x20000},
1881 {"fs-uboot", 0x20000, 0x20000},
1882 {"firmware", 0x40000, 0x5e0000},
1883 {"partition-table", 0x620000, 0x02000},
1884 {"extra-para", 0x632100, 0x01000},
1885 {"soft-version", 0x640000, 0x01000},
1886 {"support-list", 0x641000, 0x01000},
1887 {"profile", 0x642000, 0x08000},
1888 {"user-config", 0x650000, 0x10000},
1889 {"default-config", 0x660000, 0x10000},
1890 {"default-nvm", 0x670000, 0xc0000},
1891 {"default-pib", 0x730000, 0x40000},
1892 {"default-mac", 0x7e0000, 0x00020},
1893 {"pin", 0x7e0100, 0x00020},
1894 {"device-id", 0x7e0200, 0x00030},
1895 {"product-info", 0x7e1100, 0x01000},
1896 {"radio", 0x7f0000, 0x10000},
1897 {NULL, 0, 0}
1898 },
1899
1900 .first_sysupgrade_partition = "os-image",
1901 .last_sysupgrade_partition = "file-system"
1902 },
1903
1904 /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
1905 {
1906 .id = "TL-WPA8630P-V2.1-EU",
1907 .vendor = "",
1908 .support_list =
1909 "SupportList:\n"
1910 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
1911 .part_trail = 0x00,
1912 .soft_ver = SOFT_VER_DEFAULT,
1913
1914 .partitions = {
1915 {"factory-uboot", 0x00000, 0x20000},
1916 {"fs-uboot", 0x20000, 0x20000},
1917 {"firmware", 0x40000, 0x5e0000},
1918 {"extra-para", 0x680000, 0x01000},
1919 {"product-info", 0x690000, 0x01000},
1920 {"partition-table", 0x6a0000, 0x02000},
1921 {"soft-version", 0x6b0000, 0x01000},
1922 {"support-list", 0x6b1000, 0x01000},
1923 {"profile", 0x6b2000, 0x08000},
1924 {"user-config", 0x6c0000, 0x10000},
1925 {"default-config", 0x6d0000, 0x10000},
1926 {"default-nvm", 0x6e0000, 0xc0000},
1927 {"default-pib", 0x7a0000, 0x40000},
1928 {"default-mac", 0x7e0000, 0x00020},
1929 {"pin", 0x7e0100, 0x00020},
1930 {"device-id", 0x7e0200, 0x00030},
1931 {"radio", 0x7f0000, 0x10000},
1932 {NULL, 0, 0}
1933 },
1934
1935 .first_sysupgrade_partition = "os-image",
1936 .last_sysupgrade_partition = "file-system"
1937 },
1938
1939 /** Firmware layout for the TL-WR1043 v5 */
1940 {
1941 .id = "TLWR1043NV5",
1942 .vendor = "",
1943 .support_list =
1944 "SupportList:\n"
1945 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
1946 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
1947 .part_trail = 0x00,
1948 .soft_ver = SOFT_VER_TEXT("soft_ver:1.0.0\n"),
1949 .partitions = {
1950 {"factory-boot", 0x00000, 0x20000},
1951 {"fs-uboot", 0x20000, 0x20000},
1952 {"firmware", 0x40000, 0xec0000},
1953 {"default-mac", 0xf00000, 0x00200},
1954 {"pin", 0xf00200, 0x00200},
1955 {"device-id", 0xf00400, 0x00100},
1956 {"product-info", 0xf00500, 0x0fb00},
1957 {"soft-version", 0xf10000, 0x01000},
1958 {"extra-para", 0xf11000, 0x01000},
1959 {"support-list", 0xf12000, 0x0a000},
1960 {"profile", 0xf1c000, 0x04000},
1961 {"default-config", 0xf20000, 0x10000},
1962 {"user-config", 0xf30000, 0x40000},
1963 {"qos-db", 0xf70000, 0x40000},
1964 {"certificate", 0xfb0000, 0x10000},
1965 {"partition-table", 0xfc0000, 0x10000},
1966 {"log", 0xfd0000, 0x20000},
1967 {"radio", 0xff0000, 0x10000},
1968 {NULL, 0, 0}
1969 },
1970 .first_sysupgrade_partition = "os-image",
1971 .last_sysupgrade_partition = "file-system"
1972 },
1973
1974 /** Firmware layout for the TL-WR1043 v4 */
1975 {
1976 .id = "TLWR1043NDV4",
1977 .vendor = "",
1978 .support_list =
1979 "SupportList:\n"
1980 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
1981 .part_trail = 0x00,
1982 .soft_ver = SOFT_VER_DEFAULT,
1983
1984 /* We're using a dynamic kernel/rootfs split here */
1985 .partitions = {
1986 {"fs-uboot", 0x00000, 0x20000},
1987 {"firmware", 0x20000, 0xf30000},
1988 {"default-mac", 0xf50000, 0x00200},
1989 {"pin", 0xf50200, 0x00200},
1990 {"product-info", 0xf50400, 0x0fc00},
1991 {"soft-version", 0xf60000, 0x0b000},
1992 {"support-list", 0xf6b000, 0x04000},
1993 {"profile", 0xf70000, 0x04000},
1994 {"default-config", 0xf74000, 0x0b000},
1995 {"user-config", 0xf80000, 0x40000},
1996 {"partition-table", 0xfc0000, 0x10000},
1997 {"log", 0xfd0000, 0x20000},
1998 {"radio", 0xff0000, 0x10000},
1999 {NULL, 0, 0}
2000 },
2001
2002 .first_sysupgrade_partition = "os-image",
2003 .last_sysupgrade_partition = "file-system"
2004 },
2005
2006 /** Firmware layout for the TL-WR902AC v1 */
2007 {
2008 .id = "TL-WR902AC-V1",
2009 .vendor = "",
2010 .support_list =
2011 "SupportList:\n"
2012 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
2013 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
2014 .part_trail = 0x00,
2015 .soft_ver = SOFT_VER_DEFAULT,
2016
2017 /**
2018 384KB were moved from file-system to os-image
2019 in comparison to the stock image
2020 */
2021 .partitions = {
2022 {"fs-uboot", 0x00000, 0x20000},
2023 {"firmware", 0x20000, 0x730000},
2024 {"default-mac", 0x750000, 0x00200},
2025 {"pin", 0x750200, 0x00200},
2026 {"product-info", 0x750400, 0x0fc00},
2027 {"soft-version", 0x760000, 0x0b000},
2028 {"support-list", 0x76b000, 0x04000},
2029 {"profile", 0x770000, 0x04000},
2030 {"default-config", 0x774000, 0x0b000},
2031 {"user-config", 0x780000, 0x40000},
2032 {"partition-table", 0x7c0000, 0x10000},
2033 {"log", 0x7d0000, 0x20000},
2034 {"radio", 0x7f0000, 0x10000},
2035 {NULL, 0, 0}
2036 },
2037
2038 .first_sysupgrade_partition = "os-image",
2039 .last_sysupgrade_partition = "file-system",
2040 },
2041
2042 /** Firmware layout for the TL-WR941HP v1 */
2043 {
2044 .id = "TL-WR941HP-V1",
2045 .vendor = "",
2046 .support_list =
2047 "SupportList:\n"
2048 "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n",
2049 .part_trail = 0x00,
2050 .soft_ver = SOFT_VER_DEFAULT,
2051
2052 .partitions = {
2053 {"fs-uboot", 0x00000, 0x20000},
2054 {"firmware", 0x20000, 0x730000},
2055 {"default-mac", 0x750000, 0x00200},
2056 {"pin", 0x750200, 0x00200},
2057 {"product-info", 0x750400, 0x0fc00},
2058 {"soft-version", 0x760000, 0x0b000},
2059 {"support-list", 0x76b000, 0x04000},
2060 {"profile", 0x770000, 0x04000},
2061 {"default-config", 0x774000, 0x0b000},
2062 {"user-config", 0x780000, 0x40000},
2063 {"partition-table", 0x7c0000, 0x10000},
2064 {"log", 0x7d0000, 0x20000},
2065 {"radio", 0x7f0000, 0x10000},
2066 {NULL, 0, 0}
2067 },
2068
2069 .first_sysupgrade_partition = "os-image",
2070 .last_sysupgrade_partition = "file-system",
2071 },
2072
2073 /** Firmware layout for the TL-WR942N V1 */
2074 {
2075 .id = "TLWR942NV1",
2076 .vendor = "",
2077 .support_list =
2078 "SupportList:\r\n"
2079 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
2080 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
2081 .part_trail = 0x00,
2082 .soft_ver = SOFT_VER_DEFAULT,
2083
2084 .partitions = {
2085 {"fs-uboot", 0x00000, 0x20000},
2086 {"firmware", 0x20000, 0xe20000},
2087 {"default-mac", 0xe40000, 0x00200},
2088 {"pin", 0xe40200, 0x00200},
2089 {"product-info", 0xe40400, 0x0fc00},
2090 {"partition-table", 0xe50000, 0x10000},
2091 {"soft-version", 0xe60000, 0x10000},
2092 {"support-list", 0xe70000, 0x10000},
2093 {"profile", 0xe80000, 0x10000},
2094 {"default-config", 0xe90000, 0x10000},
2095 {"user-config", 0xea0000, 0x40000},
2096 {"qos-db", 0xee0000, 0x40000},
2097 {"certificate", 0xf20000, 0x10000},
2098 {"usb-config", 0xfb0000, 0x10000},
2099 {"log", 0xfc0000, 0x20000},
2100 {"radio-bk", 0xfe0000, 0x10000},
2101 {"radio", 0xff0000, 0x10000},
2102 {NULL, 0, 0}
2103 },
2104
2105 .first_sysupgrade_partition = "os-image",
2106 .last_sysupgrade_partition = "file-system",
2107 },
2108
2109 /** Firmware layout for the RE200 v2 */
2110 {
2111 .id = "RE200-V2",
2112 .vendor = "",
2113 .support_list =
2114 "SupportList:\n"
2115 "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
2116 "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
2117 "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
2118 "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
2119 "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
2120 "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
2121 "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
2122 "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
2123 "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
2124 "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
2125 "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
2126 "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
2127 "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
2128 .part_trail = 0x00,
2129 .soft_ver = SOFT_VER_DEFAULT,
2130
2131 .partitions = {
2132 {"fs-uboot", 0x00000, 0x20000},
2133 {"firmware", 0x20000, 0x7a0000},
2134 {"partition-table", 0x7c0000, 0x02000},
2135 {"default-mac", 0x7c2000, 0x00020},
2136 {"pin", 0x7c2100, 0x00020},
2137 {"product-info", 0x7c3100, 0x01000},
2138 {"soft-version", 0x7c4200, 0x01000},
2139 {"support-list", 0x7c5200, 0x01000},
2140 {"profile", 0x7c6200, 0x08000},
2141 {"config-info", 0x7ce200, 0x00400},
2142 {"user-config", 0x7d0000, 0x10000},
2143 {"default-config", 0x7e0000, 0x10000},
2144 {"radio", 0x7f0000, 0x10000},
2145 {NULL, 0, 0}
2146 },
2147
2148 .first_sysupgrade_partition = "os-image",
2149 .last_sysupgrade_partition = "file-system"
2150 },
2151
2152 /** Firmware layout for the RE200 v3 */
2153 {
2154 .id = "RE200-V3",
2155 .vendor = "",
2156 .support_list =
2157 "SupportList:\n"
2158 "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
2159 "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
2160 "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
2161 "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
2162 "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
2163 "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
2164 "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
2165 "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
2166 "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
2167 "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
2168 "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
2169 "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
2170 "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
2171 "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
2172 .part_trail = 0x00,
2173 .soft_ver = SOFT_VER_DEFAULT,
2174
2175 .partitions = {
2176 {"fs-uboot", 0x00000, 0x20000},
2177 {"firmware", 0x20000, 0x7a0000},
2178 {"partition-table", 0x7c0000, 0x02000},
2179 {"default-mac", 0x7c2000, 0x00020},
2180 {"pin", 0x7c2100, 0x00020},
2181 {"product-info", 0x7c3100, 0x01000},
2182 {"soft-version", 0x7c4200, 0x01000},
2183 {"support-list", 0x7c5200, 0x01000},
2184 {"profile", 0x7c6200, 0x08000},
2185 {"config-info", 0x7ce200, 0x00400},
2186 {"user-config", 0x7d0000, 0x10000},
2187 {"default-config", 0x7e0000, 0x10000},
2188 {"radio", 0x7f0000, 0x10000},
2189 {NULL, 0, 0}
2190 },
2191
2192 .first_sysupgrade_partition = "os-image",
2193 .last_sysupgrade_partition = "file-system"
2194 },
2195
2196 /** Firmware layout for the RE200 v4 */
2197 {
2198 .id = "RE200-V4",
2199 .vendor = "",
2200 .support_list =
2201 "SupportList:\n"
2202 "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2203 "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2204 "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2205 "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2206 "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2207 "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2208 "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2209 "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2210 "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2211 "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2212 "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2213 "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2214 "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2215 "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2216 .part_trail = 0x00,
2217 .soft_ver = SOFT_VER_TEXT("soft_ver:1.1.0\n"),
2218
2219 .partitions = {
2220 {"fs-uboot", 0x00000, 0x20000},
2221 {"firmware", 0x20000, 0x7a0000},
2222 {"partition-table", 0x7c0000, 0x02000},
2223 {"default-mac", 0x7c2000, 0x00020},
2224 {"pin", 0x7c2100, 0x00020},
2225 {"product-info", 0x7c3100, 0x01000},
2226 {"soft-version", 0x7c4200, 0x01000},
2227 {"support-list", 0x7c5200, 0x01000},
2228 {"profile", 0x7c6200, 0x08000},
2229 {"config-info", 0x7ce200, 0x00400},
2230 {"user-config", 0x7d0000, 0x10000},
2231 {"default-config", 0x7e0000, 0x10000},
2232 {"radio", 0x7f0000, 0x10000},
2233 {NULL, 0, 0}
2234 },
2235
2236 .first_sysupgrade_partition = "os-image",
2237 .last_sysupgrade_partition = "file-system"
2238 },
2239
2240 /** Firmware layout for the RE220 v2 */
2241 {
2242 .id = "RE220-V2",
2243 .vendor = "",
2244 .support_list =
2245 "SupportList:\n"
2246 "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2247 "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2248 "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2249 "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2250 "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2251 "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2252 "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2253 "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2254 "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2255 "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2256 "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2257 "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2258 "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2259 .part_trail = 0x00,
2260 .soft_ver = SOFT_VER_DEFAULT,
2261
2262 .partitions = {
2263 {"fs-uboot", 0x00000, 0x20000},
2264 {"firmware", 0x20000, 0x7a0000},
2265 {"partition-table", 0x7c0000, 0x02000},
2266 {"default-mac", 0x7c2000, 0x00020},
2267 {"pin", 0x7c2100, 0x00020},
2268 {"product-info", 0x7c3100, 0x01000},
2269 {"soft-version", 0x7c4200, 0x01000},
2270 {"support-list", 0x7c5200, 0x01000},
2271 {"profile", 0x7c6200, 0x08000},
2272 {"config-info", 0x7ce200, 0x00400},
2273 {"user-config", 0x7d0000, 0x10000},
2274 {"default-config", 0x7e0000, 0x10000},
2275 {"radio", 0x7f0000, 0x10000},
2276 {NULL, 0, 0}
2277 },
2278
2279 .first_sysupgrade_partition = "os-image",
2280 .last_sysupgrade_partition = "file-system"
2281 },
2282
2283 /** Firmware layout for the RE305 v1 */
2284 {
2285 .id = "RE305-V1",
2286 .vendor = "",
2287 .support_list =
2288 "SupportList:\n"
2289 "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2290 "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2291 "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2292 "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2293 "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2294 "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2295 "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2296 .part_trail = 0x00,
2297 .soft_ver = SOFT_VER_DEFAULT,
2298
2299 .partitions = {
2300 {"fs-uboot", 0x00000, 0x20000},
2301 {"firmware", 0x20000, 0x5e0000},
2302 {"partition-table", 0x600000, 0x02000},
2303 {"default-mac", 0x610000, 0x00020},
2304 {"pin", 0x610100, 0x00020},
2305 {"product-info", 0x611100, 0x01000},
2306 {"soft-version", 0x620000, 0x01000},
2307 {"support-list", 0x621000, 0x01000},
2308 {"profile", 0x622000, 0x08000},
2309 {"user-config", 0x630000, 0x10000},
2310 {"default-config", 0x640000, 0x10000},
2311 {"radio", 0x7f0000, 0x10000},
2312 {NULL, 0, 0}
2313 },
2314
2315 .first_sysupgrade_partition = "os-image",
2316 .last_sysupgrade_partition = "file-system"
2317 },
2318
2319 /** Firmware layout for the RE305 v3 */
2320 {
2321 .id = "RE305-V3",
2322 .vendor = "",
2323 .support_list =
2324 "SupportList:\n"
2325 "{product_name:RE305,product_ver:3.0.0,special_id:00000000}\n"
2326 "{product_name:RE305,product_ver:3.0.0,special_id:45550000}\n"
2327 "{product_name:RE305,product_ver:3.0.0,special_id:4A500000}\n"
2328 "{product_name:RE305,product_ver:3.0.0,special_id:4B520000}\n"
2329 "{product_name:RE305,product_ver:3.0.0,special_id:41550000}\n"
2330 "{product_name:RE305,product_ver:3.0.0,special_id:42520000}\n"
2331 "{product_name:RE305,product_ver:3.0.0,special_id:55530000}\n"
2332 "{product_name:RE305,product_ver:3.0.0,special_id:45530000}\n"
2333 "{product_name:RE305,product_ver:3.0.0,special_id:41530000}\n"
2334 "{product_name:RE305,product_ver:3.0.0,special_id:43410000}\n"
2335 "{product_name:RE305,product_ver:3.0.0,special_id:52550000}\n",
2336 .part_trail = 0x00,
2337 .soft_ver = SOFT_VER_TEXT("soft_ver:2.0.0\n"),
2338
2339 .partitions = {
2340 {"fs-uboot", 0x00000, 0x20000},
2341 {"firmware", 0x20000, 0x7a0000},
2342 {"partition-table", 0x7c0000, 0x02000},
2343 {"default-mac", 0x7c2000, 0x00020},
2344 {"pin", 0x7c2100, 0x00020},
2345 {"product-info", 0x7c3100, 0x01000},
2346 {"soft-version", 0x7c4200, 0x01000},
2347 {"support-list", 0x7c5200, 0x01000},
2348 {"profile", 0x7c6200, 0x08000},
2349 {"config-info", 0x7ce200, 0x00400},
2350 {"user-config", 0x7d0000, 0x10000},
2351 {"default-config", 0x7e0000, 0x10000},
2352 {"radio", 0x7f0000, 0x10000},
2353 {NULL, 0, 0}
2354 },
2355
2356 .first_sysupgrade_partition = "os-image",
2357 .last_sysupgrade_partition = "file-system"
2358 },
2359
2360 /** Firmware layout for the RE350 v1 */
2361 {
2362 .id = "RE350-V1",
2363 .vendor = "",
2364 .support_list =
2365 "SupportList:\n"
2366 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2367 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2368 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2369 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2370 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2371 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2372 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2373 .part_trail = 0x00,
2374 .soft_ver = SOFT_VER_DEFAULT,
2375
2376 /** We're using a dynamic kernel/rootfs split here */
2377 .partitions = {
2378 {"fs-uboot", 0x00000, 0x20000},
2379 {"firmware", 0x20000, 0x5e0000},
2380 {"partition-table", 0x600000, 0x02000},
2381 {"default-mac", 0x610000, 0x00020},
2382 {"pin", 0x610100, 0x00020},
2383 {"product-info", 0x611100, 0x01000},
2384 {"soft-version", 0x620000, 0x01000},
2385 {"support-list", 0x621000, 0x01000},
2386 {"profile", 0x622000, 0x08000},
2387 {"user-config", 0x630000, 0x10000},
2388 {"default-config", 0x640000, 0x10000},
2389 {"radio", 0x7f0000, 0x10000},
2390 {NULL, 0, 0}
2391 },
2392
2393 .first_sysupgrade_partition = "os-image",
2394 .last_sysupgrade_partition = "file-system"
2395 },
2396
2397 /** Firmware layout for the RE350K v1 */
2398 {
2399 .id = "RE350K-V1",
2400 .vendor = "",
2401 .support_list =
2402 "SupportList:\n"
2403 "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2404 .part_trail = 0x00,
2405 .soft_ver = SOFT_VER_DEFAULT,
2406
2407 /** We're using a dynamic kernel/rootfs split here */
2408 .partitions = {
2409 {"fs-uboot", 0x00000, 0x20000},
2410 {"firmware", 0x20000, 0xd70000},
2411 {"partition-table", 0xd90000, 0x02000},
2412 {"default-mac", 0xda0000, 0x00020},
2413 {"pin", 0xda0100, 0x00020},
2414 {"product-info", 0xda1100, 0x01000},
2415 {"soft-version", 0xdb0000, 0x01000},
2416 {"support-list", 0xdb1000, 0x01000},
2417 {"profile", 0xdb2000, 0x08000},
2418 {"user-config", 0xdc0000, 0x10000},
2419 {"default-config", 0xdd0000, 0x10000},
2420 {"device-id", 0xde0000, 0x00108},
2421 {"radio", 0xff0000, 0x10000},
2422 {NULL, 0, 0}
2423 },
2424
2425 .first_sysupgrade_partition = "os-image",
2426 .last_sysupgrade_partition = "file-system"
2427 },
2428
2429 /** Firmware layout for the RE355 */
2430 {
2431 .id = "RE355",
2432 .vendor = "",
2433 .support_list =
2434 "SupportList:\r\n"
2435 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2436 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2437 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2438 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2439 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2440 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2441 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2442 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2443 .part_trail = 0x00,
2444 .soft_ver = SOFT_VER_DEFAULT,
2445
2446 /* We're using a dynamic kernel/rootfs split here */
2447 .partitions = {
2448 {"fs-uboot", 0x00000, 0x20000},
2449 {"firmware", 0x20000, 0x5e0000},
2450 {"partition-table", 0x600000, 0x02000},
2451 {"default-mac", 0x610000, 0x00020},
2452 {"pin", 0x610100, 0x00020},
2453 {"product-info", 0x611100, 0x01000},
2454 {"soft-version", 0x620000, 0x01000},
2455 {"support-list", 0x621000, 0x01000},
2456 {"profile", 0x622000, 0x08000},
2457 {"user-config", 0x630000, 0x10000},
2458 {"default-config", 0x640000, 0x10000},
2459 {"radio", 0x7f0000, 0x10000},
2460 {NULL, 0, 0}
2461 },
2462
2463 .first_sysupgrade_partition = "os-image",
2464 .last_sysupgrade_partition = "file-system"
2465 },
2466
2467 /** Firmware layout for the RE450 */
2468 {
2469 .id = "RE450",
2470 .vendor = "",
2471 .support_list =
2472 "SupportList:\r\n"
2473 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2474 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
2475 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
2476 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
2477 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
2478 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
2479 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
2480 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
2481 .part_trail = 0x00,
2482 .soft_ver = SOFT_VER_DEFAULT,
2483
2484 /** We're using a dynamic kernel/rootfs split here */
2485 .partitions = {
2486 {"fs-uboot", 0x00000, 0x20000},
2487 {"firmware", 0x20000, 0x5e0000},
2488 {"partition-table", 0x600000, 0x02000},
2489 {"default-mac", 0x610000, 0x00020},
2490 {"pin", 0x610100, 0x00020},
2491 {"product-info", 0x611100, 0x01000},
2492 {"soft-version", 0x620000, 0x01000},
2493 {"support-list", 0x621000, 0x01000},
2494 {"profile", 0x622000, 0x08000},
2495 {"user-config", 0x630000, 0x10000},
2496 {"default-config", 0x640000, 0x10000},
2497 {"radio", 0x7f0000, 0x10000},
2498 {NULL, 0, 0}
2499 },
2500
2501 .first_sysupgrade_partition = "os-image",
2502 .last_sysupgrade_partition = "file-system"
2503 },
2504
2505 /** Firmware layout for the RE450 v2 */
2506 {
2507 .id = "RE450-V2",
2508 .vendor = "",
2509 .support_list =
2510 "SupportList:\r\n"
2511 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
2512 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
2513 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
2514 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
2515 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
2516 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
2517 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
2518 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
2519 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
2520 .part_trail = 0x00,
2521 .soft_ver = SOFT_VER_DEFAULT,
2522
2523 /* We're using a dynamic kernel/rootfs split here */
2524 .partitions = {
2525 {"fs-uboot", 0x00000, 0x20000},
2526 {"firmware", 0x20000, 0x5e0000},
2527 {"partition-table", 0x600000, 0x02000},
2528 {"default-mac", 0x610000, 0x00020},
2529 {"pin", 0x610100, 0x00020},
2530 {"product-info", 0x611100, 0x01000},
2531 {"soft-version", 0x620000, 0x01000},
2532 {"support-list", 0x621000, 0x01000},
2533 {"profile", 0x622000, 0x08000},
2534 {"user-config", 0x630000, 0x10000},
2535 {"default-config", 0x640000, 0x10000},
2536 {"radio", 0x7f0000, 0x10000},
2537 {NULL, 0, 0}
2538 },
2539
2540 .first_sysupgrade_partition = "os-image",
2541 .last_sysupgrade_partition = "file-system"
2542 },
2543
2544 /** Firmware layout for the RE450 v3 */
2545 {
2546 .id = "RE450-V3",
2547 .vendor = "",
2548 .support_list =
2549 "SupportList:\r\n"
2550 "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
2551 "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
2552 "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
2553 "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
2554 "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
2555 "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
2556 "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
2557 "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
2558 "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
2559 .part_trail = 0x00,
2560 .soft_ver = SOFT_VER_DEFAULT,
2561
2562 /* We're using a dynamic kernel/rootfs split here */
2563 .partitions = {
2564 {"fs-uboot", 0x00000, 0x20000},
2565 {"default-mac", 0x20000, 0x00020},
2566 {"pin", 0x20020, 0x00020},
2567 {"product-info", 0x21000, 0x01000},
2568 {"partition-table", 0x22000, 0x02000},
2569 {"soft-version", 0x24000, 0x01000},
2570 {"support-list", 0x25000, 0x01000},
2571 {"profile", 0x26000, 0x08000},
2572 {"user-config", 0x2e000, 0x10000},
2573 {"default-config", 0x3e000, 0x10000},
2574 {"config-info", 0x4e000, 0x00400},
2575 {"firmware", 0x50000, 0x7a0000},
2576 {"radio", 0x7f0000, 0x10000},
2577 {NULL, 0, 0}
2578 },
2579
2580 .first_sysupgrade_partition = "os-image",
2581 .last_sysupgrade_partition = "file-system"
2582 },
2583
2584 /** Firmware layout for the RE455 v1 */
2585 {
2586 .id = "RE455-V1",
2587 .vendor = "",
2588 .support_list =
2589 "SupportList:\r\n"
2590 "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
2591 "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
2592 "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
2593 "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
2594 "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
2595 "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
2596 "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
2597 "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
2598 "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
2599 .part_trail = 0x00,
2600 .soft_ver = SOFT_VER_DEFAULT,
2601
2602 /* We're using a dynamic kernel/rootfs split here */
2603 .partitions = {
2604 {"fs-uboot", 0x00000, 0x20000},
2605 {"default-mac", 0x20000, 0x00020},
2606 {"pin", 0x20020, 0x00020},
2607 {"product-info", 0x21000, 0x01000},
2608 {"partition-table", 0x22000, 0x02000},
2609 {"soft-version", 0x24000, 0x01000},
2610 {"support-list", 0x25000, 0x01000},
2611 {"profile", 0x26000, 0x08000},
2612 {"user-config", 0x2e000, 0x10000},
2613 {"default-config", 0x3e000, 0x10000},
2614 {"config-info", 0x4e000, 0x00400},
2615 {"firmware", 0x50000, 0x7a0000},
2616 {"radio", 0x7f0000, 0x10000},
2617 {NULL, 0, 0}
2618 },
2619
2620 .first_sysupgrade_partition = "os-image",
2621 .last_sysupgrade_partition = "file-system"
2622 },
2623
2624 /** Firmware layout for the RE500 */
2625 {
2626 .id = "RE500-V1",
2627 .vendor = "",
2628 .support_list =
2629 "SupportList:\r\n"
2630 "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
2631 "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
2632 "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
2633 "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
2634 "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
2635 "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
2636 "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
2637 .part_trail = 0x00,
2638 .soft_ver = SOFT_VER_DEFAULT,
2639
2640 /* We're using a dynamic kernel/rootfs split here */
2641 .partitions = {
2642 {"fs-uboot", 0x00000, 0x20000},
2643 {"firmware", 0x20000, 0xde0000},
2644 {"partition-table", 0xe00000, 0x02000},
2645 {"default-mac", 0xe10000, 0x00020},
2646 {"pin", 0xe10100, 0x00020},
2647 {"product-info", 0xe11100, 0x01000},
2648 {"soft-version", 0xe20000, 0x01000},
2649 {"support-list", 0xe21000, 0x01000},
2650 {"profile", 0xe22000, 0x08000},
2651 {"user-config", 0xe30000, 0x10000},
2652 {"default-config", 0xe40000, 0x10000},
2653 {"radio", 0xff0000, 0x10000},
2654 {NULL, 0, 0}
2655 },
2656
2657 .first_sysupgrade_partition = "os-image",
2658 .last_sysupgrade_partition = "file-system"
2659 },
2660
2661 /** Firmware layout for the RE650 */
2662 {
2663 .id = "RE650-V1",
2664 .vendor = "",
2665 .support_list =
2666 "SupportList:\r\n"
2667 "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
2668 "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
2669 "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
2670 "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
2671 "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
2672 "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
2673 "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
2674 .part_trail = 0x00,
2675 .soft_ver = SOFT_VER_DEFAULT,
2676
2677 /* We're using a dynamic kernel/rootfs split here */
2678 .partitions = {
2679 {"fs-uboot", 0x00000, 0x20000},
2680 {"firmware", 0x20000, 0xde0000},
2681 {"partition-table", 0xe00000, 0x02000},
2682 {"default-mac", 0xe10000, 0x00020},
2683 {"pin", 0xe10100, 0x00020},
2684 {"product-info", 0xe11100, 0x01000},
2685 {"soft-version", 0xe20000, 0x01000},
2686 {"support-list", 0xe21000, 0x01000},
2687 {"profile", 0xe22000, 0x08000},
2688 {"user-config", 0xe30000, 0x10000},
2689 {"default-config", 0xe40000, 0x10000},
2690 {"radio", 0xff0000, 0x10000},
2691 {NULL, 0, 0}
2692 },
2693
2694 .first_sysupgrade_partition = "os-image",
2695 .last_sysupgrade_partition = "file-system"
2696 },
2697
2698 {}
2699 };
2700
2701 #define error(_ret, _errno, _str, ...) \
2702 do { \
2703 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
2704 strerror(_errno)); \
2705 if (_ret) \
2706 exit(_ret); \
2707 } while (0)
2708
2709
2710 /** Stores a uint32 as big endian */
2711 static inline void put32(uint8_t *buf, uint32_t val) {
2712 buf[0] = val >> 24;
2713 buf[1] = val >> 16;
2714 buf[2] = val >> 8;
2715 buf[3] = val;
2716 }
2717
2718 static inline bool meta_partition_should_pad(enum partition_trail_value pv)
2719 {
2720 return (pv >= 0) && (pv <= PART_TRAIL_MAX);
2721 }
2722
2723 /** Allocate a padded meta partition with a correctly initialised header
2724 * If the `data` pointer is NULL, then the required space is only allocated,
2725 * otherwise `data_len` bytes will be copied from `data` into the partition
2726 * entry. */
2727 static struct image_partition_entry init_meta_partition_entry(
2728 const char *name, const void *data, uint32_t data_len,
2729 enum partition_trail_value pad_value)
2730 {
2731 uint32_t total_len = sizeof(struct meta_header) + data_len;
2732 if (meta_partition_should_pad(pad_value))
2733 total_len += 1;
2734
2735 struct image_partition_entry entry = {
2736 .name = name,
2737 .size = total_len,
2738 .data = malloc(total_len)
2739 };
2740 if (!entry.data)
2741 error(1, errno, "failed to allocate meta partition entry");
2742
2743 struct meta_header *header = (struct meta_header *)entry.data;
2744 header->length = htonl(data_len);
2745 header->zero = 0;
2746
2747 if (data)
2748 memcpy(entry.data+sizeof(*header), data, data_len);
2749
2750 if (meta_partition_should_pad(pad_value))
2751 entry.data[total_len - 1] = (uint8_t) pad_value;
2752
2753 return entry;
2754 }
2755
2756 /** Allocates a new image partition */
2757 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
2758 struct image_partition_entry entry = {name, len, malloc(len)};
2759 if (!entry.data)
2760 error(1, errno, "malloc");
2761
2762 return entry;
2763 }
2764
2765 /** Frees an image partition */
2766 static void free_image_partition(struct image_partition_entry entry) {
2767 free(entry.data);
2768 }
2769
2770 static time_t source_date_epoch = -1;
2771 static void set_source_date_epoch() {
2772 char *env = getenv("SOURCE_DATE_EPOCH");
2773 char *endptr = env;
2774 errno = 0;
2775 if (env && *env) {
2776 source_date_epoch = strtoull(env, &endptr, 10);
2777 if (errno || (endptr && *endptr != '\0')) {
2778 fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
2779 exit(1);
2780 }
2781 }
2782 }
2783
2784 /** Generates the partition-table partition */
2785 static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
2786 struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800);
2787
2788 char *s = (char *)entry.data, *end = (char *)(s+entry.size);
2789
2790 *(s++) = 0x00;
2791 *(s++) = 0x04;
2792 *(s++) = 0x00;
2793 *(s++) = 0x00;
2794
2795 size_t i;
2796 for (i = 0; p[i].name; i++) {
2797 size_t len = end-s;
2798 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size);
2799
2800 if (w > len-1)
2801 error(1, 0, "flash partition table overflow?");
2802
2803 s += w;
2804 }
2805
2806 s++;
2807
2808 memset(s, 0xff, end-s);
2809
2810 return entry;
2811 }
2812
2813
2814 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
2815 static inline uint8_t bcd(uint8_t v) {
2816 return 0x10 * (v/10) + v%10;
2817 }
2818
2819
2820 /** Generates the soft-version partition */
2821 static struct image_partition_entry make_soft_version(
2822 const struct device_info *info, uint32_t rev)
2823 {
2824 /** If an info string is provided, use this instead of
2825 * the structured data, and include the null-termination */
2826 if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) {
2827 uint32_t len = strlen(info->soft_ver.text) + 1;
2828 return init_meta_partition_entry("soft-version",
2829 info->soft_ver.text, len, info->part_trail);
2830 }
2831
2832 time_t t;
2833
2834 if (source_date_epoch != -1)
2835 t = source_date_epoch;
2836 else if (time(&t) == (time_t)(-1))
2837 error(1, errno, "time");
2838
2839 struct tm *tm = gmtime(&t);
2840
2841 struct soft_version s = {
2842 .pad1 = 0xff,
2843
2844 .version_major = info->soft_ver.num[0],
2845 .version_minor = info->soft_ver.num[1],
2846 .version_patch = info->soft_ver.num[2],
2847
2848 .year_hi = bcd((1900+tm->tm_year)/100),
2849 .year_lo = bcd(tm->tm_year%100),
2850 .month = bcd(tm->tm_mon+1),
2851 .day = bcd(tm->tm_mday),
2852 .rev = htonl(rev),
2853
2854 .compat_level = htonl(info->soft_ver_compat_level)
2855 };
2856
2857 if (info->soft_ver_compat_level == 0)
2858 return init_meta_partition_entry("soft-version", &s,
2859 (uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
2860 info->part_trail);
2861 else
2862 return init_meta_partition_entry("soft-version", &s,
2863 sizeof(s), info->part_trail);
2864 }
2865
2866 /** Generates the support-list partition */
2867 static struct image_partition_entry make_support_list(
2868 const struct device_info *info)
2869 {
2870 uint32_t len = strlen(info->support_list);
2871 return init_meta_partition_entry("support-list", info->support_list,
2872 len, info->part_trail);
2873 }
2874
2875 /** Partition with extra-para data */
2876 static struct image_partition_entry make_extra_para(
2877 const struct device_info *info, const uint8_t *extra_para, size_t len)
2878 {
2879 return init_meta_partition_entry("extra-para", extra_para, len,
2880 info->part_trail);
2881 }
2882
2883 /** Creates a new image partition with an arbitrary name from a file */
2884 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) {
2885 struct stat statbuf;
2886
2887 if (stat(filename, &statbuf) < 0)
2888 error(1, errno, "unable to stat file `%s'", filename);
2889
2890 size_t len = statbuf.st_size;
2891
2892 if (add_jffs2_eof) {
2893 if (file_system_partition)
2894 len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
2895 else
2896 len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
2897 }
2898
2899 struct image_partition_entry entry = alloc_image_partition(part_name, len);
2900
2901 FILE *file = fopen(filename, "rb");
2902 if (!file)
2903 error(1, errno, "unable to open file `%s'", filename);
2904
2905 if (fread(entry.data, statbuf.st_size, 1, file) != 1)
2906 error(1, errno, "unable to read file `%s'", filename);
2907
2908 if (add_jffs2_eof) {
2909 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
2910
2911 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
2912 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
2913 }
2914
2915 fclose(file);
2916
2917 return entry;
2918 }
2919
2920 /**
2921 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
2922
2923 Example image partition table:
2924
2925 fwup-ptn partition-table base 0x00800 size 0x00800
2926 fwup-ptn os-image base 0x01000 size 0x113b45
2927 fwup-ptn file-system base 0x114b45 size 0x1d0004
2928 fwup-ptn support-list base 0x2e4b49 size 0x000d1
2929
2930 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
2931 the end of the partition table is marked with a zero byte.
2932
2933 The firmware image must contain at least the partition-table and support-list partitions
2934 to be accepted. There aren't any alignment constraints for the image partitions.
2935
2936 The partition-table partition contains the actual flash layout; partitions
2937 from the image partition table are mapped to the corresponding flash partitions during
2938 the firmware upgrade. The support-list partition contains a list of devices supported by
2939 the firmware image.
2940
2941 The base offsets in the firmware partition table are relative to the end
2942 of the vendor information block, so the partition-table partition will
2943 actually start at offset 0x1814 of the image.
2944
2945 I think partition-table must be the first partition in the firmware image.
2946 */
2947 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
2948 size_t i, j;
2949 char *image_pt = (char *)buffer, *end = image_pt + 0x800;
2950
2951 size_t base = 0x800;
2952 for (i = 0; parts[i].name; i++) {
2953 for (j = 0; flash_parts[j].name; j++) {
2954 if (!strcmp(flash_parts[j].name, parts[i].name)) {
2955 if (parts[i].size > flash_parts[j].size)
2956 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
2957 break;
2958 }
2959 }
2960
2961 assert(flash_parts[j].name);
2962
2963 memcpy(buffer + base, parts[i].data, parts[i].size);
2964
2965 size_t len = end-image_pt;
2966 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);
2967
2968 if (w > len-1)
2969 error(1, 0, "image partition table overflow?");
2970
2971 image_pt += w;
2972
2973 base += parts[i].size;
2974 }
2975 }
2976
2977 /** Generates and writes the image MD5 checksum */
2978 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
2979 MD5_CTX ctx;
2980
2981 MD5_Init(&ctx);
2982 MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
2983 MD5_Update(&ctx, buffer, len);
2984 MD5_Final(md5, &ctx);
2985 }
2986
2987
2988 /**
2989 Generates the firmware image in factory format
2990
2991 Image format:
2992
2993 Bytes (hex) Usage
2994 ----------- -----
2995 0000-0003 Image size (4 bytes, big endian)
2996 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
2997 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
2998 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
2999 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
3000 1014-1813 Image partition table (2048 bytes, padded with 0xff)
3001 1814-xxxx Firmware partitions
3002 */
3003 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
3004 *len = 0x1814;
3005
3006 size_t i;
3007 for (i = 0; parts[i].name; i++)
3008 *len += parts[i].size;
3009
3010 uint8_t *image = malloc(*len);
3011 if (!image)
3012 error(1, errno, "malloc");
3013
3014 memset(image, 0xff, *len);
3015 put32(image, *len);
3016
3017 if (info->vendor) {
3018 size_t vendor_len = strlen(info->vendor);
3019 put32(image+0x14, vendor_len);
3020 memcpy(image+0x18, info->vendor, vendor_len);
3021 }
3022
3023 put_partitions(image + 0x1014, info->partitions, parts);
3024 put_md5(image+0x04, image+0x14, *len-0x14);
3025
3026 return image;
3027 }
3028
3029 /**
3030 Generates the firmware image in sysupgrade format
3031
3032 This makes some assumptions about the provided flash and image partition tables and
3033 should be generalized when TP-LINK starts building its safeloader into hardware with
3034 different flash layouts.
3035 */
3036 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
3037 size_t i, j;
3038 size_t flash_first_partition_index = 0;
3039 size_t flash_last_partition_index = 0;
3040 const struct flash_partition_entry *flash_first_partition = NULL;
3041 const struct flash_partition_entry *flash_last_partition = NULL;
3042 const struct image_partition_entry *image_last_partition = NULL;
3043
3044 /** Find first and last partitions */
3045 for (i = 0; info->partitions[i].name; i++) {
3046 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
3047 flash_first_partition = &info->partitions[i];
3048 flash_first_partition_index = i;
3049 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
3050 flash_last_partition = &info->partitions[i];
3051 flash_last_partition_index = i;
3052 }
3053 }
3054
3055 assert(flash_first_partition && flash_last_partition);
3056 assert(flash_first_partition_index < flash_last_partition_index);
3057
3058 /** Find last partition from image to calculate needed size */
3059 for (i = 0; image_parts[i].name; i++) {
3060 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
3061 image_last_partition = &image_parts[i];
3062 break;
3063 }
3064 }
3065
3066 assert(image_last_partition);
3067
3068 *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
3069
3070 uint8_t *image = malloc(*len);
3071 if (!image)
3072 error(1, errno, "malloc");
3073
3074 memset(image, 0xff, *len);
3075
3076 for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
3077 for (j = 0; image_parts[j].name; j++) {
3078 if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
3079 if (image_parts[j].size > info->partitions[i].size)
3080 error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
3081 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
3082 break;
3083 }
3084
3085 assert(image_parts[j].name);
3086 }
3087 }
3088
3089 return image;
3090 }
3091
3092 /** Generates an image according to a given layout and writes it to a file */
3093 static void build_image(const char *output,
3094 const char *kernel_image,
3095 const char *rootfs_image,
3096 uint32_t rev,
3097 bool add_jffs2_eof,
3098 bool sysupgrade,
3099 struct device_info *info) {
3100
3101 size_t i;
3102
3103 struct image_partition_entry parts[7] = {};
3104
3105 struct flash_partition_entry *firmware_partition = NULL;
3106 struct flash_partition_entry *os_image_partition = NULL;
3107 struct flash_partition_entry *file_system_partition = NULL;
3108 size_t firmware_partition_index = 0;
3109
3110 for (i = 0; info->partitions[i].name; i++) {
3111 if (!strcmp(info->partitions[i].name, "firmware"))
3112 {
3113 firmware_partition = &info->partitions[i];
3114 firmware_partition_index = i;
3115 }
3116 }
3117
3118 if (firmware_partition)
3119 {
3120 os_image_partition = &info->partitions[firmware_partition_index];
3121 file_system_partition = &info->partitions[firmware_partition_index + 1];
3122
3123 struct stat kernel;
3124 if (stat(kernel_image, &kernel) < 0)
3125 error(1, errno, "unable to stat file `%s'", kernel_image);
3126
3127 if (kernel.st_size > firmware_partition->size)
3128 error(1, 0, "kernel overflowed firmware partition\n");
3129
3130 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
3131 info->partitions[i+1] = info->partitions[i];
3132
3133 file_system_partition->name = "file-system";
3134 file_system_partition->base = firmware_partition->base + kernel.st_size;
3135
3136 /* Align partition start to erase blocks for factory images only */
3137 if (!sysupgrade)
3138 file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
3139
3140 file_system_partition->size = firmware_partition->size - file_system_partition->base;
3141
3142 os_image_partition->name = "os-image";
3143 os_image_partition->size = kernel.st_size;
3144 }
3145
3146 parts[0] = make_partition_table(info->partitions);
3147 parts[1] = make_soft_version(info, rev);
3148 parts[2] = make_support_list(info);
3149 parts[3] = read_file("os-image", kernel_image, false, NULL);
3150 parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof, file_system_partition);
3151
3152 /* Some devices need the extra-para partition to accept the firmware */
3153 if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 ||
3154 strcasecmp(info->id, "ARCHER-A7-V5") == 0 ||
3155 strcasecmp(info->id, "ARCHER-C2-V3") == 0 ||
3156 strcasecmp(info->id, "ARCHER-C7-V4") == 0 ||
3157 strcasecmp(info->id, "ARCHER-C7-V5") == 0 ||
3158 strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
3159 strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
3160 strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
3161 strcasecmp(info->id, "ARCHER-C60-V3") == 0 ||
3162 strcasecmp(info->id, "ARCHER-C6U-V1") == 0 ||
3163 strcasecmp(info->id, "ARCHER-C6-V3") == 0 ||
3164 strcasecmp(info->id, "TLWR1043NV5") == 0) {
3165 const uint8_t extra_para[2] = {0x01, 0x00};
3166 parts[5] = make_extra_para(info, extra_para,
3167 sizeof(extra_para));
3168 } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 ||
3169 strcasecmp(info->id, "TL-WA1201-V2") == 0) {
3170 const uint8_t extra_para[2] = {0x00, 0x01};
3171 parts[5] = make_extra_para(info, extra_para,
3172 sizeof(extra_para));
3173 } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 ||
3174 strcasecmp(info->id, "EAP245-V3") == 0) {
3175 const uint8_t extra_para[2] = {0x01, 0x01};
3176 parts[5] = make_extra_para(info, extra_para,
3177 sizeof(extra_para));
3178 }
3179
3180 size_t len;
3181 void *image;
3182 if (sysupgrade)
3183 image = generate_sysupgrade_image(info, parts, &len);
3184 else
3185 image = generate_factory_image(info, parts, &len);
3186
3187 FILE *file = fopen(output, "wb");
3188 if (!file)
3189 error(1, errno, "unable to open output file");
3190
3191 if (fwrite(image, len, 1, file) != 1)
3192 error(1, 0, "unable to write output file");
3193
3194 fclose(file);
3195
3196 free(image);
3197
3198 for (i = 0; parts[i].name; i++)
3199 free_image_partition(parts[i]);
3200 }
3201
3202 /** Usage output */
3203 static void usage(const char *argv0) {
3204 fprintf(stderr,
3205 "Usage: %s [OPTIONS...]\n"
3206 "\n"
3207 "Options:\n"
3208 " -h show this help\n"
3209 "\n"
3210 "Info about an image:\n"
3211 " -i <file> input file to read from\n"
3212 "Create a new image:\n"
3213 " -B <board> create image for the board specified with <board>\n"
3214 " -k <file> read kernel image from the file <file>\n"
3215 " -r <file> read rootfs image from the file <file>\n"
3216 " -o <file> write output to the file <file>\n"
3217 " -V <rev> sets the revision number to <rev>\n"
3218 " -j add jffs2 end-of-filesystem markers\n"
3219 " -S create sysupgrade instead of factory image\n"
3220 "Extract an old image:\n"
3221 " -x <file> extract all oem firmware partition\n"
3222 " -d <dir> destination to extract the firmware partition\n"
3223 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
3224 argv0
3225 );
3226 };
3227
3228
3229 static struct device_info *find_board(const char *id)
3230 {
3231 struct device_info *board = NULL;
3232
3233 for (board = boards; board->id != NULL; board++)
3234 if (strcasecmp(id, board->id) == 0)
3235 return board;
3236
3237 return NULL;
3238 }
3239
3240 static int add_flash_partition(
3241 struct flash_partition_entry *part_list,
3242 size_t max_entries,
3243 const char *name,
3244 unsigned long base,
3245 unsigned long size)
3246 {
3247 size_t ptr;
3248 /* check if the list has a free entry */
3249 for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
3250 if (part_list->name == NULL &&
3251 part_list->base == 0 &&
3252 part_list->size == 0)
3253 break;
3254 }
3255
3256 if (ptr == max_entries) {
3257 error(1, 0, "No free flash part entry available.");
3258 }
3259
3260 part_list->name = calloc(1, strlen(name) + 1);
3261 if (!part_list->name) {
3262 error(1, 0, "Unable to allocate memory");
3263 }
3264
3265 memcpy((char *)part_list->name, name, strlen(name));
3266 part_list->base = base;
3267 part_list->size = size;
3268
3269 return 0;
3270 }
3271
3272 /** read the partition table into struct flash_partition_entry */
3273 static int read_partition_table(
3274 FILE *file, long offset,
3275 struct flash_partition_entry *entries, size_t max_entries,
3276 int type)
3277 {
3278 char buf[2048];
3279 char *ptr, *end;
3280 const char *parthdr = NULL;
3281 const char *fwuphdr = "fwup-ptn";
3282 const char *flashhdr = "partition";
3283
3284 /* TODO: search for the partition table */
3285
3286 switch(type) {
3287 case 0:
3288 parthdr = fwuphdr;
3289 break;
3290 case 1:
3291 parthdr = flashhdr;
3292 break;
3293 default:
3294 error(1, 0, "Invalid partition table");
3295 }
3296
3297 if (fseek(file, offset, SEEK_SET) < 0)
3298 error(1, errno, "Can not seek in the firmware");
3299
3300 if (fread(buf, 2048, 1, file) != 1)
3301 error(1, errno, "Can not read fwup-ptn from the firmware");
3302
3303 buf[2047] = '\0';
3304
3305 /* look for the partition header */
3306 if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
3307 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
3308 return 1;
3309 }
3310
3311 ptr = buf;
3312 end = buf + sizeof(buf);
3313 while ((ptr + strlen(parthdr)) < end &&
3314 memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
3315 char *end_part;
3316 char *end_element;
3317
3318 char name[32] = { 0 };
3319 int name_len = 0;
3320 unsigned long base = 0;
3321 unsigned long size = 0;
3322
3323 end_part = memchr(ptr, '\n', (end - ptr));
3324 if (end_part == NULL) {
3325 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
3326 break;
3327 }
3328
3329 for (int i = 0; i <= 4; i++) {
3330 if (end_part <= ptr)
3331 break;
3332
3333 end_element = memchr(ptr, 0x20, (end_part - ptr));
3334 if (end_element == NULL) {
3335 error(1, errno, "Ignoring the rest of the partition entries.");
3336 break;
3337 }
3338
3339 switch (i) {
3340 /* partition header */
3341 case 0:
3342 ptr = end_element + 1;
3343 continue;
3344 /* name */
3345 case 1:
3346 name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
3347 strncpy(name, ptr, name_len);
3348 name[name_len] = '\0';
3349 ptr = end_element + 1;
3350 continue;
3351
3352 /* string "base" */
3353 case 2:
3354 ptr = end_element + 1;
3355 continue;
3356
3357 /* actual base */
3358 case 3:
3359 base = strtoul(ptr, NULL, 16);
3360 ptr = end_element + 1;
3361 continue;
3362
3363 /* string "size" */
3364 case 4:
3365 ptr = end_element + 1;
3366 /* actual size. The last element doesn't have a sepeartor */
3367 size = strtoul(ptr, NULL, 16);
3368 /* the part ends with 0x09, 0x0d, 0x0a */
3369 ptr = end_part + 1;
3370 add_flash_partition(entries, max_entries, name, base, size);
3371 continue;
3372 }
3373 }
3374 }
3375
3376 return 0;
3377 }
3378
3379 static void write_partition(
3380 FILE *input_file,
3381 size_t firmware_offset,
3382 struct flash_partition_entry *entry,
3383 FILE *output_file)
3384 {
3385 char buf[4096];
3386 size_t offset;
3387
3388 fseek(input_file, entry->base + firmware_offset, SEEK_SET);
3389
3390 for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
3391 if (fread(buf, sizeof(buf), 1, input_file) != 1)
3392 error(1, errno, "Can not read partition from input_file");
3393
3394 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
3395 error(1, errno, "Can not write partition to output_file");
3396 }
3397 /* write last chunk smaller than buffer */
3398 if (offset < entry->size) {
3399 offset = entry->size - offset;
3400 if (fread(buf, offset, 1, input_file) != 1)
3401 error(1, errno, "Can not read partition from input_file");
3402 if (fwrite(buf, offset, 1, output_file) != 1)
3403 error(1, errno, "Can not write partition to output_file");
3404 }
3405 }
3406
3407 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
3408 {
3409 FILE *output_file;
3410 char output[PATH_MAX];
3411
3412 snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
3413 output_file = fopen(output, "wb+");
3414 if (output_file == NULL) {
3415 error(1, errno, "Can not open output file %s", output);
3416 }
3417
3418 write_partition(input_file, firmware_offset, entry, output_file);
3419
3420 fclose(output_file);
3421
3422 return 0;
3423 }
3424
3425 /** extract all partitions from the firmware file */
3426 static int extract_firmware(const char *input, const char *output_directory)
3427 {
3428 struct flash_partition_entry entries[16] = { 0 };
3429 size_t max_entries = 16;
3430 size_t firmware_offset = 0x1014;
3431 FILE *input_file;
3432
3433 struct stat statbuf;
3434
3435 /* check input file */
3436 if (stat(input, &statbuf)) {
3437 error(1, errno, "Can not read input firmware %s", input);
3438 }
3439
3440 /* check if output directory exists */
3441 if (stat(output_directory, &statbuf)) {
3442 error(1, errno, "Failed to stat output directory %s", output_directory);
3443 }
3444
3445 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
3446 error(1, errno, "Given output directory is not a directory %s", output_directory);
3447 }
3448
3449 input_file = fopen(input, "rb");
3450
3451 if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) {
3452 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3453 }
3454
3455 for (size_t i = 0; i < max_entries; i++) {
3456 if (entries[i].name == NULL &&
3457 entries[i].base == 0 &&
3458 entries[i].size == 0)
3459 continue;
3460
3461 extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory);
3462 }
3463
3464 return 0;
3465 }
3466
3467 static struct flash_partition_entry *find_partition(
3468 struct flash_partition_entry *entries, size_t max_entries,
3469 const char *name, const char *error_msg)
3470 {
3471 for (size_t i = 0; i < max_entries; i++, entries++) {
3472 if (strcmp(entries->name, name) == 0)
3473 return entries;
3474 }
3475
3476 if (error_msg) {
3477 error(1, 0, "%s", error_msg);
3478 }
3479
3480 return NULL;
3481 }
3482
3483 static int firmware_info(const char *input)
3484 {
3485 struct flash_partition_entry pointers[MAX_PARTITIONS] = { };
3486 struct flash_partition_entry *e;
3487 FILE *fp;
3488 int i;
3489
3490 fp = fopen(input, "r");
3491
3492 if (read_partition_table(fp, 0x1014, pointers, MAX_PARTITIONS, 0)) {
3493 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3494 }
3495
3496 printf("Firmware image partitions:\n");
3497 printf("%-8s %-8s %s\n", "base", "size", "name");
3498 for (i = 0; i < MAX_PARTITIONS; i++) {
3499 e = &pointers[i];
3500
3501 if (!e->name && !e->base && !e->size)
3502 continue;
3503
3504 printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : "");
3505 }
3506
3507 e = find_partition(pointers, MAX_PARTITIONS, "soft-version", NULL);
3508 if (e) {
3509 size_t data_len = e->size - sizeof(struct meta_header);
3510 char *buf = malloc(data_len);
3511 struct soft_version *s;
3512 bool isstr;
3513 int i;
3514
3515 if (!buf)
3516 error(1, errno, "Failed to alloc buffer");
3517
3518 if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET))
3519 error(1, errno, "Can not seek in the firmware");
3520
3521 if (fread(buf, data_len, 1, fp) != 1)
3522 error(1, errno, "Can not read fwup-ptn data from the firmware");
3523
3524 /* Check for string ignoring padding character */
3525 isstr = true;
3526 for (i = 0; i < data_len - 1; i++) {
3527 if (!isascii(buf[i])) {
3528 isstr = false;
3529 break;
3530 }
3531 }
3532
3533 printf("\n[Software version]\n");
3534 if (isstr) {
3535 fwrite(buf, data_len, 1, stdout);
3536 putchar('\n');
3537 } else if (data_len >= offsetof(struct soft_version, rev)) {
3538 s = (struct soft_version *)buf;
3539
3540 printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch);
3541 printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day);
3542 printf("Revision: %d\n", ntohl(s->rev));
3543 } else {
3544 printf("Failed to parse data\n");
3545 }
3546
3547 free(buf);
3548 }
3549
3550 e = find_partition(pointers, MAX_PARTITIONS, "support-list", NULL);
3551 if (e) {
3552 char buf[128];
3553 size_t length;
3554 size_t bytes;
3555
3556 if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET))
3557 error(1, errno, "Can not seek in the firmware");
3558
3559 printf("\n[Support list]\n");
3560 for (length = e->size - sizeof(struct meta_header); length; length -= bytes) {
3561 bytes = fread(buf, 1, length > sizeof(buf) ? sizeof(buf) : length, fp);
3562 if (bytes <= 0)
3563 error(1, errno, "Can not read fwup-ptn data from the firmware");
3564
3565 puts(buf);
3566 }
3567 }
3568
3569 e = find_partition(pointers, MAX_PARTITIONS, "partition-table", NULL);
3570 if (e) {
3571 struct flash_partition_entry parts[MAX_PARTITIONS] = { };
3572
3573 if (read_partition_table(fp, 0x1014 + e->base + 4, parts, MAX_PARTITIONS, 1)) {
3574 error(1, 0, "Error can not read the partition table (partition)");
3575 }
3576
3577 printf("\n[Partition table]\n");
3578 printf("%-8s %-8s %s\n", "base", "size", "name");
3579 for (i = 0; i < MAX_PARTITIONS; i++) {
3580 e = &parts[i];
3581
3582 if (!e->name && !e->base && !e->size)
3583 continue;
3584
3585 printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : "");
3586 }
3587 }
3588
3589 fclose(fp);
3590
3591 return 0;
3592 }
3593
3594 static void write_ff(FILE *output_file, size_t size)
3595 {
3596 char buf[4096];
3597 size_t offset;
3598
3599 memset(buf, 0xff, sizeof(buf));
3600
3601 for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
3602 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
3603 error(1, errno, "Can not write 0xff to output_file");
3604 }
3605
3606 /* write last chunk smaller than buffer */
3607 if (offset < size) {
3608 offset = size - offset;
3609 if (fwrite(buf, offset, 1, output_file) != 1)
3610 error(1, errno, "Can not write partition to output_file");
3611 }
3612 }
3613
3614 static void convert_firmware(const char *input, const char *output)
3615 {
3616 struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 };
3617 struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 };
3618 struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL;
3619 struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL;
3620 struct flash_partition_entry *fwup_partition_table = NULL;
3621 size_t firmware_offset = 0x1014;
3622 FILE *input_file, *output_file;
3623
3624 struct stat statbuf;
3625
3626 /* check input file */
3627 if (stat(input, &statbuf)) {
3628 error(1, errno, "Can not read input firmware %s", input);
3629 }
3630
3631 input_file = fopen(input, "rb");
3632 if (!input_file)
3633 error(1, 0, "Can not open input firmware %s", input);
3634
3635 output_file = fopen(output, "wb");
3636 if (!output_file)
3637 error(1, 0, "Can not open output firmware %s", output);
3638
3639 if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) {
3640 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3641 }
3642
3643 fwup_os_image = find_partition(fwup, MAX_PARTITIONS,
3644 "os-image", "Error can not find os-image partition (fwup)");
3645 fwup_file_system = find_partition(fwup, MAX_PARTITIONS,
3646 "file-system", "Error can not find file-system partition (fwup)");
3647 fwup_partition_table = find_partition(fwup, MAX_PARTITIONS,
3648 "partition-table", "Error can not find partition-table partition");
3649
3650 /* the flash partition table has a 0x00000004 magic haeder */
3651 if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0)
3652 error(1, 0, "Error can not read the partition table (flash)");
3653
3654 flash_os_image = find_partition(flash, MAX_PARTITIONS,
3655 "os-image", "Error can not find os-image partition (flash)");
3656 flash_file_system = find_partition(flash, MAX_PARTITIONS,
3657 "file-system", "Error can not find file-system partition (flash)");
3658
3659 /* write os_image to 0x0 */
3660 write_partition(input_file, firmware_offset, fwup_os_image, output_file);
3661 write_ff(output_file, flash_os_image->size - fwup_os_image->size);
3662
3663 /* write file-system behind os_image */
3664 fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
3665 write_partition(input_file, firmware_offset, fwup_file_system, output_file);
3666 write_ff(output_file, flash_file_system->size - fwup_file_system->size);
3667
3668 fclose(output_file);
3669 fclose(input_file);
3670 }
3671
3672 int main(int argc, char *argv[]) {
3673 const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
3674 const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
3675 bool add_jffs2_eof = false, sysupgrade = false;
3676 unsigned rev = 0;
3677 struct device_info *info;
3678 set_source_date_epoch();
3679
3680 while (true) {
3681 int c;
3682
3683 c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:");
3684 if (c == -1)
3685 break;
3686
3687 switch (c) {
3688 case 'i':
3689 info_image = optarg;
3690 break;
3691
3692 case 'B':
3693 board = optarg;
3694 break;
3695
3696 case 'k':
3697 kernel_image = optarg;
3698 break;
3699
3700 case 'r':
3701 rootfs_image = optarg;
3702 break;
3703
3704 case 'o':
3705 output = optarg;
3706 break;
3707
3708 case 'V':
3709 sscanf(optarg, "r%u", &rev);
3710 break;
3711
3712 case 'j':
3713 add_jffs2_eof = true;
3714 break;
3715
3716 case 'S':
3717 sysupgrade = true;
3718 break;
3719
3720 case 'h':
3721 usage(argv[0]);
3722 return 0;
3723
3724 case 'd':
3725 output_directory = optarg;
3726 break;
3727
3728 case 'x':
3729 extract_image = optarg;
3730 break;
3731
3732 case 'z':
3733 convert_image = optarg;
3734 break;
3735
3736 default:
3737 usage(argv[0]);
3738 return 1;
3739 }
3740 }
3741
3742 if (info_image) {
3743 firmware_info(info_image);
3744 } else if (extract_image || output_directory) {
3745 if (!extract_image)
3746 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
3747 if (!output_directory)
3748 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
3749 extract_firmware(extract_image, output_directory);
3750 } else if (convert_image) {
3751 if (!output)
3752 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
3753 convert_firmware(convert_image, output);
3754 } else {
3755 if (!board)
3756 error(1, 0, "no board has been specified");
3757 if (!kernel_image)
3758 error(1, 0, "no kernel image has been specified");
3759 if (!rootfs_image)
3760 error(1, 0, "no rootfs image has been specified");
3761 if (!output)
3762 error(1, 0, "no output filename has been specified");
3763
3764 info = find_board(board);
3765
3766 if (info == NULL)
3767 error(1, 0, "unsupported board %s", board);
3768
3769 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
3770 }
3771
3772 return 0;
3773 }