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