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