03329a392617442da926fda17519f1aec7a43ee7
[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 RE350 v1 */
2292 {
2293 .id = "RE350-V1",
2294 .vendor = "",
2295 .support_list =
2296 "SupportList:\n"
2297 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2298 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2299 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2300 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2301 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2302 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2303 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2304 .part_trail = 0x00,
2305 .soft_ver = SOFT_VER_DEFAULT,
2306
2307 /** We're using a dynamic kernel/rootfs split here */
2308 .partitions = {
2309 {"fs-uboot", 0x00000, 0x20000},
2310 {"firmware", 0x20000, 0x5e0000},
2311 {"partition-table", 0x600000, 0x02000},
2312 {"default-mac", 0x610000, 0x00020},
2313 {"pin", 0x610100, 0x00020},
2314 {"product-info", 0x611100, 0x01000},
2315 {"soft-version", 0x620000, 0x01000},
2316 {"support-list", 0x621000, 0x01000},
2317 {"profile", 0x622000, 0x08000},
2318 {"user-config", 0x630000, 0x10000},
2319 {"default-config", 0x640000, 0x10000},
2320 {"radio", 0x7f0000, 0x10000},
2321 {NULL, 0, 0}
2322 },
2323
2324 .first_sysupgrade_partition = "os-image",
2325 .last_sysupgrade_partition = "file-system"
2326 },
2327
2328 /** Firmware layout for the RE350K v1 */
2329 {
2330 .id = "RE350K-V1",
2331 .vendor = "",
2332 .support_list =
2333 "SupportList:\n"
2334 "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2335 .part_trail = 0x00,
2336 .soft_ver = SOFT_VER_DEFAULT,
2337
2338 /** We're using a dynamic kernel/rootfs split here */
2339 .partitions = {
2340 {"fs-uboot", 0x00000, 0x20000},
2341 {"firmware", 0x20000, 0xd70000},
2342 {"partition-table", 0xd90000, 0x02000},
2343 {"default-mac", 0xda0000, 0x00020},
2344 {"pin", 0xda0100, 0x00020},
2345 {"product-info", 0xda1100, 0x01000},
2346 {"soft-version", 0xdb0000, 0x01000},
2347 {"support-list", 0xdb1000, 0x01000},
2348 {"profile", 0xdb2000, 0x08000},
2349 {"user-config", 0xdc0000, 0x10000},
2350 {"default-config", 0xdd0000, 0x10000},
2351 {"device-id", 0xde0000, 0x00108},
2352 {"radio", 0xff0000, 0x10000},
2353 {NULL, 0, 0}
2354 },
2355
2356 .first_sysupgrade_partition = "os-image",
2357 .last_sysupgrade_partition = "file-system"
2358 },
2359
2360 /** Firmware layout for the RE355 */
2361 {
2362 .id = "RE355",
2363 .vendor = "",
2364 .support_list =
2365 "SupportList:\r\n"
2366 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2367 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2368 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2369 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2370 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2371 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2372 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2373 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2374 .part_trail = 0x00,
2375 .soft_ver = SOFT_VER_DEFAULT,
2376
2377 /* We're using a dynamic kernel/rootfs split here */
2378 .partitions = {
2379 {"fs-uboot", 0x00000, 0x20000},
2380 {"firmware", 0x20000, 0x5e0000},
2381 {"partition-table", 0x600000, 0x02000},
2382 {"default-mac", 0x610000, 0x00020},
2383 {"pin", 0x610100, 0x00020},
2384 {"product-info", 0x611100, 0x01000},
2385 {"soft-version", 0x620000, 0x01000},
2386 {"support-list", 0x621000, 0x01000},
2387 {"profile", 0x622000, 0x08000},
2388 {"user-config", 0x630000, 0x10000},
2389 {"default-config", 0x640000, 0x10000},
2390 {"radio", 0x7f0000, 0x10000},
2391 {NULL, 0, 0}
2392 },
2393
2394 .first_sysupgrade_partition = "os-image",
2395 .last_sysupgrade_partition = "file-system"
2396 },
2397
2398 /** Firmware layout for the RE450 */
2399 {
2400 .id = "RE450",
2401 .vendor = "",
2402 .support_list =
2403 "SupportList:\r\n"
2404 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2405 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
2406 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
2407 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
2408 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
2409 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
2410 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
2411 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
2412 .part_trail = 0x00,
2413 .soft_ver = SOFT_VER_DEFAULT,
2414
2415 /** We're using a dynamic kernel/rootfs split here */
2416 .partitions = {
2417 {"fs-uboot", 0x00000, 0x20000},
2418 {"firmware", 0x20000, 0x5e0000},
2419 {"partition-table", 0x600000, 0x02000},
2420 {"default-mac", 0x610000, 0x00020},
2421 {"pin", 0x610100, 0x00020},
2422 {"product-info", 0x611100, 0x01000},
2423 {"soft-version", 0x620000, 0x01000},
2424 {"support-list", 0x621000, 0x01000},
2425 {"profile", 0x622000, 0x08000},
2426 {"user-config", 0x630000, 0x10000},
2427 {"default-config", 0x640000, 0x10000},
2428 {"radio", 0x7f0000, 0x10000},
2429 {NULL, 0, 0}
2430 },
2431
2432 .first_sysupgrade_partition = "os-image",
2433 .last_sysupgrade_partition = "file-system"
2434 },
2435
2436 /** Firmware layout for the RE450 v2 */
2437 {
2438 .id = "RE450-V2",
2439 .vendor = "",
2440 .support_list =
2441 "SupportList:\r\n"
2442 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
2443 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
2444 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
2445 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
2446 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
2447 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
2448 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
2449 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
2450 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
2451 .part_trail = 0x00,
2452 .soft_ver = SOFT_VER_DEFAULT,
2453
2454 /* We're using a dynamic kernel/rootfs split here */
2455 .partitions = {
2456 {"fs-uboot", 0x00000, 0x20000},
2457 {"firmware", 0x20000, 0x5e0000},
2458 {"partition-table", 0x600000, 0x02000},
2459 {"default-mac", 0x610000, 0x00020},
2460 {"pin", 0x610100, 0x00020},
2461 {"product-info", 0x611100, 0x01000},
2462 {"soft-version", 0x620000, 0x01000},
2463 {"support-list", 0x621000, 0x01000},
2464 {"profile", 0x622000, 0x08000},
2465 {"user-config", 0x630000, 0x10000},
2466 {"default-config", 0x640000, 0x10000},
2467 {"radio", 0x7f0000, 0x10000},
2468 {NULL, 0, 0}
2469 },
2470
2471 .first_sysupgrade_partition = "os-image",
2472 .last_sysupgrade_partition = "file-system"
2473 },
2474
2475 /** Firmware layout for the RE450 v3 */
2476 {
2477 .id = "RE450-V3",
2478 .vendor = "",
2479 .support_list =
2480 "SupportList:\r\n"
2481 "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
2482 "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
2483 "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
2484 "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
2485 "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
2486 "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
2487 "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
2488 "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
2489 "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
2490 .part_trail = 0x00,
2491 .soft_ver = SOFT_VER_DEFAULT,
2492
2493 /* We're using a dynamic kernel/rootfs split here */
2494 .partitions = {
2495 {"fs-uboot", 0x00000, 0x20000},
2496 {"default-mac", 0x20000, 0x00020},
2497 {"pin", 0x20020, 0x00020},
2498 {"product-info", 0x21000, 0x01000},
2499 {"partition-table", 0x22000, 0x02000},
2500 {"soft-version", 0x24000, 0x01000},
2501 {"support-list", 0x25000, 0x01000},
2502 {"profile", 0x26000, 0x08000},
2503 {"user-config", 0x2e000, 0x10000},
2504 {"default-config", 0x3e000, 0x10000},
2505 {"config-info", 0x4e000, 0x00400},
2506 {"firmware", 0x50000, 0x7a0000},
2507 {"radio", 0x7f0000, 0x10000},
2508 {NULL, 0, 0}
2509 },
2510
2511 .first_sysupgrade_partition = "os-image",
2512 .last_sysupgrade_partition = "file-system"
2513 },
2514
2515 /** Firmware layout for the RE455 v1 */
2516 {
2517 .id = "RE455-V1",
2518 .vendor = "",
2519 .support_list =
2520 "SupportList:\r\n"
2521 "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
2522 "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
2523 "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
2524 "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
2525 "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
2526 "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
2527 "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
2528 "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
2529 "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
2530 .part_trail = 0x00,
2531 .soft_ver = SOFT_VER_DEFAULT,
2532
2533 /* We're using a dynamic kernel/rootfs split here */
2534 .partitions = {
2535 {"fs-uboot", 0x00000, 0x20000},
2536 {"default-mac", 0x20000, 0x00020},
2537 {"pin", 0x20020, 0x00020},
2538 {"product-info", 0x21000, 0x01000},
2539 {"partition-table", 0x22000, 0x02000},
2540 {"soft-version", 0x24000, 0x01000},
2541 {"support-list", 0x25000, 0x01000},
2542 {"profile", 0x26000, 0x08000},
2543 {"user-config", 0x2e000, 0x10000},
2544 {"default-config", 0x3e000, 0x10000},
2545 {"config-info", 0x4e000, 0x00400},
2546 {"firmware", 0x50000, 0x7a0000},
2547 {"radio", 0x7f0000, 0x10000},
2548 {NULL, 0, 0}
2549 },
2550
2551 .first_sysupgrade_partition = "os-image",
2552 .last_sysupgrade_partition = "file-system"
2553 },
2554
2555 /** Firmware layout for the RE500 */
2556 {
2557 .id = "RE500-V1",
2558 .vendor = "",
2559 .support_list =
2560 "SupportList:\r\n"
2561 "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
2562 "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
2563 "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
2564 "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
2565 "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
2566 "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
2567 "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
2568 .part_trail = 0x00,
2569 .soft_ver = SOFT_VER_DEFAULT,
2570
2571 /* We're using a dynamic kernel/rootfs split here */
2572 .partitions = {
2573 {"fs-uboot", 0x00000, 0x20000},
2574 {"firmware", 0x20000, 0xde0000},
2575 {"partition-table", 0xe00000, 0x02000},
2576 {"default-mac", 0xe10000, 0x00020},
2577 {"pin", 0xe10100, 0x00020},
2578 {"product-info", 0xe11100, 0x01000},
2579 {"soft-version", 0xe20000, 0x01000},
2580 {"support-list", 0xe21000, 0x01000},
2581 {"profile", 0xe22000, 0x08000},
2582 {"user-config", 0xe30000, 0x10000},
2583 {"default-config", 0xe40000, 0x10000},
2584 {"radio", 0xff0000, 0x10000},
2585 {NULL, 0, 0}
2586 },
2587
2588 .first_sysupgrade_partition = "os-image",
2589 .last_sysupgrade_partition = "file-system"
2590 },
2591
2592 /** Firmware layout for the RE650 */
2593 {
2594 .id = "RE650-V1",
2595 .vendor = "",
2596 .support_list =
2597 "SupportList:\r\n"
2598 "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
2599 "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
2600 "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
2601 "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
2602 "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
2603 "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
2604 "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
2605 .part_trail = 0x00,
2606 .soft_ver = SOFT_VER_DEFAULT,
2607
2608 /* We're using a dynamic kernel/rootfs split here */
2609 .partitions = {
2610 {"fs-uboot", 0x00000, 0x20000},
2611 {"firmware", 0x20000, 0xde0000},
2612 {"partition-table", 0xe00000, 0x02000},
2613 {"default-mac", 0xe10000, 0x00020},
2614 {"pin", 0xe10100, 0x00020},
2615 {"product-info", 0xe11100, 0x01000},
2616 {"soft-version", 0xe20000, 0x01000},
2617 {"support-list", 0xe21000, 0x01000},
2618 {"profile", 0xe22000, 0x08000},
2619 {"user-config", 0xe30000, 0x10000},
2620 {"default-config", 0xe40000, 0x10000},
2621 {"radio", 0xff0000, 0x10000},
2622 {NULL, 0, 0}
2623 },
2624
2625 .first_sysupgrade_partition = "os-image",
2626 .last_sysupgrade_partition = "file-system"
2627 },
2628
2629 {}
2630 };
2631
2632 #define error(_ret, _errno, _str, ...) \
2633 do { \
2634 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
2635 strerror(_errno)); \
2636 if (_ret) \
2637 exit(_ret); \
2638 } while (0)
2639
2640
2641 /** Stores a uint32 as big endian */
2642 static inline void put32(uint8_t *buf, uint32_t val) {
2643 buf[0] = val >> 24;
2644 buf[1] = val >> 16;
2645 buf[2] = val >> 8;
2646 buf[3] = val;
2647 }
2648
2649 static inline bool meta_partition_should_pad(enum partition_trail_value pv)
2650 {
2651 return (pv >= 0) && (pv <= PART_TRAIL_MAX);
2652 }
2653
2654 /** Allocate a padded meta partition with a correctly initialised header
2655 * If the `data` pointer is NULL, then the required space is only allocated,
2656 * otherwise `data_len` bytes will be copied from `data` into the partition
2657 * entry. */
2658 static struct image_partition_entry init_meta_partition_entry(
2659 const char *name, const void *data, uint32_t data_len,
2660 enum partition_trail_value pad_value)
2661 {
2662 uint32_t total_len = sizeof(struct meta_header) + data_len;
2663 if (meta_partition_should_pad(pad_value))
2664 total_len += 1;
2665
2666 struct image_partition_entry entry = {
2667 .name = name,
2668 .size = total_len,
2669 .data = malloc(total_len)
2670 };
2671 if (!entry.data)
2672 error(1, errno, "failed to allocate meta partition entry");
2673
2674 struct meta_header *header = (struct meta_header *)entry.data;
2675 header->length = htonl(data_len);
2676 header->zero = 0;
2677
2678 if (data)
2679 memcpy(entry.data+sizeof(*header), data, data_len);
2680
2681 if (meta_partition_should_pad(pad_value))
2682 entry.data[total_len - 1] = (uint8_t) pad_value;
2683
2684 return entry;
2685 }
2686
2687 /** Allocates a new image partition */
2688 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
2689 struct image_partition_entry entry = {name, len, malloc(len)};
2690 if (!entry.data)
2691 error(1, errno, "malloc");
2692
2693 return entry;
2694 }
2695
2696 /** Frees an image partition */
2697 static void free_image_partition(struct image_partition_entry entry) {
2698 free(entry.data);
2699 }
2700
2701 static time_t source_date_epoch = -1;
2702 static void set_source_date_epoch() {
2703 char *env = getenv("SOURCE_DATE_EPOCH");
2704 char *endptr = env;
2705 errno = 0;
2706 if (env && *env) {
2707 source_date_epoch = strtoull(env, &endptr, 10);
2708 if (errno || (endptr && *endptr != '\0')) {
2709 fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
2710 exit(1);
2711 }
2712 }
2713 }
2714
2715 /** Generates the partition-table partition */
2716 static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
2717 struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800);
2718
2719 char *s = (char *)entry.data, *end = (char *)(s+entry.size);
2720
2721 *(s++) = 0x00;
2722 *(s++) = 0x04;
2723 *(s++) = 0x00;
2724 *(s++) = 0x00;
2725
2726 size_t i;
2727 for (i = 0; p[i].name; i++) {
2728 size_t len = end-s;
2729 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size);
2730
2731 if (w > len-1)
2732 error(1, 0, "flash partition table overflow?");
2733
2734 s += w;
2735 }
2736
2737 s++;
2738
2739 memset(s, 0xff, end-s);
2740
2741 return entry;
2742 }
2743
2744
2745 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
2746 static inline uint8_t bcd(uint8_t v) {
2747 return 0x10 * (v/10) + v%10;
2748 }
2749
2750
2751 /** Generates the soft-version partition */
2752 static struct image_partition_entry make_soft_version(
2753 const struct device_info *info, uint32_t rev)
2754 {
2755 /** If an info string is provided, use this instead of
2756 * the structured data, and include the null-termination */
2757 if (info->soft_ver.type == SOFT_VER_TYPE_TEXT) {
2758 uint32_t len = strlen(info->soft_ver.text) + 1;
2759 return init_meta_partition_entry("soft-version",
2760 info->soft_ver.text, len, info->part_trail);
2761 }
2762
2763 time_t t;
2764
2765 if (source_date_epoch != -1)
2766 t = source_date_epoch;
2767 else if (time(&t) == (time_t)(-1))
2768 error(1, errno, "time");
2769
2770 struct tm *tm = gmtime(&t);
2771
2772 struct soft_version s = {
2773 .pad1 = 0xff,
2774
2775 .version_major = info->soft_ver.num[0],
2776 .version_minor = info->soft_ver.num[1],
2777 .version_patch = info->soft_ver.num[2],
2778
2779 .year_hi = bcd((1900+tm->tm_year)/100),
2780 .year_lo = bcd(tm->tm_year%100),
2781 .month = bcd(tm->tm_mon+1),
2782 .day = bcd(tm->tm_mday),
2783 .rev = htonl(rev),
2784
2785 .compat_level = htonl(info->soft_ver_compat_level)
2786 };
2787
2788 if (info->soft_ver_compat_level == 0)
2789 return init_meta_partition_entry("soft-version", &s,
2790 (uint8_t *)(&s.compat_level) - (uint8_t *)(&s),
2791 info->part_trail);
2792 else
2793 return init_meta_partition_entry("soft-version", &s,
2794 sizeof(s), info->part_trail);
2795 }
2796
2797 /** Generates the support-list partition */
2798 static struct image_partition_entry make_support_list(
2799 const struct device_info *info)
2800 {
2801 uint32_t len = strlen(info->support_list);
2802 return init_meta_partition_entry("support-list", info->support_list,
2803 len, info->part_trail);
2804 }
2805
2806 /** Partition with extra-para data */
2807 static struct image_partition_entry make_extra_para(
2808 const struct device_info *info, const uint8_t *extra_para, size_t len)
2809 {
2810 return init_meta_partition_entry("extra-para", extra_para, len,
2811 info->part_trail);
2812 }
2813
2814 /** Creates a new image partition with an arbitrary name from a file */
2815 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) {
2816 struct stat statbuf;
2817
2818 if (stat(filename, &statbuf) < 0)
2819 error(1, errno, "unable to stat file `%s'", filename);
2820
2821 size_t len = statbuf.st_size;
2822
2823 if (add_jffs2_eof) {
2824 if (file_system_partition)
2825 len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base;
2826 else
2827 len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
2828 }
2829
2830 struct image_partition_entry entry = alloc_image_partition(part_name, len);
2831
2832 FILE *file = fopen(filename, "rb");
2833 if (!file)
2834 error(1, errno, "unable to open file `%s'", filename);
2835
2836 if (fread(entry.data, statbuf.st_size, 1, file) != 1)
2837 error(1, errno, "unable to read file `%s'", filename);
2838
2839 if (add_jffs2_eof) {
2840 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
2841
2842 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
2843 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
2844 }
2845
2846 fclose(file);
2847
2848 return entry;
2849 }
2850
2851 /**
2852 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
2853
2854 Example image partition table:
2855
2856 fwup-ptn partition-table base 0x00800 size 0x00800
2857 fwup-ptn os-image base 0x01000 size 0x113b45
2858 fwup-ptn file-system base 0x114b45 size 0x1d0004
2859 fwup-ptn support-list base 0x2e4b49 size 0x000d1
2860
2861 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
2862 the end of the partition table is marked with a zero byte.
2863
2864 The firmware image must contain at least the partition-table and support-list partitions
2865 to be accepted. There aren't any alignment constraints for the image partitions.
2866
2867 The partition-table partition contains the actual flash layout; partitions
2868 from the image partition table are mapped to the corresponding flash partitions during
2869 the firmware upgrade. The support-list partition contains a list of devices supported by
2870 the firmware image.
2871
2872 The base offsets in the firmware partition table are relative to the end
2873 of the vendor information block, so the partition-table partition will
2874 actually start at offset 0x1814 of the image.
2875
2876 I think partition-table must be the first partition in the firmware image.
2877 */
2878 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
2879 size_t i, j;
2880 char *image_pt = (char *)buffer, *end = image_pt + 0x800;
2881
2882 size_t base = 0x800;
2883 for (i = 0; parts[i].name; i++) {
2884 for (j = 0; flash_parts[j].name; j++) {
2885 if (!strcmp(flash_parts[j].name, parts[i].name)) {
2886 if (parts[i].size > flash_parts[j].size)
2887 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
2888 break;
2889 }
2890 }
2891
2892 assert(flash_parts[j].name);
2893
2894 memcpy(buffer + base, parts[i].data, parts[i].size);
2895
2896 size_t len = end-image_pt;
2897 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);
2898
2899 if (w > len-1)
2900 error(1, 0, "image partition table overflow?");
2901
2902 image_pt += w;
2903
2904 base += parts[i].size;
2905 }
2906 }
2907
2908 /** Generates and writes the image MD5 checksum */
2909 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
2910 MD5_CTX ctx;
2911
2912 MD5_Init(&ctx);
2913 MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
2914 MD5_Update(&ctx, buffer, len);
2915 MD5_Final(md5, &ctx);
2916 }
2917
2918
2919 /**
2920 Generates the firmware image in factory format
2921
2922 Image format:
2923
2924 Bytes (hex) Usage
2925 ----------- -----
2926 0000-0003 Image size (4 bytes, big endian)
2927 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
2928 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
2929 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
2930 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
2931 1014-1813 Image partition table (2048 bytes, padded with 0xff)
2932 1814-xxxx Firmware partitions
2933 */
2934 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
2935 *len = 0x1814;
2936
2937 size_t i;
2938 for (i = 0; parts[i].name; i++)
2939 *len += parts[i].size;
2940
2941 uint8_t *image = malloc(*len);
2942 if (!image)
2943 error(1, errno, "malloc");
2944
2945 memset(image, 0xff, *len);
2946 put32(image, *len);
2947
2948 if (info->vendor) {
2949 size_t vendor_len = strlen(info->vendor);
2950 put32(image+0x14, vendor_len);
2951 memcpy(image+0x18, info->vendor, vendor_len);
2952 }
2953
2954 put_partitions(image + 0x1014, info->partitions, parts);
2955 put_md5(image+0x04, image+0x14, *len-0x14);
2956
2957 return image;
2958 }
2959
2960 /**
2961 Generates the firmware image in sysupgrade format
2962
2963 This makes some assumptions about the provided flash and image partition tables and
2964 should be generalized when TP-LINK starts building its safeloader into hardware with
2965 different flash layouts.
2966 */
2967 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
2968 size_t i, j;
2969 size_t flash_first_partition_index = 0;
2970 size_t flash_last_partition_index = 0;
2971 const struct flash_partition_entry *flash_first_partition = NULL;
2972 const struct flash_partition_entry *flash_last_partition = NULL;
2973 const struct image_partition_entry *image_last_partition = NULL;
2974
2975 /** Find first and last partitions */
2976 for (i = 0; info->partitions[i].name; i++) {
2977 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
2978 flash_first_partition = &info->partitions[i];
2979 flash_first_partition_index = i;
2980 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
2981 flash_last_partition = &info->partitions[i];
2982 flash_last_partition_index = i;
2983 }
2984 }
2985
2986 assert(flash_first_partition && flash_last_partition);
2987 assert(flash_first_partition_index < flash_last_partition_index);
2988
2989 /** Find last partition from image to calculate needed size */
2990 for (i = 0; image_parts[i].name; i++) {
2991 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
2992 image_last_partition = &image_parts[i];
2993 break;
2994 }
2995 }
2996
2997 assert(image_last_partition);
2998
2999 *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
3000
3001 uint8_t *image = malloc(*len);
3002 if (!image)
3003 error(1, errno, "malloc");
3004
3005 memset(image, 0xff, *len);
3006
3007 for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
3008 for (j = 0; image_parts[j].name; j++) {
3009 if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
3010 if (image_parts[j].size > info->partitions[i].size)
3011 error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
3012 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
3013 break;
3014 }
3015
3016 assert(image_parts[j].name);
3017 }
3018 }
3019
3020 return image;
3021 }
3022
3023 /** Generates an image according to a given layout and writes it to a file */
3024 static void build_image(const char *output,
3025 const char *kernel_image,
3026 const char *rootfs_image,
3027 uint32_t rev,
3028 bool add_jffs2_eof,
3029 bool sysupgrade,
3030 struct device_info *info) {
3031
3032 size_t i;
3033
3034 struct image_partition_entry parts[7] = {};
3035
3036 struct flash_partition_entry *firmware_partition = NULL;
3037 struct flash_partition_entry *os_image_partition = NULL;
3038 struct flash_partition_entry *file_system_partition = NULL;
3039 size_t firmware_partition_index = 0;
3040
3041 for (i = 0; info->partitions[i].name; i++) {
3042 if (!strcmp(info->partitions[i].name, "firmware"))
3043 {
3044 firmware_partition = &info->partitions[i];
3045 firmware_partition_index = i;
3046 }
3047 }
3048
3049 if (firmware_partition)
3050 {
3051 os_image_partition = &info->partitions[firmware_partition_index];
3052 file_system_partition = &info->partitions[firmware_partition_index + 1];
3053
3054 struct stat kernel;
3055 if (stat(kernel_image, &kernel) < 0)
3056 error(1, errno, "unable to stat file `%s'", kernel_image);
3057
3058 if (kernel.st_size > firmware_partition->size)
3059 error(1, 0, "kernel overflowed firmware partition\n");
3060
3061 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--)
3062 info->partitions[i+1] = info->partitions[i];
3063
3064 file_system_partition->name = "file-system";
3065 file_system_partition->base = firmware_partition->base + kernel.st_size;
3066
3067 /* Align partition start to erase blocks for factory images only */
3068 if (!sysupgrade)
3069 file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000);
3070
3071 file_system_partition->size = firmware_partition->size - file_system_partition->base;
3072
3073 os_image_partition->name = "os-image";
3074 os_image_partition->size = kernel.st_size;
3075 }
3076
3077 parts[0] = make_partition_table(info->partitions);
3078 parts[1] = make_soft_version(info, rev);
3079 parts[2] = make_support_list(info);
3080 parts[3] = read_file("os-image", kernel_image, false, NULL);
3081 parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof, file_system_partition);
3082
3083 /* Some devices need the extra-para partition to accept the firmware */
3084 if (strcasecmp(info->id, "ARCHER-A6-V3") == 0 ||
3085 strcasecmp(info->id, "ARCHER-A7-V5") == 0 ||
3086 strcasecmp(info->id, "ARCHER-C2-V3") == 0 ||
3087 strcasecmp(info->id, "ARCHER-C7-V4") == 0 ||
3088 strcasecmp(info->id, "ARCHER-C7-V5") == 0 ||
3089 strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
3090 strcasecmp(info->id, "ARCHER-C59-V2") == 0 ||
3091 strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
3092 strcasecmp(info->id, "ARCHER-C60-V3") == 0 ||
3093 strcasecmp(info->id, "ARCHER-C6U-V1") == 0 ||
3094 strcasecmp(info->id, "ARCHER-C6-V3") == 0 ||
3095 strcasecmp(info->id, "TLWR1043NV5") == 0) {
3096 const uint8_t extra_para[2] = {0x01, 0x00};
3097 parts[5] = make_extra_para(info, extra_para,
3098 sizeof(extra_para));
3099 } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0 ||
3100 strcasecmp(info->id, "TL-WA1201-V2") == 0) {
3101 const uint8_t extra_para[2] = {0x00, 0x01};
3102 parts[5] = make_extra_para(info, extra_para,
3103 sizeof(extra_para));
3104 } else if (strcasecmp(info->id, "ARCHER-C6-V2-US") == 0 ||
3105 strcasecmp(info->id, "EAP245-V3") == 0) {
3106 const uint8_t extra_para[2] = {0x01, 0x01};
3107 parts[5] = make_extra_para(info, extra_para,
3108 sizeof(extra_para));
3109 }
3110
3111 size_t len;
3112 void *image;
3113 if (sysupgrade)
3114 image = generate_sysupgrade_image(info, parts, &len);
3115 else
3116 image = generate_factory_image(info, parts, &len);
3117
3118 FILE *file = fopen(output, "wb");
3119 if (!file)
3120 error(1, errno, "unable to open output file");
3121
3122 if (fwrite(image, len, 1, file) != 1)
3123 error(1, 0, "unable to write output file");
3124
3125 fclose(file);
3126
3127 free(image);
3128
3129 for (i = 0; parts[i].name; i++)
3130 free_image_partition(parts[i]);
3131 }
3132
3133 /** Usage output */
3134 static void usage(const char *argv0) {
3135 fprintf(stderr,
3136 "Usage: %s [OPTIONS...]\n"
3137 "\n"
3138 "Options:\n"
3139 " -h show this help\n"
3140 "\n"
3141 "Info about an image:\n"
3142 " -i <file> input file to read from\n"
3143 "Create a new image:\n"
3144 " -B <board> create image for the board specified with <board>\n"
3145 " -k <file> read kernel image from the file <file>\n"
3146 " -r <file> read rootfs image from the file <file>\n"
3147 " -o <file> write output to the file <file>\n"
3148 " -V <rev> sets the revision number to <rev>\n"
3149 " -j add jffs2 end-of-filesystem markers\n"
3150 " -S create sysupgrade instead of factory image\n"
3151 "Extract an old image:\n"
3152 " -x <file> extract all oem firmware partition\n"
3153 " -d <dir> destination to extract the firmware partition\n"
3154 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
3155 argv0
3156 );
3157 };
3158
3159
3160 static struct device_info *find_board(const char *id)
3161 {
3162 struct device_info *board = NULL;
3163
3164 for (board = boards; board->id != NULL; board++)
3165 if (strcasecmp(id, board->id) == 0)
3166 return board;
3167
3168 return NULL;
3169 }
3170
3171 static int add_flash_partition(
3172 struct flash_partition_entry *part_list,
3173 size_t max_entries,
3174 const char *name,
3175 unsigned long base,
3176 unsigned long size)
3177 {
3178 size_t ptr;
3179 /* check if the list has a free entry */
3180 for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
3181 if (part_list->name == NULL &&
3182 part_list->base == 0 &&
3183 part_list->size == 0)
3184 break;
3185 }
3186
3187 if (ptr == max_entries) {
3188 error(1, 0, "No free flash part entry available.");
3189 }
3190
3191 part_list->name = calloc(1, strlen(name) + 1);
3192 if (!part_list->name) {
3193 error(1, 0, "Unable to allocate memory");
3194 }
3195
3196 memcpy((char *)part_list->name, name, strlen(name));
3197 part_list->base = base;
3198 part_list->size = size;
3199
3200 return 0;
3201 }
3202
3203 /** read the partition table into struct flash_partition_entry */
3204 static int read_partition_table(
3205 FILE *file, long offset,
3206 struct flash_partition_entry *entries, size_t max_entries,
3207 int type)
3208 {
3209 char buf[2048];
3210 char *ptr, *end;
3211 const char *parthdr = NULL;
3212 const char *fwuphdr = "fwup-ptn";
3213 const char *flashhdr = "partition";
3214
3215 /* TODO: search for the partition table */
3216
3217 switch(type) {
3218 case 0:
3219 parthdr = fwuphdr;
3220 break;
3221 case 1:
3222 parthdr = flashhdr;
3223 break;
3224 default:
3225 error(1, 0, "Invalid partition table");
3226 }
3227
3228 if (fseek(file, offset, SEEK_SET) < 0)
3229 error(1, errno, "Can not seek in the firmware");
3230
3231 if (fread(buf, 2048, 1, file) != 1)
3232 error(1, errno, "Can not read fwup-ptn from the firmware");
3233
3234 buf[2047] = '\0';
3235
3236 /* look for the partition header */
3237 if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
3238 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
3239 return 1;
3240 }
3241
3242 ptr = buf;
3243 end = buf + sizeof(buf);
3244 while ((ptr + strlen(parthdr)) < end &&
3245 memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
3246 char *end_part;
3247 char *end_element;
3248
3249 char name[32] = { 0 };
3250 int name_len = 0;
3251 unsigned long base = 0;
3252 unsigned long size = 0;
3253
3254 end_part = memchr(ptr, '\n', (end - ptr));
3255 if (end_part == NULL) {
3256 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
3257 break;
3258 }
3259
3260 for (int i = 0; i <= 4; i++) {
3261 if (end_part <= ptr)
3262 break;
3263
3264 end_element = memchr(ptr, 0x20, (end_part - ptr));
3265 if (end_element == NULL) {
3266 error(1, errno, "Ignoring the rest of the partition entries.");
3267 break;
3268 }
3269
3270 switch (i) {
3271 /* partition header */
3272 case 0:
3273 ptr = end_element + 1;
3274 continue;
3275 /* name */
3276 case 1:
3277 name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
3278 strncpy(name, ptr, name_len);
3279 name[name_len] = '\0';
3280 ptr = end_element + 1;
3281 continue;
3282
3283 /* string "base" */
3284 case 2:
3285 ptr = end_element + 1;
3286 continue;
3287
3288 /* actual base */
3289 case 3:
3290 base = strtoul(ptr, NULL, 16);
3291 ptr = end_element + 1;
3292 continue;
3293
3294 /* string "size" */
3295 case 4:
3296 ptr = end_element + 1;
3297 /* actual size. The last element doesn't have a sepeartor */
3298 size = strtoul(ptr, NULL, 16);
3299 /* the part ends with 0x09, 0x0d, 0x0a */
3300 ptr = end_part + 1;
3301 add_flash_partition(entries, max_entries, name, base, size);
3302 continue;
3303 }
3304 }
3305 }
3306
3307 return 0;
3308 }
3309
3310 static void write_partition(
3311 FILE *input_file,
3312 size_t firmware_offset,
3313 struct flash_partition_entry *entry,
3314 FILE *output_file)
3315 {
3316 char buf[4096];
3317 size_t offset;
3318
3319 fseek(input_file, entry->base + firmware_offset, SEEK_SET);
3320
3321 for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
3322 if (fread(buf, sizeof(buf), 1, input_file) != 1)
3323 error(1, errno, "Can not read partition from input_file");
3324
3325 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
3326 error(1, errno, "Can not write partition to output_file");
3327 }
3328 /* write last chunk smaller than buffer */
3329 if (offset < entry->size) {
3330 offset = entry->size - offset;
3331 if (fread(buf, offset, 1, input_file) != 1)
3332 error(1, errno, "Can not read partition from input_file");
3333 if (fwrite(buf, offset, 1, output_file) != 1)
3334 error(1, errno, "Can not write partition to output_file");
3335 }
3336 }
3337
3338 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
3339 {
3340 FILE *output_file;
3341 char output[PATH_MAX];
3342
3343 snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
3344 output_file = fopen(output, "wb+");
3345 if (output_file == NULL) {
3346 error(1, errno, "Can not open output file %s", output);
3347 }
3348
3349 write_partition(input_file, firmware_offset, entry, output_file);
3350
3351 fclose(output_file);
3352
3353 return 0;
3354 }
3355
3356 /** extract all partitions from the firmware file */
3357 static int extract_firmware(const char *input, const char *output_directory)
3358 {
3359 struct flash_partition_entry entries[16] = { 0 };
3360 size_t max_entries = 16;
3361 size_t firmware_offset = 0x1014;
3362 FILE *input_file;
3363
3364 struct stat statbuf;
3365
3366 /* check input file */
3367 if (stat(input, &statbuf)) {
3368 error(1, errno, "Can not read input firmware %s", input);
3369 }
3370
3371 /* check if output directory exists */
3372 if (stat(output_directory, &statbuf)) {
3373 error(1, errno, "Failed to stat output directory %s", output_directory);
3374 }
3375
3376 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
3377 error(1, errno, "Given output directory is not a directory %s", output_directory);
3378 }
3379
3380 input_file = fopen(input, "rb");
3381
3382 if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) {
3383 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3384 }
3385
3386 for (size_t i = 0; i < max_entries; i++) {
3387 if (entries[i].name == NULL &&
3388 entries[i].base == 0 &&
3389 entries[i].size == 0)
3390 continue;
3391
3392 extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory);
3393 }
3394
3395 return 0;
3396 }
3397
3398 static struct flash_partition_entry *find_partition(
3399 struct flash_partition_entry *entries, size_t max_entries,
3400 const char *name, const char *error_msg)
3401 {
3402 for (size_t i = 0; i < max_entries; i++, entries++) {
3403 if (strcmp(entries->name, name) == 0)
3404 return entries;
3405 }
3406
3407 if (error_msg) {
3408 error(1, 0, "%s", error_msg);
3409 }
3410
3411 return NULL;
3412 }
3413
3414 static int firmware_info(const char *input)
3415 {
3416 struct flash_partition_entry pointers[MAX_PARTITIONS] = { };
3417 struct flash_partition_entry *e;
3418 FILE *fp;
3419 int i;
3420
3421 fp = fopen(input, "r");
3422
3423 if (read_partition_table(fp, 0x1014, pointers, MAX_PARTITIONS, 0)) {
3424 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3425 }
3426
3427 printf("Firmware image partitions:\n");
3428 printf("%-8s %-8s %s\n", "base", "size", "name");
3429 for (i = 0; i < MAX_PARTITIONS; i++) {
3430 e = &pointers[i];
3431
3432 if (!e->name && !e->base && !e->size)
3433 continue;
3434
3435 printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : "");
3436 }
3437
3438 e = find_partition(pointers, MAX_PARTITIONS, "soft-version", NULL);
3439 if (e) {
3440 size_t data_len = e->size - sizeof(struct meta_header);
3441 char *buf = malloc(data_len);
3442 struct soft_version *s;
3443 bool isstr;
3444 int i;
3445
3446 if (!buf)
3447 error(1, errno, "Failed to alloc buffer");
3448
3449 if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET))
3450 error(1, errno, "Can not seek in the firmware");
3451
3452 if (fread(buf, data_len, 1, fp) != 1)
3453 error(1, errno, "Can not read fwup-ptn data from the firmware");
3454
3455 /* Check for string ignoring padding character */
3456 isstr = true;
3457 for (i = 0; i < data_len - 1; i++) {
3458 if (!isascii(buf[i])) {
3459 isstr = false;
3460 break;
3461 }
3462 }
3463
3464 printf("\n[Software version]\n");
3465 if (isstr) {
3466 fwrite(buf, data_len, 1, stdout);
3467 putchar('\n');
3468 } else if (data_len >= offsetof(struct soft_version, rev)) {
3469 s = (struct soft_version *)buf;
3470
3471 printf("Version: %d.%d.%d\n", s->version_major, s->version_minor, s->version_patch);
3472 printf("Date: %02x%02x-%02x-%02x\n", s->year_hi, s->year_lo, s->month, s->day);
3473 printf("Revision: %d\n", ntohl(s->rev));
3474 } else {
3475 printf("Failed to parse data\n");
3476 }
3477
3478 free(buf);
3479 }
3480
3481 e = find_partition(pointers, MAX_PARTITIONS, "support-list", NULL);
3482 if (e) {
3483 char buf[128];
3484 size_t length;
3485 size_t bytes;
3486
3487 if (fseek(fp, 0x1014 + e->base + sizeof(struct meta_header), SEEK_SET))
3488 error(1, errno, "Can not seek in the firmware");
3489
3490 printf("\n[Support list]\n");
3491 for (length = e->size - sizeof(struct meta_header); length; length -= bytes) {
3492 bytes = fread(buf, 1, length > sizeof(buf) ? sizeof(buf) : length, fp);
3493 if (bytes <= 0)
3494 error(1, errno, "Can not read fwup-ptn data from the firmware");
3495
3496 puts(buf);
3497 }
3498 }
3499
3500 e = find_partition(pointers, MAX_PARTITIONS, "partition-table", NULL);
3501 if (e) {
3502 struct flash_partition_entry parts[MAX_PARTITIONS] = { };
3503
3504 if (read_partition_table(fp, 0x1014 + e->base + 4, parts, MAX_PARTITIONS, 1)) {
3505 error(1, 0, "Error can not read the partition table (partition)");
3506 }
3507
3508 printf("\n[Partition table]\n");
3509 printf("%-8s %-8s %s\n", "base", "size", "name");
3510 for (i = 0; i < MAX_PARTITIONS; i++) {
3511 e = &parts[i];
3512
3513 if (!e->name && !e->base && !e->size)
3514 continue;
3515
3516 printf("%08x %08x %s\n", e->base, e->size, e->name ? e->name : "");
3517 }
3518 }
3519
3520 fclose(fp);
3521
3522 return 0;
3523 }
3524
3525 static void write_ff(FILE *output_file, size_t size)
3526 {
3527 char buf[4096];
3528 size_t offset;
3529
3530 memset(buf, 0xff, sizeof(buf));
3531
3532 for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
3533 if (fwrite(buf, sizeof(buf), 1, output_file) != 1)
3534 error(1, errno, "Can not write 0xff to output_file");
3535 }
3536
3537 /* write last chunk smaller than buffer */
3538 if (offset < size) {
3539 offset = size - offset;
3540 if (fwrite(buf, offset, 1, output_file) != 1)
3541 error(1, errno, "Can not write partition to output_file");
3542 }
3543 }
3544
3545 static void convert_firmware(const char *input, const char *output)
3546 {
3547 struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 };
3548 struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 };
3549 struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL;
3550 struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL;
3551 struct flash_partition_entry *fwup_partition_table = NULL;
3552 size_t firmware_offset = 0x1014;
3553 FILE *input_file, *output_file;
3554
3555 struct stat statbuf;
3556
3557 /* check input file */
3558 if (stat(input, &statbuf)) {
3559 error(1, errno, "Can not read input firmware %s", input);
3560 }
3561
3562 input_file = fopen(input, "rb");
3563 if (!input_file)
3564 error(1, 0, "Can not open input firmware %s", input);
3565
3566 output_file = fopen(output, "wb");
3567 if (!output_file)
3568 error(1, 0, "Can not open output firmware %s", output);
3569
3570 if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) {
3571 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3572 }
3573
3574 fwup_os_image = find_partition(fwup, MAX_PARTITIONS,
3575 "os-image", "Error can not find os-image partition (fwup)");
3576 fwup_file_system = find_partition(fwup, MAX_PARTITIONS,
3577 "file-system", "Error can not find file-system partition (fwup)");
3578 fwup_partition_table = find_partition(fwup, MAX_PARTITIONS,
3579 "partition-table", "Error can not find partition-table partition");
3580
3581 /* the flash partition table has a 0x00000004 magic haeder */
3582 if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0)
3583 error(1, 0, "Error can not read the partition table (flash)");
3584
3585 flash_os_image = find_partition(flash, MAX_PARTITIONS,
3586 "os-image", "Error can not find os-image partition (flash)");
3587 flash_file_system = find_partition(flash, MAX_PARTITIONS,
3588 "file-system", "Error can not find file-system partition (flash)");
3589
3590 /* write os_image to 0x0 */
3591 write_partition(input_file, firmware_offset, fwup_os_image, output_file);
3592 write_ff(output_file, flash_os_image->size - fwup_os_image->size);
3593
3594 /* write file-system behind os_image */
3595 fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
3596 write_partition(input_file, firmware_offset, fwup_file_system, output_file);
3597 write_ff(output_file, flash_file_system->size - fwup_file_system->size);
3598
3599 fclose(output_file);
3600 fclose(input_file);
3601 }
3602
3603 int main(int argc, char *argv[]) {
3604 const char *info_image = NULL, *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
3605 const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
3606 bool add_jffs2_eof = false, sysupgrade = false;
3607 unsigned rev = 0;
3608 struct device_info *info;
3609 set_source_date_epoch();
3610
3611 while (true) {
3612 int c;
3613
3614 c = getopt(argc, argv, "i:B:k:r:o:V:jSh:x:d:z:");
3615 if (c == -1)
3616 break;
3617
3618 switch (c) {
3619 case 'i':
3620 info_image = optarg;
3621 break;
3622
3623 case 'B':
3624 board = optarg;
3625 break;
3626
3627 case 'k':
3628 kernel_image = optarg;
3629 break;
3630
3631 case 'r':
3632 rootfs_image = optarg;
3633 break;
3634
3635 case 'o':
3636 output = optarg;
3637 break;
3638
3639 case 'V':
3640 sscanf(optarg, "r%u", &rev);
3641 break;
3642
3643 case 'j':
3644 add_jffs2_eof = true;
3645 break;
3646
3647 case 'S':
3648 sysupgrade = true;
3649 break;
3650
3651 case 'h':
3652 usage(argv[0]);
3653 return 0;
3654
3655 case 'd':
3656 output_directory = optarg;
3657 break;
3658
3659 case 'x':
3660 extract_image = optarg;
3661 break;
3662
3663 case 'z':
3664 convert_image = optarg;
3665 break;
3666
3667 default:
3668 usage(argv[0]);
3669 return 1;
3670 }
3671 }
3672
3673 if (info_image) {
3674 firmware_info(info_image);
3675 } else if (extract_image || output_directory) {
3676 if (!extract_image)
3677 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
3678 if (!output_directory)
3679 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
3680 extract_firmware(extract_image, output_directory);
3681 } else if (convert_image) {
3682 if (!output)
3683 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
3684 convert_firmware(convert_image, output);
3685 } else {
3686 if (!board)
3687 error(1, 0, "no board has been specified");
3688 if (!kernel_image)
3689 error(1, 0, "no kernel image has been specified");
3690 if (!rootfs_image)
3691 error(1, 0, "no rootfs image has been specified");
3692 if (!output)
3693 error(1, 0, "no output filename has been specified");
3694
3695 info = find_board(board);
3696
3697 if (info == NULL)
3698 error(1, 0, "unsupported board %s", board);
3699
3700 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
3701 }
3702
3703 return 0;
3704 }