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