2 Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 Image generation tool for the TP-LINK SafeLoader as seen on
31 TP-LINK Pharos devices (CPE210/220/510/520)
45 #include <arpa/inet.h>
47 #include <sys/types.h>
54 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
57 #define MAX_PARTITIONS 32
59 /** An image partition table entry */
60 struct image_partition_entry
{
66 /** A flash partition table entry */
67 struct flash_partition_entry
{
73 /** Partition trailing padding definitions
74 * Values 0x00 to 0xff are reserved to indicate the padding value
75 * Values from 0x100 are reserved to indicate other behaviour */
76 enum partition_trail_value
{
79 PART_TRAIL_MAX
= 0xff,
80 PART_TRAIL_NONE
= 0x100
83 /** Firmware layout description */
87 const char *support_list
;
88 enum partition_trail_value part_trail
;
90 uint32_t soft_ver_compat_level
;
91 struct flash_partition_entry partitions
[MAX_PARTITIONS
+1];
92 const char *first_sysupgrade_partition
;
93 const char *last_sysupgrade_partition
;
96 struct __attribute__((__packed__
)) meta_header
{
101 /** The content of the soft-version structure */
102 struct __attribute__((__packed__
)) soft_version
{
104 uint8_t version_major
;
105 uint8_t version_minor
;
106 uint8_t version_patch
;
112 uint32_t compat_level
;
116 static const uint8_t jffs2_eof_mark
[4] = {0xde, 0xad, 0xc0, 0xde};
120 Salt for the MD5 hash
122 Fortunately, TP-LINK seems to use the same salt for most devices which use
123 the new image format.
125 static const uint8_t md5_salt
[16] = {
126 0x7a, 0x2b, 0x15, 0xed,
127 0x9b, 0x98, 0x59, 0x6d,
128 0xe5, 0x04, 0xab, 0x44,
129 0xac, 0x2a, 0x9f, 0x4e,
133 /** Firmware layout table */
134 static struct device_info boards
[] = {
135 /** Firmware layout for the CPE210/220 V1 */
138 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
141 "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
142 "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
143 "CPE210(TP-LINK|US|N300-2):1.1\r\n"
144 "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
145 "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
146 "CPE220(TP-LINK|US|N300-2):1.1\r\n"
147 "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
152 {"fs-uboot", 0x00000, 0x20000},
153 {"partition-table", 0x20000, 0x02000},
154 {"default-mac", 0x30000, 0x00020},
155 {"product-info", 0x31100, 0x00100},
156 {"signature", 0x32000, 0x00400},
157 {"firmware", 0x40000, 0x770000},
158 {"soft-version", 0x7b0000, 0x00100},
159 {"support-list", 0x7b1000, 0x00400},
160 {"user-config", 0x7c0000, 0x10000},
161 {"default-config", 0x7d0000, 0x10000},
162 {"log", 0x7e0000, 0x10000},
163 {"radio", 0x7f0000, 0x10000},
167 .first_sysupgrade_partition
= "os-image",
168 .last_sysupgrade_partition
= "support-list",
171 /** Firmware layout for the CPE210 V2 */
174 .vendor
= "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
177 "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
178 "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
179 "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
180 "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
181 "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
182 "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
183 "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
184 "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
185 "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
186 "CPE210(TP-LINK|US|N300-2):2.0\r\n",
191 {"fs-uboot", 0x00000, 0x20000},
192 {"partition-table", 0x20000, 0x02000},
193 {"default-mac", 0x30000, 0x00020},
194 {"product-info", 0x31100, 0x00100},
195 {"device-info", 0x31400, 0x00400},
196 {"signature", 0x32000, 0x00400},
197 {"device-id", 0x33000, 0x00100},
198 {"firmware", 0x40000, 0x770000},
199 {"soft-version", 0x7b0000, 0x00100},
200 {"support-list", 0x7b1000, 0x01000},
201 {"user-config", 0x7c0000, 0x10000},
202 {"default-config", 0x7d0000, 0x10000},
203 {"log", 0x7e0000, 0x10000},
204 {"radio", 0x7f0000, 0x10000},
208 .first_sysupgrade_partition
= "os-image",
209 .last_sysupgrade_partition
= "support-list",
212 /** Firmware layout for the CPE210 V3 */
215 .vendor
= "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n",
218 "CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n"
219 "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n"
220 "CPE210(TP-LINK|US|N300-2|55530000):3.0\r\n"
221 "CPE210(TP-LINK|UN|N300-2):3.0\r\n"
222 "CPE210(TP-LINK|EU|N300-2):3.0\r\n"
223 "CPE210(TP-LINK|EU|N300-2|45550000):3.1\r\n"
224 "CPE210(TP-LINK|UN|N300-2|00000000):3.1\r\n"
225 "CPE210(TP-LINK|US|N300-2|55530000):3.1\r\n"
226 "CPE210(TP-LINK|EU|N300-2|45550000):3.20\r\n"
227 "CPE210(TP-LINK|UN|N300-2|00000000):3.20\r\n"
228 "CPE210(TP-LINK|US|N300-2|55530000):3.20\r\n",
233 {"fs-uboot", 0x00000, 0x20000},
234 {"partition-table", 0x20000, 0x01000},
235 {"default-mac", 0x30000, 0x00020},
236 {"product-info", 0x31100, 0x00100},
237 {"device-info", 0x31400, 0x00400},
238 {"signature", 0x32000, 0x00400},
239 {"device-id", 0x33000, 0x00100},
240 {"firmware", 0x40000, 0x770000},
241 {"soft-version", 0x7b0000, 0x00100},
242 {"support-list", 0x7b1000, 0x01000},
243 {"user-config", 0x7c0000, 0x10000},
244 {"default-config", 0x7d0000, 0x10000},
245 {"log", 0x7e0000, 0x10000},
246 {"radio", 0x7f0000, 0x10000},
250 .first_sysupgrade_partition
= "os-image",
251 .last_sysupgrade_partition
= "support-list",
254 /** Firmware layout for the CPE220 V2 */
257 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
260 "CPE220(TP-LINK|EU|N300-2|00000000):2.0\r\n"
261 "CPE220(TP-LINK|EU|N300-2|45550000):2.0\r\n"
262 "CPE220(TP-LINK|EU|N300-2|55530000):2.0\r\n"
263 "CPE220(TP-LINK|UN|N300-2|00000000):2.0\r\n"
264 "CPE220(TP-LINK|UN|N300-2|45550000):2.0\r\n"
265 "CPE220(TP-LINK|UN|N300-2|55530000):2.0\r\n"
266 "CPE220(TP-LINK|US|N300-2|55530000):2.0\r\n"
267 "CPE220(TP-LINK|UN|N300-2):2.0\r\n"
268 "CPE220(TP-LINK|EU|N300-2):2.0\r\n"
269 "CPE220(TP-LINK|US|N300-2):2.0\r\n",
274 {"fs-uboot", 0x00000, 0x20000},
275 {"partition-table", 0x20000, 0x02000},
276 {"default-mac", 0x30000, 0x00020},
277 {"product-info", 0x31100, 0x00100},
278 {"signature", 0x32000, 0x00400},
279 {"firmware", 0x40000, 0x770000},
280 {"soft-version", 0x7b0000, 0x00100},
281 {"support-list", 0x7b1000, 0x00400},
282 {"user-config", 0x7c0000, 0x10000},
283 {"default-config", 0x7d0000, 0x10000},
284 {"log", 0x7e0000, 0x10000},
285 {"radio", 0x7f0000, 0x10000},
289 .first_sysupgrade_partition
= "os-image",
290 .last_sysupgrade_partition
= "support-list",
293 /** Firmware layout for the CPE220 V3 */
296 .vendor
= "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n",
299 "CPE220(TP-LINK|EU|N300-2|00000000):3.0\r\n"
300 "CPE220(TP-LINK|EU|N300-2|45550000):3.0\r\n"
301 "CPE220(TP-LINK|EU|N300-2|55530000):3.0\r\n"
302 "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n"
303 "CPE220(TP-LINK|UN|N300-2|45550000):3.0\r\n"
304 "CPE220(TP-LINK|UN|N300-2|55530000):3.0\r\n"
305 "CPE220(TP-LINK|US|N300-2|55530000):3.0\r\n"
306 "CPE220(TP-LINK|UN|N300-2):3.0\r\n"
307 "CPE220(TP-LINK|EU|N300-2):3.0\r\n"
308 "CPE220(TP-LINK|US|N300-2):3.0\r\n",
313 {"fs-uboot", 0x00000, 0x20000},
314 {"partition-table", 0x20000, 0x02000},
315 {"default-mac", 0x30000, 0x00020},
316 {"product-info", 0x31100, 0x00100},
317 {"device-info", 0x31400, 0x00400},
318 {"signature", 0x32000, 0x00400},
319 {"device-id", 0x33000, 0x00100},
320 {"firmware", 0x40000, 0x770000},
321 {"soft-version", 0x7b0000, 0x00100},
322 {"support-list", 0x7b1000, 0x01000},
323 {"user-config", 0x7c0000, 0x10000},
324 {"default-config", 0x7d0000, 0x10000},
325 {"log", 0x7e0000, 0x10000},
326 {"radio", 0x7f0000, 0x10000},
330 .first_sysupgrade_partition
= "os-image",
331 .last_sysupgrade_partition
= "support-list",
334 /** Firmware layout for the CPE510/520 V1 */
337 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
340 "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
341 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
342 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
343 "CPE510(TP-LINK|US|N300-5):1.1\r\n"
344 "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
345 "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
346 "CPE520(TP-LINK|US|N300-5):1.1\r\n"
347 "CPE520(TP-LINK|EU|N300-5):1.1\r\n",
352 {"fs-uboot", 0x00000, 0x20000},
353 {"partition-table", 0x20000, 0x02000},
354 {"default-mac", 0x30000, 0x00020},
355 {"product-info", 0x31100, 0x00100},
356 {"signature", 0x32000, 0x00400},
357 {"firmware", 0x40000, 0x770000},
358 {"soft-version", 0x7b0000, 0x00100},
359 {"support-list", 0x7b1000, 0x00400},
360 {"user-config", 0x7c0000, 0x10000},
361 {"default-config", 0x7d0000, 0x10000},
362 {"log", 0x7e0000, 0x10000},
363 {"radio", 0x7f0000, 0x10000},
367 .first_sysupgrade_partition
= "os-image",
368 .last_sysupgrade_partition
= "support-list",
371 /** Firmware layout for the CPE510 V2 */
374 .vendor
= "CPE510(TP-LINK|UN|N300-5):2.0\r\n",
377 "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n"
378 "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
379 "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n"
380 "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
381 "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n"
382 "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n"
383 "CPE510(TP-LINK|US|N300-5|00000000):2.0\r\n"
384 "CPE510(TP-LINK|US|N300-5|45550000):2.0\r\n"
385 "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n"
386 "CPE510(TP-LINK|UN|N300-5):2.0\r\n"
387 "CPE510(TP-LINK|EU|N300-5):2.0\r\n"
388 "CPE510(TP-LINK|US|N300-5):2.0\r\n",
393 {"fs-uboot", 0x00000, 0x20000},
394 {"partition-table", 0x20000, 0x02000},
395 {"default-mac", 0x30000, 0x00020},
396 {"product-info", 0x31100, 0x00100},
397 {"signature", 0x32000, 0x00400},
398 {"firmware", 0x40000, 0x770000},
399 {"soft-version", 0x7b0000, 0x00100},
400 {"support-list", 0x7b1000, 0x00400},
401 {"user-config", 0x7c0000, 0x10000},
402 {"default-config", 0x7d0000, 0x10000},
403 {"log", 0x7e0000, 0x10000},
404 {"radio", 0x7f0000, 0x10000},
408 .first_sysupgrade_partition
= "os-image",
409 .last_sysupgrade_partition
= "support-list",
412 /** Firmware layout for the CPE510 V3 */
415 .vendor
= "CPE510(TP-LINK|UN|N300-5):3.0\r\n",
418 "CPE510(TP-LINK|EU|N300-5|00000000):3.0\r\n"
419 "CPE510(TP-LINK|EU|N300-5|45550000):3.0\r\n"
420 "CPE510(TP-LINK|EU|N300-5|55530000):3.0\r\n"
421 "CPE510(TP-LINK|UN|N300-5|00000000):3.0\r\n"
422 "CPE510(TP-LINK|UN|N300-5|45550000):3.0\r\n"
423 "CPE510(TP-LINK|UN|N300-5|55530000):3.0\r\n"
424 "CPE510(TP-LINK|US|N300-5|00000000):3.0\r\n"
425 "CPE510(TP-LINK|US|N300-5|45550000):3.0\r\n"
426 "CPE510(TP-LINK|US|N300-5|55530000):3.0\r\n"
427 "CPE510(TP-LINK|UN|N300-5):3.0\r\n"
428 "CPE510(TP-LINK|EU|N300-5):3.0\r\n"
429 "CPE510(TP-LINK|US|N300-5):3.0\r\n"
430 "CPE510(TP-LINK|UN|N300-5|00000000):3.20\r\n"
431 "CPE510(TP-LINK|US|N300-5|55530000):3.20\r\n"
432 "CPE510(TP-LINK|EU|N300-5|45550000):3.20\r\n",
437 {"fs-uboot", 0x00000, 0x20000},
438 {"partition-table", 0x20000, 0x02000},
439 {"default-mac", 0x30000, 0x00020},
440 {"product-info", 0x31100, 0x00100},
441 {"signature", 0x32000, 0x00400},
442 {"firmware", 0x40000, 0x770000},
443 {"soft-version", 0x7b0000, 0x00100},
444 {"support-list", 0x7b1000, 0x00400},
445 {"user-config", 0x7c0000, 0x10000},
446 {"default-config", 0x7d0000, 0x10000},
447 {"log", 0x7e0000, 0x10000},
448 {"radio", 0x7f0000, 0x10000},
452 .first_sysupgrade_partition
= "os-image",
453 .last_sysupgrade_partition
= "support-list",
456 /** Firmware layout for the CPE610V1 */
459 .vendor
= "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n",
462 "CPE610(TP-LINK|EU|N300-5|00000000):1.0\r\n"
463 "CPE610(TP-LINK|EU|N300-5|45550000):1.0\r\n"
464 "CPE610(TP-LINK|EU|N300-5|55530000):1.0\r\n"
465 "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n"
466 "CPE610(TP-LINK|UN|N300-5|45550000):1.0\r\n"
467 "CPE610(TP-LINK|UN|N300-5|55530000):1.0\r\n"
468 "CPE610(TP-LINK|US|N300-5|55530000):1.0\r\n"
469 "CPE610(TP-LINK|UN|N300-5):1.0\r\n"
470 "CPE610(TP-LINK|EU|N300-5):1.0\r\n"
471 "CPE610(TP-LINK|US|N300-5):1.0\r\n",
476 {"fs-uboot", 0x00000, 0x20000},
477 {"partition-table", 0x20000, 0x02000},
478 {"default-mac", 0x30000, 0x00020},
479 {"product-info", 0x31100, 0x00100},
480 {"signature", 0x32000, 0x00400},
481 {"firmware", 0x40000, 0x770000},
482 {"soft-version", 0x7b0000, 0x00100},
483 {"support-list", 0x7b1000, 0x00400},
484 {"user-config", 0x7c0000, 0x10000},
485 {"default-config", 0x7d0000, 0x10000},
486 {"log", 0x7e0000, 0x10000},
487 {"radio", 0x7f0000, 0x10000},
491 .first_sysupgrade_partition
= "os-image",
492 .last_sysupgrade_partition
= "support-list",
495 /** Firmware layout for the CPE610V2 */
498 .vendor
= "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n",
501 "CPE610(TP-LINK|EU|N300-5|00000000):2.0\r\n"
502 "CPE610(TP-LINK|EU|N300-5|45550000):2.0\r\n"
503 "CPE610(TP-LINK|EU|N300-5|55530000):2.0\r\n"
504 "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n"
505 "CPE610(TP-LINK|UN|N300-5|45550000):2.0\r\n"
506 "CPE610(TP-LINK|UN|N300-5|55530000):2.0\r\n"
507 "CPE610(TP-LINK|US|N300-5|55530000):2.0\r\n"
508 "CPE610(TP-LINK|UN|N300-5):2.0\r\n"
509 "CPE610(TP-LINK|EU|N300-5):2.0\r\n"
510 "CPE610(TP-LINK|US|N300-5):2.0\r\n",
515 {"fs-uboot", 0x00000, 0x20000},
516 {"partition-table", 0x20000, 0x02000},
517 {"default-mac", 0x30000, 0x00020},
518 {"product-info", 0x31100, 0x00100},
519 {"signature", 0x32000, 0x00400},
520 {"firmware", 0x40000, 0x770000},
521 {"soft-version", 0x7b0000, 0x00100},
522 {"support-list", 0x7b1000, 0x00400},
523 {"user-config", 0x7c0000, 0x10000},
524 {"default-config", 0x7d0000, 0x10000},
525 {"log", 0x7e0000, 0x10000},
526 {"radio", 0x7f0000, 0x10000},
530 .first_sysupgrade_partition
= "os-image",
531 .last_sysupgrade_partition
= "support-list",
536 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
539 "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
540 "WBS210(TP-LINK|US|N300-2):1.20\r\n"
541 "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
546 {"fs-uboot", 0x00000, 0x20000},
547 {"partition-table", 0x20000, 0x02000},
548 {"default-mac", 0x30000, 0x00020},
549 {"product-info", 0x31100, 0x00100},
550 {"signature", 0x32000, 0x00400},
551 {"firmware", 0x40000, 0x770000},
552 {"soft-version", 0x7b0000, 0x00100},
553 {"support-list", 0x7b1000, 0x00400},
554 {"user-config", 0x7c0000, 0x10000},
555 {"default-config", 0x7d0000, 0x10000},
556 {"log", 0x7e0000, 0x10000},
557 {"radio", 0x7f0000, 0x10000},
561 .first_sysupgrade_partition
= "os-image",
562 .last_sysupgrade_partition
= "support-list",
567 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
570 "WBS210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
571 "WBS210(TP-LINK|US|N300-2|55530000):2.0\r\n"
572 "WBS210(TP-LINK|EU|N300-2|45550000):2.0\r\n",
577 {"fs-uboot", 0x00000, 0x20000},
578 {"partition-table", 0x20000, 0x02000},
579 {"default-mac", 0x30000, 0x00020},
580 {"product-info", 0x31100, 0x00100},
581 {"signature", 0x32000, 0x00400},
582 {"firmware", 0x40000, 0x770000},
583 {"soft-version", 0x7b0000, 0x00100},
584 {"support-list", 0x7b1000, 0x00400},
585 {"user-config", 0x7c0000, 0x10000},
586 {"default-config", 0x7d0000, 0x10000},
587 {"log", 0x7e0000, 0x10000},
588 {"radio", 0x7f0000, 0x10000},
592 .first_sysupgrade_partition
= "os-image",
593 .last_sysupgrade_partition
= "support-list",
598 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
601 "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
602 "WBS510(TP-LINK|US|N300-5):1.20\r\n"
603 "WBS510(TP-LINK|EU|N300-5):1.20\r\n"
604 "WBS510(TP-LINK|CA|N300-5):1.20\r\n",
609 {"fs-uboot", 0x00000, 0x20000},
610 {"partition-table", 0x20000, 0x02000},
611 {"default-mac", 0x30000, 0x00020},
612 {"product-info", 0x31100, 0x00100},
613 {"signature", 0x32000, 0x00400},
614 {"firmware", 0x40000, 0x770000},
615 {"soft-version", 0x7b0000, 0x00100},
616 {"support-list", 0x7b1000, 0x00400},
617 {"user-config", 0x7c0000, 0x10000},
618 {"default-config", 0x7d0000, 0x10000},
619 {"log", 0x7e0000, 0x10000},
620 {"radio", 0x7f0000, 0x10000},
624 .first_sysupgrade_partition
= "os-image",
625 .last_sysupgrade_partition
= "support-list",
630 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
633 "WBS510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
634 "WBS510(TP-LINK|US|N300-5|55530000):2.0\r\n"
635 "WBS510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
636 "WBS510(TP-LINK|CA|N300-5|43410000):2.0\r\n",
641 {"fs-uboot", 0x00000, 0x20000},
642 {"partition-table", 0x20000, 0x02000},
643 {"default-mac", 0x30000, 0x00020},
644 {"product-info", 0x31100, 0x00100},
645 {"signature", 0x32000, 0x00400},
646 {"firmware", 0x40000, 0x770000},
647 {"soft-version", 0x7b0000, 0x00100},
648 {"support-list", 0x7b1000, 0x00400},
649 {"user-config", 0x7c0000, 0x10000},
650 {"default-config", 0x7d0000, 0x10000},
651 {"log", 0x7e0000, 0x10000},
652 {"radio", 0x7f0000, 0x10000},
656 .first_sysupgrade_partition
= "os-image",
657 .last_sysupgrade_partition
= "support-list",
660 /** Firmware layout for the AD7200 */
666 "{product_name:AD7200,product_ver:1.0.0,special_id:00000000}\r\n",
671 {"SBL1", 0x00000, 0x20000},
672 {"MIBIB", 0x20000, 0x20000},
673 {"SBL2", 0x40000, 0x20000},
674 {"SBL3", 0x60000, 0x30000},
675 {"DDRCONFIG", 0x90000, 0x10000},
676 {"SSD", 0xa0000, 0x10000},
677 {"TZ", 0xb0000, 0x30000},
678 {"RPM", 0xe0000, 0x20000},
679 {"fs-uboot", 0x100000, 0x70000},
680 {"uboot-env", 0x170000, 0x40000},
681 {"radio", 0x1b0000, 0x40000},
682 {"os-image", 0x1f0000, 0x400000},
683 {"file-system", 0x5f0000, 0x1900000},
684 {"default-mac", 0x1ef0000, 0x00200},
685 {"pin", 0x1ef0200, 0x00200},
686 {"device-id", 0x1ef0400, 0x00200},
687 {"product-info", 0x1ef0600, 0x0fa00},
688 {"partition-table", 0x1f00000, 0x10000},
689 {"soft-version", 0x1f10000, 0x10000},
690 {"support-list", 0x1f20000, 0x10000},
691 {"profile", 0x1f30000, 0x10000},
692 {"default-config", 0x1f40000, 0x10000},
693 {"user-config", 0x1f50000, 0x40000},
694 {"qos-db", 0x1f90000, 0x40000},
695 {"usb-config", 0x1fd0000, 0x10000},
696 {"log", 0x1fe0000, 0x20000},
700 .first_sysupgrade_partition
= "os-image",
701 .last_sysupgrade_partition
= "file-system"
704 /** Firmware layout for the C2600 */
710 "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
715 We use a bigger os-image partition than the stock images (and thus
716 smaller file-system), as our kernel doesn't fit in the stock firmware's
717 2 MB os-image since kernel 4.14.
720 {"SBL1", 0x00000, 0x20000},
721 {"MIBIB", 0x20000, 0x20000},
722 {"SBL2", 0x40000, 0x20000},
723 {"SBL3", 0x60000, 0x30000},
724 {"DDRCONFIG", 0x90000, 0x10000},
725 {"SSD", 0xa0000, 0x10000},
726 {"TZ", 0xb0000, 0x30000},
727 {"RPM", 0xe0000, 0x20000},
728 {"fs-uboot", 0x100000, 0x70000},
729 {"uboot-env", 0x170000, 0x40000},
730 {"radio", 0x1b0000, 0x40000},
731 {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
732 {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
733 {"default-mac", 0x1ef0000, 0x00200},
734 {"pin", 0x1ef0200, 0x00200},
735 {"product-info", 0x1ef0400, 0x0fc00},
736 {"partition-table", 0x1f00000, 0x10000},
737 {"soft-version", 0x1f10000, 0x10000},
738 {"support-list", 0x1f20000, 0x10000},
739 {"profile", 0x1f30000, 0x10000},
740 {"default-config", 0x1f40000, 0x10000},
741 {"user-config", 0x1f50000, 0x40000},
742 {"qos-db", 0x1f90000, 0x40000},
743 {"usb-config", 0x1fd0000, 0x10000},
744 {"log", 0x1fe0000, 0x20000},
748 .first_sysupgrade_partition
= "os-image",
749 .last_sysupgrade_partition
= "file-system"
752 /** Firmware layout for the A7-V5 */
754 .id
= "ARCHER-A7-V5",
757 "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n"
758 "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n"
759 "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n"
760 "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n"
761 "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n"
762 "{product_name:Archer A7,product_ver:5.0.0,special_id:52550000}\n",
764 .soft_ver
= "soft_ver:1.0.0\n",
766 /* We're using a dynamic kernel/rootfs split here */
768 {"factory-boot", 0x00000, 0x20000},
769 {"fs-uboot", 0x20000, 0x20000},
770 {"firmware", 0x40000, 0xec0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
771 /* Stock: name file-system base 0x160000 size 0xda0000 */
772 {"default-mac", 0xf40000, 0x00200},
773 {"pin", 0xf40200, 0x00200},
774 {"device-id", 0xf40400, 0x00100},
775 {"product-info", 0xf40500, 0x0fb00},
776 {"soft-version", 0xf50000, 0x00100},
777 {"extra-para", 0xf51000, 0x01000},
778 {"support-list", 0xf52000, 0x0a000},
779 {"profile", 0xf5c000, 0x04000},
780 {"default-config", 0xf60000, 0x10000},
781 {"user-config", 0xf70000, 0x40000},
782 {"certificate", 0xfb0000, 0x10000},
783 {"partition-table", 0xfc0000, 0x10000},
784 {"log", 0xfd0000, 0x20000},
785 {"radio", 0xff0000, 0x10000},
789 .first_sysupgrade_partition
= "os-image",
790 .last_sysupgrade_partition
= "file-system",
793 /** Firmware layout for the C2v3 */
795 .id
= "ARCHER-C2-V3",
798 "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n"
799 "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n"
800 "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n",
802 .soft_ver
= "soft_ver:3.0.1\n",
804 /** We're using a dynamic kernel/rootfs split here */
807 {"factory-boot", 0x00000, 0x20000},
808 {"fs-uboot", 0x20000, 0x10000},
809 {"firmware", 0x30000, 0x7a0000},
810 {"user-config", 0x7d0000, 0x04000},
811 {"default-mac", 0x7e0000, 0x00100},
812 {"device-id", 0x7e0100, 0x00100},
813 {"extra-para", 0x7e0200, 0x00100},
814 {"pin", 0x7e0300, 0x00100},
815 {"support-list", 0x7e0400, 0x00400},
816 {"soft-version", 0x7e0800, 0x00400},
817 {"product-info", 0x7e0c00, 0x01400},
818 {"partition-table", 0x7e2000, 0x01000},
819 {"profile", 0x7e3000, 0x01000},
820 {"default-config", 0x7e4000, 0x04000},
821 {"merge-config", 0x7ec000, 0x02000},
822 {"qos-db", 0x7ee000, 0x02000},
823 {"radio", 0x7f0000, 0x10000},
827 .first_sysupgrade_partition
= "os-image",
828 .last_sysupgrade_partition
= "file-system",
831 /** Firmware layout for the C25v1 */
833 .id
= "ARCHER-C25-V1",
836 "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
837 "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
838 "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
840 .soft_ver
= "soft_ver:1.0.0\n",
842 /* We're using a dynamic kernel/rootfs split here */
844 {"factory-boot", 0x00000, 0x20000},
845 {"fs-uboot", 0x20000, 0x10000},
846 {"firmware", 0x30000, 0x7a0000}, /* Stock: name os-image base 0x30000 size 0x100000 */
847 /* Stock: name file-system base 0x130000 size 0x6a0000 */
848 {"user-config", 0x7d0000, 0x04000},
849 {"default-mac", 0x7e0000, 0x00100},
850 {"device-id", 0x7e0100, 0x00100},
851 {"extra-para", 0x7e0200, 0x00100},
852 {"pin", 0x7e0300, 0x00100},
853 {"support-list", 0x7e0400, 0x00400},
854 {"soft-version", 0x7e0800, 0x00400},
855 {"product-info", 0x7e0c00, 0x01400},
856 {"partition-table", 0x7e2000, 0x01000},
857 {"profile", 0x7e3000, 0x01000},
858 {"default-config", 0x7e4000, 0x04000},
859 {"merge-config", 0x7ec000, 0x02000},
860 {"qos-db", 0x7ee000, 0x02000},
861 {"radio", 0x7f0000, 0x10000},
865 .first_sysupgrade_partition
= "os-image",
866 .last_sysupgrade_partition
= "file-system",
869 /** Firmware layout for the C58v1 */
871 .id
= "ARCHER-C58-V1",
875 "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
876 "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
877 "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
879 .soft_ver
= "soft_ver:1.0.0\n",
882 {"fs-uboot", 0x00000, 0x10000},
883 {"default-mac", 0x10000, 0x00200},
884 {"pin", 0x10200, 0x00200},
885 {"product-info", 0x10400, 0x00100},
886 {"partition-table", 0x10500, 0x00800},
887 {"soft-version", 0x11300, 0x00200},
888 {"support-list", 0x11500, 0x00100},
889 {"device-id", 0x11600, 0x00100},
890 {"profile", 0x11700, 0x03900},
891 {"default-config", 0x15000, 0x04000},
892 {"user-config", 0x19000, 0x04000},
893 {"firmware", 0x20000, 0x7c8000},
894 {"certyficate", 0x7e8000, 0x08000},
895 {"radio", 0x7f0000, 0x10000},
899 .first_sysupgrade_partition
= "os-image",
900 .last_sysupgrade_partition
= "file-system",
903 /** Firmware layout for the C59v1 */
905 .id
= "ARCHER-C59-V1",
909 "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
910 "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
911 "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
912 "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
914 .soft_ver
= "soft_ver:1.0.0\n",
916 /* We're using a dynamic kernel/rootfs split here */
918 {"fs-uboot", 0x00000, 0x10000},
919 {"default-mac", 0x10000, 0x00200},
920 {"pin", 0x10200, 0x00200},
921 {"device-id", 0x10400, 0x00100},
922 {"product-info", 0x10500, 0x0fb00},
923 {"firmware", 0x20000, 0xe30000},
924 {"partition-table", 0xe50000, 0x10000},
925 {"soft-version", 0xe60000, 0x10000},
926 {"support-list", 0xe70000, 0x10000},
927 {"profile", 0xe80000, 0x10000},
928 {"default-config", 0xe90000, 0x10000},
929 {"user-config", 0xea0000, 0x40000},
930 {"usb-config", 0xee0000, 0x10000},
931 {"certificate", 0xef0000, 0x10000},
932 {"qos-db", 0xf00000, 0x40000},
933 {"log", 0xfe0000, 0x10000},
934 {"radio", 0xff0000, 0x10000},
938 .first_sysupgrade_partition
= "os-image",
939 .last_sysupgrade_partition
= "file-system",
942 /** Firmware layout for the C59v2 */
944 .id
= "ARCHER-C59-V2",
948 "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n"
949 "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n"
950 "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n",
952 .soft_ver
= "soft_ver:2.0.0 Build 20161206 rel.7303\n",
954 /** We're using a dynamic kernel/rootfs split here */
956 {"factory-boot", 0x00000, 0x20000},
957 {"fs-uboot", 0x20000, 0x10000},
958 {"default-mac", 0x30000, 0x00200},
959 {"pin", 0x30200, 0x00200},
960 {"device-id", 0x30400, 0x00100},
961 {"product-info", 0x30500, 0x0fb00},
962 {"firmware", 0x40000, 0xe10000},
963 {"partition-table", 0xe50000, 0x10000},
964 {"soft-version", 0xe60000, 0x10000},
965 {"support-list", 0xe70000, 0x10000},
966 {"profile", 0xe80000, 0x10000},
967 {"default-config", 0xe90000, 0x10000},
968 {"user-config", 0xea0000, 0x40000},
969 {"usb-config", 0xee0000, 0x10000},
970 {"certificate", 0xef0000, 0x10000},
971 {"extra-para", 0xf00000, 0x10000},
972 {"qos-db", 0xf10000, 0x30000},
973 {"log", 0xfe0000, 0x10000},
974 {"radio", 0xff0000, 0x10000},
978 .first_sysupgrade_partition
= "os-image",
979 .last_sysupgrade_partition
= "file-system",
982 /** Firmware layout for the Archer C6 v2 (EU/RU/JP) */
984 .id
= "ARCHER-C6-V2",
988 "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n"
989 "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n"
990 "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n",
992 .soft_ver
= "soft_ver:1.9.1\n",
995 {"fs-uboot", 0x00000, 0x20000},
996 {"default-mac", 0x20000, 0x00200},
997 {"pin", 0x20200, 0x00100},
998 {"product-info", 0x20300, 0x00200},
999 {"device-id", 0x20500, 0x0fb00},
1000 {"firmware", 0x30000, 0x7a9400},
1001 {"soft-version", 0x7d9400, 0x00100},
1002 {"extra-para", 0x7d9500, 0x00100},
1003 {"support-list", 0x7d9600, 0x00200},
1004 {"profile", 0x7d9800, 0x03000},
1005 {"default-config", 0x7dc800, 0x03000},
1006 {"partition-table", 0x7df800, 0x00800},
1007 {"user-config", 0x7e0000, 0x0c000},
1008 {"certificate", 0x7ec000, 0x04000},
1009 {"radio", 0x7f0000, 0x10000},
1013 .first_sysupgrade_partition
= "os-image",
1014 .last_sysupgrade_partition
= "file-system",
1017 /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */
1019 .id
= "ARCHER-C6-V2-US",
1023 "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n"
1024 "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n"
1025 "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n",
1027 .soft_ver
= "soft_ver:1.9.1\n",
1030 {"factory-boot", 0x00000, 0x20000},
1031 {"default-mac", 0x20000, 0x00200},
1032 {"pin", 0x20200, 0x00100},
1033 {"product-info", 0x20300, 0x00200},
1034 {"device-id", 0x20500, 0x0fb00},
1035 {"fs-uboot", 0x30000, 0x20000},
1036 {"firmware", 0x50000, 0xf89400},
1037 {"soft-version", 0xfd9400, 0x00100},
1038 {"extra-para", 0xfd9500, 0x00100},
1039 {"support-list", 0xfd9600, 0x00200},
1040 {"profile", 0xfd9800, 0x03000},
1041 {"default-config", 0xfdc800, 0x03000},
1042 {"partition-table", 0xfdf800, 0x00800},
1043 {"user-config", 0xfe0000, 0x0c000},
1044 {"certificate", 0xfec000, 0x04000},
1045 {"radio", 0xff0000, 0x10000},
1048 .first_sysupgrade_partition
= "os-image",
1049 .last_sysupgrade_partition
= "file-system",
1051 /** Firmware layout for the Archer A6 v3 */
1053 .id
= "ARCHER-A6-V3",
1057 "{product_name:Archer A6,product_ver:3.0.0,special_id:55530000}\n"
1058 "{product_name:Archer A6,product_ver:3.0.0,special_id:54570000}\n",
1060 .soft_ver
= "soft_ver:1.0.5\n",
1063 {"fs-uboot", 0x00000, 0x40000},
1064 {"firmware", 0x40000, 0xf60000},
1065 {"default-mac", 0xfa0000, 0x00200},
1066 {"pin", 0xfa0200, 0x00100},
1067 {"device-id", 0xfa0300, 0x00100},
1068 {"product-info", 0xfa0400, 0x0fc00},
1069 {"default-config", 0xfb0000, 0x08000},
1070 {"ap-def-config", 0xfb8000, 0x08000},
1071 {"user-config", 0xfc0000, 0x0a000},
1072 {"ag-config", 0xfca000, 0x04000},
1073 {"certificate", 0xfce000, 0x02000},
1074 {"ap-config", 0xfd0000, 0x06000},
1075 {"router-config", 0xfd6000, 0x06000},
1076 {"favicon", 0xfdc000, 0x02000},
1077 {"logo", 0xfde000, 0x02000},
1078 {"partition-table", 0xfe0000, 0x00800},
1079 {"soft-version", 0xfe0800, 0x00100},
1080 {"support-list", 0xfe0900, 0x00200},
1081 {"profile", 0xfe0b00, 0x03000},
1082 {"extra-para", 0xfe3b00, 0x00100},
1083 {"radio", 0xff0000, 0x10000},
1086 .first_sysupgrade_partition
= "os-image",
1087 .last_sysupgrade_partition
= "file-system",
1089 /** Firmware layout for the Archer C6U v1 */
1091 .id
= "ARCHER-C6U-V1",
1095 "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n",
1097 .soft_ver
= "soft_ver:1.0.2\n",
1100 {"fs-uboot", 0x00000, 0x40000},
1101 {"firmware", 0x40000, 0xf60000},
1102 {"default-mac", 0xfa0000, 0x00200},
1103 {"pin", 0xfa0200, 0x00100},
1104 {"device-id", 0xfa0300, 0x00100},
1105 {"product-info", 0xfa0400, 0x0fc00},
1106 {"default-config", 0xfb0000, 0x08000},
1107 {"ap-def-config", 0xfb8000, 0x08000},
1108 {"user-config", 0xfc0000, 0x0c000},
1109 {"certificate", 0xfcc000, 0x04000},
1110 {"ap-config", 0xfd0000, 0x08000},
1111 {"router-config", 0xfd8000, 0x08000},
1112 {"partition-table", 0xfe0000, 0x00800},
1113 {"soft-version", 0xfe0800, 0x00100},
1114 {"support-list", 0xfe0900, 0x00200},
1115 {"profile", 0xfe0b00, 0x03000},
1116 {"extra-para", 0xfe3b00, 0x00100},
1117 {"radio", 0xff0000, 0x10000},
1120 .first_sysupgrade_partition
= "os-image",
1121 .last_sysupgrade_partition
= "file-system",
1123 /** Firmware layout for the C60v1 */
1125 .id
= "ARCHER-C60-V1",
1129 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1130 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1131 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1133 .soft_ver
= "soft_ver:1.0.0\n",
1136 {"fs-uboot", 0x00000, 0x10000},
1137 {"default-mac", 0x10000, 0x00200},
1138 {"pin", 0x10200, 0x00200},
1139 {"product-info", 0x10400, 0x00100},
1140 {"partition-table", 0x10500, 0x00800},
1141 {"soft-version", 0x11300, 0x00200},
1142 {"support-list", 0x11500, 0x00100},
1143 {"device-id", 0x11600, 0x00100},
1144 {"profile", 0x11700, 0x03900},
1145 {"default-config", 0x15000, 0x04000},
1146 {"user-config", 0x19000, 0x04000},
1147 {"firmware", 0x20000, 0x7c8000},
1148 {"certyficate", 0x7e8000, 0x08000},
1149 {"radio", 0x7f0000, 0x10000},
1153 .first_sysupgrade_partition
= "os-image",
1154 .last_sysupgrade_partition
= "file-system",
1157 /** Firmware layout for the C60v2 */
1159 .id
= "ARCHER-C60-V2",
1163 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1164 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1165 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1167 .soft_ver
= "soft_ver:2.0.0\n",
1170 {"factory-boot", 0x00000, 0x1fb00},
1171 {"default-mac", 0x1fb00, 0x00200},
1172 {"pin", 0x1fd00, 0x00100},
1173 {"product-info", 0x1fe00, 0x00100},
1174 {"device-id", 0x1ff00, 0x00100},
1175 {"fs-uboot", 0x20000, 0x10000},
1176 {"firmware", 0x30000, 0x7a0000},
1177 {"soft-version", 0x7d9500, 0x00100},
1178 {"support-list", 0x7d9600, 0x00100},
1179 {"extra-para", 0x7d9700, 0x00100},
1180 {"profile", 0x7d9800, 0x03000},
1181 {"default-config", 0x7dc800, 0x03000},
1182 {"partition-table", 0x7df800, 0x00800},
1183 {"user-config", 0x7e0000, 0x0c000},
1184 {"certificate", 0x7ec000, 0x04000},
1185 {"radio", 0x7f0000, 0x10000},
1189 .first_sysupgrade_partition
= "os-image",
1190 .last_sysupgrade_partition
= "file-system",
1193 /** Firmware layout for the C60v3 */
1195 .id
= "ARCHER-C60-V3",
1199 "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1200 "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1201 "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1203 .soft_ver
= "soft_ver:3.0.0\n",
1206 {"factory-boot", 0x00000, 0x1fb00},
1207 {"default-mac", 0x1fb00, 0x00200},
1208 {"pin", 0x1fd00, 0x00100},
1209 {"product-info", 0x1fe00, 0x00100},
1210 {"device-id", 0x1ff00, 0x00100},
1211 {"fs-uboot", 0x20000, 0x10000},
1212 {"firmware", 0x30000, 0x7a0000},
1213 {"soft-version", 0x7d9500, 0x00100},
1214 {"support-list", 0x7d9600, 0x00100},
1215 {"extra-para", 0x7d9700, 0x00100},
1216 {"profile", 0x7d9800, 0x03000},
1217 {"default-config", 0x7dc800, 0x03000},
1218 {"partition-table", 0x7df800, 0x00800},
1219 {"user-config", 0x7e0000, 0x0c000},
1220 {"certificate", 0x7ec000, 0x04000},
1221 {"radio", 0x7f0000, 0x10000},
1225 .first_sysupgrade_partition
= "os-image",
1226 .last_sysupgrade_partition
= "file-system",
1229 /** Firmware layout for the C5 */
1231 .id
= "ARCHER-C5-V2",
1235 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1236 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1237 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1242 {"fs-uboot", 0x00000, 0x40000},
1243 {"os-image", 0x40000, 0x200000},
1244 {"file-system", 0x240000, 0xc00000},
1245 {"default-mac", 0xe40000, 0x00200},
1246 {"pin", 0xe40200, 0x00200},
1247 {"product-info", 0xe40400, 0x00200},
1248 {"partition-table", 0xe50000, 0x10000},
1249 {"soft-version", 0xe60000, 0x00200},
1250 {"support-list", 0xe61000, 0x0f000},
1251 {"profile", 0xe70000, 0x10000},
1252 {"default-config", 0xe80000, 0x10000},
1253 {"user-config", 0xe90000, 0x50000},
1254 {"log", 0xee0000, 0x100000},
1255 {"radio_bk", 0xfe0000, 0x10000},
1256 {"radio", 0xff0000, 0x10000},
1260 .first_sysupgrade_partition
= "os-image",
1261 .last_sysupgrade_partition
= "file-system"
1264 /** Firmware layout for the C7 */
1266 .id
= "ARCHER-C7-V4",
1269 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1270 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1271 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1272 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1273 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1274 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1275 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1276 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1277 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1278 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1280 .soft_ver
= "soft_ver:1.0.0\n",
1282 /* We're using a dynamic kernel/rootfs split here */
1284 {"factory-boot", 0x00000, 0x20000},
1285 {"fs-uboot", 0x20000, 0x20000},
1286 {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
1287 /* Stock: name file-system base 0x160000 size 0xda0000 */
1288 {"default-mac", 0xf00000, 0x00200},
1289 {"pin", 0xf00200, 0x00200},
1290 {"device-id", 0xf00400, 0x00100},
1291 {"product-info", 0xf00500, 0x0fb00},
1292 {"soft-version", 0xf10000, 0x00100},
1293 {"extra-para", 0xf11000, 0x01000},
1294 {"support-list", 0xf12000, 0x0a000},
1295 {"profile", 0xf1c000, 0x04000},
1296 {"default-config", 0xf20000, 0x10000},
1297 {"user-config", 0xf30000, 0x40000},
1298 {"qos-db", 0xf70000, 0x40000},
1299 {"certificate", 0xfb0000, 0x10000},
1300 {"partition-table", 0xfc0000, 0x10000},
1301 {"log", 0xfd0000, 0x20000},
1302 {"radio", 0xff0000, 0x10000},
1306 .first_sysupgrade_partition
= "os-image",
1307 .last_sysupgrade_partition
= "file-system",
1310 /** Firmware layout for the C7 v5*/
1312 .id
= "ARCHER-C7-V5",
1315 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1316 "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1317 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1318 "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1319 "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1320 "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1321 "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1322 "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1325 .soft_ver
= "soft_ver:7.0.0\n",
1327 /* We're using a dynamic kernel/rootfs split here */
1329 {"factory-boot", 0x00000, 0x20000},
1330 {"fs-uboot", 0x20000, 0x20000},
1331 {"partition-table", 0x40000, 0x10000},
1332 {"radio", 0x50000, 0x10000},
1333 {"default-mac", 0x60000, 0x00200},
1334 {"pin", 0x60200, 0x00200},
1335 {"device-id", 0x60400, 0x00100},
1336 {"product-info", 0x60500, 0x0fb00},
1337 {"soft-version", 0x70000, 0x01000},
1338 {"extra-para", 0x71000, 0x01000},
1339 {"support-list", 0x72000, 0x0a000},
1340 {"profile", 0x7c000, 0x04000},
1341 {"user-config", 0x80000, 0x40000},
1344 {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */
1345 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1347 {"log", 0xfc0000, 0x20000},
1348 {"certificate", 0xfe0000, 0x10000},
1349 {"default-config", 0xff0000, 0x10000},
1354 .first_sysupgrade_partition
= "os-image",
1355 .last_sysupgrade_partition
= "file-system",
1358 /** Firmware layout for the C9 */
1364 "{product_name:ArcherC9,"
1365 "product_ver:1.0.0,"
1366 "special_id:00000000}\n",
1371 {"fs-uboot", 0x00000, 0x40000},
1372 {"os-image", 0x40000, 0x200000},
1373 {"file-system", 0x240000, 0xc00000},
1374 {"default-mac", 0xe40000, 0x00200},
1375 {"pin", 0xe40200, 0x00200},
1376 {"product-info", 0xe40400, 0x00200},
1377 {"partition-table", 0xe50000, 0x10000},
1378 {"soft-version", 0xe60000, 0x00200},
1379 {"support-list", 0xe61000, 0x0f000},
1380 {"profile", 0xe70000, 0x10000},
1381 {"default-config", 0xe80000, 0x10000},
1382 {"user-config", 0xe90000, 0x50000},
1383 {"log", 0xee0000, 0x100000},
1384 {"radio_bk", 0xfe0000, 0x10000},
1385 {"radio", 0xff0000, 0x10000},
1389 .first_sysupgrade_partition
= "os-image",
1390 .last_sysupgrade_partition
= "file-system"
1393 /** Firmware layout for the EAP120 */
1396 .vendor
= "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1399 "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1404 {"fs-uboot", 0x00000, 0x20000},
1405 {"partition-table", 0x20000, 0x02000},
1406 {"default-mac", 0x30000, 0x00020},
1407 {"support-list", 0x31000, 0x00100},
1408 {"product-info", 0x31100, 0x00100},
1409 {"soft-version", 0x32000, 0x00100},
1410 {"os-image", 0x40000, 0x180000},
1411 {"file-system", 0x1c0000, 0x600000},
1412 {"user-config", 0x7c0000, 0x10000},
1413 {"backup-config", 0x7d0000, 0x10000},
1414 {"log", 0x7e0000, 0x10000},
1415 {"radio", 0x7f0000, 0x10000},
1419 .first_sysupgrade_partition
= "os-image",
1420 .last_sysupgrade_partition
= "file-system"
1423 /** Firmware layout for the EAP225-Outdoor v1 */
1425 .id
= "EAP225-OUTDOOR-V1",
1428 "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1429 .part_trail
= PART_TRAIL_NONE
,
1431 .soft_ver_compat_level
= 1,
1434 {"fs-uboot", 0x00000, 0x20000},
1435 {"partition-table", 0x20000, 0x02000},
1436 {"default-mac", 0x30000, 0x01000},
1437 {"support-list", 0x31000, 0x00100},
1438 {"product-info", 0x31100, 0x00400},
1439 {"soft-version", 0x32000, 0x00100},
1440 {"firmware", 0x40000, 0xd80000},
1441 {"user-config", 0xdc0000, 0x30000},
1442 {"mutil-log", 0xf30000, 0x80000},
1443 {"oops", 0xfb0000, 0x40000},
1444 {"radio", 0xff0000, 0x10000},
1448 .first_sysupgrade_partition
= "os-image",
1449 .last_sysupgrade_partition
= "file-system"
1452 /** Firmware layout for the EAP225 v3 */
1457 "EAP225(TP-Link|UN|AC1350-D):3.0\r\n",
1458 .part_trail
= PART_TRAIL_NONE
,
1460 .soft_ver_compat_level
= 1,
1463 {"fs-uboot", 0x00000, 0x20000},
1464 {"partition-table", 0x20000, 0x02000},
1465 {"default-mac", 0x30000, 0x01000},
1466 {"support-list", 0x31000, 0x00100},
1467 {"product-info", 0x31100, 0x00400},
1468 {"soft-version", 0x32000, 0x00100},
1469 {"firmware", 0x40000, 0xd80000},
1470 {"user-config", 0xdc0000, 0x30000},
1471 {"mutil-log", 0xf30000, 0x80000},
1472 {"oops", 0xfb0000, 0x40000},
1473 {"radio", 0xff0000, 0x10000},
1477 .first_sysupgrade_partition
= "os-image",
1478 .last_sysupgrade_partition
= "file-system"
1481 /** Firmware layout for the EAP225-Wall v2 */
1483 .id
= "EAP225-WALL-V2",
1486 "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
1487 .part_trail
= PART_TRAIL_NONE
,
1489 .soft_ver_compat_level
= 1,
1492 {"fs-uboot", 0x00000, 0x20000},
1493 {"partition-table", 0x20000, 0x02000},
1494 {"default-mac", 0x30000, 0x01000},
1495 {"support-list", 0x31000, 0x00100},
1496 {"product-info", 0x31100, 0x00400},
1497 {"soft-version", 0x32000, 0x00100},
1498 {"firmware", 0x40000, 0xd80000},
1499 {"user-config", 0xdc0000, 0x30000},
1500 {"mutil-log", 0xf30000, 0x80000},
1501 {"oops", 0xfb0000, 0x40000},
1502 {"radio", 0xff0000, 0x10000},
1506 .first_sysupgrade_partition
= "os-image",
1507 .last_sysupgrade_partition
= "file-system"
1510 /** Firmware layout for the EAP235-Wall v1 */
1512 .id
= "EAP235-WALL-V1",
1515 "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
1516 .part_trail
= PART_TRAIL_NONE
,
1518 .soft_ver_compat_level
= 1,
1521 {"fs-uboot", 0x00000, 0x80000},
1522 {"partition-table", 0x80000, 0x02000},
1523 {"default-mac", 0x90000, 0x01000},
1524 {"support-list", 0x91000, 0x00100},
1525 {"product-info", 0x91100, 0x00400},
1526 {"soft-version", 0x92000, 0x00100},
1527 {"firmware", 0xa0000, 0xd20000},
1528 {"user-config", 0xdc0000, 0x30000},
1529 {"mutil-log", 0xf30000, 0x80000},
1530 {"oops", 0xfb0000, 0x40000},
1531 {"radio", 0xff0000, 0x10000},
1535 .first_sysupgrade_partition
= "os-image",
1536 .last_sysupgrade_partition
= "file-system"
1539 /** Firmware layout for the EAP245 v1 */
1544 "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
1545 .part_trail
= PART_TRAIL_NONE
,
1549 {"fs-uboot", 0x00000, 0x20000},
1550 {"partition-table", 0x20000, 0x02000},
1551 {"default-mac", 0x30000, 0x01000},
1552 {"support-list", 0x31000, 0x00100},
1553 {"product-info", 0x31100, 0x00400},
1554 {"soft-version", 0x32000, 0x00100},
1555 {"firmware", 0x40000, 0xd80000},
1556 {"user-config", 0xdc0000, 0x30000},
1557 {"radio", 0xff0000, 0x10000},
1561 .first_sysupgrade_partition
= "os-image",
1562 .last_sysupgrade_partition
= "file-system"
1565 /** Firmware layout for the EAP245 v3 */
1570 "EAP245(TP-Link|UN|AC1750-D):3.0\r\n",
1571 .part_trail
= PART_TRAIL_NONE
,
1573 .soft_ver_compat_level
= 1,
1575 /** Firmware partition with dynamic kernel/rootfs split */
1577 {"factroy-boot", 0x00000, 0x40000},
1578 {"fs-uboot", 0x40000, 0x40000},
1579 {"partition-table", 0x80000, 0x10000},
1580 {"default-mac", 0x90000, 0x01000},
1581 {"support-list", 0x91000, 0x00100},
1582 {"product-info", 0x91100, 0x00400},
1583 {"soft-version", 0x92000, 0x00100},
1584 {"radio", 0xa0000, 0x10000},
1585 {"extra-para", 0xb0000, 0x10000},
1586 {"firmware", 0xc0000, 0xe40000},
1587 {"config", 0xf00000, 0x30000},
1588 {"mutil-log", 0xf30000, 0x80000},
1589 {"oops", 0xfb0000, 0x40000},
1593 .first_sysupgrade_partition
= "os-image",
1594 .last_sysupgrade_partition
= "file-system"
1597 /** Firmware layout for the TL-WA850RE v2 */
1599 .id
= "TLWA850REV2",
1603 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
1604 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
1605 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
1606 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
1607 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
1608 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
1609 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
1610 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
1611 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
1612 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
1617 576KB were moved from file-system to os-image
1618 in comparison to the stock image
1621 {"fs-uboot", 0x00000, 0x20000},
1622 {"firmware", 0x20000, 0x390000},
1623 {"partition-table", 0x3b0000, 0x02000},
1624 {"default-mac", 0x3c0000, 0x00020},
1625 {"pin", 0x3c0100, 0x00020},
1626 {"product-info", 0x3c1000, 0x01000},
1627 {"soft-version", 0x3c2000, 0x00100},
1628 {"support-list", 0x3c3000, 0x01000},
1629 {"profile", 0x3c4000, 0x08000},
1630 {"user-config", 0x3d0000, 0x10000},
1631 {"default-config", 0x3e0000, 0x10000},
1632 {"radio", 0x3f0000, 0x10000},
1636 .first_sysupgrade_partition
= "os-image",
1637 .last_sysupgrade_partition
= "file-system"
1640 /** Firmware layout for the TL-WA855RE v1 */
1642 .id
= "TLWA855REV1",
1646 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
1647 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
1648 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
1649 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
1650 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
1651 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
1652 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
1653 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
1654 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
1659 {"fs-uboot", 0x00000, 0x20000},
1660 {"os-image", 0x20000, 0x150000},
1661 {"file-system", 0x170000, 0x240000},
1662 {"partition-table", 0x3b0000, 0x02000},
1663 {"default-mac", 0x3c0000, 0x00020},
1664 {"pin", 0x3c0100, 0x00020},
1665 {"product-info", 0x3c1000, 0x01000},
1666 {"soft-version", 0x3c2000, 0x00100},
1667 {"support-list", 0x3c3000, 0x01000},
1668 {"profile", 0x3c4000, 0x08000},
1669 {"user-config", 0x3d0000, 0x10000},
1670 {"default-config", 0x3e0000, 0x10000},
1671 {"radio", 0x3f0000, 0x10000},
1675 .first_sysupgrade_partition
= "os-image",
1676 .last_sysupgrade_partition
= "file-system"
1679 /** Firmware layout for the TL-WPA8630P v2 (EU)*/
1681 .id
= "TL-WPA8630P-V2.0-EU",
1685 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
1690 {"factory-uboot", 0x00000, 0x20000},
1691 {"fs-uboot", 0x20000, 0x20000},
1692 {"firmware", 0x40000, 0x5e0000},
1693 {"partition-table", 0x620000, 0x02000},
1694 {"default-mac", 0x630000, 0x00020},
1695 {"pin", 0x630100, 0x00020},
1696 {"device-id", 0x630200, 0x00030},
1697 {"product-info", 0x631100, 0x01000},
1698 {"extra-para", 0x632100, 0x01000},
1699 {"soft-version", 0x640000, 0x01000},
1700 {"support-list", 0x641000, 0x01000},
1701 {"profile", 0x642000, 0x08000},
1702 {"user-config", 0x650000, 0x10000},
1703 {"default-config", 0x660000, 0x10000},
1704 {"default-nvm", 0x670000, 0xc0000},
1705 {"default-pib", 0x730000, 0x40000},
1706 {"radio", 0x7f0000, 0x10000},
1710 .first_sysupgrade_partition
= "os-image",
1711 .last_sysupgrade_partition
= "file-system"
1714 /** Firmware layout for the TL-WPA8630P v2 (INT)*/
1716 .id
= "TL-WPA8630P-V2-INT",
1720 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
1721 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
1722 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
1727 {"factory-uboot", 0x00000, 0x20000},
1728 {"fs-uboot", 0x20000, 0x20000},
1729 {"firmware", 0x40000, 0x5e0000},
1730 {"partition-table", 0x620000, 0x02000},
1731 {"extra-para", 0x632100, 0x01000},
1732 {"soft-version", 0x640000, 0x01000},
1733 {"support-list", 0x641000, 0x01000},
1734 {"profile", 0x642000, 0x08000},
1735 {"user-config", 0x650000, 0x10000},
1736 {"default-config", 0x660000, 0x10000},
1737 {"default-nvm", 0x670000, 0xc0000},
1738 {"default-pib", 0x730000, 0x40000},
1739 {"default-mac", 0x7e0000, 0x00020},
1740 {"pin", 0x7e0100, 0x00020},
1741 {"device-id", 0x7e0200, 0x00030},
1742 {"product-info", 0x7e1100, 0x01000},
1743 {"radio", 0x7f0000, 0x10000},
1747 .first_sysupgrade_partition
= "os-image",
1748 .last_sysupgrade_partition
= "file-system"
1751 /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
1753 .id
= "TL-WPA8630P-V2.1-EU",
1757 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
1762 {"factory-uboot", 0x00000, 0x20000},
1763 {"fs-uboot", 0x20000, 0x20000},
1764 {"firmware", 0x40000, 0x5e0000},
1765 {"extra-para", 0x680000, 0x01000},
1766 {"product-info", 0x690000, 0x01000},
1767 {"partition-table", 0x6a0000, 0x02000},
1768 {"soft-version", 0x6b0000, 0x01000},
1769 {"support-list", 0x6b1000, 0x01000},
1770 {"profile", 0x6b2000, 0x08000},
1771 {"user-config", 0x6c0000, 0x10000},
1772 {"default-config", 0x6d0000, 0x10000},
1773 {"default-nvm", 0x6e0000, 0xc0000},
1774 {"default-pib", 0x7a0000, 0x40000},
1775 {"default-mac", 0x7e0000, 0x00020},
1776 {"pin", 0x7e0100, 0x00020},
1777 {"device-id", 0x7e0200, 0x00030},
1778 {"radio", 0x7f0000, 0x10000},
1782 .first_sysupgrade_partition
= "os-image",
1783 .last_sysupgrade_partition
= "file-system"
1786 /** Firmware layout for the TL-WR1043 v5 */
1788 .id
= "TLWR1043NV5",
1792 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
1793 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
1795 .soft_ver
= "soft_ver:1.0.0\n",
1797 {"factory-boot", 0x00000, 0x20000},
1798 {"fs-uboot", 0x20000, 0x20000},
1799 {"firmware", 0x40000, 0xec0000},
1800 {"default-mac", 0xf00000, 0x00200},
1801 {"pin", 0xf00200, 0x00200},
1802 {"device-id", 0xf00400, 0x00100},
1803 {"product-info", 0xf00500, 0x0fb00},
1804 {"soft-version", 0xf10000, 0x01000},
1805 {"extra-para", 0xf11000, 0x01000},
1806 {"support-list", 0xf12000, 0x0a000},
1807 {"profile", 0xf1c000, 0x04000},
1808 {"default-config", 0xf20000, 0x10000},
1809 {"user-config", 0xf30000, 0x40000},
1810 {"qos-db", 0xf70000, 0x40000},
1811 {"certificate", 0xfb0000, 0x10000},
1812 {"partition-table", 0xfc0000, 0x10000},
1813 {"log", 0xfd0000, 0x20000},
1814 {"radio", 0xff0000, 0x10000},
1817 .first_sysupgrade_partition
= "os-image",
1818 .last_sysupgrade_partition
= "file-system"
1821 /** Firmware layout for the TL-WR1043 v4 */
1823 .id
= "TLWR1043NDV4",
1827 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
1831 /* We're using a dynamic kernel/rootfs split here */
1833 {"fs-uboot", 0x00000, 0x20000},
1834 {"firmware", 0x20000, 0xf30000},
1835 {"default-mac", 0xf50000, 0x00200},
1836 {"pin", 0xf50200, 0x00200},
1837 {"product-info", 0xf50400, 0x0fc00},
1838 {"soft-version", 0xf60000, 0x0b000},
1839 {"support-list", 0xf6b000, 0x04000},
1840 {"profile", 0xf70000, 0x04000},
1841 {"default-config", 0xf74000, 0x0b000},
1842 {"user-config", 0xf80000, 0x40000},
1843 {"partition-table", 0xfc0000, 0x10000},
1844 {"log", 0xfd0000, 0x20000},
1845 {"radio", 0xff0000, 0x10000},
1849 .first_sysupgrade_partition
= "os-image",
1850 .last_sysupgrade_partition
= "file-system"
1853 /** Firmware layout for the TL-WR902AC v1 */
1855 .id
= "TL-WR902AC-V1",
1859 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
1860 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
1865 384KB were moved from file-system to os-image
1866 in comparison to the stock image
1869 {"fs-uboot", 0x00000, 0x20000},
1870 {"firmware", 0x20000, 0x730000},
1871 {"default-mac", 0x750000, 0x00200},
1872 {"pin", 0x750200, 0x00200},
1873 {"product-info", 0x750400, 0x0fc00},
1874 {"soft-version", 0x760000, 0x0b000},
1875 {"support-list", 0x76b000, 0x04000},
1876 {"profile", 0x770000, 0x04000},
1877 {"default-config", 0x774000, 0x0b000},
1878 {"user-config", 0x780000, 0x40000},
1879 {"partition-table", 0x7c0000, 0x10000},
1880 {"log", 0x7d0000, 0x20000},
1881 {"radio", 0x7f0000, 0x10000},
1885 .first_sysupgrade_partition
= "os-image",
1886 .last_sysupgrade_partition
= "file-system",
1889 /** Firmware layout for the TL-WR942N V1 */
1895 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
1896 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
1901 {"fs-uboot", 0x00000, 0x20000},
1902 {"firmware", 0x20000, 0xe20000},
1903 {"default-mac", 0xe40000, 0x00200},
1904 {"pin", 0xe40200, 0x00200},
1905 {"product-info", 0xe40400, 0x0fc00},
1906 {"partition-table", 0xe50000, 0x10000},
1907 {"soft-version", 0xe60000, 0x10000},
1908 {"support-list", 0xe70000, 0x10000},
1909 {"profile", 0xe80000, 0x10000},
1910 {"default-config", 0xe90000, 0x10000},
1911 {"user-config", 0xea0000, 0x40000},
1912 {"qos-db", 0xee0000, 0x40000},
1913 {"certificate", 0xf20000, 0x10000},
1914 {"usb-config", 0xfb0000, 0x10000},
1915 {"log", 0xfc0000, 0x20000},
1916 {"radio-bk", 0xfe0000, 0x10000},
1917 {"radio", 0xff0000, 0x10000},
1921 .first_sysupgrade_partition
= "os-image",
1922 .last_sysupgrade_partition
= "file-system",
1925 /** Firmware layout for the RE200 v2 */
1931 "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
1932 "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
1933 "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
1934 "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
1935 "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
1936 "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
1937 "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
1938 "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
1939 "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
1940 "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
1941 "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
1942 "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
1943 "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
1948 {"fs-uboot", 0x00000, 0x20000},
1949 {"firmware", 0x20000, 0x7a0000},
1950 {"partition-table", 0x7c0000, 0x02000},
1951 {"default-mac", 0x7c2000, 0x00020},
1952 {"pin", 0x7c2100, 0x00020},
1953 {"product-info", 0x7c3100, 0x01000},
1954 {"soft-version", 0x7c4200, 0x01000},
1955 {"support-list", 0x7c5200, 0x01000},
1956 {"profile", 0x7c6200, 0x08000},
1957 {"config-info", 0x7ce200, 0x00400},
1958 {"user-config", 0x7d0000, 0x10000},
1959 {"default-config", 0x7e0000, 0x10000},
1960 {"radio", 0x7f0000, 0x10000},
1964 .first_sysupgrade_partition
= "os-image",
1965 .last_sysupgrade_partition
= "file-system"
1968 /** Firmware layout for the RE200 v3 */
1974 "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
1975 "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
1976 "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
1977 "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
1978 "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
1979 "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
1980 "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
1981 "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
1982 "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
1983 "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
1984 "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
1985 "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
1986 "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
1987 "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
1992 {"fs-uboot", 0x00000, 0x20000},
1993 {"firmware", 0x20000, 0x7a0000},
1994 {"partition-table", 0x7c0000, 0x02000},
1995 {"default-mac", 0x7c2000, 0x00020},
1996 {"pin", 0x7c2100, 0x00020},
1997 {"product-info", 0x7c3100, 0x01000},
1998 {"soft-version", 0x7c4200, 0x01000},
1999 {"support-list", 0x7c5200, 0x01000},
2000 {"profile", 0x7c6200, 0x08000},
2001 {"config-info", 0x7ce200, 0x00400},
2002 {"user-config", 0x7d0000, 0x10000},
2003 {"default-config", 0x7e0000, 0x10000},
2004 {"radio", 0x7f0000, 0x10000},
2008 .first_sysupgrade_partition
= "os-image",
2009 .last_sysupgrade_partition
= "file-system"
2012 /** Firmware layout for the RE200 v4 */
2018 "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2019 "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2020 "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2021 "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2022 "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2023 "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2024 "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2025 "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2026 "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2027 "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2028 "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2029 "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2030 "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2031 "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2033 .soft_ver
= "soft_ver:1.1.0\n",
2036 {"fs-uboot", 0x00000, 0x20000},
2037 {"firmware", 0x20000, 0x7a0000},
2038 {"partition-table", 0x7c0000, 0x02000},
2039 {"default-mac", 0x7c2000, 0x00020},
2040 {"pin", 0x7c2100, 0x00020},
2041 {"product-info", 0x7c3100, 0x01000},
2042 {"soft-version", 0x7c4200, 0x01000},
2043 {"support-list", 0x7c5200, 0x01000},
2044 {"profile", 0x7c6200, 0x08000},
2045 {"config-info", 0x7ce200, 0x00400},
2046 {"user-config", 0x7d0000, 0x10000},
2047 {"default-config", 0x7e0000, 0x10000},
2048 {"radio", 0x7f0000, 0x10000},
2052 .first_sysupgrade_partition
= "os-image",
2053 .last_sysupgrade_partition
= "file-system"
2056 /** Firmware layout for the RE220 v2 */
2062 "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2063 "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2064 "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2065 "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2066 "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2067 "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2068 "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2069 "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2070 "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2071 "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2072 "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2073 "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2074 "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2079 {"fs-uboot", 0x00000, 0x20000},
2080 {"firmware", 0x20000, 0x7a0000},
2081 {"partition-table", 0x7c0000, 0x02000},
2082 {"default-mac", 0x7c2000, 0x00020},
2083 {"pin", 0x7c2100, 0x00020},
2084 {"product-info", 0x7c3100, 0x01000},
2085 {"soft-version", 0x7c4200, 0x01000},
2086 {"support-list", 0x7c5200, 0x01000},
2087 {"profile", 0x7c6200, 0x08000},
2088 {"config-info", 0x7ce200, 0x00400},
2089 {"user-config", 0x7d0000, 0x10000},
2090 {"default-config", 0x7e0000, 0x10000},
2091 {"radio", 0x7f0000, 0x10000},
2095 .first_sysupgrade_partition
= "os-image",
2096 .last_sysupgrade_partition
= "file-system"
2099 /** Firmware layout for the RE305 v1 */
2105 "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2106 "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2107 "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2108 "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2109 "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2110 "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2111 "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2116 {"fs-uboot", 0x00000, 0x20000},
2117 {"firmware", 0x20000, 0x5e0000},
2118 {"partition-table", 0x600000, 0x02000},
2119 {"default-mac", 0x610000, 0x00020},
2120 {"pin", 0x610100, 0x00020},
2121 {"product-info", 0x611100, 0x01000},
2122 {"soft-version", 0x620000, 0x01000},
2123 {"support-list", 0x621000, 0x01000},
2124 {"profile", 0x622000, 0x08000},
2125 {"user-config", 0x630000, 0x10000},
2126 {"default-config", 0x640000, 0x10000},
2127 {"radio", 0x7f0000, 0x10000},
2131 .first_sysupgrade_partition
= "os-image",
2132 .last_sysupgrade_partition
= "file-system"
2135 /** Firmware layout for the RE350 v1 */
2141 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2142 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2143 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2144 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2145 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2146 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2147 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2151 /** We're using a dynamic kernel/rootfs split here */
2153 {"fs-uboot", 0x00000, 0x20000},
2154 {"firmware", 0x20000, 0x5e0000},
2155 {"partition-table", 0x600000, 0x02000},
2156 {"default-mac", 0x610000, 0x00020},
2157 {"pin", 0x610100, 0x00020},
2158 {"product-info", 0x611100, 0x01000},
2159 {"soft-version", 0x620000, 0x01000},
2160 {"support-list", 0x621000, 0x01000},
2161 {"profile", 0x622000, 0x08000},
2162 {"user-config", 0x630000, 0x10000},
2163 {"default-config", 0x640000, 0x10000},
2164 {"radio", 0x7f0000, 0x10000},
2168 .first_sysupgrade_partition
= "os-image",
2169 .last_sysupgrade_partition
= "file-system"
2172 /** Firmware layout for the RE350K v1 */
2178 "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2182 /** We're using a dynamic kernel/rootfs split here */
2184 {"fs-uboot", 0x00000, 0x20000},
2185 {"firmware", 0x20000, 0xd70000},
2186 {"partition-table", 0xd90000, 0x02000},
2187 {"default-mac", 0xda0000, 0x00020},
2188 {"pin", 0xda0100, 0x00020},
2189 {"product-info", 0xda1100, 0x01000},
2190 {"soft-version", 0xdb0000, 0x01000},
2191 {"support-list", 0xdb1000, 0x01000},
2192 {"profile", 0xdb2000, 0x08000},
2193 {"user-config", 0xdc0000, 0x10000},
2194 {"default-config", 0xdd0000, 0x10000},
2195 {"device-id", 0xde0000, 0x00108},
2196 {"radio", 0xff0000, 0x10000},
2200 .first_sysupgrade_partition
= "os-image",
2201 .last_sysupgrade_partition
= "file-system"
2204 /** Firmware layout for the RE355 */
2210 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2211 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2212 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2213 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2214 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2215 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2216 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2217 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2221 /* We're using a dynamic kernel/rootfs split here */
2223 {"fs-uboot", 0x00000, 0x20000},
2224 {"firmware", 0x20000, 0x5e0000},
2225 {"partition-table", 0x600000, 0x02000},
2226 {"default-mac", 0x610000, 0x00020},
2227 {"pin", 0x610100, 0x00020},
2228 {"product-info", 0x611100, 0x01000},
2229 {"soft-version", 0x620000, 0x01000},
2230 {"support-list", 0x621000, 0x01000},
2231 {"profile", 0x622000, 0x08000},
2232 {"user-config", 0x630000, 0x10000},
2233 {"default-config", 0x640000, 0x10000},
2234 {"radio", 0x7f0000, 0x10000},
2238 .first_sysupgrade_partition
= "os-image",
2239 .last_sysupgrade_partition
= "file-system"
2242 /** Firmware layout for the RE450 */
2248 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2249 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
2250 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
2251 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
2252 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
2253 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
2254 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
2255 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
2259 /** We're using a dynamic kernel/rootfs split here */
2261 {"fs-uboot", 0x00000, 0x20000},
2262 {"firmware", 0x20000, 0x5e0000},
2263 {"partition-table", 0x600000, 0x02000},
2264 {"default-mac", 0x610000, 0x00020},
2265 {"pin", 0x610100, 0x00020},
2266 {"product-info", 0x611100, 0x01000},
2267 {"soft-version", 0x620000, 0x01000},
2268 {"support-list", 0x621000, 0x01000},
2269 {"profile", 0x622000, 0x08000},
2270 {"user-config", 0x630000, 0x10000},
2271 {"default-config", 0x640000, 0x10000},
2272 {"radio", 0x7f0000, 0x10000},
2276 .first_sysupgrade_partition
= "os-image",
2277 .last_sysupgrade_partition
= "file-system"
2280 /** Firmware layout for the RE450 v2 */
2286 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
2287 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
2288 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
2289 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
2290 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
2291 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
2292 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
2293 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
2294 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
2298 /* We're using a dynamic kernel/rootfs split here */
2300 {"fs-uboot", 0x00000, 0x20000},
2301 {"firmware", 0x20000, 0x5e0000},
2302 {"partition-table", 0x600000, 0x02000},
2303 {"default-mac", 0x610000, 0x00020},
2304 {"pin", 0x610100, 0x00020},
2305 {"product-info", 0x611100, 0x01000},
2306 {"soft-version", 0x620000, 0x01000},
2307 {"support-list", 0x621000, 0x01000},
2308 {"profile", 0x622000, 0x08000},
2309 {"user-config", 0x630000, 0x10000},
2310 {"default-config", 0x640000, 0x10000},
2311 {"radio", 0x7f0000, 0x10000},
2315 .first_sysupgrade_partition
= "os-image",
2316 .last_sysupgrade_partition
= "file-system"
2319 /** Firmware layout for the RE450 v3 */
2325 "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
2326 "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
2327 "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
2328 "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
2329 "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
2330 "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
2331 "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
2332 "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
2333 "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
2337 /* We're using a dynamic kernel/rootfs split here */
2339 {"fs-uboot", 0x00000, 0x20000},
2340 {"default-mac", 0x20000, 0x00020},
2341 {"pin", 0x20020, 0x00020},
2342 {"product-info", 0x21000, 0x01000},
2343 {"partition-table", 0x22000, 0x02000},
2344 {"soft-version", 0x24000, 0x01000},
2345 {"support-list", 0x25000, 0x01000},
2346 {"profile", 0x26000, 0x08000},
2347 {"user-config", 0x2e000, 0x10000},
2348 {"default-config", 0x3e000, 0x10000},
2349 {"config-info", 0x4e000, 0x00400},
2350 {"firmware", 0x50000, 0x7a0000},
2351 {"radio", 0x7f0000, 0x10000},
2355 .first_sysupgrade_partition
= "os-image",
2356 .last_sysupgrade_partition
= "file-system"
2359 /** Firmware layout for the RE500 */
2365 "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
2366 "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
2367 "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
2368 "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
2369 "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
2370 "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
2371 "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
2375 /* We're using a dynamic kernel/rootfs split here */
2377 {"fs-uboot", 0x00000, 0x20000},
2378 {"firmware", 0x20000, 0xde0000},
2379 {"partition-table", 0xe00000, 0x02000},
2380 {"default-mac", 0xe10000, 0x00020},
2381 {"pin", 0xe10100, 0x00020},
2382 {"product-info", 0xe11100, 0x01000},
2383 {"soft-version", 0xe20000, 0x01000},
2384 {"support-list", 0xe21000, 0x01000},
2385 {"profile", 0xe22000, 0x08000},
2386 {"user-config", 0xe30000, 0x10000},
2387 {"default-config", 0xe40000, 0x10000},
2388 {"radio", 0xff0000, 0x10000},
2392 .first_sysupgrade_partition
= "os-image",
2393 .last_sysupgrade_partition
= "file-system"
2396 /** Firmware layout for the RE650 */
2402 "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
2403 "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
2404 "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
2405 "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
2406 "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
2407 "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
2408 "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
2412 /* We're using a dynamic kernel/rootfs split here */
2414 {"fs-uboot", 0x00000, 0x20000},
2415 {"firmware", 0x20000, 0xde0000},
2416 {"partition-table", 0xe00000, 0x02000},
2417 {"default-mac", 0xe10000, 0x00020},
2418 {"pin", 0xe10100, 0x00020},
2419 {"product-info", 0xe11100, 0x01000},
2420 {"soft-version", 0xe20000, 0x01000},
2421 {"support-list", 0xe21000, 0x01000},
2422 {"profile", 0xe22000, 0x08000},
2423 {"user-config", 0xe30000, 0x10000},
2424 {"default-config", 0xe40000, 0x10000},
2425 {"radio", 0xff0000, 0x10000},
2429 .first_sysupgrade_partition
= "os-image",
2430 .last_sysupgrade_partition
= "file-system"
2436 #define error(_ret, _errno, _str, ...) \
2438 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
2439 strerror(_errno)); \
2445 /** Stores a uint32 as big endian */
2446 static inline void put32(uint8_t *buf
, uint32_t val
) {
2453 static inline bool meta_partition_should_pad(enum partition_trail_value pv
)
2455 return (pv
>= 0) && (pv
<= PART_TRAIL_MAX
);
2458 /** Allocate a padded meta partition with a correctly initialised header
2459 * If the `data` pointer is NULL, then the required space is only allocated,
2460 * otherwise `data_len` bytes will be copied from `data` into the partition
2462 static struct image_partition_entry
init_meta_partition_entry(
2463 const char *name
, const void *data
, uint32_t data_len
,
2464 enum partition_trail_value pad_value
)
2466 uint32_t total_len
= sizeof(struct meta_header
) + data_len
;
2467 if (meta_partition_should_pad(pad_value
))
2470 struct image_partition_entry entry
= {
2473 .data
= malloc(total_len
)
2476 error(1, errno
, "failed to allocate meta partition entry");
2478 struct meta_header
*header
= (struct meta_header
*)entry
.data
;
2479 header
->length
= htonl(data_len
);
2483 memcpy(entry
.data
+sizeof(*header
), data
, data_len
);
2485 if (meta_partition_should_pad(pad_value
))
2486 entry
.data
[total_len
- 1] = (uint8_t) pad_value
;
2491 /** Allocates a new image partition */
2492 static struct image_partition_entry
alloc_image_partition(const char *name
, size_t len
) {
2493 struct image_partition_entry entry
= {name
, len
, malloc(len
)};
2495 error(1, errno
, "malloc");
2500 /** Frees an image partition */
2501 static void free_image_partition(struct image_partition_entry entry
) {
2505 static time_t source_date_epoch
= -1;
2506 static void set_source_date_epoch() {
2507 char *env
= getenv("SOURCE_DATE_EPOCH");
2511 source_date_epoch
= strtoull(env
, &endptr
, 10);
2512 if (errno
|| (endptr
&& *endptr
!= '\0')) {
2513 fprintf(stderr
, "Invalid SOURCE_DATE_EPOCH");
2519 /** Generates the partition-table partition */
2520 static struct image_partition_entry
make_partition_table(const struct flash_partition_entry
*p
) {
2521 struct image_partition_entry entry
= alloc_image_partition("partition-table", 0x800);
2523 char *s
= (char *)entry
.data
, *end
= (char *)(s
+entry
.size
);
2531 for (i
= 0; p
[i
].name
; i
++) {
2533 size_t w
= snprintf(s
, len
, "partition %s base 0x%05x size 0x%05x\n", p
[i
].name
, p
[i
].base
, p
[i
].size
);
2536 error(1, 0, "flash partition table overflow?");
2543 memset(s
, 0xff, end
-s
);
2549 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
2550 static inline uint8_t bcd(uint8_t v
) {
2551 return 0x10 * (v
/10) + v
%10;
2555 /** Generates the soft-version partition */
2556 static struct image_partition_entry
make_soft_version(
2557 const struct device_info
*info
, uint32_t rev
)
2559 /** If an info string is provided, use this instead of
2560 * the structured data, and include the null-termination */
2561 if (info
->soft_ver
) {
2562 uint32_t len
= strlen(info
->soft_ver
) + 1;
2563 return init_meta_partition_entry("soft-version",
2564 info
->soft_ver
, len
, info
->part_trail
);
2569 if (source_date_epoch
!= -1)
2570 t
= source_date_epoch
;
2571 else if (time(&t
) == (time_t)(-1))
2572 error(1, errno
, "time");
2574 struct tm
*tm
= gmtime(&t
);
2576 struct soft_version s
= {
2583 .year_hi
= bcd((1900+tm
->tm_year
)/100),
2584 .year_lo
= bcd(tm
->tm_year
%100),
2585 .month
= bcd(tm
->tm_mon
+1),
2586 .day
= bcd(tm
->tm_mday
),
2588 .compat_level
= htonl(info
->soft_ver_compat_level
)
2591 if (info
->soft_ver_compat_level
== 0)
2592 return init_meta_partition_entry("soft-version", &s
,
2593 (uint8_t *)(&s
.compat_level
) - (uint8_t *)(&s
),
2596 return init_meta_partition_entry("soft-version", &s
,
2597 sizeof(s
), info
->part_trail
);
2600 /** Generates the support-list partition */
2601 static struct image_partition_entry
make_support_list(
2602 const struct device_info
*info
)
2604 uint32_t len
= strlen(info
->support_list
);
2605 return init_meta_partition_entry("support-list", info
->support_list
,
2606 len
, info
->part_trail
);
2609 /** Partition with extra-para data */
2610 static struct image_partition_entry
make_extra_para(
2611 const struct device_info
*info
, const uint8_t *extra_para
, size_t len
)
2613 return init_meta_partition_entry("extra-para", extra_para
, len
,
2617 /** Creates a new image partition with an arbitrary name from a file */
2618 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
) {
2619 struct stat statbuf
;
2621 if (stat(filename
, &statbuf
) < 0)
2622 error(1, errno
, "unable to stat file `%s'", filename
);
2624 size_t len
= statbuf
.st_size
;
2626 if (add_jffs2_eof
) {
2627 if (file_system_partition
)
2628 len
= ALIGN(len
+ file_system_partition
->base
, 0x10000) + sizeof(jffs2_eof_mark
) - file_system_partition
->base
;
2630 len
= ALIGN(len
, 0x10000) + sizeof(jffs2_eof_mark
);
2633 struct image_partition_entry entry
= alloc_image_partition(part_name
, len
);
2635 FILE *file
= fopen(filename
, "rb");
2637 error(1, errno
, "unable to open file `%s'", filename
);
2639 if (fread(entry
.data
, statbuf
.st_size
, 1, file
) != 1)
2640 error(1, errno
, "unable to read file `%s'", filename
);
2642 if (add_jffs2_eof
) {
2643 uint8_t *eof
= entry
.data
+ statbuf
.st_size
, *end
= entry
.data
+entry
.size
;
2645 memset(eof
, 0xff, end
- eof
- sizeof(jffs2_eof_mark
));
2646 memcpy(end
- sizeof(jffs2_eof_mark
), jffs2_eof_mark
, sizeof(jffs2_eof_mark
));
2655 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
2657 Example image partition table:
2659 fwup-ptn partition-table base 0x00800 size 0x00800
2660 fwup-ptn os-image base 0x01000 size 0x113b45
2661 fwup-ptn file-system base 0x114b45 size 0x1d0004
2662 fwup-ptn support-list base 0x2e4b49 size 0x000d1
2664 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
2665 the end of the partition table is marked with a zero byte.
2667 The firmware image must contain at least the partition-table and support-list partitions
2668 to be accepted. There aren't any alignment constraints for the image partitions.
2670 The partition-table partition contains the actual flash layout; partitions
2671 from the image partition table are mapped to the corresponding flash partitions during
2672 the firmware upgrade. The support-list partition contains a list of devices supported by
2675 The base offsets in the firmware partition table are relative to the end
2676 of the vendor information block, so the partition-table partition will
2677 actually start at offset 0x1814 of the image.
2679 I think partition-table must be the first partition in the firmware image.
2681 static void put_partitions(uint8_t *buffer
, const struct flash_partition_entry
*flash_parts
, const struct image_partition_entry
*parts
) {
2683 char *image_pt
= (char *)buffer
, *end
= image_pt
+ 0x800;
2685 size_t base
= 0x800;
2686 for (i
= 0; parts
[i
].name
; i
++) {
2687 for (j
= 0; flash_parts
[j
].name
; j
++) {
2688 if (!strcmp(flash_parts
[j
].name
, parts
[i
].name
)) {
2689 if (parts
[i
].size
> flash_parts
[j
].size
)
2690 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts
[j
].name
, (unsigned)flash_parts
[j
].size
);
2695 assert(flash_parts
[j
].name
);
2697 memcpy(buffer
+ base
, parts
[i
].data
, parts
[i
].size
);
2699 size_t len
= end
-image_pt
;
2700 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
);
2703 error(1, 0, "image partition table overflow?");
2707 base
+= parts
[i
].size
;
2711 /** Generates and writes the image MD5 checksum */
2712 static void put_md5(uint8_t *md5
, uint8_t *buffer
, unsigned int len
) {
2716 MD5_Update(&ctx
, md5_salt
, (unsigned int)sizeof(md5_salt
));
2717 MD5_Update(&ctx
, buffer
, len
);
2718 MD5_Final(md5
, &ctx
);
2723 Generates the firmware image in factory format
2729 0000-0003 Image size (4 bytes, big endian)
2730 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
2731 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
2732 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
2733 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
2734 1014-1813 Image partition table (2048 bytes, padded with 0xff)
2735 1814-xxxx Firmware partitions
2737 static void * generate_factory_image(struct device_info
*info
, const struct image_partition_entry
*parts
, size_t *len
) {
2741 for (i
= 0; parts
[i
].name
; i
++)
2742 *len
+= parts
[i
].size
;
2744 uint8_t *image
= malloc(*len
);
2746 error(1, errno
, "malloc");
2748 memset(image
, 0xff, *len
);
2752 size_t vendor_len
= strlen(info
->vendor
);
2753 put32(image
+0x14, vendor_len
);
2754 memcpy(image
+0x18, info
->vendor
, vendor_len
);
2757 put_partitions(image
+ 0x1014, info
->partitions
, parts
);
2758 put_md5(image
+0x04, image
+0x14, *len
-0x14);
2764 Generates the firmware image in sysupgrade format
2766 This makes some assumptions about the provided flash and image partition tables and
2767 should be generalized when TP-LINK starts building its safeloader into hardware with
2768 different flash layouts.
2770 static void * generate_sysupgrade_image(struct device_info
*info
, const struct image_partition_entry
*image_parts
, size_t *len
) {
2772 size_t flash_first_partition_index
= 0;
2773 size_t flash_last_partition_index
= 0;
2774 const struct flash_partition_entry
*flash_first_partition
= NULL
;
2775 const struct flash_partition_entry
*flash_last_partition
= NULL
;
2776 const struct image_partition_entry
*image_last_partition
= NULL
;
2778 /** Find first and last partitions */
2779 for (i
= 0; info
->partitions
[i
].name
; i
++) {
2780 if (!strcmp(info
->partitions
[i
].name
, info
->first_sysupgrade_partition
)) {
2781 flash_first_partition
= &info
->partitions
[i
];
2782 flash_first_partition_index
= i
;
2783 } else if (!strcmp(info
->partitions
[i
].name
, info
->last_sysupgrade_partition
)) {
2784 flash_last_partition
= &info
->partitions
[i
];
2785 flash_last_partition_index
= i
;
2789 assert(flash_first_partition
&& flash_last_partition
);
2790 assert(flash_first_partition_index
< flash_last_partition_index
);
2792 /** Find last partition from image to calculate needed size */
2793 for (i
= 0; image_parts
[i
].name
; i
++) {
2794 if (!strcmp(image_parts
[i
].name
, info
->last_sysupgrade_partition
)) {
2795 image_last_partition
= &image_parts
[i
];
2800 assert(image_last_partition
);
2802 *len
= flash_last_partition
->base
- flash_first_partition
->base
+ image_last_partition
->size
;
2804 uint8_t *image
= malloc(*len
);
2806 error(1, errno
, "malloc");
2808 memset(image
, 0xff, *len
);
2810 for (i
= flash_first_partition_index
; i
<= flash_last_partition_index
; i
++) {
2811 for (j
= 0; image_parts
[j
].name
; j
++) {
2812 if (!strcmp(info
->partitions
[i
].name
, image_parts
[j
].name
)) {
2813 if (image_parts
[j
].size
> info
->partitions
[i
].size
)
2814 error(1, 0, "%s partition too big (more than %u bytes)", info
->partitions
[i
].name
, (unsigned)info
->partitions
[i
].size
);
2815 memcpy(image
+ info
->partitions
[i
].base
- flash_first_partition
->base
, image_parts
[j
].data
, image_parts
[j
].size
);
2819 assert(image_parts
[j
].name
);
2826 /** Generates an image according to a given layout and writes it to a file */
2827 static void build_image(const char *output
,
2828 const char *kernel_image
,
2829 const char *rootfs_image
,
2833 struct device_info
*info
) {
2837 struct image_partition_entry parts
[7] = {};
2839 struct flash_partition_entry
*firmware_partition
= NULL
;
2840 struct flash_partition_entry
*os_image_partition
= NULL
;
2841 struct flash_partition_entry
*file_system_partition
= NULL
;
2842 size_t firmware_partition_index
= 0;
2844 for (i
= 0; info
->partitions
[i
].name
; i
++) {
2845 if (!strcmp(info
->partitions
[i
].name
, "firmware"))
2847 firmware_partition
= &info
->partitions
[i
];
2848 firmware_partition_index
= i
;
2852 if (firmware_partition
)
2854 os_image_partition
= &info
->partitions
[firmware_partition_index
];
2855 file_system_partition
= &info
->partitions
[firmware_partition_index
+ 1];
2858 if (stat(kernel_image
, &kernel
) < 0)
2859 error(1, errno
, "unable to stat file `%s'", kernel_image
);
2861 if (kernel
.st_size
> firmware_partition
->size
)
2862 error(1, 0, "kernel overflowed firmware partition\n");
2864 for (i
= MAX_PARTITIONS
-1; i
>= firmware_partition_index
+ 1; i
--)
2865 info
->partitions
[i
+1] = info
->partitions
[i
];
2867 file_system_partition
->name
= "file-system";
2868 file_system_partition
->base
= firmware_partition
->base
+ kernel
.st_size
;
2870 /* Align partition start to erase blocks for factory images only */
2872 file_system_partition
->base
= ALIGN(firmware_partition
->base
+ kernel
.st_size
, 0x10000);
2874 file_system_partition
->size
= firmware_partition
->size
- file_system_partition
->base
;
2876 os_image_partition
->name
= "os-image";
2877 os_image_partition
->size
= kernel
.st_size
;
2880 parts
[0] = make_partition_table(info
->partitions
);
2881 parts
[1] = make_soft_version(info
, rev
);
2882 parts
[2] = make_support_list(info
);
2883 parts
[3] = read_file("os-image", kernel_image
, false, NULL
);
2884 parts
[4] = read_file("file-system", rootfs_image
, add_jffs2_eof
, file_system_partition
);
2886 /* Some devices need the extra-para partition to accept the firmware */
2887 if (strcasecmp(info
->id
, "ARCHER-A6-V3") == 0 ||
2888 strcasecmp(info
->id
, "ARCHER-A7-V5") == 0 ||
2889 strcasecmp(info
->id
, "ARCHER-C2-V3") == 0 ||
2890 strcasecmp(info
->id
, "ARCHER-C7-V4") == 0 ||
2891 strcasecmp(info
->id
, "ARCHER-C7-V5") == 0 ||
2892 strcasecmp(info
->id
, "ARCHER-C25-V1") == 0 ||
2893 strcasecmp(info
->id
, "ARCHER-C59-V2") == 0 ||
2894 strcasecmp(info
->id
, "ARCHER-C60-V2") == 0 ||
2895 strcasecmp(info
->id
, "ARCHER-C60-V3") == 0 ||
2896 strcasecmp(info
->id
, "ARCHER-C6U-V1") == 0 ||
2897 strcasecmp(info
->id
, "TLWR1043NV5") == 0) {
2898 const uint8_t extra_para
[2] = {0x01, 0x00};
2899 parts
[5] = make_extra_para(info
, extra_para
,
2900 sizeof(extra_para
));
2901 } else if (strcasecmp(info
->id
, "ARCHER-C6-V2") == 0) {
2902 const uint8_t extra_para
[2] = {0x00, 0x01};
2903 parts
[5] = make_extra_para(info
, extra_para
,
2904 sizeof(extra_para
));
2905 } else if (strcasecmp(info
->id
, "ARCHER-C6-V2-US") == 0 ||
2906 strcasecmp(info
->id
, "EAP245-V3") == 0) {
2907 const uint8_t extra_para
[2] = {0x01, 0x01};
2908 parts
[5] = make_extra_para(info
, extra_para
,
2909 sizeof(extra_para
));
2915 image
= generate_sysupgrade_image(info
, parts
, &len
);
2917 image
= generate_factory_image(info
, parts
, &len
);
2919 FILE *file
= fopen(output
, "wb");
2921 error(1, errno
, "unable to open output file");
2923 if (fwrite(image
, len
, 1, file
) != 1)
2924 error(1, 0, "unable to write output file");
2930 for (i
= 0; parts
[i
].name
; i
++)
2931 free_image_partition(parts
[i
]);
2935 static void usage(const char *argv0
) {
2937 "Usage: %s [OPTIONS...]\n"
2940 " -h show this help\n"
2942 "Create a new image:\n"
2943 " -B <board> create image for the board specified with <board>\n"
2944 " -k <file> read kernel image from the file <file>\n"
2945 " -r <file> read rootfs image from the file <file>\n"
2946 " -o <file> write output to the file <file>\n"
2947 " -V <rev> sets the revision number to <rev>\n"
2948 " -j add jffs2 end-of-filesystem markers\n"
2949 " -S create sysupgrade instead of factory image\n"
2950 "Extract an old image:\n"
2951 " -x <file> extract all oem firmware partition\n"
2952 " -d <dir> destination to extract the firmware partition\n"
2953 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
2959 static struct device_info
*find_board(const char *id
)
2961 struct device_info
*board
= NULL
;
2963 for (board
= boards
; board
->id
!= NULL
; board
++)
2964 if (strcasecmp(id
, board
->id
) == 0)
2970 static int add_flash_partition(
2971 struct flash_partition_entry
*part_list
,
2978 /* check if the list has a free entry */
2979 for (ptr
= 0; ptr
< max_entries
; ptr
++, part_list
++) {
2980 if (part_list
->name
== NULL
&&
2981 part_list
->base
== 0 &&
2982 part_list
->size
== 0)
2986 if (ptr
== max_entries
) {
2987 error(1, 0, "No free flash part entry available.");
2990 part_list
->name
= calloc(1, strlen(name
) + 1);
2991 if (!part_list
->name
) {
2992 error(1, 0, "Unable to allocate memory");
2995 memcpy((char *)part_list
->name
, name
, strlen(name
));
2996 part_list
->base
= base
;
2997 part_list
->size
= size
;
3002 /** read the partition table into struct flash_partition_entry */
3003 static int read_partition_table(
3004 FILE *file
, long offset
,
3005 struct flash_partition_entry
*entries
, size_t max_entries
,
3010 const char *parthdr
= NULL
;
3011 const char *fwuphdr
= "fwup-ptn";
3012 const char *flashhdr
= "partition";
3014 /* TODO: search for the partition table */
3024 error(1, 0, "Invalid partition table");
3027 if (fseek(file
, offset
, SEEK_SET
) < 0)
3028 error(1, errno
, "Can not seek in the firmware");
3030 if (fread(buf
, 2048, 1, file
) != 1)
3031 error(1, errno
, "Can not read fwup-ptn from the firmware");
3035 /* look for the partition header */
3036 if (memcmp(buf
, parthdr
, strlen(parthdr
)) != 0) {
3037 fprintf(stderr
, "DEBUG: can not find fwuphdr\n");
3042 end
= buf
+ sizeof(buf
);
3043 while ((ptr
+ strlen(parthdr
)) < end
&&
3044 memcmp(ptr
, parthdr
, strlen(parthdr
)) == 0) {
3048 char name
[32] = { 0 };
3050 unsigned long base
= 0;
3051 unsigned long size
= 0;
3053 end_part
= memchr(ptr
, '\n', (end
- ptr
));
3054 if (end_part
== NULL
) {
3055 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
3059 for (int i
= 0; i
<= 4; i
++) {
3060 if (end_part
<= ptr
)
3063 end_element
= memchr(ptr
, 0x20, (end_part
- ptr
));
3064 if (end_element
== NULL
) {
3065 error(1, errno
, "Ignoring the rest of the partition entries.");
3070 /* partition header */
3072 ptr
= end_element
+ 1;
3076 name_len
= (end_element
- ptr
) > 31 ? 31 : (end_element
- ptr
);
3077 strncpy(name
, ptr
, name_len
);
3078 name
[name_len
] = '\0';
3079 ptr
= end_element
+ 1;
3084 ptr
= end_element
+ 1;
3089 base
= strtoul(ptr
, NULL
, 16);
3090 ptr
= end_element
+ 1;
3095 ptr
= end_element
+ 1;
3096 /* actual size. The last element doesn't have a sepeartor */
3097 size
= strtoul(ptr
, NULL
, 16);
3098 /* the part ends with 0x09, 0x0d, 0x0a */
3100 add_flash_partition(entries
, max_entries
, name
, base
, size
);
3109 static void write_partition(
3111 size_t firmware_offset
,
3112 struct flash_partition_entry
*entry
,
3118 fseek(input_file
, entry
->base
+ firmware_offset
, SEEK_SET
);
3120 for (offset
= 0; sizeof(buf
) + offset
<= entry
->size
; offset
+= sizeof(buf
)) {
3121 if (fread(buf
, sizeof(buf
), 1, input_file
) != 1)
3122 error(1, errno
, "Can not read partition from input_file");
3124 if (fwrite(buf
, sizeof(buf
), 1, output_file
) != 1)
3125 error(1, errno
, "Can not write partition to output_file");
3127 /* write last chunk smaller than buffer */
3128 if (offset
< entry
->size
) {
3129 offset
= entry
->size
- offset
;
3130 if (fread(buf
, offset
, 1, input_file
) != 1)
3131 error(1, errno
, "Can not read partition from input_file");
3132 if (fwrite(buf
, offset
, 1, output_file
) != 1)
3133 error(1, errno
, "Can not write partition to output_file");
3137 static int extract_firmware_partition(FILE *input_file
, size_t firmware_offset
, struct flash_partition_entry
*entry
, const char *output_directory
)
3140 char output
[PATH_MAX
];
3142 snprintf(output
, PATH_MAX
, "%s/%s", output_directory
, entry
->name
);
3143 output_file
= fopen(output
, "wb+");
3144 if (output_file
== NULL
) {
3145 error(1, errno
, "Can not open output file %s", output
);
3148 write_partition(input_file
, firmware_offset
, entry
, output_file
);
3150 fclose(output_file
);
3155 /** extract all partitions from the firmware file */
3156 static int extract_firmware(const char *input
, const char *output_directory
)
3158 struct flash_partition_entry entries
[16] = { 0 };
3159 size_t max_entries
= 16;
3160 size_t firmware_offset
= 0x1014;
3163 struct stat statbuf
;
3165 /* check input file */
3166 if (stat(input
, &statbuf
)) {
3167 error(1, errno
, "Can not read input firmware %s", input
);
3170 /* check if output directory exists */
3171 if (stat(output_directory
, &statbuf
)) {
3172 error(1, errno
, "Failed to stat output directory %s", output_directory
);
3175 if ((statbuf
.st_mode
& S_IFMT
) != S_IFDIR
) {
3176 error(1, errno
, "Given output directory is not a directory %s", output_directory
);
3179 input_file
= fopen(input
, "rb");
3181 if (read_partition_table(input_file
, firmware_offset
, entries
, 16, 0) != 0) {
3182 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3185 for (size_t i
= 0; i
< max_entries
; i
++) {
3186 if (entries
[i
].name
== NULL
&&
3187 entries
[i
].base
== 0 &&
3188 entries
[i
].size
== 0)
3191 extract_firmware_partition(input_file
, firmware_offset
, &entries
[i
], output_directory
);
3197 static struct flash_partition_entry
*find_partition(
3198 struct flash_partition_entry
*entries
, size_t max_entries
,
3199 const char *name
, const char *error_msg
)
3201 for (size_t i
= 0; i
< max_entries
; i
++, entries
++) {
3202 if (strcmp(entries
->name
, name
) == 0)
3206 error(1, 0, "%s", error_msg
);
3210 static void write_ff(FILE *output_file
, size_t size
)
3215 memset(buf
, 0xff, sizeof(buf
));
3217 for (offset
= 0; offset
+ sizeof(buf
) < size
; offset
+= sizeof(buf
)) {
3218 if (fwrite(buf
, sizeof(buf
), 1, output_file
) != 1)
3219 error(1, errno
, "Can not write 0xff to output_file");
3222 /* write last chunk smaller than buffer */
3223 if (offset
< size
) {
3224 offset
= size
- offset
;
3225 if (fwrite(buf
, offset
, 1, output_file
) != 1)
3226 error(1, errno
, "Can not write partition to output_file");
3230 static void convert_firmware(const char *input
, const char *output
)
3232 struct flash_partition_entry fwup
[MAX_PARTITIONS
] = { 0 };
3233 struct flash_partition_entry flash
[MAX_PARTITIONS
] = { 0 };
3234 struct flash_partition_entry
*fwup_os_image
= NULL
, *fwup_file_system
= NULL
;
3235 struct flash_partition_entry
*flash_os_image
= NULL
, *flash_file_system
= NULL
;
3236 struct flash_partition_entry
*fwup_partition_table
= NULL
;
3237 size_t firmware_offset
= 0x1014;
3238 FILE *input_file
, *output_file
;
3240 struct stat statbuf
;
3242 /* check input file */
3243 if (stat(input
, &statbuf
)) {
3244 error(1, errno
, "Can not read input firmware %s", input
);
3247 input_file
= fopen(input
, "rb");
3249 error(1, 0, "Can not open input firmware %s", input
);
3251 output_file
= fopen(output
, "wb");
3253 error(1, 0, "Can not open output firmware %s", output
);
3255 if (read_partition_table(input_file
, firmware_offset
, fwup
, MAX_PARTITIONS
, 0) != 0) {
3256 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3259 fwup_os_image
= find_partition(fwup
, MAX_PARTITIONS
,
3260 "os-image", "Error can not find os-image partition (fwup)");
3261 fwup_file_system
= find_partition(fwup
, MAX_PARTITIONS
,
3262 "file-system", "Error can not find file-system partition (fwup)");
3263 fwup_partition_table
= find_partition(fwup
, MAX_PARTITIONS
,
3264 "partition-table", "Error can not find partition-table partition");
3266 /* the flash partition table has a 0x00000004 magic haeder */
3267 if (read_partition_table(input_file
, firmware_offset
+ fwup_partition_table
->base
+ 4, flash
, MAX_PARTITIONS
, 1) != 0)
3268 error(1, 0, "Error can not read the partition table (flash)");
3270 flash_os_image
= find_partition(flash
, MAX_PARTITIONS
,
3271 "os-image", "Error can not find os-image partition (flash)");
3272 flash_file_system
= find_partition(flash
, MAX_PARTITIONS
,
3273 "file-system", "Error can not find file-system partition (flash)");
3275 /* write os_image to 0x0 */
3276 write_partition(input_file
, firmware_offset
, fwup_os_image
, output_file
);
3277 write_ff(output_file
, flash_os_image
->size
- fwup_os_image
->size
);
3279 /* write file-system behind os_image */
3280 fseek(output_file
, flash_file_system
->base
- flash_os_image
->base
, SEEK_SET
);
3281 write_partition(input_file
, firmware_offset
, fwup_file_system
, output_file
);
3282 write_ff(output_file
, flash_file_system
->size
- fwup_file_system
->size
);
3284 fclose(output_file
);
3288 int main(int argc
, char *argv
[]) {
3289 const char *board
= NULL
, *kernel_image
= NULL
, *rootfs_image
= NULL
, *output
= NULL
;
3290 const char *extract_image
= NULL
, *output_directory
= NULL
, *convert_image
= NULL
;
3291 bool add_jffs2_eof
= false, sysupgrade
= false;
3293 struct device_info
*info
;
3294 set_source_date_epoch();
3299 c
= getopt(argc
, argv
, "B:k:r:o:V:jSh:x:d:z:");
3309 kernel_image
= optarg
;
3313 rootfs_image
= optarg
;
3321 sscanf(optarg
, "r%u", &rev
);
3325 add_jffs2_eof
= true;
3337 output_directory
= optarg
;
3341 extract_image
= optarg
;
3345 convert_image
= optarg
;
3354 if (extract_image
|| output_directory
) {
3356 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
3357 if (!output_directory
)
3358 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
3359 extract_firmware(extract_image
, output_directory
);
3360 } else if (convert_image
) {
3362 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
3363 convert_firmware(convert_image
, output
);
3366 error(1, 0, "no board has been specified");
3368 error(1, 0, "no kernel image has been specified");
3370 error(1, 0, "no rootfs image has been specified");
3372 error(1, 0, "no output filename has been specified");
3374 info
= find_board(board
);
3377 error(1, 0, "unsupported board %s", board
);
3379 build_image(output
, kernel_image
, rootfs_image
, rev
, add_jffs2_eof
, sysupgrade
, info
);