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