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