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