2 Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 Image generation tool for the TP-LINK SafeLoader as seen on
31 TP-LINK Pharos devices (CPE210/220/510/520)
45 #include <arpa/inet.h>
47 #include <sys/types.h>
54 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
57 #define MAX_PARTITIONS 32
59 /** An image partition table entry */
60 struct image_partition_entry
{
66 /** A flash partition table entry */
67 struct flash_partition_entry
{
73 /** Firmware layout description */
77 const char *support_list
;
80 uint32_t soft_ver_compat_level
;
81 struct flash_partition_entry partitions
[MAX_PARTITIONS
+1];
82 const char *first_sysupgrade_partition
;
83 const char *last_sysupgrade_partition
;
86 struct __attribute__((__packed__
)) meta_header
{
91 /** The content of the soft-version structure */
92 struct __attribute__((__packed__
)) soft_version
{
94 uint8_t version_major
;
95 uint8_t version_minor
;
96 uint8_t version_patch
;
102 uint32_t compat_level
;
106 static const uint8_t jffs2_eof_mark
[4] = {0xde, 0xad, 0xc0, 0xde};
110 Salt for the MD5 hash
112 Fortunately, TP-LINK seems to use the same salt for most devices which use
113 the new image format.
115 static const uint8_t md5_salt
[16] = {
116 0x7a, 0x2b, 0x15, 0xed,
117 0x9b, 0x98, 0x59, 0x6d,
118 0xe5, 0x04, 0xab, 0x44,
119 0xac, 0x2a, 0x9f, 0x4e,
123 /** Firmware layout table */
124 static struct device_info boards
[] = {
125 /** Firmware layout for the CPE210/220 V1 */
128 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
131 "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
132 "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
133 "CPE210(TP-LINK|US|N300-2):1.1\r\n"
134 "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
135 "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
136 "CPE220(TP-LINK|US|N300-2):1.1\r\n"
137 "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
138 .support_trail
= '\xff',
142 {"fs-uboot", 0x00000, 0x20000},
143 {"partition-table", 0x20000, 0x02000},
144 {"default-mac", 0x30000, 0x00020},
145 {"product-info", 0x31100, 0x00100},
146 {"signature", 0x32000, 0x00400},
147 {"os-image", 0x40000, 0x300000},
148 {"file-system", 0x340000, 0x470000},
149 {"soft-version", 0x7b0000, 0x00100},
150 {"support-list", 0x7b1000, 0x00400},
151 {"user-config", 0x7c0000, 0x10000},
152 {"default-config", 0x7d0000, 0x10000},
153 {"log", 0x7e0000, 0x10000},
154 {"radio", 0x7f0000, 0x10000},
158 .first_sysupgrade_partition
= "os-image",
159 .last_sysupgrade_partition
= "support-list",
162 /** Firmware layout for the CPE210 V2 */
165 .vendor
= "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
168 "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
169 "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
170 "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
171 "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
172 "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
173 "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
174 "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
175 "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
176 "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
177 "CPE210(TP-LINK|US|N300-2):2.0\r\n",
178 .support_trail
= '\xff',
182 {"fs-uboot", 0x00000, 0x20000},
183 {"partition-table", 0x20000, 0x02000},
184 {"default-mac", 0x30000, 0x00020},
185 {"product-info", 0x31100, 0x00100},
186 {"device-info", 0x31400, 0x00400},
187 {"signature", 0x32000, 0x00400},
188 {"device-id", 0x33000, 0x00100},
189 {"firmware", 0x40000, 0x770000},
190 {"soft-version", 0x7b0000, 0x00100},
191 {"support-list", 0x7b1000, 0x01000},
192 {"user-config", 0x7c0000, 0x10000},
193 {"default-config", 0x7d0000, 0x10000},
194 {"log", 0x7e0000, 0x10000},
195 {"radio", 0x7f0000, 0x10000},
199 .first_sysupgrade_partition
= "os-image",
200 .last_sysupgrade_partition
= "support-list",
203 /** Firmware layout for the CPE210 V3 */
206 .vendor
= "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n",
209 "CPE210(TP-LINK|EU|N300-2|45550000):3.0\r\n"
210 "CPE210(TP-LINK|UN|N300-2|00000000):3.0\r\n"
211 "CPE210(TP-LINK|US|N300-2|55530000):3.0\r\n"
212 "CPE210(TP-LINK|UN|N300-2):3.0\r\n"
213 "CPE210(TP-LINK|EU|N300-2):3.0\r\n"
214 "CPE210(TP-LINK|EU|N300-2|45550000):3.1\r\n"
215 "CPE210(TP-LINK|UN|N300-2|00000000):3.1\r\n"
216 "CPE210(TP-LINK|US|N300-2|55530000):3.1\r\n"
217 "CPE210(TP-LINK|EU|N300-2|45550000):3.20\r\n"
218 "CPE210(TP-LINK|UN|N300-2|00000000):3.20\r\n"
219 "CPE210(TP-LINK|US|N300-2|55530000):3.20\r\n",
220 .support_trail
= '\xff',
224 {"fs-uboot", 0x00000, 0x20000},
225 {"partition-table", 0x20000, 0x01000},
226 {"default-mac", 0x30000, 0x00020},
227 {"product-info", 0x31100, 0x00100},
228 {"device-info", 0x31400, 0x00400},
229 {"signature", 0x32000, 0x00400},
230 {"device-id", 0x33000, 0x00100},
231 {"firmware", 0x40000, 0x770000},
232 {"soft-version", 0x7b0000, 0x00100},
233 {"support-list", 0x7b1000, 0x01000},
234 {"user-config", 0x7c0000, 0x10000},
235 {"default-config", 0x7d0000, 0x10000},
236 {"log", 0x7e0000, 0x10000},
237 {"radio", 0x7f0000, 0x10000},
241 .first_sysupgrade_partition
= "os-image",
242 .last_sysupgrade_partition
= "support-list",
245 /** Firmware layout for the CPE220 V2 */
248 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
251 "CPE220(TP-LINK|EU|N300-2|00000000):2.0\r\n"
252 "CPE220(TP-LINK|EU|N300-2|45550000):2.0\r\n"
253 "CPE220(TP-LINK|EU|N300-2|55530000):2.0\r\n"
254 "CPE220(TP-LINK|UN|N300-2|00000000):2.0\r\n"
255 "CPE220(TP-LINK|UN|N300-2|45550000):2.0\r\n"
256 "CPE220(TP-LINK|UN|N300-2|55530000):2.0\r\n"
257 "CPE220(TP-LINK|US|N300-2|55530000):2.0\r\n"
258 "CPE220(TP-LINK|UN|N300-2):2.0\r\n"
259 "CPE220(TP-LINK|EU|N300-2):2.0\r\n"
260 "CPE220(TP-LINK|US|N300-2):2.0\r\n",
261 .support_trail
= '\xff',
265 {"fs-uboot", 0x00000, 0x20000},
266 {"partition-table", 0x20000, 0x02000},
267 {"default-mac", 0x30000, 0x00020},
268 {"product-info", 0x31100, 0x00100},
269 {"signature", 0x32000, 0x00400},
270 {"os-image", 0x40000, 0x300000},
271 {"file-system", 0x340000, 0x470000},
272 {"soft-version", 0x7b0000, 0x00100},
273 {"support-list", 0x7b1000, 0x00400},
274 {"user-config", 0x7c0000, 0x10000},
275 {"default-config", 0x7d0000, 0x10000},
276 {"log", 0x7e0000, 0x10000},
277 {"radio", 0x7f0000, 0x10000},
281 .first_sysupgrade_partition
= "os-image",
282 .last_sysupgrade_partition
= "support-list",
285 /** Firmware layout for the CPE220 V3 */
288 .vendor
= "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n",
291 "CPE220(TP-LINK|EU|N300-2|00000000):3.0\r\n"
292 "CPE220(TP-LINK|EU|N300-2|45550000):3.0\r\n"
293 "CPE220(TP-LINK|EU|N300-2|55530000):3.0\r\n"
294 "CPE220(TP-LINK|UN|N300-2|00000000):3.0\r\n"
295 "CPE220(TP-LINK|UN|N300-2|45550000):3.0\r\n"
296 "CPE220(TP-LINK|UN|N300-2|55530000):3.0\r\n"
297 "CPE220(TP-LINK|US|N300-2|55530000):3.0\r\n"
298 "CPE220(TP-LINK|UN|N300-2):3.0\r\n"
299 "CPE220(TP-LINK|EU|N300-2):3.0\r\n"
300 "CPE220(TP-LINK|US|N300-2):3.0\r\n",
301 .support_trail
= '\xff',
305 {"fs-uboot", 0x00000, 0x20000},
306 {"partition-table", 0x20000, 0x02000},
307 {"default-mac", 0x30000, 0x00020},
308 {"product-info", 0x31100, 0x00100},
309 {"device-info", 0x31400, 0x00400},
310 {"signature", 0x32000, 0x00400},
311 {"device-id", 0x33000, 0x00100},
312 {"firmware", 0x40000, 0x770000},
313 {"soft-version", 0x7b0000, 0x00100},
314 {"support-list", 0x7b1000, 0x01000},
315 {"user-config", 0x7c0000, 0x10000},
316 {"default-config", 0x7d0000, 0x10000},
317 {"log", 0x7e0000, 0x10000},
318 {"radio", 0x7f0000, 0x10000},
322 .first_sysupgrade_partition
= "os-image",
323 .last_sysupgrade_partition
= "support-list",
326 /** Firmware layout for the CPE510/520 V1 */
329 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
332 "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
333 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
334 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
335 "CPE510(TP-LINK|US|N300-5):1.1\r\n"
336 "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
337 "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
338 "CPE520(TP-LINK|US|N300-5):1.1\r\n"
339 "CPE520(TP-LINK|EU|N300-5):1.1\r\n",
340 .support_trail
= '\xff',
344 {"fs-uboot", 0x00000, 0x20000},
345 {"partition-table", 0x20000, 0x02000},
346 {"default-mac", 0x30000, 0x00020},
347 {"product-info", 0x31100, 0x00100},
348 {"signature", 0x32000, 0x00400},
349 {"os-image", 0x40000, 0x300000},
350 {"file-system", 0x340000, 0x470000},
351 {"soft-version", 0x7b0000, 0x00100},
352 {"support-list", 0x7b1000, 0x00400},
353 {"user-config", 0x7c0000, 0x10000},
354 {"default-config", 0x7d0000, 0x10000},
355 {"log", 0x7e0000, 0x10000},
356 {"radio", 0x7f0000, 0x10000},
360 .first_sysupgrade_partition
= "os-image",
361 .last_sysupgrade_partition
= "support-list",
364 /** Firmware layout for the CPE510 V2 */
367 .vendor
= "CPE510(TP-LINK|UN|N300-5):2.0\r\n",
370 "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n"
371 "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
372 "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n"
373 "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
374 "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n"
375 "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n"
376 "CPE510(TP-LINK|US|N300-5|00000000):2.0\r\n"
377 "CPE510(TP-LINK|US|N300-5|45550000):2.0\r\n"
378 "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n"
379 "CPE510(TP-LINK|UN|N300-5):2.0\r\n"
380 "CPE510(TP-LINK|EU|N300-5):2.0\r\n"
381 "CPE510(TP-LINK|US|N300-5):2.0\r\n",
382 .support_trail
= '\xff',
386 {"fs-uboot", 0x00000, 0x20000},
387 {"partition-table", 0x20000, 0x02000},
388 {"default-mac", 0x30000, 0x00020},
389 {"product-info", 0x31100, 0x00100},
390 {"signature", 0x32000, 0x00400},
391 {"os-image", 0x40000, 0x300000},
392 {"file-system", 0x340000, 0x470000},
393 {"soft-version", 0x7b0000, 0x00100},
394 {"support-list", 0x7b1000, 0x00400},
395 {"user-config", 0x7c0000, 0x10000},
396 {"default-config", 0x7d0000, 0x10000},
397 {"log", 0x7e0000, 0x10000},
398 {"radio", 0x7f0000, 0x10000},
402 .first_sysupgrade_partition
= "os-image",
403 .last_sysupgrade_partition
= "support-list",
406 /** Firmware layout for the CPE510 V3 */
409 .vendor
= "CPE510(TP-LINK|UN|N300-5):3.0\r\n",
412 "CPE510(TP-LINK|EU|N300-5|00000000):3.0\r\n"
413 "CPE510(TP-LINK|EU|N300-5|45550000):3.0\r\n"
414 "CPE510(TP-LINK|EU|N300-5|55530000):3.0\r\n"
415 "CPE510(TP-LINK|UN|N300-5|00000000):3.0\r\n"
416 "CPE510(TP-LINK|UN|N300-5|45550000):3.0\r\n"
417 "CPE510(TP-LINK|UN|N300-5|55530000):3.0\r\n"
418 "CPE510(TP-LINK|US|N300-5|00000000):3.0\r\n"
419 "CPE510(TP-LINK|US|N300-5|45550000):3.0\r\n"
420 "CPE510(TP-LINK|US|N300-5|55530000):3.0\r\n"
421 "CPE510(TP-LINK|UN|N300-5):3.0\r\n"
422 "CPE510(TP-LINK|EU|N300-5):3.0\r\n"
423 "CPE510(TP-LINK|US|N300-5):3.0\r\n",
424 .support_trail
= '\xff',
428 {"fs-uboot", 0x00000, 0x20000},
429 {"partition-table", 0x20000, 0x02000},
430 {"default-mac", 0x30000, 0x00020},
431 {"product-info", 0x31100, 0x00100},
432 {"signature", 0x32000, 0x00400},
433 {"os-image", 0x40000, 0x300000},
434 {"file-system", 0x340000, 0x470000},
435 {"soft-version", 0x7b0000, 0x00100},
436 {"support-list", 0x7b1000, 0x00400},
437 {"user-config", 0x7c0000, 0x10000},
438 {"default-config", 0x7d0000, 0x10000},
439 {"log", 0x7e0000, 0x10000},
440 {"radio", 0x7f0000, 0x10000},
444 .first_sysupgrade_partition
= "os-image",
445 .last_sysupgrade_partition
= "support-list",
448 /** Firmware layout for the CPE610V1 */
451 .vendor
= "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n",
454 "CPE610(TP-LINK|EU|N300-5|00000000):1.0\r\n"
455 "CPE610(TP-LINK|EU|N300-5|45550000):1.0\r\n"
456 "CPE610(TP-LINK|EU|N300-5|55530000):1.0\r\n"
457 "CPE610(TP-LINK|UN|N300-5|00000000):1.0\r\n"
458 "CPE610(TP-LINK|UN|N300-5|45550000):1.0\r\n"
459 "CPE610(TP-LINK|UN|N300-5|55530000):1.0\r\n"
460 "CPE610(TP-LINK|US|N300-5|55530000):1.0\r\n"
461 "CPE610(TP-LINK|UN|N300-5):1.0\r\n"
462 "CPE610(TP-LINK|EU|N300-5):1.0\r\n"
463 "CPE610(TP-LINK|US|N300-5):1.0\r\n",
464 .support_trail
= '\xff',
468 {"fs-uboot", 0x00000, 0x20000},
469 {"partition-table", 0x20000, 0x02000},
470 {"default-mac", 0x30000, 0x00020},
471 {"product-info", 0x31100, 0x00100},
472 {"signature", 0x32000, 0x00400},
473 {"os-image", 0x40000, 0x300000},
474 {"file-system", 0x340000, 0x470000},
475 {"soft-version", 0x7b0000, 0x00100},
476 {"support-list", 0x7b1000, 0x00400},
477 {"user-config", 0x7c0000, 0x10000},
478 {"default-config", 0x7d0000, 0x10000},
479 {"log", 0x7e0000, 0x10000},
480 {"radio", 0x7f0000, 0x10000},
484 .first_sysupgrade_partition
= "os-image",
485 .last_sysupgrade_partition
= "support-list",
488 /** Firmware layout for the CPE610V2 */
491 .vendor
= "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n",
494 "CPE610(TP-LINK|EU|N300-5|00000000):2.0\r\n"
495 "CPE610(TP-LINK|EU|N300-5|45550000):2.0\r\n"
496 "CPE610(TP-LINK|EU|N300-5|55530000):2.0\r\n"
497 "CPE610(TP-LINK|UN|N300-5|00000000):2.0\r\n"
498 "CPE610(TP-LINK|UN|N300-5|45550000):2.0\r\n"
499 "CPE610(TP-LINK|UN|N300-5|55530000):2.0\r\n"
500 "CPE610(TP-LINK|US|N300-5|55530000):2.0\r\n"
501 "CPE610(TP-LINK|UN|N300-5):2.0\r\n"
502 "CPE610(TP-LINK|EU|N300-5):2.0\r\n"
503 "CPE610(TP-LINK|US|N300-5):2.0\r\n",
504 .support_trail
= '\xff',
508 {"fs-uboot", 0x00000, 0x20000},
509 {"partition-table", 0x20000, 0x02000},
510 {"default-mac", 0x30000, 0x00020},
511 {"product-info", 0x31100, 0x00100},
512 {"signature", 0x32000, 0x00400},
513 {"os-image", 0x40000, 0x300000},
514 {"file-system", 0x340000, 0x470000},
515 {"soft-version", 0x7b0000, 0x00100},
516 {"support-list", 0x7b1000, 0x00400},
517 {"user-config", 0x7c0000, 0x10000},
518 {"default-config", 0x7d0000, 0x10000},
519 {"log", 0x7e0000, 0x10000},
520 {"radio", 0x7f0000, 0x10000},
524 .first_sysupgrade_partition
= "os-image",
525 .last_sysupgrade_partition
= "support-list",
530 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
533 "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
534 "WBS210(TP-LINK|US|N300-2):1.20\r\n"
535 "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
536 .support_trail
= '\xff',
540 {"fs-uboot", 0x00000, 0x20000},
541 {"partition-table", 0x20000, 0x02000},
542 {"default-mac", 0x30000, 0x00020},
543 {"product-info", 0x31100, 0x00100},
544 {"signature", 0x32000, 0x00400},
545 {"os-image", 0x40000, 0x300000},
546 {"file-system", 0x340000, 0x470000},
547 {"soft-version", 0x7b0000, 0x00100},
548 {"support-list", 0x7b1000, 0x00400},
549 {"user-config", 0x7c0000, 0x10000},
550 {"default-config", 0x7d0000, 0x10000},
551 {"log", 0x7e0000, 0x10000},
552 {"radio", 0x7f0000, 0x10000},
556 .first_sysupgrade_partition
= "os-image",
557 .last_sysupgrade_partition
= "support-list",
562 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
565 "WBS210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
566 "WBS210(TP-LINK|US|N300-2|55530000):2.0\r\n"
567 "WBS210(TP-LINK|EU|N300-2|45550000):2.0\r\n",
568 .support_trail
= '\xff',
572 {"fs-uboot", 0x00000, 0x20000},
573 {"partition-table", 0x20000, 0x02000},
574 {"default-mac", 0x30000, 0x00020},
575 {"product-info", 0x31100, 0x00100},
576 {"signature", 0x32000, 0x00400},
577 {"os-image", 0x40000, 0x300000},
578 {"file-system", 0x340000, 0x470000},
579 {"soft-version", 0x7b0000, 0x00100},
580 {"support-list", 0x7b1000, 0x00400},
581 {"user-config", 0x7c0000, 0x10000},
582 {"default-config", 0x7d0000, 0x10000},
583 {"log", 0x7e0000, 0x10000},
584 {"radio", 0x7f0000, 0x10000},
588 .first_sysupgrade_partition
= "os-image",
589 .last_sysupgrade_partition
= "support-list",
594 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
597 "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
598 "WBS510(TP-LINK|US|N300-5):1.20\r\n"
599 "WBS510(TP-LINK|EU|N300-5):1.20\r\n"
600 "WBS510(TP-LINK|CA|N300-5):1.20\r\n",
601 .support_trail
= '\xff',
605 {"fs-uboot", 0x00000, 0x20000},
606 {"partition-table", 0x20000, 0x02000},
607 {"default-mac", 0x30000, 0x00020},
608 {"product-info", 0x31100, 0x00100},
609 {"signature", 0x32000, 0x00400},
610 {"os-image", 0x40000, 0x300000},
611 {"file-system", 0x340000, 0x470000},
612 {"soft-version", 0x7b0000, 0x00100},
613 {"support-list", 0x7b1000, 0x00400},
614 {"user-config", 0x7c0000, 0x10000},
615 {"default-config", 0x7d0000, 0x10000},
616 {"log", 0x7e0000, 0x10000},
617 {"radio", 0x7f0000, 0x10000},
621 .first_sysupgrade_partition
= "os-image",
622 .last_sysupgrade_partition
= "support-list",
627 .vendor
= "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
630 "WBS510(TP-LINK|UN|N300-5|00000000):2.0\r\n"
631 "WBS510(TP-LINK|US|N300-5|55530000):2.0\r\n"
632 "WBS510(TP-LINK|EU|N300-5|45550000):2.0\r\n"
633 "WBS510(TP-LINK|CA|N300-5|43410000):2.0\r\n",
634 .support_trail
= '\xff',
638 {"fs-uboot", 0x00000, 0x20000},
639 {"partition-table", 0x20000, 0x02000},
640 {"default-mac", 0x30000, 0x00020},
641 {"product-info", 0x31100, 0x00100},
642 {"signature", 0x32000, 0x00400},
643 {"os-image", 0x40000, 0x300000},
644 {"file-system", 0x340000, 0x470000},
645 {"soft-version", 0x7b0000, 0x00100},
646 {"support-list", 0x7b1000, 0x00400},
647 {"user-config", 0x7c0000, 0x10000},
648 {"default-config", 0x7d0000, 0x10000},
649 {"log", 0x7e0000, 0x10000},
650 {"radio", 0x7f0000, 0x10000},
654 .first_sysupgrade_partition
= "os-image",
655 .last_sysupgrade_partition
= "support-list",
658 /** Firmware layout for the C2600 */
664 "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
665 .support_trail
= '\x00',
669 We use a bigger os-image partition than the stock images (and thus
670 smaller file-system), as our kernel doesn't fit in the stock firmware's
671 2 MB os-image since kernel 4.14.
674 {"SBL1", 0x00000, 0x20000},
675 {"MIBIB", 0x20000, 0x20000},
676 {"SBL2", 0x40000, 0x20000},
677 {"SBL3", 0x60000, 0x30000},
678 {"DDRCONFIG", 0x90000, 0x10000},
679 {"SSD", 0xa0000, 0x10000},
680 {"TZ", 0xb0000, 0x30000},
681 {"RPM", 0xe0000, 0x20000},
682 {"fs-uboot", 0x100000, 0x70000},
683 {"uboot-env", 0x170000, 0x40000},
684 {"radio", 0x1b0000, 0x40000},
685 {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
686 {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
687 {"default-mac", 0x1ef0000, 0x00200},
688 {"pin", 0x1ef0200, 0x00200},
689 {"product-info", 0x1ef0400, 0x0fc00},
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 A7-V5 */
708 .id
= "ARCHER-A7-V5",
711 "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n"
712 "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n"
713 "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n"
714 "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n"
715 "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n",
716 .support_trail
= '\x00',
717 .soft_ver
= "soft_ver:1.0.0\n",
719 /* We're using a dynamic kernel/rootfs split here */
721 {"factory-boot", 0x00000, 0x20000},
722 {"fs-uboot", 0x20000, 0x20000},
723 {"firmware", 0x40000, 0xec0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
724 /* Stock: name file-system base 0x160000 size 0xda0000 */
725 {"default-mac", 0xf40000, 0x00200},
726 {"pin", 0xf40200, 0x00200},
727 {"device-id", 0xf40400, 0x00100},
728 {"product-info", 0xf40500, 0x0fb00},
729 {"soft-version", 0xf50000, 0x00100},
730 {"extra-para", 0xf51000, 0x01000},
731 {"support-list", 0xf52000, 0x0a000},
732 {"profile", 0xf5c000, 0x04000},
733 {"default-config", 0xf60000, 0x10000},
734 {"user-config", 0xf70000, 0x40000},
735 {"certificate", 0xfb0000, 0x10000},
736 {"partition-table", 0xfc0000, 0x10000},
737 {"log", 0xfd0000, 0x20000},
738 {"radio", 0xff0000, 0x10000},
742 .first_sysupgrade_partition
= "os-image",
743 .last_sysupgrade_partition
= "file-system",
746 /** Firmware layout for the C2v3 */
748 .id
= "ARCHER-C2-V3",
751 "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n"
752 "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n"
753 "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n",
754 .support_trail
= '\x00',
755 .soft_ver
= "soft_ver:3.0.1\n",
757 /** We're using a dynamic kernel/rootfs split here */
760 {"factory-boot", 0x00000, 0x20000},
761 {"fs-uboot", 0x20000, 0x10000},
762 {"firmware", 0x30000, 0x7a0000},
763 {"user-config", 0x7d0000, 0x04000},
764 {"default-mac", 0x7e0000, 0x00100},
765 {"device-id", 0x7e0100, 0x00100},
766 {"extra-para", 0x7e0200, 0x00100},
767 {"pin", 0x7e0300, 0x00100},
768 {"support-list", 0x7e0400, 0x00400},
769 {"soft-version", 0x7e0800, 0x00400},
770 {"product-info", 0x7e0c00, 0x01400},
771 {"partition-table", 0x7e2000, 0x01000},
772 {"profile", 0x7e3000, 0x01000},
773 {"default-config", 0x7e4000, 0x04000},
774 {"merge-config", 0x7ec000, 0x02000},
775 {"qos-db", 0x7ee000, 0x02000},
776 {"radio", 0x7f0000, 0x10000},
780 .first_sysupgrade_partition
= "os-image",
781 .last_sysupgrade_partition
= "file-system",
784 /** Firmware layout for the C25v1 */
786 .id
= "ARCHER-C25-V1",
789 "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
790 "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
791 "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
792 .support_trail
= '\x00',
793 .soft_ver
= "soft_ver:1.0.0\n",
795 /* We're using a dynamic kernel/rootfs split here */
797 {"factory-boot", 0x00000, 0x20000},
798 {"fs-uboot", 0x20000, 0x10000},
799 {"firmware", 0x30000, 0x7a0000}, /* Stock: name os-image base 0x30000 size 0x100000 */
800 /* Stock: name file-system base 0x130000 size 0x6a0000 */
801 {"user-config", 0x7d0000, 0x04000},
802 {"default-mac", 0x7e0000, 0x00100},
803 {"device-id", 0x7e0100, 0x00100},
804 {"extra-para", 0x7e0200, 0x00100},
805 {"pin", 0x7e0300, 0x00100},
806 {"support-list", 0x7e0400, 0x00400},
807 {"soft-version", 0x7e0800, 0x00400},
808 {"product-info", 0x7e0c00, 0x01400},
809 {"partition-table", 0x7e2000, 0x01000},
810 {"profile", 0x7e3000, 0x01000},
811 {"default-config", 0x7e4000, 0x04000},
812 {"merge-config", 0x7ec000, 0x02000},
813 {"qos-db", 0x7ee000, 0x02000},
814 {"radio", 0x7f0000, 0x10000},
818 .first_sysupgrade_partition
= "os-image",
819 .last_sysupgrade_partition
= "file-system",
822 /** Firmware layout for the C58v1 */
824 .id
= "ARCHER-C58-V1",
828 "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
829 "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
830 "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
831 .support_trail
= '\x00',
832 .soft_ver
= "soft_ver:1.0.0\n",
835 {"fs-uboot", 0x00000, 0x10000},
836 {"default-mac", 0x10000, 0x00200},
837 {"pin", 0x10200, 0x00200},
838 {"product-info", 0x10400, 0x00100},
839 {"partition-table", 0x10500, 0x00800},
840 {"soft-version", 0x11300, 0x00200},
841 {"support-list", 0x11500, 0x00100},
842 {"device-id", 0x11600, 0x00100},
843 {"profile", 0x11700, 0x03900},
844 {"default-config", 0x15000, 0x04000},
845 {"user-config", 0x19000, 0x04000},
846 {"firmware", 0x20000, 0x7c8000},
847 {"certyficate", 0x7e8000, 0x08000},
848 {"radio", 0x7f0000, 0x10000},
852 .first_sysupgrade_partition
= "os-image",
853 .last_sysupgrade_partition
= "file-system",
856 /** Firmware layout for the C59v1 */
858 .id
= "ARCHER-C59-V1",
862 "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
863 "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
864 "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
865 "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
866 .support_trail
= '\x00',
867 .soft_ver
= "soft_ver:1.0.0\n",
869 /* We're using a dynamic kernel/rootfs split here */
871 {"fs-uboot", 0x00000, 0x10000},
872 {"default-mac", 0x10000, 0x00200},
873 {"pin", 0x10200, 0x00200},
874 {"device-id", 0x10400, 0x00100},
875 {"product-info", 0x10500, 0x0fb00},
876 {"firmware", 0x20000, 0xe30000},
877 {"partition-table", 0xe50000, 0x10000},
878 {"soft-version", 0xe60000, 0x10000},
879 {"support-list", 0xe70000, 0x10000},
880 {"profile", 0xe80000, 0x10000},
881 {"default-config", 0xe90000, 0x10000},
882 {"user-config", 0xea0000, 0x40000},
883 {"usb-config", 0xee0000, 0x10000},
884 {"certificate", 0xef0000, 0x10000},
885 {"qos-db", 0xf00000, 0x40000},
886 {"log", 0xfe0000, 0x10000},
887 {"radio", 0xff0000, 0x10000},
891 .first_sysupgrade_partition
= "os-image",
892 .last_sysupgrade_partition
= "file-system",
895 /** Firmware layout for the C59v2 */
897 .id
= "ARCHER-C59-V2",
901 "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n"
902 "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n"
903 "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n",
904 .support_trail
= '\x00',
905 .soft_ver
= "soft_ver:2.0.0 Build 20161206 rel.7303\n",
907 /** We're using a dynamic kernel/rootfs split here */
909 {"factory-boot", 0x00000, 0x20000},
910 {"fs-uboot", 0x20000, 0x10000},
911 {"default-mac", 0x30000, 0x00200},
912 {"pin", 0x30200, 0x00200},
913 {"device-id", 0x30400, 0x00100},
914 {"product-info", 0x30500, 0x0fb00},
915 {"firmware", 0x40000, 0xe10000},
916 {"partition-table", 0xe50000, 0x10000},
917 {"soft-version", 0xe60000, 0x10000},
918 {"support-list", 0xe70000, 0x10000},
919 {"profile", 0xe80000, 0x10000},
920 {"default-config", 0xe90000, 0x10000},
921 {"user-config", 0xea0000, 0x40000},
922 {"usb-config", 0xee0000, 0x10000},
923 {"certificate", 0xef0000, 0x10000},
924 {"extra-para", 0xf00000, 0x10000},
925 {"qos-db", 0xf10000, 0x30000},
926 {"log", 0xfe0000, 0x10000},
927 {"radio", 0xff0000, 0x10000},
931 .first_sysupgrade_partition
= "os-image",
932 .last_sysupgrade_partition
= "file-system",
935 /** Firmware layout for the Archer C6 v2 (EU/RU/JP) */
937 .id
= "ARCHER-C6-V2",
941 "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n"
942 "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n"
943 "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n",
944 .support_trail
= '\x00',
945 .soft_ver
= "soft_ver:1.9.1\n",
948 {"fs-uboot", 0x00000, 0x20000},
949 {"default-mac", 0x20000, 0x00200},
950 {"pin", 0x20200, 0x00100},
951 {"product-info", 0x20300, 0x00200},
952 {"device-id", 0x20500, 0x0fb00},
953 {"firmware", 0x30000, 0x7a9400},
954 {"soft-version", 0x7d9400, 0x00100},
955 {"extra-para", 0x7d9500, 0x00100},
956 {"support-list", 0x7d9600, 0x00200},
957 {"profile", 0x7d9800, 0x03000},
958 {"default-config", 0x7dc800, 0x03000},
959 {"partition-table", 0x7df800, 0x00800},
960 {"user-config", 0x7e0000, 0x0c000},
961 {"certificate", 0x7ec000, 0x04000},
962 {"radio", 0x7f0000, 0x10000},
966 .first_sysupgrade_partition
= "os-image",
967 .last_sysupgrade_partition
= "file-system",
970 /** Firmware layout for the Archer C6 v2 (US) and A6 v2 (US/TW) */
972 .id
= "ARCHER-C6-V2-US",
976 "{product_name:Archer A6,product_ver:2.0.0,special_id:55530000}\n"
977 "{product_name:Archer A6,product_ver:2.0.0,special_id:54570000}\n"
978 "{product_name:Archer C6,product_ver:2.0.0,special_id:55530000}\n",
979 .support_trail
= '\x00',
980 .soft_ver
= "soft_ver:1.9.1\n",
983 {"factory-boot", 0x00000, 0x20000},
984 {"default-mac", 0x20000, 0x00200},
985 {"pin", 0x20200, 0x00100},
986 {"product-info", 0x20300, 0x00200},
987 {"device-id", 0x20500, 0x0fb00},
988 {"fs-uboot", 0x30000, 0x20000},
989 {"firmware", 0x50000, 0xf89400},
990 {"soft-version", 0xfd9400, 0x00100},
991 {"extra-para", 0xfd9500, 0x00100},
992 {"support-list", 0xfd9600, 0x00200},
993 {"profile", 0xfd9800, 0x03000},
994 {"default-config", 0xfdc800, 0x03000},
995 {"partition-table", 0xfdf800, 0x00800},
996 {"user-config", 0xfe0000, 0x0c000},
997 {"certificate", 0xfec000, 0x04000},
998 {"radio", 0xff0000, 0x10000},
1001 .first_sysupgrade_partition
= "os-image",
1002 .last_sysupgrade_partition
= "file-system",
1005 /** Firmware layout for the C60v1 */
1007 .id
= "ARCHER-C60-V1",
1011 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
1012 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
1013 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
1014 .support_trail
= '\x00',
1015 .soft_ver
= "soft_ver:1.0.0\n",
1018 {"fs-uboot", 0x00000, 0x10000},
1019 {"default-mac", 0x10000, 0x00200},
1020 {"pin", 0x10200, 0x00200},
1021 {"product-info", 0x10400, 0x00100},
1022 {"partition-table", 0x10500, 0x00800},
1023 {"soft-version", 0x11300, 0x00200},
1024 {"support-list", 0x11500, 0x00100},
1025 {"device-id", 0x11600, 0x00100},
1026 {"profile", 0x11700, 0x03900},
1027 {"default-config", 0x15000, 0x04000},
1028 {"user-config", 0x19000, 0x04000},
1029 {"firmware", 0x20000, 0x7c8000},
1030 {"certyficate", 0x7e8000, 0x08000},
1031 {"radio", 0x7f0000, 0x10000},
1035 .first_sysupgrade_partition
= "os-image",
1036 .last_sysupgrade_partition
= "file-system",
1039 /** Firmware layout for the C60v2 */
1041 .id
= "ARCHER-C60-V2",
1045 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
1046 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
1047 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
1048 .support_trail
= '\x00',
1049 .soft_ver
= "soft_ver:2.0.0\n",
1052 {"factory-boot", 0x00000, 0x1fb00},
1053 {"default-mac", 0x1fb00, 0x00200},
1054 {"pin", 0x1fd00, 0x00100},
1055 {"product-info", 0x1fe00, 0x00100},
1056 {"device-id", 0x1ff00, 0x00100},
1057 {"fs-uboot", 0x20000, 0x10000},
1058 {"firmware", 0x30000, 0x7a0000},
1059 {"soft-version", 0x7d9500, 0x00100},
1060 {"support-list", 0x7d9600, 0x00100},
1061 {"extra-para", 0x7d9700, 0x00100},
1062 {"profile", 0x7d9800, 0x03000},
1063 {"default-config", 0x7dc800, 0x03000},
1064 {"partition-table", 0x7df800, 0x00800},
1065 {"user-config", 0x7e0000, 0x0c000},
1066 {"certificate", 0x7ec000, 0x04000},
1067 {"radio", 0x7f0000, 0x10000},
1071 .first_sysupgrade_partition
= "os-image",
1072 .last_sysupgrade_partition
= "file-system",
1075 /** Firmware layout for the C60v3 */
1077 .id
= "ARCHER-C60-V3",
1081 "{product_name:Archer C60,product_ver:3.0.0,special_id:42520000}\r\n"
1082 "{product_name:Archer C60,product_ver:3.0.0,special_id:45550000}\r\n"
1083 "{product_name:Archer C60,product_ver:3.0.0,special_id:55530000}\r\n",
1084 .support_trail
= '\x00',
1085 .soft_ver
= "soft_ver:3.0.0\n",
1088 {"factory-boot", 0x00000, 0x1fb00},
1089 {"default-mac", 0x1fb00, 0x00200},
1090 {"pin", 0x1fd00, 0x00100},
1091 {"product-info", 0x1fe00, 0x00100},
1092 {"device-id", 0x1ff00, 0x00100},
1093 {"fs-uboot", 0x20000, 0x10000},
1094 {"firmware", 0x30000, 0x7a0000},
1095 {"soft-version", 0x7d9500, 0x00100},
1096 {"support-list", 0x7d9600, 0x00100},
1097 {"extra-para", 0x7d9700, 0x00100},
1098 {"profile", 0x7d9800, 0x03000},
1099 {"default-config", 0x7dc800, 0x03000},
1100 {"partition-table", 0x7df800, 0x00800},
1101 {"user-config", 0x7e0000, 0x0c000},
1102 {"certificate", 0x7ec000, 0x04000},
1103 {"radio", 0x7f0000, 0x10000},
1107 .first_sysupgrade_partition
= "os-image",
1108 .last_sysupgrade_partition
= "file-system",
1111 /** Firmware layout for the C5 */
1113 .id
= "ARCHER-C5-V2",
1117 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
1118 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
1119 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
1120 .support_trail
= '\x00',
1124 {"fs-uboot", 0x00000, 0x40000},
1125 {"os-image", 0x40000, 0x200000},
1126 {"file-system", 0x240000, 0xc00000},
1127 {"default-mac", 0xe40000, 0x00200},
1128 {"pin", 0xe40200, 0x00200},
1129 {"product-info", 0xe40400, 0x00200},
1130 {"partition-table", 0xe50000, 0x10000},
1131 {"soft-version", 0xe60000, 0x00200},
1132 {"support-list", 0xe61000, 0x0f000},
1133 {"profile", 0xe70000, 0x10000},
1134 {"default-config", 0xe80000, 0x10000},
1135 {"user-config", 0xe90000, 0x50000},
1136 {"log", 0xee0000, 0x100000},
1137 {"radio_bk", 0xfe0000, 0x10000},
1138 {"radio", 0xff0000, 0x10000},
1142 .first_sysupgrade_partition
= "os-image",
1143 .last_sysupgrade_partition
= "file-system"
1146 /** Firmware layout for the C7 */
1148 .id
= "ARCHER-C7-V4",
1151 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
1152 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
1153 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
1154 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
1155 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
1156 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
1157 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
1158 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
1159 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
1160 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
1161 .support_trail
= '\x00',
1162 .soft_ver
= "soft_ver:1.0.0\n",
1164 /* We're using a dynamic kernel/rootfs split here */
1166 {"factory-boot", 0x00000, 0x20000},
1167 {"fs-uboot", 0x20000, 0x20000},
1168 {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */
1169 /* Stock: name file-system base 0x160000 size 0xda0000 */
1170 {"default-mac", 0xf00000, 0x00200},
1171 {"pin", 0xf00200, 0x00200},
1172 {"device-id", 0xf00400, 0x00100},
1173 {"product-info", 0xf00500, 0x0fb00},
1174 {"soft-version", 0xf10000, 0x00100},
1175 {"extra-para", 0xf11000, 0x01000},
1176 {"support-list", 0xf12000, 0x0a000},
1177 {"profile", 0xf1c000, 0x04000},
1178 {"default-config", 0xf20000, 0x10000},
1179 {"user-config", 0xf30000, 0x40000},
1180 {"qos-db", 0xf70000, 0x40000},
1181 {"certificate", 0xfb0000, 0x10000},
1182 {"partition-table", 0xfc0000, 0x10000},
1183 {"log", 0xfd0000, 0x20000},
1184 {"radio", 0xff0000, 0x10000},
1188 .first_sysupgrade_partition
= "os-image",
1189 .last_sysupgrade_partition
= "file-system",
1192 /** Firmware layout for the C7 v5*/
1194 .id
= "ARCHER-C7-V5",
1197 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
1198 "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n"
1199 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n"
1200 "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n"
1201 "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n"
1202 "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n"
1203 "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n"
1204 "{product_name:Archer C7,product_ver:5.0.0,special_id:4B520000}\n",
1206 .support_trail
= '\x00',
1207 .soft_ver
= "soft_ver:1.0.0\n",
1209 /* We're using a dynamic kernel/rootfs split here */
1211 {"factory-boot", 0x00000, 0x20000},
1212 {"fs-uboot", 0x20000, 0x20000},
1213 {"partition-table", 0x40000, 0x10000},
1214 {"radio", 0x50000, 0x10000},
1215 {"default-mac", 0x60000, 0x00200},
1216 {"pin", 0x60200, 0x00200},
1217 {"device-id", 0x60400, 0x00100},
1218 {"product-info", 0x60500, 0x0fb00},
1219 {"soft-version", 0x70000, 0x01000},
1220 {"extra-para", 0x71000, 0x01000},
1221 {"support-list", 0x72000, 0x0a000},
1222 {"profile", 0x7c000, 0x04000},
1223 {"user-config", 0x80000, 0x40000},
1226 {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */
1227 /* Stock: name file-system base 0x1e0000 size 0xde0000 */
1229 {"log", 0xfc0000, 0x20000},
1230 {"certificate", 0xfe0000, 0x10000},
1231 {"default-config", 0xff0000, 0x10000},
1236 .first_sysupgrade_partition
= "os-image",
1237 .last_sysupgrade_partition
= "file-system",
1240 /** Firmware layout for the C9 */
1246 "{product_name:ArcherC9,"
1247 "product_ver:1.0.0,"
1248 "special_id:00000000}\n",
1249 .support_trail
= '\x00',
1253 {"fs-uboot", 0x00000, 0x40000},
1254 {"os-image", 0x40000, 0x200000},
1255 {"file-system", 0x240000, 0xc00000},
1256 {"default-mac", 0xe40000, 0x00200},
1257 {"pin", 0xe40200, 0x00200},
1258 {"product-info", 0xe40400, 0x00200},
1259 {"partition-table", 0xe50000, 0x10000},
1260 {"soft-version", 0xe60000, 0x00200},
1261 {"support-list", 0xe61000, 0x0f000},
1262 {"profile", 0xe70000, 0x10000},
1263 {"default-config", 0xe80000, 0x10000},
1264 {"user-config", 0xe90000, 0x50000},
1265 {"log", 0xee0000, 0x100000},
1266 {"radio_bk", 0xfe0000, 0x10000},
1267 {"radio", 0xff0000, 0x10000},
1271 .first_sysupgrade_partition
= "os-image",
1272 .last_sysupgrade_partition
= "file-system"
1275 /** Firmware layout for the EAP120 */
1278 .vendor
= "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1281 "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
1282 .support_trail
= '\xff',
1286 {"fs-uboot", 0x00000, 0x20000},
1287 {"partition-table", 0x20000, 0x02000},
1288 {"default-mac", 0x30000, 0x00020},
1289 {"support-list", 0x31000, 0x00100},
1290 {"product-info", 0x31100, 0x00100},
1291 {"soft-version", 0x32000, 0x00100},
1292 {"os-image", 0x40000, 0x180000},
1293 {"file-system", 0x1c0000, 0x600000},
1294 {"user-config", 0x7c0000, 0x10000},
1295 {"backup-config", 0x7d0000, 0x10000},
1296 {"log", 0x7e0000, 0x10000},
1297 {"radio", 0x7f0000, 0x10000},
1301 .first_sysupgrade_partition
= "os-image",
1302 .last_sysupgrade_partition
= "file-system"
1305 /** Firmware layout for the EAP225-Outdoor v1 */
1307 .id
= "EAP225-OUTDOOR-V1",
1310 "EAP225-Outdoor(TP-Link|UN|AC1200-D):1.0\r\n",
1311 .support_trail
= '\xff',
1313 .soft_ver_compat_level
= 1,
1316 {"fs-uboot", 0x00000, 0x20000},
1317 {"partition-table", 0x20000, 0x02000},
1318 {"default-mac", 0x30000, 0x01000},
1319 {"support-list", 0x31000, 0x00100},
1320 {"product-info", 0x31100, 0x00400},
1321 {"soft-version", 0x32000, 0x00100},
1322 {"firmware", 0x40000, 0xd80000},
1323 {"user-config", 0xdc0000, 0x30000},
1324 {"mutil-log", 0xf30000, 0x80000},
1325 {"oops", 0xfb0000, 0x40000},
1326 {"radio", 0xff0000, 0x10000},
1330 .first_sysupgrade_partition
= "os-image",
1331 .last_sysupgrade_partition
= "file-system"
1334 /** Firmware layout for the EAP225 v3 */
1339 "EAP225(TP-Link|UN|AC1350-D):3.0\r\n",
1340 .support_trail
= '\xff',
1342 .soft_ver_compat_level
= 1,
1345 {"fs-uboot", 0x00000, 0x20000},
1346 {"partition-table", 0x20000, 0x02000},
1347 {"default-mac", 0x30000, 0x01000},
1348 {"support-list", 0x31000, 0x00100},
1349 {"product-info", 0x31100, 0x00400},
1350 {"soft-version", 0x32000, 0x00100},
1351 {"firmware", 0x40000, 0xd80000},
1352 {"user-config", 0xdc0000, 0x30000},
1353 {"mutil-log", 0xf30000, 0x80000},
1354 {"oops", 0xfb0000, 0x40000},
1355 {"radio", 0xff0000, 0x10000},
1359 .first_sysupgrade_partition
= "os-image",
1360 .last_sysupgrade_partition
= "file-system"
1363 /** Firmware layout for the EAP225-Wall v2 */
1365 .id
= "EAP225-WALL-V2",
1368 "EAP225-Wall(TP-Link|UN|AC1200-D):2.0\r\n",
1369 .support_trail
= '\xff',
1371 .soft_ver_compat_level
= 1,
1374 {"fs-uboot", 0x00000, 0x20000},
1375 {"partition-table", 0x20000, 0x02000},
1376 {"default-mac", 0x30000, 0x01000},
1377 {"support-list", 0x31000, 0x00100},
1378 {"product-info", 0x31100, 0x00400},
1379 {"soft-version", 0x32000, 0x00100},
1380 {"firmware", 0x40000, 0xd80000},
1381 {"user-config", 0xdc0000, 0x30000},
1382 {"mutil-log", 0xf30000, 0x80000},
1383 {"oops", 0xfb0000, 0x40000},
1384 {"radio", 0xff0000, 0x10000},
1388 .first_sysupgrade_partition
= "os-image",
1389 .last_sysupgrade_partition
= "file-system"
1392 /** Firmware layout for the EAP245 v1 */
1397 "EAP245(TP-LINK|UN|AC1750-D):1.0\r\n",
1398 .support_trail
= '\xff',
1402 {"fs-uboot", 0x00000, 0x20000},
1403 {"partition-table", 0x20000, 0x02000},
1404 {"default-mac", 0x30000, 0x01000},
1405 {"support-list", 0x31000, 0x00100},
1406 {"product-info", 0x31100, 0x00400},
1407 {"soft-version", 0x32000, 0x00100},
1408 {"firmware", 0x40000, 0xd80000},
1409 {"user-config", 0xdc0000, 0x30000},
1410 {"radio", 0xff0000, 0x10000},
1414 .first_sysupgrade_partition
= "os-image",
1415 .last_sysupgrade_partition
= "file-system"
1418 /** Firmware layout for the EAP245 v3 */
1423 "EAP245(TP-Link|UN|AC1750-D):3.0\r\n",
1424 .support_trail
= '\xff',
1426 .soft_ver_compat_level
= 1,
1428 /** Firmware partition with dynamic kernel/rootfs split */
1430 {"factroy-boot", 0x00000, 0x40000},
1431 {"fs-uboot", 0x40000, 0x40000},
1432 {"partition-table", 0x80000, 0x10000},
1433 {"default-mac", 0x90000, 0x01000},
1434 {"support-list", 0x91000, 0x00100},
1435 {"product-info", 0x91100, 0x00400},
1436 {"soft-version", 0x92000, 0x00100},
1437 {"radio", 0xa0000, 0x10000},
1438 {"extra-para", 0xb0000, 0x10000},
1439 {"firmware", 0xc0000, 0xe40000},
1440 {"config", 0xf00000, 0x30000},
1441 {"mutil-log", 0xf30000, 0x80000},
1442 {"oops", 0xfb0000, 0x40000},
1446 .first_sysupgrade_partition
= "os-image",
1447 .last_sysupgrade_partition
= "file-system"
1450 /** Firmware layout for the TL-WA850RE v2 */
1452 .id
= "TLWA850REV2",
1456 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
1457 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
1458 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
1459 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
1460 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
1461 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
1462 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
1463 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
1464 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
1465 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
1466 .support_trail
= '\x00',
1470 576KB were moved from file-system to os-image
1471 in comparison to the stock image
1474 {"fs-uboot", 0x00000, 0x20000},
1475 {"firmware", 0x20000, 0x390000},
1476 {"partition-table", 0x3b0000, 0x02000},
1477 {"default-mac", 0x3c0000, 0x00020},
1478 {"pin", 0x3c0100, 0x00020},
1479 {"product-info", 0x3c1000, 0x01000},
1480 {"soft-version", 0x3c2000, 0x00100},
1481 {"support-list", 0x3c3000, 0x01000},
1482 {"profile", 0x3c4000, 0x08000},
1483 {"user-config", 0x3d0000, 0x10000},
1484 {"default-config", 0x3e0000, 0x10000},
1485 {"radio", 0x3f0000, 0x10000},
1489 .first_sysupgrade_partition
= "os-image",
1490 .last_sysupgrade_partition
= "file-system"
1493 /** Firmware layout for the TL-WA855RE v1 */
1495 .id
= "TLWA855REV1",
1499 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
1500 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
1501 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
1502 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
1503 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
1504 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
1505 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
1506 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
1507 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
1508 .support_trail
= '\x00',
1512 {"fs-uboot", 0x00000, 0x20000},
1513 {"os-image", 0x20000, 0x150000},
1514 {"file-system", 0x170000, 0x240000},
1515 {"partition-table", 0x3b0000, 0x02000},
1516 {"default-mac", 0x3c0000, 0x00020},
1517 {"pin", 0x3c0100, 0x00020},
1518 {"product-info", 0x3c1000, 0x01000},
1519 {"soft-version", 0x3c2000, 0x00100},
1520 {"support-list", 0x3c3000, 0x01000},
1521 {"profile", 0x3c4000, 0x08000},
1522 {"user-config", 0x3d0000, 0x10000},
1523 {"default-config", 0x3e0000, 0x10000},
1524 {"radio", 0x3f0000, 0x10000},
1528 .first_sysupgrade_partition
= "os-image",
1529 .last_sysupgrade_partition
= "file-system"
1532 /** Firmware layout for the TL-WPA8630P v2 (EU)*/
1534 .id
= "TL-WPA8630P-V2.0-EU",
1538 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:45550000}\n",
1539 .support_trail
= '\x00',
1543 {"factory-uboot", 0x00000, 0x20000},
1544 {"fs-uboot", 0x20000, 0x20000},
1545 {"firmware", 0x40000, 0x5e0000},
1546 {"partition-table", 0x620000, 0x02000},
1547 {"default-mac", 0x630000, 0x00020},
1548 {"pin", 0x630100, 0x00020},
1549 {"device-id", 0x630200, 0x00030},
1550 {"product-info", 0x631100, 0x01000},
1551 {"extra-para", 0x632100, 0x01000},
1552 {"soft-version", 0x640000, 0x01000},
1553 {"support-list", 0x641000, 0x01000},
1554 {"profile", 0x642000, 0x08000},
1555 {"user-config", 0x650000, 0x10000},
1556 {"default-config", 0x660000, 0x10000},
1557 {"default-nvm", 0x670000, 0xc0000},
1558 {"default-pib", 0x730000, 0x40000},
1559 {"radio", 0x7f0000, 0x10000},
1563 .first_sysupgrade_partition
= "os-image",
1564 .last_sysupgrade_partition
= "file-system"
1567 /** Firmware layout for the TL-WPA8630P v2 (INT)*/
1569 .id
= "TL-WPA8630P-V2-INT",
1573 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:41550000}\n"
1574 "{product_name:TL-WPA8630P,product_ver:2.0.0,special_id:44450000}\n"
1575 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:41550000}\n",
1576 .support_trail
= '\x00',
1580 {"factory-uboot", 0x00000, 0x20000},
1581 {"fs-uboot", 0x20000, 0x20000},
1582 {"firmware", 0x40000, 0x5e0000},
1583 {"partition-table", 0x620000, 0x02000},
1584 {"extra-para", 0x632100, 0x01000},
1585 {"soft-version", 0x640000, 0x01000},
1586 {"support-list", 0x641000, 0x01000},
1587 {"profile", 0x642000, 0x08000},
1588 {"user-config", 0x650000, 0x10000},
1589 {"default-config", 0x660000, 0x10000},
1590 {"default-nvm", 0x670000, 0xc0000},
1591 {"default-pib", 0x730000, 0x40000},
1592 {"default-mac", 0x7e0000, 0x00020},
1593 {"pin", 0x7e0100, 0x00020},
1594 {"device-id", 0x7e0200, 0x00030},
1595 {"product-info", 0x7e1100, 0x01000},
1596 {"radio", 0x7f0000, 0x10000},
1600 .first_sysupgrade_partition
= "os-image",
1601 .last_sysupgrade_partition
= "file-system"
1604 /** Firmware layout for the TL-WPA8630P v2.1 (EU)*/
1606 .id
= "TL-WPA8630P-V2.1-EU",
1610 "{product_name:TL-WPA8630P,product_ver:2.1.0,special_id:45550000}\n",
1611 .support_trail
= '\x00',
1615 {"factory-uboot", 0x00000, 0x20000},
1616 {"fs-uboot", 0x20000, 0x20000},
1617 {"firmware", 0x40000, 0x5e0000},
1618 {"extra-para", 0x680000, 0x01000},
1619 {"product-info", 0x690000, 0x01000},
1620 {"partition-table", 0x6a0000, 0x02000},
1621 {"soft-version", 0x6b0000, 0x01000},
1622 {"support-list", 0x6b1000, 0x01000},
1623 {"profile", 0x6b2000, 0x08000},
1624 {"user-config", 0x6c0000, 0x10000},
1625 {"default-config", 0x6d0000, 0x10000},
1626 {"default-nvm", 0x6e0000, 0xc0000},
1627 {"default-pib", 0x7a0000, 0x40000},
1628 {"default-mac", 0x7e0000, 0x00020},
1629 {"pin", 0x7e0100, 0x00020},
1630 {"device-id", 0x7e0200, 0x00030},
1631 {"radio", 0x7f0000, 0x10000},
1635 .first_sysupgrade_partition
= "os-image",
1636 .last_sysupgrade_partition
= "file-system"
1639 /** Firmware layout for the TL-WR1043 v5 */
1641 .id
= "TLWR1043NV5",
1645 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
1646 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
1647 .support_trail
= '\x00',
1648 .soft_ver
= "soft_ver:1.0.0\n",
1650 {"factory-boot", 0x00000, 0x20000},
1651 {"fs-uboot", 0x20000, 0x20000},
1652 {"firmware", 0x40000, 0xec0000},
1653 {"default-mac", 0xf00000, 0x00200},
1654 {"pin", 0xf00200, 0x00200},
1655 {"device-id", 0xf00400, 0x00100},
1656 {"product-info", 0xf00500, 0x0fb00},
1657 {"soft-version", 0xf10000, 0x01000},
1658 {"extra-para", 0xf11000, 0x01000},
1659 {"support-list", 0xf12000, 0x0a000},
1660 {"profile", 0xf1c000, 0x04000},
1661 {"default-config", 0xf20000, 0x10000},
1662 {"user-config", 0xf30000, 0x40000},
1663 {"qos-db", 0xf70000, 0x40000},
1664 {"certificate", 0xfb0000, 0x10000},
1665 {"partition-table", 0xfc0000, 0x10000},
1666 {"log", 0xfd0000, 0x20000},
1667 {"radio", 0xff0000, 0x10000},
1670 .first_sysupgrade_partition
= "os-image",
1671 .last_sysupgrade_partition
= "file-system"
1674 /** Firmware layout for the TL-WR1043 v4 */
1676 .id
= "TLWR1043NDV4",
1680 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
1681 .support_trail
= '\x00',
1684 /* We're using a dynamic kernel/rootfs split here */
1686 {"fs-uboot", 0x00000, 0x20000},
1687 {"firmware", 0x20000, 0xf30000},
1688 {"default-mac", 0xf50000, 0x00200},
1689 {"pin", 0xf50200, 0x00200},
1690 {"product-info", 0xf50400, 0x0fc00},
1691 {"soft-version", 0xf60000, 0x0b000},
1692 {"support-list", 0xf6b000, 0x04000},
1693 {"profile", 0xf70000, 0x04000},
1694 {"default-config", 0xf74000, 0x0b000},
1695 {"user-config", 0xf80000, 0x40000},
1696 {"partition-table", 0xfc0000, 0x10000},
1697 {"log", 0xfd0000, 0x20000},
1698 {"radio", 0xff0000, 0x10000},
1702 .first_sysupgrade_partition
= "os-image",
1703 .last_sysupgrade_partition
= "file-system"
1706 /** Firmware layout for the TL-WR902AC v1 */
1708 .id
= "TL-WR902AC-V1",
1712 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
1713 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
1714 .support_trail
= '\x00',
1718 384KB were moved from file-system to os-image
1719 in comparison to the stock image
1722 {"fs-uboot", 0x00000, 0x20000},
1723 {"firmware", 0x20000, 0x730000},
1724 {"default-mac", 0x750000, 0x00200},
1725 {"pin", 0x750200, 0x00200},
1726 {"product-info", 0x750400, 0x0fc00},
1727 {"soft-version", 0x760000, 0x0b000},
1728 {"support-list", 0x76b000, 0x04000},
1729 {"profile", 0x770000, 0x04000},
1730 {"default-config", 0x774000, 0x0b000},
1731 {"user-config", 0x780000, 0x40000},
1732 {"partition-table", 0x7c0000, 0x10000},
1733 {"log", 0x7d0000, 0x20000},
1734 {"radio", 0x7f0000, 0x10000},
1738 .first_sysupgrade_partition
= "os-image",
1739 .last_sysupgrade_partition
= "file-system",
1742 /** Firmware layout for the TL-WR942N V1 */
1748 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
1749 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
1750 .support_trail
= '\x00',
1754 {"fs-uboot", 0x00000, 0x20000},
1755 {"firmware", 0x20000, 0xe20000},
1756 {"default-mac", 0xe40000, 0x00200},
1757 {"pin", 0xe40200, 0x00200},
1758 {"product-info", 0xe40400, 0x0fc00},
1759 {"partition-table", 0xe50000, 0x10000},
1760 {"soft-version", 0xe60000, 0x10000},
1761 {"support-list", 0xe70000, 0x10000},
1762 {"profile", 0xe80000, 0x10000},
1763 {"default-config", 0xe90000, 0x10000},
1764 {"user-config", 0xea0000, 0x40000},
1765 {"qos-db", 0xee0000, 0x40000},
1766 {"certificate", 0xf20000, 0x10000},
1767 {"usb-config", 0xfb0000, 0x10000},
1768 {"log", 0xfc0000, 0x20000},
1769 {"radio-bk", 0xfe0000, 0x10000},
1770 {"radio", 0xff0000, 0x10000},
1774 .first_sysupgrade_partition
= "os-image",
1775 .last_sysupgrade_partition
= "file-system",
1778 /** Firmware layout for the RE200 v2 */
1784 "{product_name:RE200,product_ver:2.0.0,special_id:00000000}\n"
1785 "{product_name:RE200,product_ver:2.0.0,special_id:41520000}\n"
1786 "{product_name:RE200,product_ver:2.0.0,special_id:41550000}\n"
1787 "{product_name:RE200,product_ver:2.0.0,special_id:42520000}\n"
1788 "{product_name:RE200,product_ver:2.0.0,special_id:43410000}\n"
1789 "{product_name:RE200,product_ver:2.0.0,special_id:45530000}\n"
1790 "{product_name:RE200,product_ver:2.0.0,special_id:45550000}\n"
1791 "{product_name:RE200,product_ver:2.0.0,special_id:49440000}\n"
1792 "{product_name:RE200,product_ver:2.0.0,special_id:4a500000}\n"
1793 "{product_name:RE200,product_ver:2.0.0,special_id:4b520000}\n"
1794 "{product_name:RE200,product_ver:2.0.0,special_id:52550000}\n"
1795 "{product_name:RE200,product_ver:2.0.0,special_id:54570000}\n"
1796 "{product_name:RE200,product_ver:2.0.0,special_id:55530000}\n",
1797 .support_trail
= '\x00',
1801 {"fs-uboot", 0x00000, 0x20000},
1802 {"firmware", 0x20000, 0x7a0000},
1803 {"partition-table", 0x7c0000, 0x02000},
1804 {"default-mac", 0x7c2000, 0x00020},
1805 {"pin", 0x7c2100, 0x00020},
1806 {"product-info", 0x7c3100, 0x01000},
1807 {"soft-version", 0x7c4200, 0x01000},
1808 {"support-list", 0x7c5200, 0x01000},
1809 {"profile", 0x7c6200, 0x08000},
1810 {"config-info", 0x7ce200, 0x00400},
1811 {"user-config", 0x7d0000, 0x10000},
1812 {"default-config", 0x7e0000, 0x10000},
1813 {"radio", 0x7f0000, 0x10000},
1817 .first_sysupgrade_partition
= "os-image",
1818 .last_sysupgrade_partition
= "file-system"
1821 /** Firmware layout for the RE200 v3 */
1827 "{product_name:RE200,product_ver:3.0.0,special_id:00000000}\n"
1828 "{product_name:RE200,product_ver:3.0.0,special_id:41520000}\n"
1829 "{product_name:RE200,product_ver:3.0.0,special_id:41550000}\n"
1830 "{product_name:RE200,product_ver:3.0.0,special_id:42520000}\n"
1831 "{product_name:RE200,product_ver:3.0.0,special_id:43410000}\n"
1832 "{product_name:RE200,product_ver:3.0.0,special_id:45470000}\n"
1833 "{product_name:RE200,product_ver:3.0.0,special_id:45530000}\n"
1834 "{product_name:RE200,product_ver:3.0.0,special_id:45550000}\n"
1835 "{product_name:RE200,product_ver:3.0.0,special_id:49440000}\n"
1836 "{product_name:RE200,product_ver:3.0.0,special_id:4A500000}\n"
1837 "{product_name:RE200,product_ver:3.0.0,special_id:4B520000}\n"
1838 "{product_name:RE200,product_ver:3.0.0,special_id:52550000}\n"
1839 "{product_name:RE200,product_ver:3.0.0,special_id:54570000}\n"
1840 "{product_name:RE200,product_ver:3.0.0,special_id:55530000}\n",
1841 .support_trail
= '\x00',
1845 {"fs-uboot", 0x00000, 0x20000},
1846 {"firmware", 0x20000, 0x7a0000},
1847 {"partition-table", 0x7c0000, 0x02000},
1848 {"default-mac", 0x7c2000, 0x00020},
1849 {"pin", 0x7c2100, 0x00020},
1850 {"product-info", 0x7c3100, 0x01000},
1851 {"soft-version", 0x7c4200, 0x01000},
1852 {"support-list", 0x7c5200, 0x01000},
1853 {"profile", 0x7c6200, 0x08000},
1854 {"config-info", 0x7ce200, 0x00400},
1855 {"user-config", 0x7d0000, 0x10000},
1856 {"default-config", 0x7e0000, 0x10000},
1857 {"radio", 0x7f0000, 0x10000},
1861 .first_sysupgrade_partition
= "os-image",
1862 .last_sysupgrade_partition
= "file-system"
1865 /** Firmware layout for the RE200 v4 */
1871 "{product_name:RE200,product_ver:4.0.0,special_id:00000000}\n"
1872 "{product_name:RE200,product_ver:4.0.0,special_id:45550000}\n"
1873 "{product_name:RE200,product_ver:4.0.0,special_id:4A500000}\n"
1874 "{product_name:RE200,product_ver:4.0.0,special_id:4B520000}\n"
1875 "{product_name:RE200,product_ver:4.0.0,special_id:43410000}\n"
1876 "{product_name:RE200,product_ver:4.0.0,special_id:41550000}\n"
1877 "{product_name:RE200,product_ver:4.0.0,special_id:42520000}\n"
1878 "{product_name:RE200,product_ver:4.0.0,special_id:55530000}\n"
1879 "{product_name:RE200,product_ver:4.0.0,special_id:41520000}\n"
1880 "{product_name:RE200,product_ver:4.0.0,special_id:52550000}\n"
1881 "{product_name:RE200,product_ver:4.0.0,special_id:54570000}\n"
1882 "{product_name:RE200,product_ver:4.0.0,special_id:45530000}\n"
1883 "{product_name:RE200,product_ver:4.0.0,special_id:49440000}\n"
1884 "{product_name:RE200,product_ver:4.0.0,special_id:45470000}\n",
1885 .support_trail
= '\x00',
1886 .soft_ver
= "soft_ver:1.1.0\n",
1889 {"fs-uboot", 0x00000, 0x20000},
1890 {"firmware", 0x20000, 0x7a0000},
1891 {"partition-table", 0x7c0000, 0x02000},
1892 {"default-mac", 0x7c2000, 0x00020},
1893 {"pin", 0x7c2100, 0x00020},
1894 {"product-info", 0x7c3100, 0x01000},
1895 {"soft-version", 0x7c4200, 0x01000},
1896 {"support-list", 0x7c5200, 0x01000},
1897 {"profile", 0x7c6200, 0x08000},
1898 {"config-info", 0x7ce200, 0x00400},
1899 {"user-config", 0x7d0000, 0x10000},
1900 {"default-config", 0x7e0000, 0x10000},
1901 {"radio", 0x7f0000, 0x10000},
1905 .first_sysupgrade_partition
= "os-image",
1906 .last_sysupgrade_partition
= "file-system"
1909 /** Firmware layout for the RE220 v2 */
1915 "{product_name:RE220,product_ver:2.0.0,special_id:00000000}\n"
1916 "{product_name:RE220,product_ver:2.0.0,special_id:41520000}\n"
1917 "{product_name:RE220,product_ver:2.0.0,special_id:41550000}\n"
1918 "{product_name:RE220,product_ver:2.0.0,special_id:42520000}\n"
1919 "{product_name:RE220,product_ver:2.0.0,special_id:43410000}\n"
1920 "{product_name:RE220,product_ver:2.0.0,special_id:45530000}\n"
1921 "{product_name:RE220,product_ver:2.0.0,special_id:45550000}\n"
1922 "{product_name:RE220,product_ver:2.0.0,special_id:49440000}\n"
1923 "{product_name:RE220,product_ver:2.0.0,special_id:4a500000}\n"
1924 "{product_name:RE220,product_ver:2.0.0,special_id:4b520000}\n"
1925 "{product_name:RE220,product_ver:2.0.0,special_id:52550000}\n"
1926 "{product_name:RE220,product_ver:2.0.0,special_id:54570000}\n"
1927 "{product_name:RE220,product_ver:2.0.0,special_id:55530000}\n",
1928 .support_trail
= '\x00',
1932 {"fs-uboot", 0x00000, 0x20000},
1933 {"firmware", 0x20000, 0x7a0000},
1934 {"partition-table", 0x7c0000, 0x02000},
1935 {"default-mac", 0x7c2000, 0x00020},
1936 {"pin", 0x7c2100, 0x00020},
1937 {"product-info", 0x7c3100, 0x01000},
1938 {"soft-version", 0x7c4200, 0x01000},
1939 {"support-list", 0x7c5200, 0x01000},
1940 {"profile", 0x7c6200, 0x08000},
1941 {"config-info", 0x7ce200, 0x00400},
1942 {"user-config", 0x7d0000, 0x10000},
1943 {"default-config", 0x7e0000, 0x10000},
1944 {"radio", 0x7f0000, 0x10000},
1948 .first_sysupgrade_partition
= "os-image",
1949 .last_sysupgrade_partition
= "file-system"
1952 /** Firmware layout for the RE305 v1 */
1958 "{product_name:RE305,product_ver:1.0.0,special_id:45550000}\n"
1959 "{product_name:RE305,product_ver:1.0.0,special_id:55530000}\n"
1960 "{product_name:RE305,product_ver:1.0.0,special_id:4a500000}\n"
1961 "{product_name:RE305,product_ver:1.0.0,special_id:42520000}\n"
1962 "{product_name:RE305,product_ver:1.0.0,special_id:4b520000}\n"
1963 "{product_name:RE305,product_ver:1.0.0,special_id:41550000}\n"
1964 "{product_name:RE305,product_ver:1.0.0,special_id:43410000}\n",
1965 .support_trail
= '\x00',
1969 {"fs-uboot", 0x00000, 0x20000},
1970 {"firmware", 0x20000, 0x5e0000},
1971 {"partition-table", 0x600000, 0x02000},
1972 {"default-mac", 0x610000, 0x00020},
1973 {"pin", 0x610100, 0x00020},
1974 {"product-info", 0x611100, 0x01000},
1975 {"soft-version", 0x620000, 0x01000},
1976 {"support-list", 0x621000, 0x01000},
1977 {"profile", 0x622000, 0x08000},
1978 {"user-config", 0x630000, 0x10000},
1979 {"default-config", 0x640000, 0x10000},
1980 {"radio", 0x7f0000, 0x10000},
1984 .first_sysupgrade_partition
= "os-image",
1985 .last_sysupgrade_partition
= "file-system"
1988 /** Firmware layout for the RE350 v1 */
1994 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
1995 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
1996 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
1997 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
1998 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
1999 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
2000 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
2001 .support_trail
= '\x00',
2004 /** We're using a dynamic kernel/rootfs split here */
2006 {"fs-uboot", 0x00000, 0x20000},
2007 {"firmware", 0x20000, 0x5e0000},
2008 {"partition-table", 0x600000, 0x02000},
2009 {"default-mac", 0x610000, 0x00020},
2010 {"pin", 0x610100, 0x00020},
2011 {"product-info", 0x611100, 0x01000},
2012 {"soft-version", 0x620000, 0x01000},
2013 {"support-list", 0x621000, 0x01000},
2014 {"profile", 0x622000, 0x08000},
2015 {"user-config", 0x630000, 0x10000},
2016 {"default-config", 0x640000, 0x10000},
2017 {"radio", 0x7f0000, 0x10000},
2021 .first_sysupgrade_partition
= "os-image",
2022 .last_sysupgrade_partition
= "file-system"
2025 /** Firmware layout for the RE350K v1 */
2031 "{product_name:RE350K,product_ver:1.0.0,special_id:00000000,product_region:US}\n",
2032 .support_trail
= '\x00',
2035 /** We're using a dynamic kernel/rootfs split here */
2037 {"fs-uboot", 0x00000, 0x20000},
2038 {"firmware", 0x20000, 0xd70000},
2039 {"partition-table", 0xd90000, 0x02000},
2040 {"default-mac", 0xda0000, 0x00020},
2041 {"pin", 0xda0100, 0x00020},
2042 {"product-info", 0xda1100, 0x01000},
2043 {"soft-version", 0xdb0000, 0x01000},
2044 {"support-list", 0xdb1000, 0x01000},
2045 {"profile", 0xdb2000, 0x08000},
2046 {"user-config", 0xdc0000, 0x10000},
2047 {"default-config", 0xdd0000, 0x10000},
2048 {"device-id", 0xde0000, 0x00108},
2049 {"radio", 0xff0000, 0x10000},
2053 .first_sysupgrade_partition
= "os-image",
2054 .last_sysupgrade_partition
= "file-system"
2057 /** Firmware layout for the RE355 */
2063 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
2064 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
2065 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
2066 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
2067 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
2068 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
2069 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
2070 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
2071 .support_trail
= '\x00',
2074 /* We're using a dynamic kernel/rootfs split here */
2076 {"fs-uboot", 0x00000, 0x20000},
2077 {"firmware", 0x20000, 0x5e0000},
2078 {"partition-table", 0x600000, 0x02000},
2079 {"default-mac", 0x610000, 0x00020},
2080 {"pin", 0x610100, 0x00020},
2081 {"product-info", 0x611100, 0x01000},
2082 {"soft-version", 0x620000, 0x01000},
2083 {"support-list", 0x621000, 0x01000},
2084 {"profile", 0x622000, 0x08000},
2085 {"user-config", 0x630000, 0x10000},
2086 {"default-config", 0x640000, 0x10000},
2087 {"radio", 0x7f0000, 0x10000},
2091 .first_sysupgrade_partition
= "os-image",
2092 .last_sysupgrade_partition
= "file-system"
2095 /** Firmware layout for the RE450 */
2101 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
2102 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
2103 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
2104 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
2105 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
2106 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
2107 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
2108 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
2109 .support_trail
= '\x00',
2112 /** We're using a dynamic kernel/rootfs split here */
2114 {"fs-uboot", 0x00000, 0x20000},
2115 {"firmware", 0x20000, 0x5e0000},
2116 {"partition-table", 0x600000, 0x02000},
2117 {"default-mac", 0x610000, 0x00020},
2118 {"pin", 0x610100, 0x00020},
2119 {"product-info", 0x611100, 0x01000},
2120 {"soft-version", 0x620000, 0x01000},
2121 {"support-list", 0x621000, 0x01000},
2122 {"profile", 0x622000, 0x08000},
2123 {"user-config", 0x630000, 0x10000},
2124 {"default-config", 0x640000, 0x10000},
2125 {"radio", 0x7f0000, 0x10000},
2129 .first_sysupgrade_partition
= "os-image",
2130 .last_sysupgrade_partition
= "file-system"
2133 /** Firmware layout for the RE450 v2 */
2139 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n"
2140 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n"
2141 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n"
2142 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n"
2143 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n"
2144 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n"
2145 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n"
2146 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n"
2147 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n",
2148 .support_trail
= '\x00',
2151 /* We're using a dynamic kernel/rootfs split here */
2153 {"fs-uboot", 0x00000, 0x20000},
2154 {"firmware", 0x20000, 0x5e0000},
2155 {"partition-table", 0x600000, 0x02000},
2156 {"default-mac", 0x610000, 0x00020},
2157 {"pin", 0x610100, 0x00020},
2158 {"product-info", 0x611100, 0x01000},
2159 {"soft-version", 0x620000, 0x01000},
2160 {"support-list", 0x621000, 0x01000},
2161 {"profile", 0x622000, 0x08000},
2162 {"user-config", 0x630000, 0x10000},
2163 {"default-config", 0x640000, 0x10000},
2164 {"radio", 0x7f0000, 0x10000},
2168 .first_sysupgrade_partition
= "os-image",
2169 .last_sysupgrade_partition
= "file-system"
2172 /** Firmware layout for the RE450 v3 */
2178 "{product_name:RE450,product_ver:3.0.0,special_id:00000000}\r\n"
2179 "{product_name:RE450,product_ver:3.0.0,special_id:55530000}\r\n"
2180 "{product_name:RE450,product_ver:3.0.0,special_id:45550000}\r\n"
2181 "{product_name:RE450,product_ver:3.0.0,special_id:4A500000}\r\n"
2182 "{product_name:RE450,product_ver:3.0.0,special_id:43410000}\r\n"
2183 "{product_name:RE450,product_ver:3.0.0,special_id:41550000}\r\n"
2184 "{product_name:RE450,product_ver:3.0.0,special_id:41530000}\r\n"
2185 "{product_name:RE450,product_ver:3.0.0,special_id:4B520000}\r\n"
2186 "{product_name:RE450,product_ver:3.0.0,special_id:42520000}\r\n",
2187 .support_trail
= '\x00',
2190 /* We're using a dynamic kernel/rootfs split here */
2192 {"fs-uboot", 0x00000, 0x20000},
2193 {"default-mac", 0x20000, 0x00020},
2194 {"pin", 0x20020, 0x00020},
2195 {"product-info", 0x21000, 0x01000},
2196 {"partition-table", 0x22000, 0x02000},
2197 {"soft-version", 0x24000, 0x01000},
2198 {"support-list", 0x25000, 0x01000},
2199 {"profile", 0x26000, 0x08000},
2200 {"user-config", 0x2e000, 0x10000},
2201 {"default-config", 0x3e000, 0x10000},
2202 {"config-info", 0x4e000, 0x00400},
2203 {"firmware", 0x50000, 0x7a0000},
2204 {"radio", 0x7f0000, 0x10000},
2208 .first_sysupgrade_partition
= "os-image",
2209 .last_sysupgrade_partition
= "file-system"
2212 /** Firmware layout for the RE500 */
2218 "{product_name:RE500,product_ver:1.0.0,special_id:00000000}\r\n"
2219 "{product_name:RE500,product_ver:1.0.0,special_id:55530000}\r\n"
2220 "{product_name:RE500,product_ver:1.0.0,special_id:45550000}\r\n"
2221 "{product_name:RE500,product_ver:1.0.0,special_id:4A500000}\r\n"
2222 "{product_name:RE500,product_ver:1.0.0,special_id:43410000}\r\n"
2223 "{product_name:RE500,product_ver:1.0.0,special_id:41550000}\r\n"
2224 "{product_name:RE500,product_ver:1.0.0,special_id:41530000}\r\n",
2225 .support_trail
= '\x00',
2228 /* We're using a dynamic kernel/rootfs split here */
2230 {"fs-uboot", 0x00000, 0x20000},
2231 {"firmware", 0x20000, 0xde0000},
2232 {"partition-table", 0xe00000, 0x02000},
2233 {"default-mac", 0xe10000, 0x00020},
2234 {"pin", 0xe10100, 0x00020},
2235 {"product-info", 0xe11100, 0x01000},
2236 {"soft-version", 0xe20000, 0x01000},
2237 {"support-list", 0xe21000, 0x01000},
2238 {"profile", 0xe22000, 0x08000},
2239 {"user-config", 0xe30000, 0x10000},
2240 {"default-config", 0xe40000, 0x10000},
2241 {"radio", 0xff0000, 0x10000},
2245 .first_sysupgrade_partition
= "os-image",
2246 .last_sysupgrade_partition
= "file-system"
2249 /** Firmware layout for the RE650 */
2255 "{product_name:RE650,product_ver:1.0.0,special_id:00000000}\r\n"
2256 "{product_name:RE650,product_ver:1.0.0,special_id:55530000}\r\n"
2257 "{product_name:RE650,product_ver:1.0.0,special_id:45550000}\r\n"
2258 "{product_name:RE650,product_ver:1.0.0,special_id:4A500000}\r\n"
2259 "{product_name:RE650,product_ver:1.0.0,special_id:43410000}\r\n"
2260 "{product_name:RE650,product_ver:1.0.0,special_id:41550000}\r\n"
2261 "{product_name:RE650,product_ver:1.0.0,special_id:41530000}\r\n",
2262 .support_trail
= '\x00',
2265 /* We're using a dynamic kernel/rootfs split here */
2267 {"fs-uboot", 0x00000, 0x20000},
2268 {"firmware", 0x20000, 0xde0000},
2269 {"partition-table", 0xe00000, 0x02000},
2270 {"default-mac", 0xe10000, 0x00020},
2271 {"pin", 0xe10100, 0x00020},
2272 {"product-info", 0xe11100, 0x01000},
2273 {"soft-version", 0xe20000, 0x01000},
2274 {"support-list", 0xe21000, 0x01000},
2275 {"profile", 0xe22000, 0x08000},
2276 {"user-config", 0xe30000, 0x10000},
2277 {"default-config", 0xe40000, 0x10000},
2278 {"radio", 0xff0000, 0x10000},
2282 .first_sysupgrade_partition
= "os-image",
2283 .last_sysupgrade_partition
= "file-system"
2289 #define error(_ret, _errno, _str, ...) \
2291 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
2292 strerror(_errno)); \
2298 /** Stores a uint32 as big endian */
2299 static inline void put32(uint8_t *buf
, uint32_t val
) {
2306 /** Allocate a padded meta partition with a correctly initialised header
2307 * If the `data` pointer is NULL, then the required space is only allocated,
2308 * otherwise `data_len` bytes will be copied from `data` into the partition
2310 static struct image_partition_entry
init_meta_partition_entry(
2311 const char *name
, const void *data
, uint32_t data_len
,
2314 uint32_t total_len
= sizeof(struct meta_header
) + data_len
+ 1;
2315 struct image_partition_entry entry
= {
2318 .data
= malloc(total_len
)
2321 error(1, errno
, "failed to allocate meta partition entry");
2323 struct meta_header
*header
= (struct meta_header
*)entry
.data
;
2324 header
->length
= htonl(data_len
);
2328 memcpy(entry
.data
+sizeof(*header
), data
, data_len
);
2330 entry
.data
[total_len
- 1] = pad_value
;
2335 /** Allocates a new image partition */
2336 static struct image_partition_entry
alloc_image_partition(const char *name
, size_t len
) {
2337 struct image_partition_entry entry
= {name
, len
, malloc(len
)};
2339 error(1, errno
, "malloc");
2344 /** Frees an image partition */
2345 static void free_image_partition(struct image_partition_entry entry
) {
2349 static time_t source_date_epoch
= -1;
2350 static void set_source_date_epoch() {
2351 char *env
= getenv("SOURCE_DATE_EPOCH");
2355 source_date_epoch
= strtoull(env
, &endptr
, 10);
2356 if (errno
|| (endptr
&& *endptr
!= '\0')) {
2357 fprintf(stderr
, "Invalid SOURCE_DATE_EPOCH");
2363 /** Generates the partition-table partition */
2364 static struct image_partition_entry
make_partition_table(const struct flash_partition_entry
*p
) {
2365 struct image_partition_entry entry
= alloc_image_partition("partition-table", 0x800);
2367 char *s
= (char *)entry
.data
, *end
= (char *)(s
+entry
.size
);
2375 for (i
= 0; p
[i
].name
; i
++) {
2377 size_t w
= snprintf(s
, len
, "partition %s base 0x%05x size 0x%05x\n", p
[i
].name
, p
[i
].base
, p
[i
].size
);
2380 error(1, 0, "flash partition table overflow?");
2387 memset(s
, 0xff, end
-s
);
2393 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
2394 static inline uint8_t bcd(uint8_t v
) {
2395 return 0x10 * (v
/10) + v
%10;
2399 /** Generates the soft-version partition */
2400 static struct image_partition_entry
make_soft_version(
2401 const struct device_info
*info
, uint32_t rev
)
2403 /** If an info string is provided, use this instead of
2404 * the structured data, and include the null-termination */
2405 if (info
->soft_ver
) {
2406 uint32_t len
= strlen(info
->soft_ver
) + 1;
2407 return init_meta_partition_entry("soft-version",
2408 info
->soft_ver
, len
, 0);
2413 if (source_date_epoch
!= -1)
2414 t
= source_date_epoch
;
2415 else if (time(&t
) == (time_t)(-1))
2416 error(1, errno
, "time");
2418 struct tm
*tm
= gmtime(&t
);
2420 struct soft_version s
= {
2427 .year_hi
= bcd((1900+tm
->tm_year
)/100),
2428 .year_lo
= bcd(tm
->tm_year
%100),
2429 .month
= bcd(tm
->tm_mon
+1),
2430 .day
= bcd(tm
->tm_mday
),
2432 .compat_level
= htonl(info
->soft_ver_compat_level
)
2435 if (info
->soft_ver_compat_level
== 0)
2436 return init_meta_partition_entry("soft-version", &s
,
2437 (uint8_t *)(&s
.compat_level
) - (uint8_t *)(&s
), 0xff);
2439 return init_meta_partition_entry("soft-version", &s
,
2443 /** Generates the support-list partition */
2444 static struct image_partition_entry
make_support_list(
2445 const struct device_info
*info
)
2447 uint32_t len
= strlen(info
->support_list
);
2448 return init_meta_partition_entry("support-list", info
->support_list
,
2449 len
, info
->support_trail
);
2452 /** Partition with extra-para data */
2453 static struct image_partition_entry
make_extra_para(
2454 const struct device_info
*info
, const uint8_t *extra_para
, size_t len
)
2456 return init_meta_partition_entry("extra-para", extra_para
, len
, 0x00);
2459 /** Creates a new image partition with an arbitrary name from a file */
2460 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
) {
2461 struct stat statbuf
;
2463 if (stat(filename
, &statbuf
) < 0)
2464 error(1, errno
, "unable to stat file `%s'", filename
);
2466 size_t len
= statbuf
.st_size
;
2468 if (add_jffs2_eof
) {
2469 if (file_system_partition
)
2470 len
= ALIGN(len
+ file_system_partition
->base
, 0x10000) + sizeof(jffs2_eof_mark
) - file_system_partition
->base
;
2472 len
= ALIGN(len
, 0x10000) + sizeof(jffs2_eof_mark
);
2475 struct image_partition_entry entry
= alloc_image_partition(part_name
, len
);
2477 FILE *file
= fopen(filename
, "rb");
2479 error(1, errno
, "unable to open file `%s'", filename
);
2481 if (fread(entry
.data
, statbuf
.st_size
, 1, file
) != 1)
2482 error(1, errno
, "unable to read file `%s'", filename
);
2484 if (add_jffs2_eof
) {
2485 uint8_t *eof
= entry
.data
+ statbuf
.st_size
, *end
= entry
.data
+entry
.size
;
2487 memset(eof
, 0xff, end
- eof
- sizeof(jffs2_eof_mark
));
2488 memcpy(end
- sizeof(jffs2_eof_mark
), jffs2_eof_mark
, sizeof(jffs2_eof_mark
));
2497 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
2499 Example image partition table:
2501 fwup-ptn partition-table base 0x00800 size 0x00800
2502 fwup-ptn os-image base 0x01000 size 0x113b45
2503 fwup-ptn file-system base 0x114b45 size 0x1d0004
2504 fwup-ptn support-list base 0x2e4b49 size 0x000d1
2506 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
2507 the end of the partition table is marked with a zero byte.
2509 The firmware image must contain at least the partition-table and support-list partitions
2510 to be accepted. There aren't any alignment constraints for the image partitions.
2512 The partition-table partition contains the actual flash layout; partitions
2513 from the image partition table are mapped to the corresponding flash partitions during
2514 the firmware upgrade. The support-list partition contains a list of devices supported by
2517 The base offsets in the firmware partition table are relative to the end
2518 of the vendor information block, so the partition-table partition will
2519 actually start at offset 0x1814 of the image.
2521 I think partition-table must be the first partition in the firmware image.
2523 static void put_partitions(uint8_t *buffer
, const struct flash_partition_entry
*flash_parts
, const struct image_partition_entry
*parts
) {
2525 char *image_pt
= (char *)buffer
, *end
= image_pt
+ 0x800;
2527 size_t base
= 0x800;
2528 for (i
= 0; parts
[i
].name
; i
++) {
2529 for (j
= 0; flash_parts
[j
].name
; j
++) {
2530 if (!strcmp(flash_parts
[j
].name
, parts
[i
].name
)) {
2531 if (parts
[i
].size
> flash_parts
[j
].size
)
2532 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts
[j
].name
, (unsigned)flash_parts
[j
].size
);
2537 assert(flash_parts
[j
].name
);
2539 memcpy(buffer
+ base
, parts
[i
].data
, parts
[i
].size
);
2541 size_t len
= end
-image_pt
;
2542 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
);
2545 error(1, 0, "image partition table overflow?");
2549 base
+= parts
[i
].size
;
2553 /** Generates and writes the image MD5 checksum */
2554 static void put_md5(uint8_t *md5
, uint8_t *buffer
, unsigned int len
) {
2558 MD5_Update(&ctx
, md5_salt
, (unsigned int)sizeof(md5_salt
));
2559 MD5_Update(&ctx
, buffer
, len
);
2560 MD5_Final(md5
, &ctx
);
2565 Generates the firmware image in factory format
2571 0000-0003 Image size (4 bytes, big endian)
2572 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
2573 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
2574 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
2575 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
2576 1014-1813 Image partition table (2048 bytes, padded with 0xff)
2577 1814-xxxx Firmware partitions
2579 static void * generate_factory_image(struct device_info
*info
, const struct image_partition_entry
*parts
, size_t *len
) {
2583 for (i
= 0; parts
[i
].name
; i
++)
2584 *len
+= parts
[i
].size
;
2586 uint8_t *image
= malloc(*len
);
2588 error(1, errno
, "malloc");
2590 memset(image
, 0xff, *len
);
2594 size_t vendor_len
= strlen(info
->vendor
);
2595 put32(image
+0x14, vendor_len
);
2596 memcpy(image
+0x18, info
->vendor
, vendor_len
);
2599 put_partitions(image
+ 0x1014, info
->partitions
, parts
);
2600 put_md5(image
+0x04, image
+0x14, *len
-0x14);
2606 Generates the firmware image in sysupgrade format
2608 This makes some assumptions about the provided flash and image partition tables and
2609 should be generalized when TP-LINK starts building its safeloader into hardware with
2610 different flash layouts.
2612 static void * generate_sysupgrade_image(struct device_info
*info
, const struct image_partition_entry
*image_parts
, size_t *len
) {
2614 size_t flash_first_partition_index
= 0;
2615 size_t flash_last_partition_index
= 0;
2616 const struct flash_partition_entry
*flash_first_partition
= NULL
;
2617 const struct flash_partition_entry
*flash_last_partition
= NULL
;
2618 const struct image_partition_entry
*image_last_partition
= NULL
;
2620 /** Find first and last partitions */
2621 for (i
= 0; info
->partitions
[i
].name
; i
++) {
2622 if (!strcmp(info
->partitions
[i
].name
, info
->first_sysupgrade_partition
)) {
2623 flash_first_partition
= &info
->partitions
[i
];
2624 flash_first_partition_index
= i
;
2625 } else if (!strcmp(info
->partitions
[i
].name
, info
->last_sysupgrade_partition
)) {
2626 flash_last_partition
= &info
->partitions
[i
];
2627 flash_last_partition_index
= i
;
2631 assert(flash_first_partition
&& flash_last_partition
);
2632 assert(flash_first_partition_index
< flash_last_partition_index
);
2634 /** Find last partition from image to calculate needed size */
2635 for (i
= 0; image_parts
[i
].name
; i
++) {
2636 if (!strcmp(image_parts
[i
].name
, info
->last_sysupgrade_partition
)) {
2637 image_last_partition
= &image_parts
[i
];
2642 assert(image_last_partition
);
2644 *len
= flash_last_partition
->base
- flash_first_partition
->base
+ image_last_partition
->size
;
2646 uint8_t *image
= malloc(*len
);
2648 error(1, errno
, "malloc");
2650 memset(image
, 0xff, *len
);
2652 for (i
= flash_first_partition_index
; i
<= flash_last_partition_index
; i
++) {
2653 for (j
= 0; image_parts
[j
].name
; j
++) {
2654 if (!strcmp(info
->partitions
[i
].name
, image_parts
[j
].name
)) {
2655 if (image_parts
[j
].size
> info
->partitions
[i
].size
)
2656 error(1, 0, "%s partition too big (more than %u bytes)", info
->partitions
[i
].name
, (unsigned)info
->partitions
[i
].size
);
2657 memcpy(image
+ info
->partitions
[i
].base
- flash_first_partition
->base
, image_parts
[j
].data
, image_parts
[j
].size
);
2661 assert(image_parts
[j
].name
);
2668 /** Generates an image according to a given layout and writes it to a file */
2669 static void build_image(const char *output
,
2670 const char *kernel_image
,
2671 const char *rootfs_image
,
2675 struct device_info
*info
) {
2679 struct image_partition_entry parts
[7] = {};
2681 struct flash_partition_entry
*firmware_partition
= NULL
;
2682 struct flash_partition_entry
*os_image_partition
= NULL
;
2683 struct flash_partition_entry
*file_system_partition
= NULL
;
2684 size_t firmware_partition_index
= 0;
2686 for (i
= 0; info
->partitions
[i
].name
; i
++) {
2687 if (!strcmp(info
->partitions
[i
].name
, "firmware"))
2689 firmware_partition
= &info
->partitions
[i
];
2690 firmware_partition_index
= i
;
2694 if (firmware_partition
)
2696 os_image_partition
= &info
->partitions
[firmware_partition_index
];
2697 file_system_partition
= &info
->partitions
[firmware_partition_index
+ 1];
2700 if (stat(kernel_image
, &kernel
) < 0)
2701 error(1, errno
, "unable to stat file `%s'", kernel_image
);
2703 if (kernel
.st_size
> firmware_partition
->size
)
2704 error(1, 0, "kernel overflowed firmware partition\n");
2706 for (i
= MAX_PARTITIONS
-1; i
>= firmware_partition_index
+ 1; i
--)
2707 info
->partitions
[i
+1] = info
->partitions
[i
];
2709 file_system_partition
->name
= "file-system";
2710 file_system_partition
->base
= firmware_partition
->base
+ kernel
.st_size
;
2712 /* Align partition start to erase blocks for factory images only */
2714 file_system_partition
->base
= ALIGN(firmware_partition
->base
+ kernel
.st_size
, 0x10000);
2716 file_system_partition
->size
= firmware_partition
->size
- file_system_partition
->base
;
2718 os_image_partition
->name
= "os-image";
2719 os_image_partition
->size
= kernel
.st_size
;
2722 parts
[0] = make_partition_table(info
->partitions
);
2723 parts
[1] = make_soft_version(info
, rev
);
2724 parts
[2] = make_support_list(info
);
2725 parts
[3] = read_file("os-image", kernel_image
, false, NULL
);
2726 parts
[4] = read_file("file-system", rootfs_image
, add_jffs2_eof
, file_system_partition
);
2728 /* Some devices need the extra-para partition to accept the firmware */
2729 if (strcasecmp(info
->id
, "ARCHER-A7-V5") == 0 ||
2730 strcasecmp(info
->id
, "ARCHER-C2-V3") == 0 ||
2731 strcasecmp(info
->id
, "ARCHER-C7-V4") == 0 ||
2732 strcasecmp(info
->id
, "ARCHER-C7-V5") == 0 ||
2733 strcasecmp(info
->id
, "ARCHER-C25-V1") == 0 ||
2734 strcasecmp(info
->id
, "ARCHER-C59-V2") == 0 ||
2735 strcasecmp(info
->id
, "ARCHER-C60-V2") == 0 ||
2736 strcasecmp(info
->id
, "ARCHER-C60-V3") == 0 ||
2737 strcasecmp(info
->id
, "TLWR1043NV5") == 0) {
2738 const uint8_t extra_para
[2] = {0x01, 0x00};
2739 parts
[5] = make_extra_para(info
, extra_para
,
2740 sizeof(extra_para
));
2741 } else if (strcasecmp(info
->id
, "ARCHER-C6-V2") == 0) {
2742 const uint8_t extra_para
[2] = {0x00, 0x01};
2743 parts
[5] = make_extra_para(info
, extra_para
,
2744 sizeof(extra_para
));
2745 } else if (strcasecmp(info
->id
, "ARCHER-C6-V2-US") == 0 ||
2746 strcasecmp(info
->id
, "EAP245-V3") == 0) {
2747 const uint8_t extra_para
[2] = {0x01, 0x01};
2748 parts
[5] = make_extra_para(info
, extra_para
,
2749 sizeof(extra_para
));
2755 image
= generate_sysupgrade_image(info
, parts
, &len
);
2757 image
= generate_factory_image(info
, parts
, &len
);
2759 FILE *file
= fopen(output
, "wb");
2761 error(1, errno
, "unable to open output file");
2763 if (fwrite(image
, len
, 1, file
) != 1)
2764 error(1, 0, "unable to write output file");
2770 for (i
= 0; parts
[i
].name
; i
++)
2771 free_image_partition(parts
[i
]);
2775 static void usage(const char *argv0
) {
2777 "Usage: %s [OPTIONS...]\n"
2780 " -h show this help\n"
2782 "Create a new image:\n"
2783 " -B <board> create image for the board specified with <board>\n"
2784 " -k <file> read kernel image from the file <file>\n"
2785 " -r <file> read rootfs image from the file <file>\n"
2786 " -o <file> write output to the file <file>\n"
2787 " -V <rev> sets the revision number to <rev>\n"
2788 " -j add jffs2 end-of-filesystem markers\n"
2789 " -S create sysupgrade instead of factory image\n"
2790 "Extract an old image:\n"
2791 " -x <file> extract all oem firmware partition\n"
2792 " -d <dir> destination to extract the firmware partition\n"
2793 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
2799 static struct device_info
*find_board(const char *id
)
2801 struct device_info
*board
= NULL
;
2803 for (board
= boards
; board
->id
!= NULL
; board
++)
2804 if (strcasecmp(id
, board
->id
) == 0)
2810 static int add_flash_partition(
2811 struct flash_partition_entry
*part_list
,
2818 /* check if the list has a free entry */
2819 for (ptr
= 0; ptr
< max_entries
; ptr
++, part_list
++) {
2820 if (part_list
->name
== NULL
&&
2821 part_list
->base
== 0 &&
2822 part_list
->size
== 0)
2826 if (ptr
== max_entries
) {
2827 error(1, 0, "No free flash part entry available.");
2830 part_list
->name
= calloc(1, strlen(name
) + 1);
2831 if (!part_list
->name
) {
2832 error(1, 0, "Unable to allocate memory");
2835 memcpy((char *)part_list
->name
, name
, strlen(name
));
2836 part_list
->base
= base
;
2837 part_list
->size
= size
;
2842 /** read the partition table into struct flash_partition_entry */
2843 static int read_partition_table(
2844 FILE *file
, long offset
,
2845 struct flash_partition_entry
*entries
, size_t max_entries
,
2850 const char *parthdr
= NULL
;
2851 const char *fwuphdr
= "fwup-ptn";
2852 const char *flashhdr
= "partition";
2854 /* TODO: search for the partition table */
2864 error(1, 0, "Invalid partition table");
2867 if (fseek(file
, offset
, SEEK_SET
) < 0)
2868 error(1, errno
, "Can not seek in the firmware");
2870 if (fread(buf
, 2048, 1, file
) != 1)
2871 error(1, errno
, "Can not read fwup-ptn from the firmware");
2875 /* look for the partition header */
2876 if (memcmp(buf
, parthdr
, strlen(parthdr
)) != 0) {
2877 fprintf(stderr
, "DEBUG: can not find fwuphdr\n");
2882 end
= buf
+ sizeof(buf
);
2883 while ((ptr
+ strlen(parthdr
)) < end
&&
2884 memcmp(ptr
, parthdr
, strlen(parthdr
)) == 0) {
2888 char name
[32] = { 0 };
2890 unsigned long base
= 0;
2891 unsigned long size
= 0;
2893 end_part
= memchr(ptr
, '\n', (end
- ptr
));
2894 if (end_part
== NULL
) {
2895 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
2899 for (int i
= 0; i
<= 4; i
++) {
2900 if (end_part
<= ptr
)
2903 end_element
= memchr(ptr
, 0x20, (end_part
- ptr
));
2904 if (end_element
== NULL
) {
2905 error(1, errno
, "Ignoring the rest of the partition entries.");
2910 /* partition header */
2912 ptr
= end_element
+ 1;
2916 name_len
= (end_element
- ptr
) > 31 ? 31 : (end_element
- ptr
);
2917 strncpy(name
, ptr
, name_len
);
2918 name
[name_len
] = '\0';
2919 ptr
= end_element
+ 1;
2924 ptr
= end_element
+ 1;
2929 base
= strtoul(ptr
, NULL
, 16);
2930 ptr
= end_element
+ 1;
2935 ptr
= end_element
+ 1;
2936 /* actual size. The last element doesn't have a sepeartor */
2937 size
= strtoul(ptr
, NULL
, 16);
2938 /* the part ends with 0x09, 0x0d, 0x0a */
2940 add_flash_partition(entries
, max_entries
, name
, base
, size
);
2949 static void write_partition(
2951 size_t firmware_offset
,
2952 struct flash_partition_entry
*entry
,
2958 fseek(input_file
, entry
->base
+ firmware_offset
, SEEK_SET
);
2960 for (offset
= 0; sizeof(buf
) + offset
<= entry
->size
; offset
+= sizeof(buf
)) {
2961 if (fread(buf
, sizeof(buf
), 1, input_file
) != 1)
2962 error(1, errno
, "Can not read partition from input_file");
2964 if (fwrite(buf
, sizeof(buf
), 1, output_file
) != 1)
2965 error(1, errno
, "Can not write partition to output_file");
2967 /* write last chunk smaller than buffer */
2968 if (offset
< entry
->size
) {
2969 offset
= entry
->size
- offset
;
2970 if (fread(buf
, offset
, 1, input_file
) != 1)
2971 error(1, errno
, "Can not read partition from input_file");
2972 if (fwrite(buf
, offset
, 1, output_file
) != 1)
2973 error(1, errno
, "Can not write partition to output_file");
2977 static int extract_firmware_partition(FILE *input_file
, size_t firmware_offset
, struct flash_partition_entry
*entry
, const char *output_directory
)
2980 char output
[PATH_MAX
];
2982 snprintf(output
, PATH_MAX
, "%s/%s", output_directory
, entry
->name
);
2983 output_file
= fopen(output
, "wb+");
2984 if (output_file
== NULL
) {
2985 error(1, errno
, "Can not open output file %s", output
);
2988 write_partition(input_file
, firmware_offset
, entry
, output_file
);
2990 fclose(output_file
);
2995 /** extract all partitions from the firmware file */
2996 static int extract_firmware(const char *input
, const char *output_directory
)
2998 struct flash_partition_entry entries
[16] = { 0 };
2999 size_t max_entries
= 16;
3000 size_t firmware_offset
= 0x1014;
3003 struct stat statbuf
;
3005 /* check input file */
3006 if (stat(input
, &statbuf
)) {
3007 error(1, errno
, "Can not read input firmware %s", input
);
3010 /* check if output directory exists */
3011 if (stat(output_directory
, &statbuf
)) {
3012 error(1, errno
, "Failed to stat output directory %s", output_directory
);
3015 if ((statbuf
.st_mode
& S_IFMT
) != S_IFDIR
) {
3016 error(1, errno
, "Given output directory is not a directory %s", output_directory
);
3019 input_file
= fopen(input
, "rb");
3021 if (read_partition_table(input_file
, firmware_offset
, entries
, 16, 0) != 0) {
3022 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3025 for (size_t i
= 0; i
< max_entries
; i
++) {
3026 if (entries
[i
].name
== NULL
&&
3027 entries
[i
].base
== 0 &&
3028 entries
[i
].size
== 0)
3031 extract_firmware_partition(input_file
, firmware_offset
, &entries
[i
], output_directory
);
3037 static struct flash_partition_entry
*find_partition(
3038 struct flash_partition_entry
*entries
, size_t max_entries
,
3039 const char *name
, const char *error_msg
)
3041 for (size_t i
= 0; i
< max_entries
; i
++, entries
++) {
3042 if (strcmp(entries
->name
, name
) == 0)
3046 error(1, 0, "%s", error_msg
);
3050 static void write_ff(FILE *output_file
, size_t size
)
3055 memset(buf
, 0xff, sizeof(buf
));
3057 for (offset
= 0; offset
+ sizeof(buf
) < size
; offset
+= sizeof(buf
)) {
3058 if (fwrite(buf
, sizeof(buf
), 1, output_file
) != 1)
3059 error(1, errno
, "Can not write 0xff to output_file");
3062 /* write last chunk smaller than buffer */
3063 if (offset
< size
) {
3064 offset
= size
- offset
;
3065 if (fwrite(buf
, offset
, 1, output_file
) != 1)
3066 error(1, errno
, "Can not write partition to output_file");
3070 static void convert_firmware(const char *input
, const char *output
)
3072 struct flash_partition_entry fwup
[MAX_PARTITIONS
] = { 0 };
3073 struct flash_partition_entry flash
[MAX_PARTITIONS
] = { 0 };
3074 struct flash_partition_entry
*fwup_os_image
= NULL
, *fwup_file_system
= NULL
;
3075 struct flash_partition_entry
*flash_os_image
= NULL
, *flash_file_system
= NULL
;
3076 struct flash_partition_entry
*fwup_partition_table
= NULL
;
3077 size_t firmware_offset
= 0x1014;
3078 FILE *input_file
, *output_file
;
3080 struct stat statbuf
;
3082 /* check input file */
3083 if (stat(input
, &statbuf
)) {
3084 error(1, errno
, "Can not read input firmware %s", input
);
3087 input_file
= fopen(input
, "rb");
3089 error(1, 0, "Can not open input firmware %s", input
);
3091 output_file
= fopen(output
, "wb");
3093 error(1, 0, "Can not open output firmware %s", output
);
3095 if (read_partition_table(input_file
, firmware_offset
, fwup
, MAX_PARTITIONS
, 0) != 0) {
3096 error(1, 0, "Error can not read the partition table (fwup-ptn)");
3099 fwup_os_image
= find_partition(fwup
, MAX_PARTITIONS
,
3100 "os-image", "Error can not find os-image partition (fwup)");
3101 fwup_file_system
= find_partition(fwup
, MAX_PARTITIONS
,
3102 "file-system", "Error can not find file-system partition (fwup)");
3103 fwup_partition_table
= find_partition(fwup
, MAX_PARTITIONS
,
3104 "partition-table", "Error can not find partition-table partition");
3106 /* the flash partition table has a 0x00000004 magic haeder */
3107 if (read_partition_table(input_file
, firmware_offset
+ fwup_partition_table
->base
+ 4, flash
, MAX_PARTITIONS
, 1) != 0)
3108 error(1, 0, "Error can not read the partition table (flash)");
3110 flash_os_image
= find_partition(flash
, MAX_PARTITIONS
,
3111 "os-image", "Error can not find os-image partition (flash)");
3112 flash_file_system
= find_partition(flash
, MAX_PARTITIONS
,
3113 "file-system", "Error can not find file-system partition (flash)");
3115 /* write os_image to 0x0 */
3116 write_partition(input_file
, firmware_offset
, fwup_os_image
, output_file
);
3117 write_ff(output_file
, flash_os_image
->size
- fwup_os_image
->size
);
3119 /* write file-system behind os_image */
3120 fseek(output_file
, flash_file_system
->base
- flash_os_image
->base
, SEEK_SET
);
3121 write_partition(input_file
, firmware_offset
, fwup_file_system
, output_file
);
3122 write_ff(output_file
, flash_file_system
->size
- fwup_file_system
->size
);
3124 fclose(output_file
);
3128 int main(int argc
, char *argv
[]) {
3129 const char *board
= NULL
, *kernel_image
= NULL
, *rootfs_image
= NULL
, *output
= NULL
;
3130 const char *extract_image
= NULL
, *output_directory
= NULL
, *convert_image
= NULL
;
3131 bool add_jffs2_eof
= false, sysupgrade
= false;
3133 struct device_info
*info
;
3134 set_source_date_epoch();
3139 c
= getopt(argc
, argv
, "B:k:r:o:V:jSh:x:d:z:");
3149 kernel_image
= optarg
;
3153 rootfs_image
= optarg
;
3161 sscanf(optarg
, "r%u", &rev
);
3165 add_jffs2_eof
= true;
3177 output_directory
= optarg
;
3181 extract_image
= optarg
;
3185 convert_image
= optarg
;
3194 if (extract_image
|| output_directory
) {
3196 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
3197 if (!output_directory
)
3198 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
3199 extract_firmware(extract_image
, output_directory
);
3200 } else if (convert_image
) {
3202 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
3203 convert_firmware(convert_image
, output
);
3206 error(1, 0, "no board has been specified");
3208 error(1, 0, "no kernel image has been specified");
3210 error(1, 0, "no rootfs image has been specified");
3212 error(1, 0, "no output filename has been specified");
3214 info
= find_board(board
);
3217 error(1, 0, "unsupported board %s", board
);
3219 build_image(output
, kernel_image
, rootfs_image
, rev
, add_jffs2_eof
, sysupgrade
, info
);