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