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)
47 #include <arpa/inet.h>
49 #include <sys/types.h>
56 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
59 #define MAX_PARTITIONS 32
61 /** An image partition table entry */
62 struct image_partition_entry
{
68 /** A flash partition table entry */
69 struct flash_partition_entry
{
75 /** Partition trailing padding definitions
76 * Values 0x00 to 0xff are reserved to indicate the padding value
77 * Values from 0x100 are reserved to indicate other behaviour */
78 enum partition_trail_value
{
81 PART_TRAIL_MAX
= 0xff,
82 PART_TRAIL_NONE
= 0x100
85 /** Firmware layout description */
89 const char *support_list
;
90 enum partition_trail_value part_trail
;
92 uint32_t soft_ver_compat_level
;
93 struct flash_partition_entry partitions
[MAX_PARTITIONS
+1];
94 const char *first_sysupgrade_partition
;
95 const char *last_sysupgrade_partition
;
98 struct __attribute__((__packed__
)) meta_header
{
103 /** The content of the soft-version structure */
104 struct __attribute__((__packed__
)) soft_version
{
106 uint8_t version_major
;
107 uint8_t version_minor
;
108 uint8_t version_patch
;
114 uint32_t compat_level
;
118 static const uint8_t jffs2_eof_mark
[4] = {0xde, 0xad, 0xc0, 0xde};
122 Salt for the MD5 hash
124 Fortunately, TP-LINK seems to use the same salt for most devices which use
125 the new image format.
127 static const uint8_t md5_salt
[16] = {
128 0x7a, 0x2b, 0x15, 0xed,
129 0x9b, 0x98, 0x59, 0x6d,
130 0xe5, 0x04, 0xab, 0x44,
131 0xac, 0x2a, 0x9f, 0x4e,
135 /** Firmware layout table */
136 static struct device_info boards
[] = {
137 /** Firmware layout for the CPE210/220 V1 */
140 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
143 "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
144 "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
145 "CPE210(TP-LINK|US|N300-2):1.1\r\n"
146 "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
147 "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
148 "CPE220(TP-LINK|US|N300-2):1.1\r\n"
149 "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
154 {"fs-uboot", 0x00000, 0x20000},
155 {"partition-table", 0x20000, 0x02000},
156 {"default-mac", 0x30000, 0x00020},
157 {"product-info", 0x31100, 0x00100},
158 {"signature", 0x32000, 0x00400},
159 {"firmware", 0x40000, 0x770000},
160 {"soft-version", 0x7b0000, 0x00100},
161 {"support-list", 0x7b1000, 0x00400},
162 {"user-config", 0x7c0000, 0x10000},
163 {"default-config", 0x7d0000, 0x10000},
164 {"log", 0x7e0000, 0x10000},
165 {"radio", 0x7f0000, 0x10000},
169 .first_sysupgrade_partition
= "os-image",
170 .last_sysupgrade_partition
= "support-list",
173 /** Firmware layout for the CPE210 V2 */
176 .vendor
= "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
179 "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
180 "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
181 "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
182 "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
183 "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
184 "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
185 "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
186 "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
187 "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
188 "CPE210(TP-LINK|US|N300-2):2.0\r\n",
193 {"fs-uboot", 0x00000, 0x20000},
194 {"partition-table", 0x20000, 0x02000},
195 {"default-mac", 0x30000, 0x00020},
196 {"product-info", 0x31100, 0x00100},
197 {"device-info", 0x31400, 0x00400},
198 {"signature", 0x32000, 0x00400},
199 {"device-id", 0x33000, 0x00100},
200 {"firmware", 0x40000, 0x770000},
201 {"soft-version", 0x7b0000, 0x00100},
202 {"support-list", 0x7b1000, 0x01000},
203 {"user-config", 0x7c0000, 0x10000},
204 {"default-config", 0x7d0000, 0x10000},
205 {"log", 0x7e0000, 0x10000},
206 {"radio", 0x7f0000, 0x10000},
210 .first_sysupgrade_partition
= "os-image",
211 .last_sysupgrade_partition
= "support-list",
214 /** Firmware layout for the CPE210 V3 */
217 .vendor
= "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n",
220 "CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n"
221 "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n"
222 "CPE210(TP-LINK|US|N300-2|55530000):3.0\r\n"
223 "CPE210(TP-LINK|UN|N300-2):3.0\r\n"
224 "CPE210(TP-LINK|EU|N300-2):3.0\r\n"
225 "CPE210(TP-LINK|EU|N300-2|45550000):3.1\r\n"
226 "CPE210(TP-LINK|UN|N300-2|00000000):3.1\r\n"
227 "CPE210(TP-LINK|US|N300-2|55530000):3.1\r\n"
228 "CPE210(TP-LINK|EU|N300-2|45550000):3.20\r\n"
229 "CPE210(TP-LINK|UN|N300-2|00000000):3.20\r\n"
230 "CPE210(TP-LINK|US|N300-2|55530000):3.20\r\n",
235 {"fs-uboot", 0x00000, 0x20000},
236 {"partition-table", 0x20000, 0x01000},
237 {"default-mac", 0x30000, 0x00020},
238 {"product-info", 0x31100, 0x00100},
239 {"device-info", 0x31400, 0x00400},
240 {"signature", 0x32000, 0x00400},
241 {"device-id", 0x33000, 0x00100},
242 {"firmware", 0x40000, 0x770000},
243 {"soft-version", 0x7b0000, 0x00100},
244 {"support-list", 0x7b1000, 0x01000},
245 {"user-config", 0x7c0000, 0x10000},
246 {"default-config", 0x7d0000, 0x10000},
247 {"log", 0x7e0000, 0x10000},
248 {"radio", 0x7f0000, 0x10000},
252 .first_sysupgrade_partition
= "os-image",
253 .last_sysupgrade_partition
= "support-list",
256 /** Firmware layout for the CPE220 V2 */
259 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
262 "CPE220(TP-LINK|EU|N300-2|00000000):2.0\r\n"
263 "CPE220(TP-LINK|EU|N300-2|45550000):2.0\r\n"
264 "CPE220(TP-LINK|EU|N300-2|55530000):2.0\r\n"
265 "CPE220(TP-LINK|UN|N300-2|00000000):2.0\r\n"
266 "CPE220(TP-LINK|UN|N300-2|45550000):2.0\r\n"
267 "CPE220(TP-LINK|UN|N300-2|55530000):2.0\r\n"
268 "CPE220(TP-LINK|US|N300-2|55530000):2.0\r\n"
269 "CPE220(TP-LINK|UN|N300-2):2.0\r\n"
270 "CPE220(TP-LINK|EU|N300-2):2.0\r\n"
271 "CPE220(TP-LINK|US|N300-2):2.0\r\n",
276 {"fs-uboot", 0x00000, 0x20000},
277 {"partition-table", 0x20000, 0x02000},
278 {"default-mac", 0x30000, 0x00020},
279 {"product-info", 0x31100, 0x00100},
280 {"signature", 0x32000, 0x00400},
281 {"firmware", 0x40000, 0x770000},
282 {"soft-version", 0x7b0000, 0x00100},
283 {"support-list", 0x7b1000, 0x00400},
284 {"user-config", 0x7c0000, 0x10000},
285 {"default-config", 0x7d0000, 0x10000},
286 {"log", 0x7e0000, 0x10000},
287 {"radio", 0x7f0000, 0x10000},
291 .first_sysupgrade_partition
= "os-image",
292 .last_sysupgrade_partition
= "support-list",
295 /** Firmware layout for the CPE220 V3 */
298 .vendor
= "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n",
301 "CPE220(TP-LINK|EU|N300-2|00000000):3.0\r\n"
302 "CPE220(TP-LINK|EU|N300-2|45550000):3.0\r\n"
303 "CPE220(TP-LINK|EU|N300-2|55530000):3.0\r\n"
304 "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n"
305 "CPE220(TP-LINK|UN|N300-2|45550000):3.0\r\n"
306 "CPE220(TP-LINK|UN|N300-2|55530000):3.0\r\n"
307 "CPE220(TP-LINK|US|N300-2|55530000):3.0\r\n"
308 "CPE220(TP-LINK|UN|N300-2):3.0\r\n"
309 "CPE220(TP-LINK|EU|N300-2):3.0\r\n"
310 "CPE220(TP-LINK|US|N300-2):3.0\r\n",
315 {"fs-uboot", 0x00000, 0x20000},
316 {"partition-table", 0x20000, 0x02000},
317 {"default-mac", 0x30000, 0x00020},
318 {"product-info", 0x31100, 0x00100},
319 {"device-info", 0x31400, 0x00400},
320 {"signature", 0x32000, 0x00400},
321 {"device-id", 0x33000, 0x00100},
322 {"firmware", 0x40000, 0x770000},
323 {"soft-version", 0x7b0000, 0x00100},
324 {"support-list", 0x7b1000, 0x01000},
325 {"user-config", 0x7c0000, 0x10000},
326 {"default-config", 0x7d0000, 0x10000},
327 {"log", 0x7e0000, 0x10000},
328 {"radio", 0x7f0000, 0x10000},
332 .first_sysupgrade_partition
= "os-image",
333 .last_sysupgrade_partition
= "support-list",
336 /** Firmware layout for the CPE510/520 V1 */
339 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
342 "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
343 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
344 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
345 "CPE510(TP-LINK|US|N300-5):1.1\r\n"
346 "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
347 "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
348 "CPE520(TP-LINK|US|N300-5):1.1\r\n"
349 "CPE520(TP-LINK|EU|N300-5):1.1\r\n",
354 {"fs-uboot", 0x00000, 0x20000},
355 {"partition-table", 0x20000, 0x02000},
356 {"default-mac", 0x30000, 0x00020},
357 {"product-info", 0x31100, 0x00100},
358 {"signature", 0x32000, 0x00400},
359 {"firmware", 0x40000, 0x770000},
360 {"soft-version", 0x7b0000, 0x00100},
361 {"support-list", 0x7b1000, 0x00400},
362 {"user-config", 0x7c0000, 0x10000},
363 {"default-config", 0x7d0000, 0x10000},
364 {"log", 0x7e0000, 0x10000},
365 {"radio", 0x7f0000, 0x10000},
369 .first_sysupgrade_partition
= "os-image",
370 .last_sysupgrade_partition
= "support-list",
373 /** Firmware layout for the CPE510 V2 */
376 .vendor
= "CPE510(TP-LINK|UN|N300-5):2.0\r\n",
379 "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n"
380 "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
381 "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n"
382 "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
383 "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n"
384 "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n"
385 "CPE510(TP-LINK|US|N300-5|00000000):2.0\r\n"
386 "CPE510(TP-LINK|US|N300-5|45550000):2.0\r\n"
387 "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n"
388 "CPE510(TP-LINK|UN|N300-5):2.0\r\n"
389 "CPE510(TP-LINK|EU|N300-5):2.0\r\n"
390 "CPE510(TP-LINK|US|N300-5):2.0\r\n",
395 {"fs-uboot", 0x00000, 0x20000},
396 {"partition-table", 0x20000, 0x02000},
397 {"default-mac", 0x30000, 0x00020},
398 {"product-info", 0x31100, 0x00100},
399 {"signature", 0x32000, 0x00400},
400 {"firmware", 0x40000, 0x770000},
401 {"soft-version", 0x7b0000, 0x00100},
402 {"support-list", 0x7b1000, 0x00400},
403 {"user-config", 0x7c0000, 0x10000},
404 {"default-config", 0x7d0000, 0x10000},
405 {"log", 0x7e0000, 0x10000},
406 {"radio", 0x7f0000, 0x10000},
410 .first_sysupgrade_partition
= "os-image",
411 .last_sysupgrade_partition
= "support-list",
414 /** Firmware layout for the CPE510 V3 */
417 .vendor
= "CPE510(TP-LINK|UN|N300-5):3.0\r\n",
420 "CPE510(TP-LINK|EU|N300-5|00000000):3.0\r\n"
421 "CPE510(TP-LINK|EU|N300-5|45550000):3.0\r\n"
422 "CPE510(TP-LINK|EU|N300-5|55530000):3.0\r\n"
423 "CPE510(TP-LINK|UN|N300-5|00000000):3.0\r\n"
424 "CPE510(TP-LINK|UN|N300-5|45550000):3.0\r\n"
425 "CPE510(TP-LINK|UN|N300-5|55530000):3.0\r\n"
426 "CPE510(TP-LINK|US|N300-5|00000000):3.0\r\n"
427 "CPE510(TP-LINK|US|N300-5|45550000):3.0\r\n"
428 "CPE510(TP-LINK|US|N300-5|55530000):3.0\r\n"
429 "CPE510(TP-LINK|UN|N300-5):3.0\r\n"
430 "CPE510(TP-LINK|EU|N300-5):3.0\r\n"
431 "CPE510(TP-LINK|US|N300-5):3.0\r\n"
432 "CPE510(TP-LINK|UN|N300-5|00000000):3.20\r\n"
433 "CPE510(TP-LINK|US|N300-5|55530000):3.20\r\n"
434 "CPE510(TP-LINK|EU|N300-5|45550000):3.20\r\n",
439 {"fs-uboot", 0x00000, 0x20000},
440 {"partition-table", 0x20000, 0x02000},
441 {"default-mac", 0x30000, 0x00020},
442 {"product-info", 0x31100, 0x00100},
443 {"signature", 0x32000, 0x00400},
444 {"firmware", 0x40000, 0x770000},
445 {"soft-version", 0x7b0000, 0x00100},
446 {"support-list", 0x7b1000, 0x00400},
447 {"user-config", 0x7c0000, 0x10000},
448 {"default-config", 0x7d0000, 0x10000},
449 {"log", 0x7e0000, 0x10000},
450 {"radio", 0x7f0000, 0x10000},
454 .first_sysupgrade_partition
= "os-image",
455 .last_sysupgrade_partition
= "support-list",
458 /** Firmware layout for the CPE610V1 */
461 .vendor
= "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n",
464 "CPE610(TP-LINK|EU|N300-5|00000000):1.0\r\n"
465 "CPE610(TP-LINK|EU|N300-5|45550000):1.0\r\n"
466 "CPE610(TP-LINK|EU|N300-5|55530000):1.0\r\n"
467 "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n"
468 "CPE610(TP-LINK|UN|N300-5|45550000):1.0\r\n"
469 "CPE610(TP-LINK|UN|N300-5|55530000):1.0\r\n"
470 "CPE610(TP-LINK|US|N300-5|55530000):1.0\r\n"
471 "CPE610(TP-LINK|UN|N300-5):1.0\r\n"
472 "CPE610(TP-LINK|EU|N300-5):1.0\r\n"
473 "CPE610(TP-LINK|US|N300-5):1.0\r\n",
478 {"fs-uboot", 0x00000, 0x20000},
479 {"partition-table", 0x20000, 0x02000},
480 {"default-mac", 0x30000, 0x00020},
481 {"product-info", 0x31100, 0x00100},
482 {"signature", 0x32000, 0x00400},
483 {"firmware", 0x40000, 0x770000},
484 {"soft-version", 0x7b0000, 0x00100},
485 {"support-list", 0x7b1000, 0x00400},
486 {"user-config", 0x7c0000, 0x10000},
487 {"default-config", 0x7d0000, 0x10000},
488 {"log", 0x7e0000, 0x10000},
489 {"radio", 0x7f0000, 0x10000},
493 .first_sysupgrade_partition
= "os-image",
494 .last_sysupgrade_partition
= "support-list",
497 /** Firmware layout for the CPE610V2 */
500 .vendor
= "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n",
503 "CPE610(TP-LINK|EU|N300-5|00000000):2.0\r\n"
504 "CPE610(TP-LINK|EU|N300-5|45550000):2.0\r\n"
505 "CPE610(TP-LINK|EU|N300-5|55530000):2.0\r\n"
506 "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n"
507 "CPE610(TP-LINK|UN|N300-5|45550000):2.0\r\n"
508 "CPE610(TP-LINK|UN|N300-5|55530000):2.0\r\n"
509 "CPE610(TP-LINK|US|N300-5|55530000):2.0\r\n"
510 "CPE610(TP-LINK|UN|N300-5):2.0\r\n"
511 "CPE610(TP-LINK|EU|N300-5):2.0\r\n"
512 "CPE610(TP-LINK|US|N300-5):2.0\r\n",
517 {"fs-uboot", 0x00000, 0x20000},
518 {"partition-table", 0x20000, 0x02000},
519 {"default-mac", 0x30000, 0x00020},
520 {"product-info", 0x31100, 0x00100},
521 {"signature", 0x32000, 0x00400},
522 {"firmware", 0x40000, 0x770000},
523 {"soft-version", 0x7b0000, 0x00100},
524 {"support-list", 0x7b1000, 0x00400},
525 {"user-config", 0x7c0000, 0x10000},
526 {"default-config", 0x7d0000, 0x10000},
527 {"log", 0x7e0000, 0x10000},
528 {"radio", 0x7f0000, 0x10000},
532 .first_sysupgrade_partition
= "os-image",
533 .last_sysupgrade_partition
= "support-list",
538 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
541 "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
542 "WBS210(TP-LINK|US|N300-2):1.20\r\n"
543 "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
548 {"fs-uboot", 0x00000, 0x20000},
549 {"partition-table", 0x20000, 0x02000},
550 {"default-mac", 0x30000, 0x00020},
551 {"product-info", 0x31100, 0x00100},
552 {"signature", 0x32000, 0x00400},
553 {"firmware", 0x40000, 0x770000},
554 {"soft-version", 0x7b0000, 0x00100},
555 {"support-list", 0x7b1000, 0x00400},
556 {"user-config", 0x7c0000, 0x10000},
557 {"default-config", 0x7d0000, 0x10000},
558 {"log", 0x7e0000, 0x10000},
559 {"radio", 0x7f0000, 0x10000},
563 .first_sysupgrade_partition
= "os-image",
564 .last_sysupgrade_partition
= "support-list",
569 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
572 "WBS210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
573 "WBS210(TP-LINK|US|N300-2|55530000):2.0\r\n"
574 "WBS210(TP-LINK|EU|N300-2|45550000):2.0\r\n",
579 {"fs-uboot", 0x00000, 0x20000},
580 {"partition-table", 0x20000, 0x02000},
581 {"default-mac", 0x30000, 0x00020},
582 {"product-info", 0x31100, 0x00100},
583 {"signature", 0x32000, 0x00400},
584 {"firmware", 0x40000, 0x770000},
585 {"soft-version", 0x7b0000, 0x00100},
586 {"support-list", 0x7b1000, 0x00400},
587 {"user-config", 0x7c0000, 0x10000},
588 {"default-config", 0x7d0000, 0x10000},
589 {"log", 0x7e0000, 0x10000},
590 {"radio", 0x7f0000, 0x10000},
594 .first_sysupgrade_partition
= "os-image",
595 .last_sysupgrade_partition
= "support-list",
600 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
603 "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
604 "WBS510(TP-LINK|US|N300-5):1.20\r\n"
605 "WBS510(TP-LINK|EU|N300-5):1.20\r\n"
606 "WBS510(TP-LINK|CA|N300-5):1.20\r\n",
611 {"fs-uboot", 0x00000, 0x20000},
612 {"partition-table", 0x20000, 0x02000},
613 {"default-mac", 0x30000, 0x00020},
614 {"product-info", 0x31100, 0x00100},
615 {"signature", 0x32000, 0x00400},
616 {"firmware", 0x40000, 0x770000},
617 {"soft-version", 0x7b0000, 0x00100},
618 {"support-list", 0x7b1000, 0x00400},
619 {"user-config", 0x7c0000, 0x10000},
620 {"default-config", 0x7d0000, 0x10000},
621 {"log", 0x7e0000, 0x10000},
622 {"radio", 0x7f0000, 0x10000},
626 .first_sysupgrade_partition
= "os-image",
627 .last_sysupgrade_partition
= "support-list",
632 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
635 "WBS510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
636 "WBS510(TP-LINK|US|N300-5|55530000):2.0\r\n"
637 "WBS510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
638 "WBS510(TP-LINK|CA|N300-5|43410000):2.0\r\n",
643 {"fs-uboot", 0x00000, 0x20000},
644 {"partition-table", 0x20000, 0x02000},
645 {"default-mac", 0x30000, 0x00020},
646 {"product-info", 0x31100, 0x00100},
647 {"signature", 0x32000, 0x00400},
648 {"firmware", 0x40000, 0x770000},
649 {"soft-version", 0x7b0000, 0x00100},
650 {"support-list", 0x7b1000, 0x00400},
651 {"user-config", 0x7c0000, 0x10000},
652 {"default-config", 0x7d0000, 0x10000},
653 {"log", 0x7e0000, 0x10000},
654 {"radio", 0x7f0000, 0x10000},
658 .first_sysupgrade_partition
= "os-image",
659 .last_sysupgrade_partition
= "support-list",
662 /** Firmware layout for the AD7200 */
668 "{product_name:AD7200,product_ver:1.0.0,special_id:00000000}\r\n",
673 {"SBL1", 0x00000, 0x20000},
674 {"MIBIB", 0x20000, 0x20000},
675 {"SBL2", 0x40000, 0x20000},
676 {"SBL3", 0x60000, 0x30000},
677 {"DDRCONFIG", 0x90000, 0x10000},
678 {"SSD", 0xa0000, 0x10000},
679 {"TZ", 0xb0000, 0x30000},
680 {"RPM", 0xe0000, 0x20000},
681 {"fs-uboot", 0x100000, 0x70000},
682 {"uboot-env", 0x170000, 0x40000},
683 {"radio", 0x1b0000, 0x40000},
684 {"os-image", 0x1f0000, 0x400000},
685 {"file-system", 0x5f0000, 0x1900000},
686 {"default-mac", 0x1ef0000, 0x00200},
687 {"pin", 0x1ef0200, 0x00200},
688 {"device-id", 0x1ef0400, 0x00200},
689 {"product-info", 0x1ef0600, 0x0fa00},
690 {"partition-table", 0x1f00000, 0x10000},
691 {"soft-version", 0x1f10000, 0x10000},
692 {"support-list", 0x1f20000, 0x10000},
693 {"profile", 0x1f30000, 0x10000},
694 {"default-config", 0x1f40000, 0x10000},
695 {"user-config", 0x1f50000, 0x40000},
696 {"qos-db", 0x1f90000, 0x40000},
697 {"usb-config", 0x1fd0000, 0x10000},
698 {"log", 0x1fe0000, 0x20000},
702 .first_sysupgrade_partition
= "os-image",
703 .last_sysupgrade_partition
= "file-system"
706 /** Firmware layout for the C2600 */
712 "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
717 We use a bigger os-image partition than the stock images (and thus
718 smaller file-system), as our kernel doesn't fit in the stock firmware's
719 2 MB os-image since kernel 4.14.
722 {"SBL1", 0x00000, 0x20000},
723 {"MIBIB", 0x20000, 0x20000},
724 {"SBL2", 0x40000, 0x20000},
725 {"SBL3", 0x60000, 0x30000},
726 {"DDRCONFIG", 0x90000, 0x10000},
727 {"SSD", 0xa0000, 0x10000},
728 {"TZ", 0xb0000, 0x30000},
729 {"RPM", 0xe0000, 0x20000},
730 {"fs-uboot", 0x100000, 0x70000},
731 {"uboot-env", 0x170000, 0x40000},
732 {"radio", 0x1b0000, 0x40000},
733 {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
734 {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
735 {"default-mac", 0x1ef0000, 0x00200},
736 {"pin", 0x1ef0200, 0x00200},
737 {"product-info", 0x1ef0400, 0x0fc00},
738 {"partition-table", 0x1f00000, 0x10000},
739 {"soft-version", 0x1f10000, 0x10000},
740 {"support-list", 0x1f20000, 0x10000},
741 {"profile", 0x1f30000, 0x10000},
742 {"default-config", 0x1f40000, 0x10000},
743 {"user-config", 0x1f50000, 0x40000},
744 {"qos-db", 0x1f90000, 0x40000},
745 {"usb-config", 0x1fd0000, 0x10000},
746 {"log", 0x1fe0000, 0x20000},
750 .first_sysupgrade_partition
= "os-image",
751 .last_sysupgrade_partition
= "file-system"
754 /** Firmware layout for the A7-V5 */
756 .id
= "ARCHER-A7-V5",
759 "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n"
760 "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n"
761 "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n"
762 "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n"
763 "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n"
764 "{product_name:Archer A7,product_ver:5.0.0,special_id:52550000}\n",
766 .soft_ver
= "soft_ver:1.0.0\n",
768 /* We're using a dynamic kernel/rootfs split here */
770 {"factory-boot", 0x00000, 0x20000},
771 {"fs-uboot", 0x20000, 0x20000},
772 {"firmware", 0x40000, 0xec0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
773 /* Stock: name file-system base 0x160000 size 0xda0000 */
774 {"default-mac", 0xf40000, 0x00200},
775 {"pin", 0xf40200, 0x00200},
776 {"device-id", 0xf40400, 0x00100},
777 {"product-info", 0xf40500, 0x0fb00},
778 {"soft-version", 0xf50000, 0x00100},
779 {"extra-para", 0xf51000, 0x01000},
780 {"support-list", 0xf52000, 0x0a000},
781 {"profile", 0xf5c000, 0x04000},
782 {"default-config", 0xf60000, 0x10000},
783 {"user-config", 0xf70000, 0x40000},
784 {"certificate", 0xfb0000, 0x10000},
785 {"partition-table", 0xfc0000, 0x10000},
786 {"log", 0xfd0000, 0x20000},
787 {"radio", 0xff0000, 0x10000},
791 .first_sysupgrade_partition
= "os-image",
792 .last_sysupgrade_partition
= "file-system",
795 /** Firmware layout for the C2v3 */
797 .id
= "ARCHER-C2-V3",
800 "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n"
801 "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n"
802 "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n",
804 .soft_ver
= "soft_ver:3.0.1\n",
806 /** We're using a dynamic kernel/rootfs split here */
809 {"factory-boot", 0x00000, 0x20000},
810 {"fs-uboot", 0x20000, 0x10000},
811 {"firmware", 0x30000, 0x7a0000},
812 {"user-config", 0x7d0000, 0x04000},
813 {"default-mac", 0x7e0000, 0x00100},
814 {"device-id", 0x7e0100, 0x00100},
815 {"extra-para", 0x7e0200, 0x00100},
816 {"pin", 0x7e0300, 0x00100},
817 {"support-list", 0x7e0400, 0x00400},
818 {"soft-version", 0x7e0800, 0x00400},
819 {"product-info", 0x7e0c00, 0x01400},
820 {"partition-table", 0x7e2000, 0x01000},
821 {"profile", 0x7e3000, 0x01000},
822 {"default-config", 0x7e4000, 0x04000},
823 {"merge-config", 0x7ec000, 0x02000},
824 {"qos-db", 0x7ee000, 0x02000},
825 {"radio", 0x7f0000, 0x10000},
829 .first_sysupgrade_partition
= "os-image",
830 .last_sysupgrade_partition
= "file-system",
833 /** Firmware layout for the C25v1 */
835 .id
= "ARCHER-C25-V1",
838 "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
839 "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
840 "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
842 .soft_ver
= "soft_ver:1.0.0\n",
844 /* We're using a dynamic kernel/rootfs split here */
846 {"factory-boot", 0x00000, 0x20000},
847 {"fs-uboot", 0x20000, 0x10000},
848 {"firmware", 0x30000, 0x7a0000}, /* Stock: name os-image base 0x30000 size 0x100000 */
849 /* Stock: name file-system base 0x130000 size 0x6a0000 */
850 {"user-config", 0x7d0000, 0x04000},
851 {"default-mac", 0x7e0000, 0x00100},
852 {"device-id", 0x7e0100, 0x00100},
853 {"extra-para", 0x7e0200, 0x00100},
854 {"pin", 0x7e0300, 0x00100},
855 {"support-list", 0x7e0400, 0x00400},
856 {"soft-version", 0x7e0800, 0x00400},
857 {"product-info", 0x7e0c00, 0x01400},
858 {"partition-table", 0x7e2000, 0x01000},
859 {"profile", 0x7e3000, 0x01000},
860 {"default-config", 0x7e4000, 0x04000},
861 {"merge-config", 0x7ec000, 0x02000},
862 {"qos-db", 0x7ee000, 0x02000},
863 {"radio", 0x7f0000, 0x10000},
867 .first_sysupgrade_partition
= "os-image",
868 .last_sysupgrade_partition
= "file-system",
871 /** Firmware layout for the C58v1 */
873 .id
= "ARCHER-C58-V1",
877 "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
878 "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
879 "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
881 .soft_ver
= "soft_ver:1.0.0\n",
884 {"fs-uboot", 0x00000, 0x10000},
885 {"default-mac", 0x10000, 0x00200},
886 {"pin", 0x10200, 0x00200},
887 {"product-info", 0x10400, 0x00100},
888 {"partition-table", 0x10500, 0x00800},
889 {"soft-version", 0x11300, 0x00200},
890 {"support-list", 0x11500, 0x00100},
891 {"device-id", 0x11600, 0x00100},
892 {"profile", 0x11700, 0x03900},
893 {"default-config", 0x15000, 0x04000},
894 {"user-config", 0x19000, 0x04000},
895 {"firmware", 0x20000, 0x7c8000},
896 {"certyficate", 0x7e8000, 0x08000},
897 {"radio", 0x7f0000, 0x10000},
901 .first_sysupgrade_partition
= "os-image",
902 .last_sysupgrade_partition
= "file-system",
905 /** Firmware layout for the C59v1 */
907 .id
= "ARCHER-C59-V1",
911 "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
912 "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
913 "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
914 "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
916 .soft_ver
= "soft_ver:1.0.0\n",
918 /* We're using a dynamic kernel/rootfs split here */
920 {"fs-uboot", 0x00000, 0x10000},
921 {"default-mac", 0x10000, 0x00200},
922 {"pin", 0x10200, 0x00200},
923 {"device-id", 0x10400, 0x00100},
924 {"product-info", 0x10500, 0x0fb00},
925 {"firmware", 0x20000, 0xe30000},
926 {"partition-table", 0xe50000, 0x10000},
927 {"soft-version", 0xe60000, 0x10000},
928 {"support-list", 0xe70000, 0x10000},
929 {"profile", 0xe80000, 0x10000},
930 {"default-config", 0xe90000, 0x10000},
931 {"user-config", 0xea0000, 0x40000},
932 {"usb-config", 0xee0000, 0x10000},
933 {"certificate", 0xef0000, 0x10000},
934 {"qos-db", 0xf00000, 0x40000},
935 {"log", 0xfe0000, 0x10000},
936 {"radio", 0xff0000, 0x10000},
940 .first_sysupgrade_partition
= "os-image",
941 .last_sysupgrade_partition
= "file-system",
944 /** Firmware layout for the C59v2 */
946 .id
= "ARCHER-C59-V2",
950 "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n"
951 "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n"
952 "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n",
954 .soft_ver
= "soft_ver:2.0.0 Build 20161206 rel.7303\n",
956 /** We're using a dynamic kernel/rootfs split here */
958 {"factory-boot", 0x00000, 0x20000},
959 {"fs-uboot", 0x20000, 0x10000},
960 {"default-mac", 0x30000, 0x00200},
961 {"pin", 0x30200, 0x00200},
962 {"device-id", 0x30400, 0x00100},
963 {"product-info", 0x30500, 0x0fb00},
964 {"firmware", 0x40000, 0xe10000},
965 {"partition-table", 0xe50000, 0x10000},
966 {"soft-version", 0xe60000, 0x10000},
967 {"support-list", 0xe70000, 0x10000},
968 {"profile", 0xe80000, 0x10000},
969 {"default-config", 0xe90000, 0x10000},
970 {"user-config", 0xea0000, 0x40000},
971 {"usb-config", 0xee0000, 0x10000},
972 {"certificate", 0xef0000, 0x10000},
973 {"extra-para", 0xf00000, 0x10000},
974 {"qos-db", 0xf10000, 0x30000},
975 {"log", 0xfe0000, 0x10000},
976 {"radio", 0xff0000, 0x10000},
980 .first_sysupgrade_partition
= "os-image",
981 .last_sysupgrade_partition
= "file-system",
984 /** Firmware layout for the Archer C6 v2 (EU/RU/JP) */
986 .id
= "ARCHER-C6-V2",
990 "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n"
991 "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n"
992 "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n",
994 .soft_ver
= "soft_ver:1.9.1\n",
997 {"fs-uboot", 0x00000, 0x20000},
998 {"default-mac", 0x20000, 0x00200},
999 {"pin", 0x20200, 0x00100},
1000 {"product-info", 0x20300, 0x00200},
1001 {"device-id", 0x20500, 0x0fb00},
1002 {"firmware", 0x30000, 0x7a9400},
1003 {"soft-version", 0x7d9400, 0x00100},
1004 {"extra-para", 0x7d9500, 0x00100},
1005 {"support-list", 0x7d9600, 0x00200},
1006 {"profile", 0x7d9800, 0x03000},
1007 {"default-config", 0x7dc800, 0x03000},
1008 {"partition-table", 0x7df800, 0x00800},
1009 {"user-config", 0x7e0000, 0x0c000},
1010 {"certificate", 0x7ec000, 0x04000},
1011 {"radio", 0x7f0000, 0x10000},
1015 .first_sysupgrade_partition
= "os-image",
1016 .last_sysupgrade_partition
= "file-system",
1019 /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */
1021 .id
= "ARCHER-C6-V2-US",
1025 "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n"
1026 "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n"
1027 "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n",
1029 .soft_ver
= "soft_ver:1.9.1\n",
1032 {"factory-boot", 0x00000, 0x20000},
1033 {"default-mac", 0x20000, 0x00200},
1034 {"pin", 0x20200, 0x00100},
1035 {"product-info", 0x20300, 0x00200},
1036 {"device-id", 0x20500, 0x0fb00},
1037 {"fs-uboot", 0x30000, 0x20000},
1038 {"firmware", 0x50000, 0xf89400},
1039 {"soft-version", 0xfd9400, 0x00100},
1040 {"extra-para", 0xfd9500, 0x00100},
1041 {"support-list", 0xfd9600, 0x00200},
1042 {"profile", 0xfd9800, 0x03000},
1043 {"default-config", 0xfdc800, 0x03000},
1044 {"partition-table", 0xfdf800, 0x00800},
1045 {"user-config", 0xfe0000, 0x0c000},
1046 {"certificate", 0xfec000, 0x04000},
1047 {"radio", 0xff0000, 0x10000},
1050 .first_sysupgrade_partition
= "os-image",
1051 .last_sysupgrade_partition
= "file-system",
1053 /** Firmware layout for the Archer C6 v3 */
1055 .id
= "ARCHER-C6-V3",
1059 "{product_name:Archer C6,product_ver:3.20,special_id:55530000}"
1060 "{product_name:Archer C6,product_ver:3.20,special_id:45550000}"
1061 "{product_name:Archer C6,product_ver:3.20,special_id:52550000}"
1062 "{product_name:Archer C6,product_ver:3.20,special_id:4A500000}"
1063 "{product_name:Archer C6,product_ver:3.20,special_id:4B520000}",
1065 .soft_ver
= "soft_ver:1.0.9\n",
1068 {"fs-uboot", 0x00000, 0x40000},
1069 {"firmware", 0x40000, 0xf60000},
1070 {"default-mac", 0xfa0000, 0x00200},
1071 {"pin", 0xfa0200, 0x00100},
1072 {"device-id", 0xfa0300, 0x00100},
1073 {"product-info", 0xfa0400, 0x0fc00},
1074 {"default-config", 0xfb0000, 0x08000},
1075 {"ap-def-config", 0xfb8000, 0x08000},
1076 {"user-config", 0xfc0000, 0x0a000},
1077 {"ag-config", 0xfca000, 0x04000},
1078 {"certificate", 0xfce000, 0x02000},
1079 {"ap-config", 0xfd0000, 0x06000},
1080 {"router-config", 0xfd6000, 0x06000},
1081 {"favicon", 0xfdc000, 0x02000},
1082 {"logo", 0xfde000, 0x02000},
1083 {"partition-table", 0xfe0000, 0x00800},
1084 {"soft-version", 0xfe0800, 0x00100},
1085 {"support-list", 0xfe0900, 0x00200},
1086 {"profile", 0xfe0b00, 0x03000},
1087 {"extra-para", 0xfe3b00, 0x00100},
1088 {"radio", 0xff0000, 0x10000},
1091 .first_sysupgrade_partition
= "os-image",
1092 .last_sysupgrade_partition
= "file-system",
1094 /** Firmware layout for the Archer A6 v3 */
1096 .id
= "ARCHER-A6-V3",
1100 "{product_name:Archer A6,product_ver:3.0.0,special_id:43410000}\n"
1101 "{product_name:Archer A6,product_ver:3.0.0,special_id:55530000}\n"
1102 "{product_name:Archer A6,product_ver:3.0.0,special_id:54570000}\n",
1104 .soft_ver
= "soft_ver:1.0.5\n",
1107 {"fs-uboot", 0x00000, 0x40000},
1108 {"firmware", 0x40000, 0xf60000},
1109 {"default-mac", 0xfa0000, 0x00200},
1110 {"pin", 0xfa0200, 0x00100},
1111 {"device-id", 0xfa0300, 0x00100},
1112 {"product-info", 0xfa0400, 0x0fc00},
1113 {"default-config", 0xfb0000, 0x08000},
1114 {"ap-def-config", 0xfb8000, 0x08000},
1115 {"user-config", 0xfc0000, 0x0a000},
1116 {"ag-config", 0xfca000, 0x04000},
1117 {"certificate", 0xfce000, 0x02000},
1118 {"ap-config", 0xfd0000, 0x06000},
1119 {"router-config", 0xfd6000, 0x06000},
1120 {"favicon", 0xfdc000, 0x02000},
1121 {"logo", 0xfde000, 0x02000},
1122 {"partition-table", 0xfe0000, 0x00800},
1123 {"soft-version", 0xfe0800, 0x00100},
1124 {"support-list", 0xfe0900, 0x00200},
1125 {"profile", 0xfe0b00, 0x03000},
1126 {"extra-para", 0xfe3b00, 0x00100},
1127 {"radio", 0xff0000, 0x10000},
1130 .first_sysupgrade_partition
= "os-image",
1131 .last_sysupgrade_partition
= "file-system",
1133 /** Firmware layout for the Archer C6U v1 */
1135 .id
= "ARCHER-C6U-V1",
1139 "{product_name:Archer C6U,product_ver:1.0.0,special_id:45550000}\n",
1141 .soft_ver
= "soft_ver:1.0.2\n",
1144 {"fs-uboot", 0x00000, 0x40000},
1145 {"firmware", 0x40000, 0xf60000},
1146 {"default-mac", 0xfa0000, 0x00200},
1147 {"pin", 0xfa0200, 0x00100},
1148 {"device-id", 0xfa0300, 0x00100},
1149 {"product-info", 0xfa0400, 0x0fc00},
1150 {"default-config", 0xfb0000, 0x08000},
1151 {"ap-def-config", 0xfb8000, 0x08000},
1152 {"user-config", 0xfc0000, 0x0c000},
1153 {"certificate", 0xfcc000, 0x04000},
1154 {"ap-config", 0xfd0000, 0x08000},
1155 {"router-config", 0xfd8000, 0x08000},
1156 {"partition-table", 0xfe0000, 0x00800},
1157 {"soft-version", 0xfe0800, 0x00100},
1158 {"support-list", 0xfe0900, 0x00200},
1159 {"profile", 0xfe0b00, 0x03000},
1160 {"extra-para", 0xfe3b00, 0x00100},
1161 {"radio", 0xff0000, 0x10000},
1164 .first_sysupgrade_partition
= "os-image",
1165 .last_sysupgrade_partition
= "file-system",
1167 /** Firmware layout for the C60v1 */
1169 .id
= "ARCHER-C60-V1",
1173 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1174 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1175 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1177 .soft_ver
= "soft_ver:1.0.0\n",
1180 {"fs-uboot", 0x00000, 0x10000},
1181 {"default-mac", 0x10000, 0x00200},
1182 {"pin", 0x10200, 0x00200},
1183 {"product-info", 0x10400, 0x00100},
1184 {"partition-table", 0x10500, 0x00800},
1185 {"soft-version", 0x11300, 0x00200},
1186 {"support-list", 0x11500, 0x00100},
1187 {"device-id", 0x11600, 0x00100},
1188 {"profile", 0x11700, 0x03900},
1189 {"default-config", 0x15000, 0x04000},
1190 {"user-config", 0x19000, 0x04000},
1191 {"firmware", 0x20000, 0x7c8000},
1192 {"certyficate", 0x7e8000, 0x08000},
1193 {"radio", 0x7f0000, 0x10000},
1197 .first_sysupgrade_partition
= "os-image",
1198 .last_sysupgrade_partition
= "file-system",
1201 /** Firmware layout for the C60v2 */
1203 .id
= "ARCHER-C60-V2",
1207 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1208 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1209 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1211 .soft_ver
= "soft_ver:2.0.0\n",
1214 {"factory-boot", 0x00000, 0x1fb00},
1215 {"default-mac", 0x1fb00, 0x00200},
1216 {"pin", 0x1fd00, 0x00100},
1217 {"product-info", 0x1fe00, 0x00100},
1218 {"device-id", 0x1ff00, 0x00100},
1219 {"fs-uboot", 0x20000, 0x10000},
1220 {"firmware", 0x30000, 0x7a0000},
1221 {"soft-version", 0x7d9500, 0x00100},
1222 {"support-list", 0x7d9600, 0x00100},
1223 {"extra-para", 0x7d9700, 0x00100},
1224 {"profile", 0x7d9800, 0x03000},
1225 {"default-config", 0x7dc800, 0x03000},
1226 {"partition-table", 0x7df800, 0x00800},
1227 {"user-config", 0x7e0000, 0x0c000},
1228 {"certificate", 0x7ec000, 0x04000},
1229 {"radio", 0x7f0000, 0x10000},
1233 .first_sysupgrade_partition
= "os-image",
1234 .last_sysupgrade_partition
= "file-system",
1237 /** Firmware layout for the C60v3 */
1239 .id
= "ARCHER-C60-V3",
1243 "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1244 "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1245 "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1247 .soft_ver
= "soft_ver:3.0.0\n",
1250 {"factory-boot", 0x00000, 0x1fb00},
1251 {"default-mac", 0x1fb00, 0x00200},
1252 {"pin", 0x1fd00, 0x00100},
1253 {"product-info", 0x1fe00, 0x00100},
1254 {"device-id", 0x1ff00, 0x00100},
1255 {"fs-uboot", 0x20000, 0x10000},
1256 {"firmware", 0x30000, 0x7a0000},
1257 {"soft-version", 0x7d9500, 0x00100},
1258 {"support-list", 0x7d9600, 0x00100},
1259 {"extra-para", 0x7d9700, 0x00100},
1260 {"profile", 0x7d9800, 0x03000},
1261 {"default-config", 0x7dc800, 0x03000},
1262 {"partition-table", 0x7df800, 0x00800},
1263 {"user-config", 0x7e0000, 0x0c000},
1264 {"certificate", 0x7ec000, 0x04000},
1265 {"radio", 0x7f0000, 0x10000},
1269 .first_sysupgrade_partition
= "os-image",
1270 .last_sysupgrade_partition
= "file-system",
1273 /** Firmware layout for the C5 */
1275 .id
= "ARCHER-C5-V2",
1279 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1280 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1281 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1286 {"fs-uboot", 0x00000, 0x40000},
1287 {"os-image", 0x40000, 0x200000},
1288 {"file-system", 0x240000, 0xc00000},
1289 {"default-mac", 0xe40000, 0x00200},
1290 {"pin", 0xe40200, 0x00200},
1291 {"product-info", 0xe40400, 0x00200},
1292 {"partition-table", 0xe50000, 0x10000},
1293 {"soft-version", 0xe60000, 0x00200},
1294 {"support-list", 0xe61000, 0x0f000},
1295 {"profile", 0xe70000, 0x10000},
1296 {"default-config", 0xe80000, 0x10000},
1297 {"user-config", 0xe90000, 0x50000},
1298 {"log", 0xee0000, 0x100000},
1299 {"radio_bk", 0xfe0000, 0x10000},
1300 {"radio", 0xff0000, 0x10000},
1304 .first_sysupgrade_partition
= "os-image",
1305 .last_sysupgrade_partition
= "file-system"
1308 /** Firmware layout for the C7 */
1310 .id
= "ARCHER-C7-V4",
1313 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1314 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1315 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1316 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1317 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1318 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1319 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1320 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1321 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1322 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1324 .soft_ver
= "soft_ver:1.0.0\n",
1326 /* We're using a dynamic kernel/rootfs split here */
1328 {"factory-boot", 0x00000, 0x20000},
1329 {"fs-uboot", 0x20000, 0x20000},
1330 {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
1331 /* Stock: name file-system base 0x160000 size 0xda0000 */
1332 {"default-mac", 0xf00000, 0x00200},
1333 {"pin", 0xf00200, 0x00200},
1334 {"device-id", 0xf00400, 0x00100},
1335 {"product-info", 0xf00500, 0x0fb00},
1336 {"soft-version", 0xf10000, 0x00100},
1337 {"extra-para", 0xf11000, 0x01000},
1338 {"support-list", 0xf12000, 0x0a000},
1339 {"profile", 0xf1c000, 0x04000},
1340 {"default-config", 0xf20000, 0x10000},
1341 {"user-config", 0xf30000, 0x40000},
1342 {"qos-db", 0xf70000, 0x40000},
1343 {"certificate", 0xfb0000, 0x10000},
1344 {"partition-table", 0xfc0000, 0x10000},
1345 {"log", 0xfd0000, 0x20000},
1346 {"radio", 0xff0000, 0x10000},
1350 .first_sysupgrade_partition
= "os-image",
1351 .last_sysupgrade_partition
= "file-system",
1354 /** Firmware layout for the C7 v5*/
1356 .id
= "ARCHER-C7-V5",
1359 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1360 "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1361 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1362 "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1363 "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1364 "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1365 "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1366 "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1369 .soft_ver
= "soft_ver:7.0.0\n",
1371 /* We're using a dynamic kernel/rootfs split here */
1373 {"factory-boot", 0x00000, 0x20000},
1374 {"fs-uboot", 0x20000, 0x20000},
1375 {"partition-table", 0x40000, 0x10000},
1376 {"radio", 0x50000, 0x10000},
1377 {"default-mac", 0x60000, 0x00200},
1378 {"pin", 0x60200, 0x00200},
1379 {"device-id", 0x60400, 0x00100},
1380 {"product-info", 0x60500, 0x0fb00},
1381 {"soft-version", 0x70000, 0x01000},
1382 {"extra-para", 0x71000, 0x01000},
1383 {"support-list", 0x72000, 0x0a000},
1384 {"profile", 0x7c000, 0x04000},
1385 {"user-config", 0x80000, 0x40000},
1388 {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */
1389 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1391 {"log", 0xfc0000, 0x20000},
1392 {"certificate", 0xfe0000, 0x10000},
1393 {"default-config", 0xff0000, 0x10000},
1398 .first_sysupgrade_partition
= "os-image",
1399 .last_sysupgrade_partition
= "file-system",
1402 /** Firmware layout for the C9 */
1408 "{product_name:ArcherC9,"
1409 "product_ver:1.0.0,"
1410 "special_id:00000000}\n",
1415 {"fs-uboot", 0x00000, 0x40000},
1416 {"os-image", 0x40000, 0x200000},
1417 {"file-system", 0x240000, 0xc00000},
1418 {"default-mac", 0xe40000, 0x00200},
1419 {"pin", 0xe40200, 0x00200},
1420 {"product-info", 0xe40400, 0x00200},
1421 {"partition-table", 0xe50000, 0x10000},
1422 {"soft-version", 0xe60000, 0x00200},
1423 {"support-list", 0xe61000, 0x0f000},
1424 {"profile", 0xe70000, 0x10000},
1425 {"default-config", 0xe80000, 0x10000},
1426 {"user-config", 0xe90000, 0x50000},
1427 {"log", 0xee0000, 0x100000},
1428 {"radio_bk", 0xfe0000, 0x10000},
1429 {"radio", 0xff0000, 0x10000},
1433 .first_sysupgrade_partition
= "os-image",
1434 .last_sysupgrade_partition
= "file-system"
1437 /** Firmware layout for the EAP120 */
1440 .vendor
= "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1443 "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1448 {"fs-uboot", 0x00000, 0x20000},
1449 {"partition-table", 0x20000, 0x02000},
1450 {"default-mac", 0x30000, 0x00020},
1451 {"support-list", 0x31000, 0x00100},
1452 {"product-info", 0x31100, 0x00100},
1453 {"soft-version", 0x32000, 0x00100},
1454 {"os-image", 0x40000, 0x180000},
1455 {"file-system", 0x1c0000, 0x600000},
1456 {"user-config", 0x7c0000, 0x10000},
1457 {"backup-config", 0x7d0000, 0x10000},
1458 {"log", 0x7e0000, 0x10000},
1459 {"radio", 0x7f0000, 0x10000},
1463 .first_sysupgrade_partition
= "os-image",
1464 .last_sysupgrade_partition
= "file-system"
1467 /** Firmware layout for the EAP225-Outdoor v1 */
1469 .id
= "EAP225-OUTDOOR-V1",
1472 "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1473 .part_trail
= PART_TRAIL_NONE
,
1475 .soft_ver_compat_level
= 1,
1478 {"fs-uboot", 0x00000, 0x20000},
1479 {"partition-table", 0x20000, 0x02000},
1480 {"default-mac", 0x30000, 0x01000},
1481 {"support-list", 0x31000, 0x00100},
1482 {"product-info", 0x31100, 0x00400},
1483 {"soft-version", 0x32000, 0x00100},
1484 {"firmware", 0x40000, 0xd80000},
1485 {"user-config", 0xdc0000, 0x30000},
1486 {"mutil-log", 0xf30000, 0x80000},
1487 {"oops", 0xfb0000, 0x40000},
1488 {"radio", 0xff0000, 0x10000},
1492 .first_sysupgrade_partition
= "os-image",
1493 .last_sysupgrade_partition
= "file-system"
1496 /** Firmware layout for the EAP225 v3 */
1501 "EAP225(TP-Link|UN|AC1350-D):3.0\r\n",
1502 .part_trail
= PART_TRAIL_NONE
,
1504 .soft_ver_compat_level
= 1,
1507 {"fs-uboot", 0x00000, 0x20000},
1508 {"partition-table", 0x20000, 0x02000},
1509 {"default-mac", 0x30000, 0x01000},
1510 {"support-list", 0x31000, 0x00100},
1511 {"product-info", 0x31100, 0x00400},
1512 {"soft-version", 0x32000, 0x00100},
1513 {"firmware", 0x40000, 0xd80000},
1514 {"user-config", 0xdc0000, 0x30000},
1515 {"mutil-log", 0xf30000, 0x80000},
1516 {"oops", 0xfb0000, 0x40000},
1517 {"radio", 0xff0000, 0x10000},
1521 .first_sysupgrade_partition
= "os-image",
1522 .last_sysupgrade_partition
= "file-system"
1525 /** Firmware layout for the EAP225-Wall v2 */
1527 .id
= "EAP225-WALL-V2",
1530 "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
1531 .part_trail
= PART_TRAIL_NONE
,
1533 .soft_ver_compat_level
= 1,
1536 {"fs-uboot", 0x00000, 0x20000},
1537 {"partition-table", 0x20000, 0x02000},
1538 {"default-mac", 0x30000, 0x01000},
1539 {"support-list", 0x31000, 0x00100},
1540 {"product-info", 0x31100, 0x00400},
1541 {"soft-version", 0x32000, 0x00100},
1542 {"firmware", 0x40000, 0xd80000},
1543 {"user-config", 0xdc0000, 0x30000},
1544 {"mutil-log", 0xf30000, 0x80000},
1545 {"oops", 0xfb0000, 0x40000},
1546 {"radio", 0xff0000, 0x10000},
1550 .first_sysupgrade_partition
= "os-image",
1551 .last_sysupgrade_partition
= "file-system"
1554 /** Firmware layout for the EAP235-Wall v1 */
1556 .id
= "EAP235-WALL-V1",
1559 "EAP235-Wall(TP-Link|UN|AC1200-D):1.0\r\n",
1560 .part_trail
= PART_TRAIL_NONE
,
1562 .soft_ver_compat_level
= 1,
1565 {"fs-uboot", 0x00000, 0x80000},
1566 {"partition-table", 0x80000, 0x02000},
1567 {"default-mac", 0x90000, 0x01000},
1568 {"support-list", 0x91000, 0x00100},
1569 {"product-info", 0x91100, 0x00400},
1570 {"soft-version", 0x92000, 0x00100},
1571 {"firmware", 0xa0000, 0xd20000},
1572 {"user-config", 0xdc0000, 0x30000},
1573 {"mutil-log", 0xf30000, 0x80000},
1574 {"oops", 0xfb0000, 0x40000},
1575 {"radio", 0xff0000, 0x10000},
1579 .first_sysupgrade_partition
= "os-image",
1580 .last_sysupgrade_partition
= "file-system"
1583 /** Firmware layout for the EAP245 v1 */
1588 "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
1589 .part_trail
= PART_TRAIL_NONE
,
1593 {"fs-uboot", 0x00000, 0x20000},
1594 {"partition-table", 0x20000, 0x02000},
1595 {"default-mac", 0x30000, 0x01000},
1596 {"support-list", 0x31000, 0x00100},
1597 {"product-info", 0x31100, 0x00400},
1598 {"soft-version", 0x32000, 0x00100},
1599 {"firmware", 0x40000, 0xd80000},
1600 {"user-config", 0xdc0000, 0x30000},
1601 {"radio", 0xff0000, 0x10000},
1605 .first_sysupgrade_partition
= "os-image",
1606 .last_sysupgrade_partition
= "file-system"
1609 /** Firmware layout for the EAP245 v3 */
1614 "EAP245(TP-Link|UN|AC1750-D):3.0\r\n",
1615 .part_trail
= PART_TRAIL_NONE
,
1617 .soft_ver_compat_level
= 1,
1619 /** Firmware partition with dynamic kernel/rootfs split */
1621 {"factroy-boot", 0x00000, 0x40000},
1622 {"fs-uboot", 0x40000, 0x40000},
1623 {"partition-table", 0x80000, 0x10000},
1624 {"default-mac", 0x90000, 0x01000},
1625 {"support-list", 0x91000, 0x00100},
1626 {"product-info", 0x91100, 0x00400},
1627 {"soft-version", 0x92000, 0x00100},
1628 {"radio", 0xa0000, 0x10000},
1629 {"extra-para", 0xb0000, 0x10000},
1630 {"firmware", 0xc0000, 0xe40000},
1631 {"config", 0xf00000, 0x30000},
1632 {"mutil-log", 0xf30000, 0x80000},
1633 {"oops", 0xfb0000, 0x40000},
1637 .first_sysupgrade_partition
= "os-image",
1638 .last_sysupgrade_partition
= "file-system"
1641 /** Firmware layout for the TL-WA850RE v2 */
1643 .id
= "TLWA850REV2",
1647 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
1648 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
1649 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
1650 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
1651 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
1652 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
1653 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
1654 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
1655 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
1656 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
1661 576KB were moved from file-system to os-image
1662 in comparison to the stock image
1665 {"fs-uboot", 0x00000, 0x20000},
1666 {"firmware", 0x20000, 0x390000},
1667 {"partition-table", 0x3b0000, 0x02000},
1668 {"default-mac", 0x3c0000, 0x00020},
1669 {"pin", 0x3c0100, 0x00020},
1670 {"product-info", 0x3c1000, 0x01000},
1671 {"soft-version", 0x3c2000, 0x00100},
1672 {"support-list", 0x3c3000, 0x01000},
1673 {"profile", 0x3c4000, 0x08000},
1674 {"user-config", 0x3d0000, 0x10000},
1675 {"default-config", 0x3e0000, 0x10000},
1676 {"radio", 0x3f0000, 0x10000},
1680 .first_sysupgrade_partition
= "os-image",
1681 .last_sysupgrade_partition
= "file-system"
1684 /** Firmware layout for the TL-WA855RE v1 */
1686 .id
= "TLWA855REV1",
1690 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
1691 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
1692 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
1693 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
1694 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
1695 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
1696 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
1697 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
1698 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
1703 {"fs-uboot", 0x00000, 0x20000},
1704 {"os-image", 0x20000, 0x150000},
1705 {"file-system", 0x170000, 0x240000},
1706 {"partition-table", 0x3b0000, 0x02000},
1707 {"default-mac", 0x3c0000, 0x00020},
1708 {"pin", 0x3c0100, 0x00020},
1709 {"product-info", 0x3c1000, 0x01000},
1710 {"soft-version", 0x3c2000, 0x00100},
1711 {"support-list", 0x3c3000, 0x01000},
1712 {"profile", 0x3c4000, 0x08000},
1713 {"user-config", 0x3d0000, 0x10000},
1714 {"default-config", 0x3e0000, 0x10000},
1715 {"radio", 0x3f0000, 0x10000},
1719 .first_sysupgrade_partition
= "os-image",
1720 .last_sysupgrade_partition
= "file-system"
1723 /** Firmware layout for the TL-WPA8630P v2 (EU)*/
1725 .id
= "TL-WPA8630P-V2.0-EU",
1729 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
1734 {"factory-uboot", 0x00000, 0x20000},
1735 {"fs-uboot", 0x20000, 0x20000},
1736 {"firmware", 0x40000, 0x5e0000},
1737 {"partition-table", 0x620000, 0x02000},
1738 {"default-mac", 0x630000, 0x00020},
1739 {"pin", 0x630100, 0x00020},
1740 {"device-id", 0x630200, 0x00030},
1741 {"product-info", 0x631100, 0x01000},
1742 {"extra-para", 0x632100, 0x01000},
1743 {"soft-version", 0x640000, 0x01000},
1744 {"support-list", 0x641000, 0x01000},
1745 {"profile", 0x642000, 0x08000},
1746 {"user-config", 0x650000, 0x10000},
1747 {"default-config", 0x660000, 0x10000},
1748 {"default-nvm", 0x670000, 0xc0000},
1749 {"default-pib", 0x730000, 0x40000},
1750 {"radio", 0x7f0000, 0x10000},
1754 .first_sysupgrade_partition
= "os-image",
1755 .last_sysupgrade_partition
= "file-system"
1758 /** Firmware layout for the TL-WPA8630P v2 (INT)*/
1760 .id
= "TL-WPA8630P-V2-INT",
1764 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
1765 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
1766 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
1771 {"factory-uboot", 0x00000, 0x20000},
1772 {"fs-uboot", 0x20000, 0x20000},
1773 {"firmware", 0x40000, 0x5e0000},
1774 {"partition-table", 0x620000, 0x02000},
1775 {"extra-para", 0x632100, 0x01000},
1776 {"soft-version", 0x640000, 0x01000},
1777 {"support-list", 0x641000, 0x01000},
1778 {"profile", 0x642000, 0x08000},
1779 {"user-config", 0x650000, 0x10000},
1780 {"default-config", 0x660000, 0x10000},
1781 {"default-nvm", 0x670000, 0xc0000},
1782 {"default-pib", 0x730000, 0x40000},
1783 {"default-mac", 0x7e0000, 0x00020},
1784 {"pin", 0x7e0100, 0x00020},
1785 {"device-id", 0x7e0200, 0x00030},
1786 {"product-info", 0x7e1100, 0x01000},
1787 {"radio", 0x7f0000, 0x10000},
1791 .first_sysupgrade_partition
= "os-image",
1792 .last_sysupgrade_partition
= "file-system"
1795 /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
1797 .id
= "TL-WPA8630P-V2.1-EU",
1801 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
1806 {"factory-uboot", 0x00000, 0x20000},
1807 {"fs-uboot", 0x20000, 0x20000},
1808 {"firmware", 0x40000, 0x5e0000},
1809 {"extra-para", 0x680000, 0x01000},
1810 {"product-info", 0x690000, 0x01000},
1811 {"partition-table", 0x6a0000, 0x02000},
1812 {"soft-version", 0x6b0000, 0x01000},
1813 {"support-list", 0x6b1000, 0x01000},
1814 {"profile", 0x6b2000, 0x08000},
1815 {"user-config", 0x6c0000, 0x10000},
1816 {"default-config", 0x6d0000, 0x10000},
1817 {"default-nvm", 0x6e0000, 0xc0000},
1818 {"default-pib", 0x7a0000, 0x40000},
1819 {"default-mac", 0x7e0000, 0x00020},
1820 {"pin", 0x7e0100, 0x00020},
1821 {"device-id", 0x7e0200, 0x00030},
1822 {"radio", 0x7f0000, 0x10000},
1826 .first_sysupgrade_partition
= "os-image",
1827 .last_sysupgrade_partition
= "file-system"
1830 /** Firmware layout for the TL-WR1043 v5 */
1832 .id
= "TLWR1043NV5",
1836 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
1837 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
1839 .soft_ver
= "soft_ver:1.0.0\n",
1841 {"factory-boot", 0x00000, 0x20000},
1842 {"fs-uboot", 0x20000, 0x20000},
1843 {"firmware", 0x40000, 0xec0000},
1844 {"default-mac", 0xf00000, 0x00200},
1845 {"pin", 0xf00200, 0x00200},
1846 {"device-id", 0xf00400, 0x00100},
1847 {"product-info", 0xf00500, 0x0fb00},
1848 {"soft-version", 0xf10000, 0x01000},
1849 {"extra-para", 0xf11000, 0x01000},
1850 {"support-list", 0xf12000, 0x0a000},
1851 {"profile", 0xf1c000, 0x04000},
1852 {"default-config", 0xf20000, 0x10000},
1853 {"user-config", 0xf30000, 0x40000},
1854 {"qos-db", 0xf70000, 0x40000},
1855 {"certificate", 0xfb0000, 0x10000},
1856 {"partition-table", 0xfc0000, 0x10000},
1857 {"log", 0xfd0000, 0x20000},
1858 {"radio", 0xff0000, 0x10000},
1861 .first_sysupgrade_partition
= "os-image",
1862 .last_sysupgrade_partition
= "file-system"
1865 /** Firmware layout for the TL-WR1043 v4 */
1867 .id
= "TLWR1043NDV4",
1871 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
1875 /* We're using a dynamic kernel/rootfs split here */
1877 {"fs-uboot", 0x00000, 0x20000},
1878 {"firmware", 0x20000, 0xf30000},
1879 {"default-mac", 0xf50000, 0x00200},
1880 {"pin", 0xf50200, 0x00200},
1881 {"product-info", 0xf50400, 0x0fc00},
1882 {"soft-version", 0xf60000, 0x0b000},
1883 {"support-list", 0xf6b000, 0x04000},
1884 {"profile", 0xf70000, 0x04000},
1885 {"default-config", 0xf74000, 0x0b000},
1886 {"user-config", 0xf80000, 0x40000},
1887 {"partition-table", 0xfc0000, 0x10000},
1888 {"log", 0xfd0000, 0x20000},
1889 {"radio", 0xff0000, 0x10000},
1893 .first_sysupgrade_partition
= "os-image",
1894 .last_sysupgrade_partition
= "file-system"
1897 /** Firmware layout for the TL-WR902AC v1 */
1899 .id
= "TL-WR902AC-V1",
1903 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
1904 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
1909 384KB were moved from file-system to os-image
1910 in comparison to the stock image
1913 {"fs-uboot", 0x00000, 0x20000},
1914 {"firmware", 0x20000, 0x730000},
1915 {"default-mac", 0x750000, 0x00200},
1916 {"pin", 0x750200, 0x00200},
1917 {"product-info", 0x750400, 0x0fc00},
1918 {"soft-version", 0x760000, 0x0b000},
1919 {"support-list", 0x76b000, 0x04000},
1920 {"profile", 0x770000, 0x04000},
1921 {"default-config", 0x774000, 0x0b000},
1922 {"user-config", 0x780000, 0x40000},
1923 {"partition-table", 0x7c0000, 0x10000},
1924 {"log", 0x7d0000, 0x20000},
1925 {"radio", 0x7f0000, 0x10000},
1929 .first_sysupgrade_partition
= "os-image",
1930 .last_sysupgrade_partition
= "file-system",
1933 /** Firmware layout for the TL-WR941HP v1 */
1935 .id
= "TL-WR941HP-V1",
1939 "{product_name:TL-WR941HP,product_ver:1.0.0,special_id:00000000}\n",
1944 {"fs-uboot", 0x00000, 0x20000},
1945 {"firmware", 0x20000, 0x730000},
1946 {"default-mac", 0x750000, 0x00200},
1947 {"pin", 0x750200, 0x00200},
1948 {"product-info", 0x750400, 0x0fc00},
1949 {"soft-version", 0x760000, 0x0b000},
1950 {"support-list", 0x76b000, 0x04000},
1951 {"profile", 0x770000, 0x04000},
1952 {"default-config", 0x774000, 0x0b000},
1953 {"user-config", 0x780000, 0x40000},
1954 {"partition-table", 0x7c0000, 0x10000},
1955 {"log", 0x7d0000, 0x20000},
1956 {"radio", 0x7f0000, 0x10000},
1960 .first_sysupgrade_partition
= "os-image",
1961 .last_sysupgrade_partition
= "file-system",
1964 /** Firmware layout for the TL-WR942N V1 */
1970 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
1971 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
1976 {"fs-uboot", 0x00000, 0x20000},
1977 {"firmware", 0x20000, 0xe20000},
1978 {"default-mac", 0xe40000, 0x00200},
1979 {"pin", 0xe40200, 0x00200},
1980 {"product-info", 0xe40400, 0x0fc00},
1981 {"partition-table", 0xe50000, 0x10000},
1982 {"soft-version", 0xe60000, 0x10000},
1983 {"support-list", 0xe70000, 0x10000},
1984 {"profile", 0xe80000, 0x10000},
1985 {"default-config", 0xe90000, 0x10000},
1986 {"user-config", 0xea0000, 0x40000},
1987 {"qos-db", 0xee0000, 0x40000},
1988 {"certificate", 0xf20000, 0x10000},
1989 {"usb-config", 0xfb0000, 0x10000},
1990 {"log", 0xfc0000, 0x20000},
1991 {"radio-bk", 0xfe0000, 0x10000},
1992 {"radio", 0xff0000, 0x10000},
1996 .first_sysupgrade_partition
= "os-image",
1997 .last_sysupgrade_partition
= "file-system",
2000 /** Firmware layout for the RE200 v2 */
2006 "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
2007 "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
2008 "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
2009 "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
2010 "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
2011 "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
2012 "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
2013 "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
2014 "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
2015 "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
2016 "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
2017 "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
2018 "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
2023 {"fs-uboot", 0x00000, 0x20000},
2024 {"firmware", 0x20000, 0x7a0000},
2025 {"partition-table", 0x7c0000, 0x02000},
2026 {"default-mac", 0x7c2000, 0x00020},
2027 {"pin", 0x7c2100, 0x00020},
2028 {"product-info", 0x7c3100, 0x01000},
2029 {"soft-version", 0x7c4200, 0x01000},
2030 {"support-list", 0x7c5200, 0x01000},
2031 {"profile", 0x7c6200, 0x08000},
2032 {"config-info", 0x7ce200, 0x00400},
2033 {"user-config", 0x7d0000, 0x10000},
2034 {"default-config", 0x7e0000, 0x10000},
2035 {"radio", 0x7f0000, 0x10000},
2039 .first_sysupgrade_partition
= "os-image",
2040 .last_sysupgrade_partition
= "file-system"
2043 /** Firmware layout for the RE200 v3 */
2049 "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
2050 "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
2051 "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
2052 "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
2053 "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
2054 "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
2055 "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
2056 "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
2057 "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
2058 "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
2059 "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
2060 "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
2061 "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
2062 "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
2067 {"fs-uboot", 0x00000, 0x20000},
2068 {"firmware", 0x20000, 0x7a0000},
2069 {"partition-table", 0x7c0000, 0x02000},
2070 {"default-mac", 0x7c2000, 0x00020},
2071 {"pin", 0x7c2100, 0x00020},
2072 {"product-info", 0x7c3100, 0x01000},
2073 {"soft-version", 0x7c4200, 0x01000},
2074 {"support-list", 0x7c5200, 0x01000},
2075 {"profile", 0x7c6200, 0x08000},
2076 {"config-info", 0x7ce200, 0x00400},
2077 {"user-config", 0x7d0000, 0x10000},
2078 {"default-config", 0x7e0000, 0x10000},
2079 {"radio", 0x7f0000, 0x10000},
2083 .first_sysupgrade_partition
= "os-image",
2084 .last_sysupgrade_partition
= "file-system"
2087 /** Firmware layout for the RE200 v4 */
2093 "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
2094 "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
2095 "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
2096 "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
2097 "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
2098 "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
2099 "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
2100 "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
2101 "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
2102 "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
2103 "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
2104 "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
2105 "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
2106 "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
2108 .soft_ver
= "soft_ver:1.1.0\n",
2111 {"fs-uboot", 0x00000, 0x20000},
2112 {"firmware", 0x20000, 0x7a0000},
2113 {"partition-table", 0x7c0000, 0x02000},
2114 {"default-mac", 0x7c2000, 0x00020},
2115 {"pin", 0x7c2100, 0x00020},
2116 {"product-info", 0x7c3100, 0x01000},
2117 {"soft-version", 0x7c4200, 0x01000},
2118 {"support-list", 0x7c5200, 0x01000},
2119 {"profile", 0x7c6200, 0x08000},
2120 {"config-info", 0x7ce200, 0x00400},
2121 {"user-config", 0x7d0000, 0x10000},
2122 {"default-config", 0x7e0000, 0x10000},
2123 {"radio", 0x7f0000, 0x10000},
2127 .first_sysupgrade_partition
= "os-image",
2128 .last_sysupgrade_partition
= "file-system"
2131 /** Firmware layout for the RE220 v2 */
2137 "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
2138 "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
2139 "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
2140 "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
2141 "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
2142 "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
2143 "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
2144 "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
2145 "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
2146 "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
2147 "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
2148 "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
2149 "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
2154 {"fs-uboot", 0x00000, 0x20000},
2155 {"firmware", 0x20000, 0x7a0000},
2156 {"partition-table", 0x7c0000, 0x02000},
2157 {"default-mac", 0x7c2000, 0x00020},
2158 {"pin", 0x7c2100, 0x00020},
2159 {"product-info", 0x7c3100, 0x01000},
2160 {"soft-version", 0x7c4200, 0x01000},
2161 {"support-list", 0x7c5200, 0x01000},
2162 {"profile", 0x7c6200, 0x08000},
2163 {"config-info", 0x7ce200, 0x00400},
2164 {"user-config", 0x7d0000, 0x10000},
2165 {"default-config", 0x7e0000, 0x10000},
2166 {"radio", 0x7f0000, 0x10000},
2170 .first_sysupgrade_partition
= "os-image",
2171 .last_sysupgrade_partition
= "file-system"
2174 /** Firmware layout for the RE305 v1 */
2180 "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
2181 "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
2182 "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
2183 "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
2184 "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
2185 "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
2186 "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
2191 {"fs-uboot", 0x00000, 0x20000},
2192 {"firmware", 0x20000, 0x5e0000},
2193 {"partition-table", 0x600000, 0x02000},
2194 {"default-mac", 0x610000, 0x00020},
2195 {"pin", 0x610100, 0x00020},
2196 {"product-info", 0x611100, 0x01000},
2197 {"soft-version", 0x620000, 0x01000},
2198 {"support-list", 0x621000, 0x01000},
2199 {"profile", 0x622000, 0x08000},
2200 {"user-config", 0x630000, 0x10000},
2201 {"default-config", 0x640000, 0x10000},
2202 {"radio", 0x7f0000, 0x10000},
2206 .first_sysupgrade_partition
= "os-image",
2207 .last_sysupgrade_partition
= "file-system"
2210 /** Firmware layout for the RE350 v1 */
2216 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
2217 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
2218 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
2219 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
2220 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
2221 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2222 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2226 /** We're using a dynamic kernel/rootfs split here */
2228 {"fs-uboot", 0x00000, 0x20000},
2229 {"firmware", 0x20000, 0x5e0000},
2230 {"partition-table", 0x600000, 0x02000},
2231 {"default-mac", 0x610000, 0x00020},
2232 {"pin", 0x610100, 0x00020},
2233 {"product-info", 0x611100, 0x01000},
2234 {"soft-version", 0x620000, 0x01000},
2235 {"support-list", 0x621000, 0x01000},
2236 {"profile", 0x622000, 0x08000},
2237 {"user-config", 0x630000, 0x10000},
2238 {"default-config", 0x640000, 0x10000},
2239 {"radio", 0x7f0000, 0x10000},
2243 .first_sysupgrade_partition
= "os-image",
2244 .last_sysupgrade_partition
= "file-system"
2247 /** Firmware layout for the RE350K v1 */
2253 "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2257 /** We're using a dynamic kernel/rootfs split here */
2259 {"fs-uboot", 0x00000, 0x20000},
2260 {"firmware", 0x20000, 0xd70000},
2261 {"partition-table", 0xd90000, 0x02000},
2262 {"default-mac", 0xda0000, 0x00020},
2263 {"pin", 0xda0100, 0x00020},
2264 {"product-info", 0xda1100, 0x01000},
2265 {"soft-version", 0xdb0000, 0x01000},
2266 {"support-list", 0xdb1000, 0x01000},
2267 {"profile", 0xdb2000, 0x08000},
2268 {"user-config", 0xdc0000, 0x10000},
2269 {"default-config", 0xdd0000, 0x10000},
2270 {"device-id", 0xde0000, 0x00108},
2271 {"radio", 0xff0000, 0x10000},
2275 .first_sysupgrade_partition
= "os-image",
2276 .last_sysupgrade_partition
= "file-system"
2279 /** Firmware layout for the RE355 */
2285 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2286 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2287 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2288 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2289 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2290 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2291 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2292 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2296 /* We're using a dynamic kernel/rootfs split here */
2298 {"fs-uboot", 0x00000, 0x20000},
2299 {"firmware", 0x20000, 0x5e0000},
2300 {"partition-table", 0x600000, 0x02000},
2301 {"default-mac", 0x610000, 0x00020},
2302 {"pin", 0x610100, 0x00020},
2303 {"product-info", 0x611100, 0x01000},
2304 {"soft-version", 0x620000, 0x01000},
2305 {"support-list", 0x621000, 0x01000},
2306 {"profile", 0x622000, 0x08000},
2307 {"user-config", 0x630000, 0x10000},
2308 {"default-config", 0x640000, 0x10000},
2309 {"radio", 0x7f0000, 0x10000},
2313 .first_sysupgrade_partition
= "os-image",
2314 .last_sysupgrade_partition
= "file-system"
2317 /** Firmware layout for the RE450 */
2323 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2324 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
2325 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
2326 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
2327 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
2328 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
2329 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
2330 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
2334 /** We're using a dynamic kernel/rootfs split here */
2336 {"fs-uboot", 0x00000, 0x20000},
2337 {"firmware", 0x20000, 0x5e0000},
2338 {"partition-table", 0x600000, 0x02000},
2339 {"default-mac", 0x610000, 0x00020},
2340 {"pin", 0x610100, 0x00020},
2341 {"product-info", 0x611100, 0x01000},
2342 {"soft-version", 0x620000, 0x01000},
2343 {"support-list", 0x621000, 0x01000},
2344 {"profile", 0x622000, 0x08000},
2345 {"user-config", 0x630000, 0x10000},
2346 {"default-config", 0x640000, 0x10000},
2347 {"radio", 0x7f0000, 0x10000},
2351 .first_sysupgrade_partition
= "os-image",
2352 .last_sysupgrade_partition
= "file-system"
2355 /** Firmware layout for the RE450 v2 */
2361 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
2362 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
2363 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
2364 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
2365 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
2366 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
2367 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
2368 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
2369 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
2373 /* We're using a dynamic kernel/rootfs split here */
2375 {"fs-uboot", 0x00000, 0x20000},
2376 {"firmware", 0x20000, 0x5e0000},
2377 {"partition-table", 0x600000, 0x02000},
2378 {"default-mac", 0x610000, 0x00020},
2379 {"pin", 0x610100, 0x00020},
2380 {"product-info", 0x611100, 0x01000},
2381 {"soft-version", 0x620000, 0x01000},
2382 {"support-list", 0x621000, 0x01000},
2383 {"profile", 0x622000, 0x08000},
2384 {"user-config", 0x630000, 0x10000},
2385 {"default-config", 0x640000, 0x10000},
2386 {"radio", 0x7f0000, 0x10000},
2390 .first_sysupgrade_partition
= "os-image",
2391 .last_sysupgrade_partition
= "file-system"
2394 /** Firmware layout for the RE450 v3 */
2400 "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
2401 "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
2402 "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
2403 "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
2404 "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
2405 "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
2406 "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
2407 "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
2408 "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
2412 /* We're using a dynamic kernel/rootfs split here */
2414 {"fs-uboot", 0x00000, 0x20000},
2415 {"default-mac", 0x20000, 0x00020},
2416 {"pin", 0x20020, 0x00020},
2417 {"product-info", 0x21000, 0x01000},
2418 {"partition-table", 0x22000, 0x02000},
2419 {"soft-version", 0x24000, 0x01000},
2420 {"support-list", 0x25000, 0x01000},
2421 {"profile", 0x26000, 0x08000},
2422 {"user-config", 0x2e000, 0x10000},
2423 {"default-config", 0x3e000, 0x10000},
2424 {"config-info", 0x4e000, 0x00400},
2425 {"firmware", 0x50000, 0x7a0000},
2426 {"radio", 0x7f0000, 0x10000},
2430 .first_sysupgrade_partition
= "os-image",
2431 .last_sysupgrade_partition
= "file-system"
2434 /** Firmware layout for the RE455 v1 */
2440 "{product_name:RE455,product_ver:1.0.0,special_id:00000000}\r\n"
2441 "{product_name:RE455,product_ver:1.0.0,special_id:55530000}\r\n"
2442 "{product_name:RE455,product_ver:1.0.0,special_id:45550000}\r\n"
2443 "{product_name:RE455,product_ver:1.0.0,special_id:4A500000}\r\n"
2444 "{product_name:RE455,product_ver:1.0.0,special_id:43410000}\r\n"
2445 "{product_name:RE455,product_ver:1.0.0,special_id:41550000}\r\n"
2446 "{product_name:RE455,product_ver:1.0.0,special_id:41530000}\r\n"
2447 "{product_name:RE455,product_ver:1.0.0,special_id:4B520000}\r\n"
2448 "{product_name:RE455,product_ver:1.0.0,special_id:42520000}\r\n",
2452 /* We're using a dynamic kernel/rootfs split here */
2454 {"fs-uboot", 0x00000, 0x20000},
2455 {"default-mac", 0x20000, 0x00020},
2456 {"pin", 0x20020, 0x00020},
2457 {"product-info", 0x21000, 0x01000},
2458 {"partition-table", 0x22000, 0x02000},
2459 {"soft-version", 0x24000, 0x01000},
2460 {"support-list", 0x25000, 0x01000},
2461 {"profile", 0x26000, 0x08000},
2462 {"user-config", 0x2e000, 0x10000},
2463 {"default-config", 0x3e000, 0x10000},
2464 {"config-info", 0x4e000, 0x00400},
2465 {"firmware", 0x50000, 0x7a0000},
2466 {"radio", 0x7f0000, 0x10000},
2470 .first_sysupgrade_partition
= "os-image",
2471 .last_sysupgrade_partition
= "file-system"
2474 /** Firmware layout for the RE500 */
2480 "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
2481 "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
2482 "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
2483 "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
2484 "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
2485 "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
2486 "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
2490 /* We're using a dynamic kernel/rootfs split here */
2492 {"fs-uboot", 0x00000, 0x20000},
2493 {"firmware", 0x20000, 0xde0000},
2494 {"partition-table", 0xe00000, 0x02000},
2495 {"default-mac", 0xe10000, 0x00020},
2496 {"pin", 0xe10100, 0x00020},
2497 {"product-info", 0xe11100, 0x01000},
2498 {"soft-version", 0xe20000, 0x01000},
2499 {"support-list", 0xe21000, 0x01000},
2500 {"profile", 0xe22000, 0x08000},
2501 {"user-config", 0xe30000, 0x10000},
2502 {"default-config", 0xe40000, 0x10000},
2503 {"radio", 0xff0000, 0x10000},
2507 .first_sysupgrade_partition
= "os-image",
2508 .last_sysupgrade_partition
= "file-system"
2511 /** Firmware layout for the RE650 */
2517 "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
2518 "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
2519 "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
2520 "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
2521 "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
2522 "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
2523 "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
2527 /* We're using a dynamic kernel/rootfs split here */
2529 {"fs-uboot", 0x00000, 0x20000},
2530 {"firmware", 0x20000, 0xde0000},
2531 {"partition-table", 0xe00000, 0x02000},
2532 {"default-mac", 0xe10000, 0x00020},
2533 {"pin", 0xe10100, 0x00020},
2534 {"product-info", 0xe11100, 0x01000},
2535 {"soft-version", 0xe20000, 0x01000},
2536 {"support-list", 0xe21000, 0x01000},
2537 {"profile", 0xe22000, 0x08000},
2538 {"user-config", 0xe30000, 0x10000},
2539 {"default-config", 0xe40000, 0x10000},
2540 {"radio", 0xff0000, 0x10000},
2544 .first_sysupgrade_partition
= "os-image",
2545 .last_sysupgrade_partition
= "file-system"
2551 #define error(_ret, _errno, _str, ...) \
2553 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
2554 strerror(_errno)); \
2560 /** Stores a uint32 as big endian */
2561 static inline void put32(uint8_t *buf
, uint32_t val
) {
2568 static inline bool meta_partition_should_pad(enum partition_trail_value pv
)
2570 return (pv
>= 0) && (pv
<= PART_TRAIL_MAX
);
2573 /** Allocate a padded meta partition with a correctly initialised header
2574 * If the `data` pointer is NULL, then the required space is only allocated,
2575 * otherwise `data_len` bytes will be copied from `data` into the partition
2577 static struct image_partition_entry
init_meta_partition_entry(
2578 const char *name
, const void *data
, uint32_t data_len
,
2579 enum partition_trail_value pad_value
)
2581 uint32_t total_len
= sizeof(struct meta_header
) + data_len
;
2582 if (meta_partition_should_pad(pad_value
))
2585 struct image_partition_entry entry
= {
2588 .data
= malloc(total_len
)
2591 error(1, errno
, "failed to allocate meta partition entry");
2593 struct meta_header
*header
= (struct meta_header
*)entry
.data
;
2594 header
->length
= htonl(data_len
);
2598 memcpy(entry
.data
+sizeof(*header
), data
, data_len
);
2600 if (meta_partition_should_pad(pad_value
))
2601 entry
.data
[total_len
- 1] = (uint8_t) pad_value
;
2606 /** Allocates a new image partition */
2607 static struct image_partition_entry
alloc_image_partition(const char *name
, size_t len
) {
2608 struct image_partition_entry entry
= {name
, len
, malloc(len
)};
2610 error(1, errno
, "malloc");
2615 /** Frees an image partition */
2616 static void free_image_partition(struct image_partition_entry entry
) {
2620 static time_t source_date_epoch
= -1;
2621 static void set_source_date_epoch() {
2622 char *env
= getenv("SOURCE_DATE_EPOCH");
2626 source_date_epoch
= strtoull(env
, &endptr
, 10);
2627 if (errno
|| (endptr
&& *endptr
!= '\0')) {
2628 fprintf(stderr
, "Invalid SOURCE_DATE_EPOCH");
2634 /** Generates the partition-table partition */
2635 static struct image_partition_entry
make_partition_table(const struct flash_partition_entry
*p
) {
2636 struct image_partition_entry entry
= alloc_image_partition("partition-table", 0x800);
2638 char *s
= (char *)entry
.data
, *end
= (char *)(s
+entry
.size
);
2646 for (i
= 0; p
[i
].name
; i
++) {
2648 size_t w
= snprintf(s
, len
, "partition %s base 0x%05x size 0x%05x\n", p
[i
].name
, p
[i
].base
, p
[i
].size
);
2651 error(1, 0, "flash partition table overflow?");
2658 memset(s
, 0xff, end
-s
);
2664 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
2665 static inline uint8_t bcd(uint8_t v
) {
2666 return 0x10 * (v
/10) + v
%10;
2670 /** Generates the soft-version partition */
2671 static struct image_partition_entry
make_soft_version(
2672 const struct device_info
*info
, uint32_t rev
)
2674 /** If an info string is provided, use this instead of
2675 * the structured data, and include the null-termination */
2676 if (info
->soft_ver
) {
2677 uint32_t len
= strlen(info
->soft_ver
) + 1;
2678 return init_meta_partition_entry("soft-version",
2679 info
->soft_ver
, len
, info
->part_trail
);
2684 if (source_date_epoch
!= -1)
2685 t
= source_date_epoch
;
2686 else if (time(&t
) == (time_t)(-1))
2687 error(1, errno
, "time");
2689 struct tm
*tm
= gmtime(&t
);
2691 struct soft_version s
= {
2698 .year_hi
= bcd((1900+tm
->tm_year
)/100),
2699 .year_lo
= bcd(tm
->tm_year
%100),
2700 .month
= bcd(tm
->tm_mon
+1),
2701 .day
= bcd(tm
->tm_mday
),
2703 .compat_level
= htonl(info
->soft_ver_compat_level
)
2706 if (info
->soft_ver_compat_level
== 0)
2707 return init_meta_partition_entry("soft-version", &s
,
2708 (uint8_t *)(&s
.compat_level
) - (uint8_t *)(&s
),
2711 return init_meta_partition_entry("soft-version", &s
,
2712 sizeof(s
), info
->part_trail
);
2715 /** Generates the support-list partition */
2716 static struct image_partition_entry
make_support_list(
2717 const struct device_info
*info
)
2719 uint32_t len
= strlen(info
->support_list
);
2720 return init_meta_partition_entry("support-list", info
->support_list
,
2721 len
, info
->part_trail
);
2724 /** Partition with extra-para data */
2725 static struct image_partition_entry
make_extra_para(
2726 const struct device_info
*info
, const uint8_t *extra_para
, size_t len
)
2728 return init_meta_partition_entry("extra-para", extra_para
, len
,
2732 /** Creates a new image partition with an arbitrary name from a file */
2733 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
) {
2734 struct stat statbuf
;
2736 if (stat(filename
, &statbuf
) < 0)
2737 error(1, errno
, "unable to stat file `%s'", filename
);
2739 size_t len
= statbuf
.st_size
;
2741 if (add_jffs2_eof
) {
2742 if (file_system_partition
)
2743 len
= ALIGN(len
+ file_system_partition
->base
, 0x10000) + sizeof(jffs2_eof_mark
) - file_system_partition
->base
;
2745 len
= ALIGN(len
, 0x10000) + sizeof(jffs2_eof_mark
);
2748 struct image_partition_entry entry
= alloc_image_partition(part_name
, len
);
2750 FILE *file
= fopen(filename
, "rb");
2752 error(1, errno
, "unable to open file `%s'", filename
);
2754 if (fread(entry
.data
, statbuf
.st_size
, 1, file
) != 1)
2755 error(1, errno
, "unable to read file `%s'", filename
);
2757 if (add_jffs2_eof
) {
2758 uint8_t *eof
= entry
.data
+ statbuf
.st_size
, *end
= entry
.data
+entry
.size
;
2760 memset(eof
, 0xff, end
- eof
- sizeof(jffs2_eof_mark
));
2761 memcpy(end
- sizeof(jffs2_eof_mark
), jffs2_eof_mark
, sizeof(jffs2_eof_mark
));
2770 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
2772 Example image partition table:
2774 fwup-ptn partition-table base 0x00800 size 0x00800
2775 fwup-ptn os-image base 0x01000 size 0x113b45
2776 fwup-ptn file-system base 0x114b45 size 0x1d0004
2777 fwup-ptn support-list base 0x2e4b49 size 0x000d1
2779 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
2780 the end of the partition table is marked with a zero byte.
2782 The firmware image must contain at least the partition-table and support-list partitions
2783 to be accepted. There aren't any alignment constraints for the image partitions.
2785 The partition-table partition contains the actual flash layout; partitions
2786 from the image partition table are mapped to the corresponding flash partitions during
2787 the firmware upgrade. The support-list partition contains a list of devices supported by
2790 The base offsets in the firmware partition table are relative to the end
2791 of the vendor information block, so the partition-table partition will
2792 actually start at offset 0x1814 of the image.
2794 I think partition-table must be the first partition in the firmware image.
2796 static void put_partitions(uint8_t *buffer
, const struct flash_partition_entry
*flash_parts
, const struct image_partition_entry
*parts
) {
2798 char *image_pt
= (char *)buffer
, *end
= image_pt
+ 0x800;
2800 size_t base
= 0x800;
2801 for (i
= 0; parts
[i
].name
; i
++) {
2802 for (j
= 0; flash_parts
[j
].name
; j
++) {
2803 if (!strcmp(flash_parts
[j
].name
, parts
[i
].name
)) {
2804 if (parts
[i
].size
> flash_parts
[j
].size
)
2805 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts
[j
].name
, (unsigned)flash_parts
[j
].size
);
2810 assert(flash_parts
[j
].name
);
2812 memcpy(buffer
+ base
, parts
[i
].data
, parts
[i
].size
);
2814 size_t len
= end
-image_pt
;
2815 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
);
2818 error(1, 0, "image partition table overflow?");
2822 base
+= parts
[i
].size
;
2826 /** Generates and writes the image MD5 checksum */
2827 static void put_md5(uint8_t *md5
, uint8_t *buffer
, unsigned int len
) {
2831 MD5_Update(&ctx
, md5_salt
, (unsigned int)sizeof(md5_salt
));
2832 MD5_Update(&ctx
, buffer
, len
);
2833 MD5_Final(md5
, &ctx
);
2838 Generates the firmware image in factory format
2844 0000-0003 Image size (4 bytes, big endian)
2845 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
2846 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
2847 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
2848 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
2849 1014-1813 Image partition table (2048 bytes, padded with 0xff)
2850 1814-xxxx Firmware partitions
2852 static void * generate_factory_image(struct device_info
*info
, const struct image_partition_entry
*parts
, size_t *len
) {
2856 for (i
= 0; parts
[i
].name
; i
++)
2857 *len
+= parts
[i
].size
;
2859 uint8_t *image
= malloc(*len
);
2861 error(1, errno
, "malloc");
2863 memset(image
, 0xff, *len
);
2867 size_t vendor_len
= strlen(info
->vendor
);
2868 put32(image
+0x14, vendor_len
);
2869 memcpy(image
+0x18, info
->vendor
, vendor_len
);
2872 put_partitions(image
+ 0x1014, info
->partitions
, parts
);
2873 put_md5(image
+0x04, image
+0x14, *len
-0x14);
2879 Generates the firmware image in sysupgrade format
2881 This makes some assumptions about the provided flash and image partition tables and
2882 should be generalized when TP-LINK starts building its safeloader into hardware with
2883 different flash layouts.
2885 static void * generate_sysupgrade_image(struct device_info
*info
, const struct image_partition_entry
*image_parts
, size_t *len
) {
2887 size_t flash_first_partition_index
= 0;
2888 size_t flash_last_partition_index
= 0;
2889 const struct flash_partition_entry
*flash_first_partition
= NULL
;
2890 const struct flash_partition_entry
*flash_last_partition
= NULL
;
2891 const struct image_partition_entry
*image_last_partition
= NULL
;
2893 /** Find first and last partitions */
2894 for (i
= 0; info
->partitions
[i
].name
; i
++) {
2895 if (!strcmp(info
->partitions
[i
].name
, info
->first_sysupgrade_partition
)) {
2896 flash_first_partition
= &info
->partitions
[i
];
2897 flash_first_partition_index
= i
;
2898 } else if (!strcmp(info
->partitions
[i
].name
, info
->last_sysupgrade_partition
)) {
2899 flash_last_partition
= &info
->partitions
[i
];
2900 flash_last_partition_index
= i
;
2904 assert(flash_first_partition
&& flash_last_partition
);
2905 assert(flash_first_partition_index
< flash_last_partition_index
);
2907 /** Find last partition from image to calculate needed size */
2908 for (i
= 0; image_parts
[i
].name
; i
++) {
2909 if (!strcmp(image_parts
[i
].name
, info
->last_sysupgrade_partition
)) {
2910 image_last_partition
= &image_parts
[i
];
2915 assert(image_last_partition
);
2917 *len
= flash_last_partition
->base
- flash_first_partition
->base
+ image_last_partition
->size
;
2919 uint8_t *image
= malloc(*len
);
2921 error(1, errno
, "malloc");
2923 memset(image
, 0xff, *len
);
2925 for (i
= flash_first_partition_index
; i
<= flash_last_partition_index
; i
++) {
2926 for (j
= 0; image_parts
[j
].name
; j
++) {
2927 if (!strcmp(info
->partitions
[i
].name
, image_parts
[j
].name
)) {
2928 if (image_parts
[j
].size
> info
->partitions
[i
].size
)
2929 error(1, 0, "%s partition too big (more than %u bytes)", info
->partitions
[i
].name
, (unsigned)info
->partitions
[i
].size
);
2930 memcpy(image
+ info
->partitions
[i
].base
- flash_first_partition
->base
, image_parts
[j
].data
, image_parts
[j
].size
);
2934 assert(image_parts
[j
].name
);
2941 /** Generates an image according to a given layout and writes it to a file */
2942 static void build_image(const char *output
,
2943 const char *kernel_image
,
2944 const char *rootfs_image
,
2948 struct device_info
*info
) {
2952 struct image_partition_entry parts
[7] = {};
2954 struct flash_partition_entry
*firmware_partition
= NULL
;
2955 struct flash_partition_entry
*os_image_partition
= NULL
;
2956 struct flash_partition_entry
*file_system_partition
= NULL
;
2957 size_t firmware_partition_index
= 0;
2959 for (i
= 0; info
->partitions
[i
].name
; i
++) {
2960 if (!strcmp(info
->partitions
[i
].name
, "firmware"))
2962 firmware_partition
= &info
->partitions
[i
];
2963 firmware_partition_index
= i
;
2967 if (firmware_partition
)
2969 os_image_partition
= &info
->partitions
[firmware_partition_index
];
2970 file_system_partition
= &info
->partitions
[firmware_partition_index
+ 1];
2973 if (stat(kernel_image
, &kernel
) < 0)
2974 error(1, errno
, "unable to stat file `%s'", kernel_image
);
2976 if (kernel
.st_size
> firmware_partition
->size
)
2977 error(1, 0, "kernel overflowed firmware partition\n");
2979 for (i
= MAX_PARTITIONS
-1; i
>= firmware_partition_index
+ 1; i
--)
2980 info
->partitions
[i
+1] = info
->partitions
[i
];
2982 file_system_partition
->name
= "file-system";
2983 file_system_partition
->base
= firmware_partition
->base
+ kernel
.st_size
;
2985 /* Align partition start to erase blocks for factory images only */
2987 file_system_partition
->base
= ALIGN(firmware_partition
->base
+ kernel
.st_size
, 0x10000);
2989 file_system_partition
->size
= firmware_partition
->size
- file_system_partition
->base
;
2991 os_image_partition
->name
= "os-image";
2992 os_image_partition
->size
= kernel
.st_size
;
2995 parts
[0] = make_partition_table(info
->partitions
);
2996 parts
[1] = make_soft_version(info
, rev
);
2997 parts
[2] = make_support_list(info
);
2998 parts
[3] = read_file("os-image", kernel_image
, false, NULL
);
2999 parts
[4] = read_file("file-system", rootfs_image
, add_jffs2_eof
, file_system_partition
);
3001 /* Some devices need the extra-para partition to accept the firmware */
3002 if (strcasecmp(info
->id
, "ARCHER-A6-V3") == 0 ||
3003 strcasecmp(info
->id
, "ARCHER-A7-V5") == 0 ||
3004 strcasecmp(info
->id
, "ARCHER-C2-V3") == 0 ||
3005 strcasecmp(info
->id
, "ARCHER-C7-V4") == 0 ||
3006 strcasecmp(info
->id
, "ARCHER-C7-V5") == 0 ||
3007 strcasecmp(info
->id
, "ARCHER-C25-V1") == 0 ||
3008 strcasecmp(info
->id
, "ARCHER-C59-V2") == 0 ||
3009 strcasecmp(info
->id
, "ARCHER-C60-V2") == 0 ||
3010 strcasecmp(info
->id
, "ARCHER-C60-V3") == 0 ||
3011 strcasecmp(info
->id
, "ARCHER-C6U-V1") == 0 ||
3012 strcasecmp(info
->id
, "ARCHER-C6-V3") == 0 ||
3013 strcasecmp(info
->id
, "TLWR1043NV5") == 0) {
3014 const uint8_t extra_para
[2] = {0x01, 0x00};
3015 parts
[5] = make_extra_para(info
, extra_para
,
3016 sizeof(extra_para
));
3017 } else if (strcasecmp(info
->id
, "ARCHER-C6-V2") == 0) {
3018 const uint8_t extra_para
[2] = {0x00, 0x01};
3019 parts
[5] = make_extra_para(info
, extra_para
,
3020 sizeof(extra_para
));
3021 } else if (strcasecmp(info
->id
, "ARCHER-C6-V2-US") == 0 ||
3022 strcasecmp(info
->id
, "EAP245-V3") == 0) {
3023 const uint8_t extra_para
[2] = {0x01, 0x01};
3024 parts
[5] = make_extra_para(info
, extra_para
,
3025 sizeof(extra_para
));
3031 image
= generate_sysupgrade_image(info
, parts
, &len
);
3033 image
= generate_factory_image(info
, parts
, &len
);
3035 FILE *file
= fopen(output
, "wb");
3037 error(1, errno
, "unable to open output file");
3039 if (fwrite(image
, len
, 1, file
) != 1)
3040 error(1, 0, "unable to write output file");
3046 for (i
= 0; parts
[i
].name
; i
++)
3047 free_image_partition(parts
[i
]);
3051 static void usage(const char *argv0
) {
3053 "Usage: %s [OPTIONS...]\n"
3056 " -h show this help\n"
3058 "Info about an image:\n"
3059 " -i <file> input file to read from\n"
3060 "Create a new image:\n"
3061 " -B <board> create image for the board specified with <board>\n"
3062 " -k <file> read kernel image from the file <file>\n"
3063 " -r <file> read rootfs image from the file <file>\n"
3064 " -o <file> write output to the file <file>\n"
3065 " -V <rev> sets the revision number to <rev>\n"
3066 " -j add jffs2 end-of-filesystem markers\n"
3067 " -S create sysupgrade instead of factory image\n"
3068 "Extract an old image:\n"
3069 " -x <file> extract all oem firmware partition\n"
3070 " -d <dir> destination to extract the firmware partition\n"
3071 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
3077 static struct device_info
*find_board(const char *id
)
3079 struct device_info
*board
= NULL
;
3081 for (board
= boards
; board
->id
!= NULL
; board
++)
3082 if (strcasecmp(id
, board
->id
) == 0)
3088 static int add_flash_partition(
3089 struct flash_partition_entry
*part_list
,
3096 /* check if the list has a free entry */
3097 for (ptr
= 0; ptr
< max_entries
; ptr
++, part_list
++) {
3098 if (part_list
->name
== NULL
&&
3099 part_list
->base
== 0 &&
3100 part_list
->size
== 0)
3104 if (ptr
== max_entries
) {
3105 error(1, 0, "No free flash part entry available.");
3108 part_list
->name
= calloc(1, strlen(name
) + 1);
3109 if (!part_list
->name
) {
3110 error(1, 0, "Unable to allocate memory");
3113 memcpy((char *)part_list
->name
, name
, strlen(name
));
3114 part_list
->base
= base
;
3115 part_list
->size
= size
;
3120 /** read the partition table into struct flash_partition_entry */
3121 static int read_partition_table(
3122 FILE *file
, long offset
,
3123 struct flash_partition_entry
*entries
, size_t max_entries
,
3128 const char *parthdr
= NULL
;
3129 const char *fwuphdr
= "fwup-ptn";
3130 const char *flashhdr
= "partition";
3132 /* TODO: search for the partition table */
3142 error(1, 0, "Invalid partition table");
3145 if (fseek(file
, offset
, SEEK_SET
) < 0)
3146 error(1, errno
, "Can not seek in the firmware");
3148 if (fread(buf
, 2048, 1, file
) != 1)
3149 error(1, errno
, "Can not read fwup-ptn from the firmware");
3153 /* look for the partition header */
3154 if (memcmp(buf
, parthdr
, strlen(parthdr
)) != 0) {
3155 fprintf(stderr
, "DEBUG: can not find fwuphdr\n");
3160 end
= buf
+ sizeof(buf
);
3161 while ((ptr
+ strlen(parthdr
)) < end
&&
3162 memcmp(ptr
, parthdr
, strlen(parthdr
)) == 0) {
3166 char name
[32] = { 0 };
3168 unsigned long base
= 0;
3169 unsigned long size
= 0;
3171 end_part
= memchr(ptr
, '\n', (end
- ptr
));
3172 if (end_part
== NULL
) {
3173 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
3177 for (int i
= 0; i
<= 4; i
++) {
3178 if (end_part
<= ptr
)
3181 end_element
= memchr(ptr
, 0x20, (end_part
- ptr
));
3182 if (end_element
== NULL
) {
3183 error(1, errno
, "Ignoring the rest of the partition entries.");
3188 /* partition header */
3190 ptr
= end_element
+ 1;
3194 name_len
= (end_element
- ptr
) > 31 ? 31 : (end_element
- ptr
);
3195 strncpy(name
, ptr
, name_len
);
3196 name
[name_len
] = '\0';
3197 ptr
= end_element
+ 1;
3202 ptr
= end_element
+ 1;
3207 base
= strtoul(ptr
, NULL
, 16);
3208 ptr
= end_element
+ 1;
3213 ptr
= end_element
+ 1;
3214 /* actual size. The last element doesn't have a sepeartor */
3215 size
= strtoul(ptr
, NULL
, 16);
3216 /* the part ends with 0x09, 0x0d, 0x0a */
3218 add_flash_partition(entries
, max_entries
, name
, base
, size
);
3227 static void write_partition(
3229 size_t firmware_offset
,
3230 struct flash_partition_entry
*entry
,
3236 fseek(input_file
, entry
->base
+ firmware_offset
, SEEK_SET
);
3238 for (offset
= 0; sizeof(buf
) + offset
<= entry
->size
; offset
+= sizeof(buf
)) {
3239 if (fread(buf
, sizeof(buf
), 1, input_file
) != 1)
3240 error(1, errno
, "Can not read partition from input_file");
3242 if (fwrite(buf
, sizeof(buf
), 1, output_file
) != 1)
3243 error(1, errno
, "Can not write partition to output_file");
3245 /* write last chunk smaller than buffer */
3246 if (offset
< entry
->size
) {
3247 offset
= entry
->size
- offset
;
3248 if (fread(buf
, offset
, 1, input_file
) != 1)
3249 error(1, errno
, "Can not read partition from input_file");
3250 if (fwrite(buf
, offset
, 1, output_file
) != 1)
3251 error(1, errno
, "Can not write partition to output_file");
3255 static int extract_firmware_partition(FILE *input_file
, size_t firmware_offset
, struct flash_partition_entry
*entry
, const char *output_directory
)
3258 char output
[PATH_MAX
];
3260 snprintf(output
, PATH_MAX
, "%s/%s", output_directory
, entry
->name
);
3261 output_file
= fopen(output
, "wb+");
3262 if (output_file
== NULL
) {
3263 error(1, errno
, "Can not open output file %s", output
);
3266 write_partition(input_file
, firmware_offset
, entry
, output_file
);
3268 fclose(output_file
);
3273 /** extract all partitions from the firmware file */
3274 static int extract_firmware(const char *input
, const char *output_directory
)
3276 struct flash_partition_entry entries
[16] = { 0 };
3277 size_t max_entries
= 16;
3278 size_t firmware_offset
= 0x1014;
3281 struct stat statbuf
;
3283 /* check input file */
3284 if (stat(input
, &statbuf
)) {
3285 error(1, errno
, "Can not read input firmware %s", input
);
3288 /* check if output directory exists */
3289 if (stat(output_directory
, &statbuf
)) {
3290 error(1, errno
, "Failed to stat output directory %s", output_directory
);
3293 if ((statbuf
.st_mode
& S_IFMT
) != S_IFDIR
) {
3294 error(1, errno
, "Given output directory is not a directory %s", output_directory
);
3297 input_file
= fopen(input
, "rb");
3299 if (read_partition_table(input_file
, firmware_offset
, entries
, 16, 0) != 0) {
3300 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3303 for (size_t i
= 0; i
< max_entries
; i
++) {
3304 if (entries
[i
].name
== NULL
&&
3305 entries
[i
].base
== 0 &&
3306 entries
[i
].size
== 0)
3309 extract_firmware_partition(input_file
, firmware_offset
, &entries
[i
], output_directory
);
3315 static struct flash_partition_entry
*find_partition(
3316 struct flash_partition_entry
*entries
, size_t max_entries
,
3317 const char *name
, const char *error_msg
)
3319 for (size_t i
= 0; i
< max_entries
; i
++, entries
++) {
3320 if (strcmp(entries
->name
, name
) == 0)
3325 error(1, 0, "%s", error_msg
);
3331 static int firmware_info(const char *input
)
3333 struct flash_partition_entry pointers
[MAX_PARTITIONS
] = { };
3334 struct flash_partition_entry
*e
;
3338 fp
= fopen(input
, "r");
3340 if (read_partition_table(fp
, 0x1014, pointers
, MAX_PARTITIONS
, 0)) {
3341 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3344 printf("Firmware image partitions:\n");
3345 printf("%-8s %-8s %s\n", "base", "size", "name");
3346 for (i
= 0; i
< MAX_PARTITIONS
; i
++) {
3349 if (!e
->name
&& !e
->base
&& !e
->size
)
3352 printf("%08x %08x %s\n", e
->base
, e
->size
, e
->name
? e
->name
: "");
3355 e
= find_partition(pointers
, MAX_PARTITIONS
, "soft-version", NULL
);
3357 size_t data_len
= e
->size
- sizeof(struct meta_header
);
3358 char *buf
= malloc(data_len
);
3359 struct soft_version
*s
;
3364 error(1, errno
, "Failed to alloc buffer");
3366 if (fseek(fp
, 0x1014 + e
->base
+ sizeof(struct meta_header
), SEEK_SET
))
3367 error(1, errno
, "Can not seek in the firmware");
3369 if (fread(buf
, data_len
, 1, fp
) != 1)
3370 error(1, errno
, "Can not read fwup-ptn data from the firmware");
3372 /* Check for string ignoring padding character */
3374 for (i
= 0; i
< data_len
- 1; i
++) {
3375 if (!isascii(buf
[i
])) {
3381 printf("\n[Software version]\n");
3383 fwrite(buf
, data_len
, 1, stdout
);
3385 } else if (data_len
>= offsetof(struct soft_version
, rev
)) {
3386 s
= (struct soft_version
*)buf
;
3388 printf("Version: %d.%d.%d\n", s
->version_major
, s
->version_minor
, s
->version_patch
);
3389 printf("Date: %02x%02x-%02x-%02x\n", s
->year_hi
, s
->year_lo
, s
->month
, s
->day
);
3391 printf("Failed to parse data\n");
3397 e
= find_partition(pointers
, MAX_PARTITIONS
, "support-list", NULL
);
3403 if (fseek(fp
, 0x1014 + e
->base
+ sizeof(struct meta_header
), SEEK_SET
))
3404 error(1, errno
, "Can not seek in the firmware");
3406 printf("\n[Support list]\n");
3407 for (length
= e
->size
- sizeof(struct meta_header
); length
; length
-= bytes
) {
3408 bytes
= fread(buf
, 1, length
> sizeof(buf
) ? sizeof(buf
) : length
, fp
);
3410 error(1, errno
, "Can not read fwup-ptn data from the firmware");
3416 e
= find_partition(pointers
, MAX_PARTITIONS
, "partition-table", NULL
);
3418 struct flash_partition_entry parts
[MAX_PARTITIONS
] = { };
3420 if (read_partition_table(fp
, 0x1014 + e
->base
+ 4, parts
, MAX_PARTITIONS
, 1)) {
3421 error(1, 0, "Error can not read the partition table (partition)");
3424 printf("\n[Partition table]\n");
3425 printf("%-8s %-8s %s\n", "base", "size", "name");
3426 for (i
= 0; i
< MAX_PARTITIONS
; i
++) {
3429 if (!e
->name
&& !e
->base
&& !e
->size
)
3432 printf("%08x %08x %s\n", e
->base
, e
->size
, e
->name
? e
->name
: "");
3441 static void write_ff(FILE *output_file
, size_t size
)
3446 memset(buf
, 0xff, sizeof(buf
));
3448 for (offset
= 0; offset
+ sizeof(buf
) < size
; offset
+= sizeof(buf
)) {
3449 if (fwrite(buf
, sizeof(buf
), 1, output_file
) != 1)
3450 error(1, errno
, "Can not write 0xff to output_file");
3453 /* write last chunk smaller than buffer */
3454 if (offset
< size
) {
3455 offset
= size
- offset
;
3456 if (fwrite(buf
, offset
, 1, output_file
) != 1)
3457 error(1, errno
, "Can not write partition to output_file");
3461 static void convert_firmware(const char *input
, const char *output
)
3463 struct flash_partition_entry fwup
[MAX_PARTITIONS
] = { 0 };
3464 struct flash_partition_entry flash
[MAX_PARTITIONS
] = { 0 };
3465 struct flash_partition_entry
*fwup_os_image
= NULL
, *fwup_file_system
= NULL
;
3466 struct flash_partition_entry
*flash_os_image
= NULL
, *flash_file_system
= NULL
;
3467 struct flash_partition_entry
*fwup_partition_table
= NULL
;
3468 size_t firmware_offset
= 0x1014;
3469 FILE *input_file
, *output_file
;
3471 struct stat statbuf
;
3473 /* check input file */
3474 if (stat(input
, &statbuf
)) {
3475 error(1, errno
, "Can not read input firmware %s", input
);
3478 input_file
= fopen(input
, "rb");
3480 error(1, 0, "Can not open input firmware %s", input
);
3482 output_file
= fopen(output
, "wb");
3484 error(1, 0, "Can not open output firmware %s", output
);
3486 if (read_partition_table(input_file
, firmware_offset
, fwup
, MAX_PARTITIONS
, 0) != 0) {
3487 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3490 fwup_os_image
= find_partition(fwup
, MAX_PARTITIONS
,
3491 "os-image", "Error can not find os-image partition (fwup)");
3492 fwup_file_system
= find_partition(fwup
, MAX_PARTITIONS
,
3493 "file-system", "Error can not find file-system partition (fwup)");
3494 fwup_partition_table
= find_partition(fwup
, MAX_PARTITIONS
,
3495 "partition-table", "Error can not find partition-table partition");
3497 /* the flash partition table has a 0x00000004 magic haeder */
3498 if (read_partition_table(input_file
, firmware_offset
+ fwup_partition_table
->base
+ 4, flash
, MAX_PARTITIONS
, 1) != 0)
3499 error(1, 0, "Error can not read the partition table (flash)");
3501 flash_os_image
= find_partition(flash
, MAX_PARTITIONS
,
3502 "os-image", "Error can not find os-image partition (flash)");
3503 flash_file_system
= find_partition(flash
, MAX_PARTITIONS
,
3504 "file-system", "Error can not find file-system partition (flash)");
3506 /* write os_image to 0x0 */
3507 write_partition(input_file
, firmware_offset
, fwup_os_image
, output_file
);
3508 write_ff(output_file
, flash_os_image
->size
- fwup_os_image
->size
);
3510 /* write file-system behind os_image */
3511 fseek(output_file
, flash_file_system
->base
- flash_os_image
->base
, SEEK_SET
);
3512 write_partition(input_file
, firmware_offset
, fwup_file_system
, output_file
);
3513 write_ff(output_file
, flash_file_system
->size
- fwup_file_system
->size
);
3515 fclose(output_file
);
3519 int main(int argc
, char *argv
[]) {
3520 const char *info_image
= NULL
, *board
= NULL
, *kernel_image
= NULL
, *rootfs_image
= NULL
, *output
= NULL
;
3521 const char *extract_image
= NULL
, *output_directory
= NULL
, *convert_image
= NULL
;
3522 bool add_jffs2_eof
= false, sysupgrade
= false;
3524 struct device_info
*info
;
3525 set_source_date_epoch();
3530 c
= getopt(argc
, argv
, "i:B:k:r:o:V:jSh:x:d:z:");
3536 info_image
= optarg
;
3544 kernel_image
= optarg
;
3548 rootfs_image
= optarg
;
3556 sscanf(optarg
, "r%u", &rev
);
3560 add_jffs2_eof
= true;
3572 output_directory
= optarg
;
3576 extract_image
= optarg
;
3580 convert_image
= optarg
;
3590 firmware_info(info_image
);
3591 } else if (extract_image
|| output_directory
) {
3593 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
3594 if (!output_directory
)
3595 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
3596 extract_firmware(extract_image
, output_directory
);
3597 } else if (convert_image
) {
3599 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
3600 convert_firmware(convert_image
, output
);
3603 error(1, 0, "no board has been specified");
3605 error(1, 0, "no kernel image has been specified");
3607 error(1, 0, "no rootfs image has been specified");
3609 error(1, 0, "no output filename has been specified");
3611 info
= find_board(board
);
3614 error(1, 0, "unsupported board %s", board
);
3616 build_image(output
, kernel_image
, rootfs_image
, rev
, add_jffs2_eof
, sysupgrade
, info
);