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