OpenWrt – Diff between revs 2 and 3

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 2 Rev 3
1 /* 1 /*
2 Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net> 2 Copyright (c) 2014, Matthias Schiffer <mschiffer@universe-factory.net>
3 All rights reserved. 3 All rights reserved.
4   4  
5 Redistribution and use in source and binary forms, with or without 5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met: 6 modification, are permitted provided that the following conditions are met:
7   7  
8 1. Redistributions of source code must retain the above copyright notice, 8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer. 9 this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice, 10 2. Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation 11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution. 12 and/or other materials provided with the distribution.
13   13  
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 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 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 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 17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 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, 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 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. 23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25   25  
26   26  
27 /* 27 /*
28 tplink-safeloader 28 tplink-safeloader
29   29  
30 Image generation tool for the TP-LINK SafeLoader as seen on 30 Image generation tool for the TP-LINK SafeLoader as seen on
31 TP-LINK Pharos devices (CPE210/220/510/520) 31 TP-LINK Pharos devices (CPE210/220/510/520)
32 */ 32 */
33   33  
34   34  
35 #include <assert.h> 35 #include <assert.h>
36 #include <errno.h> 36 #include <errno.h>
37 #include <stdbool.h> 37 #include <stdbool.h>
38 #include <stdio.h> 38 #include <stdio.h>
39 #include <stdint.h> 39 #include <stdint.h>
40 #include <stdlib.h> 40 #include <stdlib.h>
41 #include <string.h> 41 #include <string.h>
42 #include <time.h> 42 #include <time.h>
43 #include <unistd.h> 43 #include <unistd.h>
44   44  
45 #include <arpa/inet.h> 45 #include <arpa/inet.h>
46   46  
47 #include <sys/types.h> 47 #include <sys/types.h>
48 #include <sys/stat.h> 48 #include <sys/stat.h>
49 #include <limits.h> 49 #include <limits.h>
50   50  
51 #include "md5.h" 51 #include "md5.h"
52   52  
53   53  
54 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) 54 #define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); })
55   55  
56   56  
57 #define MAX_PARTITIONS 32 57 #define MAX_PARTITIONS 32
58   58  
59 /** An image partition table entry */ 59 /** An image partition table entry */
60 struct image_partition_entry { 60 struct image_partition_entry {
61 const char *name; 61 const char *name;
62 size_t size; 62 size_t size;
63 uint8_t *data; 63 uint8_t *data;
64 }; 64 };
65   65  
66 /** A flash partition table entry */ 66 /** A flash partition table entry */
67 struct flash_partition_entry { 67 struct flash_partition_entry {
68 char *name; 68 const char *name;
69 uint32_t base; 69 uint32_t base;
70 uint32_t size; 70 uint32_t size;
71 }; 71 };
72   72  
73 /** Firmware layout description */ 73 /** Firmware layout description */
74 struct device_info { 74 struct device_info {
75 const char *id; 75 const char *id;
76 const char *vendor; 76 const char *vendor;
77 const char *support_list; 77 const char *support_list;
78 char support_trail; 78 char support_trail;
79 const char *soft_ver; 79 const char *soft_ver;
80 struct flash_partition_entry partitions[MAX_PARTITIONS+1]; 80 const struct flash_partition_entry partitions[MAX_PARTITIONS+1];
81 const char *first_sysupgrade_partition; 81 const char *first_sysupgrade_partition;
82 const char *last_sysupgrade_partition; 82 const char *last_sysupgrade_partition;
83 }; 83 };
84   84  
85 /** The content of the soft-version structure */ 85 /** The content of the soft-version structure */
86 struct __attribute__((__packed__)) soft_version { 86 struct __attribute__((__packed__)) soft_version {
87 uint32_t magic; 87 uint32_t magic;
88 uint32_t zero; 88 uint32_t zero;
89 uint8_t pad1; 89 uint8_t pad1;
90 uint8_t version_major; 90 uint8_t version_major;
91 uint8_t version_minor; 91 uint8_t version_minor;
92 uint8_t version_patch; 92 uint8_t version_patch;
93 uint8_t year_hi; 93 uint8_t year_hi;
94 uint8_t year_lo; 94 uint8_t year_lo;
95 uint8_t month; 95 uint8_t month;
96 uint8_t day; 96 uint8_t day;
97 uint32_t rev; 97 uint32_t rev;
98 uint8_t pad2; 98 uint8_t pad2;
99 }; 99 };
100   100  
101   101  
102 static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; 102 static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
103   103  
104   104  
105 /** 105 /**
106 Salt for the MD5 hash 106 Salt for the MD5 hash
107   107  
108 Fortunately, TP-LINK seems to use the same salt for most devices which use 108 Fortunately, TP-LINK seems to use the same salt for most devices which use
109 the new image format. 109 the new image format.
110 */ 110 */
111 static const uint8_t md5_salt[16] = { 111 static const uint8_t md5_salt[16] = {
112 0x7a, 0x2b, 0x15, 0xed, 112 0x7a, 0x2b, 0x15, 0xed,
113 0x9b, 0x98, 0x59, 0x6d, 113 0x9b, 0x98, 0x59, 0x6d,
114 0xe5, 0x04, 0xab, 0x44, 114 0xe5, 0x04, 0xab, 0x44,
115 0xac, 0x2a, 0x9f, 0x4e, 115 0xac, 0x2a, 0x9f, 0x4e,
116 }; 116 };
117   117  
118   118  
119 /** Firmware layout table */ 119 /** Firmware layout table */
120 static struct device_info boards[] = { 120 static struct device_info boards[] = {
121 /** Firmware layout for the CPE210/220 */ 121 /** Firmware layout for the CPE210/220 */
122 { 122 {
123 .id = "CPE210", 123 .id = "CPE210",
124 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", 124 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
125 .support_list = 125 .support_list =
126 "SupportList:\r\n" 126 "SupportList:\r\n"
127 "CPE210(TP-LINK|UN|N300-2):1.0\r\n" 127 "CPE210(TP-LINK|UN|N300-2):1.0\r\n"
128 "CPE210(TP-LINK|UN|N300-2):1.1\r\n" 128 "CPE210(TP-LINK|UN|N300-2):1.1\r\n"
129 "CPE210(TP-LINK|US|N300-2):1.1\r\n" 129 "CPE210(TP-LINK|US|N300-2):1.1\r\n"
130 "CPE210(TP-LINK|EU|N300-2):1.1\r\n" 130 "CPE210(TP-LINK|EU|N300-2):1.1\r\n"
131 "CPE220(TP-LINK|UN|N300-2):1.1\r\n" 131 "CPE220(TP-LINK|UN|N300-2):1.1\r\n"
132 "CPE220(TP-LINK|US|N300-2):1.1\r\n" 132 "CPE220(TP-LINK|US|N300-2):1.1\r\n"
133 "CPE220(TP-LINK|EU|N300-2):1.1\r\n", 133 "CPE220(TP-LINK|EU|N300-2):1.1\r\n",
134 .support_trail = '\xff', 134 .support_trail = '\xff',
135 .soft_ver = NULL, 135 .soft_ver = NULL,
136   136  
137 .partitions = { 137 .partitions = {
138 {"fs-uboot", 0x00000, 0x20000}, 138 {"fs-uboot", 0x00000, 0x20000},
139 {"partition-table", 0x20000, 0x02000}, 139 {"partition-table", 0x20000, 0x02000},
140 {"default-mac", 0x30000, 0x00020}, 140 {"default-mac", 0x30000, 0x00020},
141 {"product-info", 0x31100, 0x00100}, 141 {"product-info", 0x31100, 0x00100},
142 {"signature", 0x32000, 0x00400}, 142 {"signature", 0x32000, 0x00400},
143 {"os-image", 0x40000, 0x1c0000}, 143 {"os-image", 0x40000, 0x1c0000},
144 {"file-system", 0x200000, 0x5b0000}, 144 {"file-system", 0x200000, 0x5b0000},
145 {"soft-version", 0x7b0000, 0x00100}, 145 {"soft-version", 0x7b0000, 0x00100},
146 {"support-list", 0x7b1000, 0x00400}, 146 {"support-list", 0x7b1000, 0x00400},
147 {"user-config", 0x7c0000, 0x10000}, 147 {"user-config", 0x7c0000, 0x10000},
148 {"default-config", 0x7d0000, 0x10000}, 148 {"default-config", 0x7d0000, 0x10000},
149 {"log", 0x7e0000, 0x10000}, 149 {"log", 0x7e0000, 0x10000},
150 {"radio", 0x7f0000, 0x10000}, 150 {"radio", 0x7f0000, 0x10000},
151 {NULL, 0, 0} 151 {NULL, 0, 0}
152 }, 152 },
153   153  
154 .first_sysupgrade_partition = "os-image", 154 .first_sysupgrade_partition = "os-image",
155 .last_sysupgrade_partition = "support-list", 155 .last_sysupgrade_partition = "support-list",
156 }, 156 },
157   157  
158 /** Firmware layout for the CPE210 V2 */ 158 /** Firmware layout for the CPE210 V2 */
159 { 159 {
160 .id = "CPE210V2", 160 .id = "CPE210V2",
161 .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n", 161 .vendor = "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n",
162 .support_list = 162 .support_list =
163 "SupportList:\r\n" 163 "SupportList:\r\n"
164 "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n" 164 "CPE210(TP-LINK|EU|N300-2|00000000):2.0\r\n"
165 "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n" 165 "CPE210(TP-LINK|EU|N300-2|45550000):2.0\r\n"
166 "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n" 166 "CPE210(TP-LINK|EU|N300-2|55530000):2.0\r\n"
167 "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n" 167 "CPE210(TP-LINK|UN|N300-2|00000000):2.0\r\n"
168 "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n" 168 "CPE210(TP-LINK|UN|N300-2|45550000):2.0\r\n"
169 "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n" 169 "CPE210(TP-LINK|UN|N300-2|55530000):2.0\r\n"
170 "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n" 170 "CPE210(TP-LINK|US|N300-2|55530000):2.0\r\n"
171 "CPE210(TP-LINK|UN|N300-2):2.0\r\n" 171 "CPE210(TP-LINK|UN|N300-2):2.0\r\n"
172 "CPE210(TP-LINK|EU|N300-2):2.0\r\n" 172 "CPE210(TP-LINK|EU|N300-2):2.0\r\n"
173 "CPE210(TP-LINK|US|N300-2):2.0\r\n", 173 "CPE210(TP-LINK|US|N300-2):2.0\r\n",
174 .support_trail = '\xff', 174 .support_trail = '\xff',
175 .soft_ver = NULL, 175 .soft_ver = NULL,
176   176  
177 .partitions = { 177 .partitions = {
178 {"fs-uboot", 0x00000, 0x20000}, 178 {"fs-uboot", 0x00000, 0x20000},
179 {"partition-table", 0x20000, 0x02000}, 179 {"partition-table", 0x20000, 0x02000},
180 {"default-mac", 0x30000, 0x00020}, 180 {"default-mac", 0x30000, 0x00020},
181 {"product-info", 0x31100, 0x00100}, 181 {"product-info", 0x31100, 0x00100},
182 {"device-info", 0x31400, 0x00400}, 182 {"device-info", 0x31400, 0x00400},
183 {"signature", 0x32000, 0x00400}, 183 {"signature", 0x32000, 0x00400},
184 {"device-id", 0x33000, 0x00100}, 184 {"device-id", 0x33000, 0x00100},
185 {"os-image", 0x40000, 0x1c0000}, 185 {"os-image", 0x40000, 0x1c0000},
186 {"file-system", 0x200000, 0x5b0000}, 186 {"file-system", 0x200000, 0x5b0000},
187 {"soft-version", 0x7b0000, 0x00100}, 187 {"soft-version", 0x7b0000, 0x00100},
188 {"support-list", 0x7b1000, 0x01000}, 188 {"support-list", 0x7b1000, 0x01000},
189 {"user-config", 0x7c0000, 0x10000}, 189 {"user-config", 0x7c0000, 0x10000},
190 {"default-config", 0x7d0000, 0x10000}, 190 {"default-config", 0x7d0000, 0x10000},
191 {"log", 0x7e0000, 0x10000}, 191 {"log", 0x7e0000, 0x10000},
192 {"radio", 0x7f0000, 0x10000}, 192 {"radio", 0x7f0000, 0x10000},
193 {NULL, 0, 0} 193 {NULL, 0, 0}
194 }, 194 },
195   195  
196 .first_sysupgrade_partition = "os-image", 196 .first_sysupgrade_partition = "os-image",
197 .last_sysupgrade_partition = "support-list", 197 .last_sysupgrade_partition = "support-list",
198 }, 198 },
199   199  
200 /** Firmware layout for the CPE510/520 */ 200 /** Firmware layout for the CPE510/520 */
201 { 201 {
202 .id = "CPE510", 202 .id = "CPE510",
203 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", 203 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
204 .support_list = 204 .support_list =
205 "SupportList:\r\n" 205 "SupportList:\r\n"
206 "CPE510(TP-LINK|UN|N300-5):1.0\r\n" 206 "CPE510(TP-LINK|UN|N300-5):1.0\r\n"
207 "CPE510(TP-LINK|UN|N300-5):1.1\r\n" 207 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
208 "CPE510(TP-LINK|UN|N300-5):1.1\r\n" 208 "CPE510(TP-LINK|UN|N300-5):1.1\r\n"
209 "CPE510(TP-LINK|US|N300-5):1.1\r\n" 209 "CPE510(TP-LINK|US|N300-5):1.1\r\n"
210 "CPE510(TP-LINK|EU|N300-5):1.1\r\n" 210 "CPE510(TP-LINK|EU|N300-5):1.1\r\n"
211 "CPE520(TP-LINK|UN|N300-5):1.1\r\n" 211 "CPE520(TP-LINK|UN|N300-5):1.1\r\n"
212 "CPE520(TP-LINK|US|N300-5):1.1\r\n" 212 "CPE520(TP-LINK|US|N300-5):1.1\r\n"
213 "CPE520(TP-LINK|EU|N300-5):1.1\r\n" 213 "CPE520(TP-LINK|EU|N300-5):1.1\r\n",
214 "CPE510(TP-LINK|EU|N300-5|00000000):2.0\r\n" -  
215 "CPE510(TP-LINK|EU|N300-5|45550000):2.0\r\n" -  
216 "CPE510(TP-LINK|EU|N300-5|55530000):2.0\r\n" -  
217 "CPE510(TP-LINK|UN|N300-5|00000000):2.0\r\n" -  
218 "CPE510(TP-LINK|UN|N300-5|45550000):2.0\r\n" -  
219 "CPE510(TP-LINK|UN|N300-5|55530000):2.0\r\n" -  
220 "CPE510(TP-LINK|US|N300-5|55530000):2.0\r\n" -  
221 "CPE510(TP-LINK|UN|N300-5):2.0\r\n" -  
222 "CPE510(TP-LINK|EU|N300-5):2.0\r\n" -  
223 "CPE510(TP-LINK|US|N300-5):2.0\r\n", -  
224 .support_trail = '\xff', 214 .support_trail = '\xff',
225 .soft_ver = NULL, 215 .soft_ver = NULL,
226   216  
227 .partitions = { 217 .partitions = {
228 {"fs-uboot", 0x00000, 0x20000}, 218 {"fs-uboot", 0x00000, 0x20000},
229 {"partition-table", 0x20000, 0x02000}, 219 {"partition-table", 0x20000, 0x02000},
230 {"default-mac", 0x30000, 0x00020}, 220 {"default-mac", 0x30000, 0x00020},
231 {"product-info", 0x31100, 0x00100}, 221 {"product-info", 0x31100, 0x00100},
232 {"signature", 0x32000, 0x00400}, 222 {"signature", 0x32000, 0x00400},
233 {"os-image", 0x40000, 0x1c0000}, 223 {"os-image", 0x40000, 0x1c0000},
234 {"file-system", 0x200000, 0x5b0000}, 224 {"file-system", 0x200000, 0x5b0000},
235 {"soft-version", 0x7b0000, 0x00100}, 225 {"soft-version", 0x7b0000, 0x00100},
236 {"support-list", 0x7b1000, 0x00400}, 226 {"support-list", 0x7b1000, 0x00400},
237 {"user-config", 0x7c0000, 0x10000}, 227 {"user-config", 0x7c0000, 0x10000},
238 {"default-config", 0x7d0000, 0x10000}, 228 {"default-config", 0x7d0000, 0x10000},
239 {"log", 0x7e0000, 0x10000}, 229 {"log", 0x7e0000, 0x10000},
240 {"radio", 0x7f0000, 0x10000}, 230 {"radio", 0x7f0000, 0x10000},
241 {NULL, 0, 0} 231 {NULL, 0, 0}
242 }, 232 },
243   233  
244 .first_sysupgrade_partition = "os-image", 234 .first_sysupgrade_partition = "os-image",
245 .last_sysupgrade_partition = "support-list", 235 .last_sysupgrade_partition = "support-list",
246 }, 236 },
247   237  
248 { 238 {
249 .id = "WBS210", 239 .id = "WBS210",
250 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", 240 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
251 .support_list = 241 .support_list =
252 "SupportList:\r\n" 242 "SupportList:\r\n"
253 "WBS210(TP-LINK|UN|N300-2):1.20\r\n" 243 "WBS210(TP-LINK|UN|N300-2):1.20\r\n"
254 "WBS210(TP-LINK|US|N300-2):1.20\r\n" 244 "WBS210(TP-LINK|US|N300-2):1.20\r\n"
255 "WBS210(TP-LINK|EU|N300-2):1.20\r\n", 245 "WBS210(TP-LINK|EU|N300-2):1.20\r\n",
256 .support_trail = '\xff', 246 .support_trail = '\xff',
257 .soft_ver = NULL, 247 .soft_ver = NULL,
258   248  
259 .partitions = { 249 .partitions = {
260 {"fs-uboot", 0x00000, 0x20000}, 250 {"fs-uboot", 0x00000, 0x20000},
261 {"partition-table", 0x20000, 0x02000}, 251 {"partition-table", 0x20000, 0x02000},
262 {"default-mac", 0x30000, 0x00020}, 252 {"default-mac", 0x30000, 0x00020},
263 {"product-info", 0x31100, 0x00100}, 253 {"product-info", 0x31100, 0x00100},
264 {"signature", 0x32000, 0x00400}, 254 {"signature", 0x32000, 0x00400},
265 {"os-image", 0x40000, 0x1c0000}, 255 {"os-image", 0x40000, 0x1c0000},
266 {"file-system", 0x200000, 0x5b0000}, 256 {"file-system", 0x200000, 0x5b0000},
267 {"soft-version", 0x7b0000, 0x00100}, 257 {"soft-version", 0x7b0000, 0x00100},
268 {"support-list", 0x7b1000, 0x00400}, 258 {"support-list", 0x7b1000, 0x00400},
269 {"user-config", 0x7c0000, 0x10000}, 259 {"user-config", 0x7c0000, 0x10000},
270 {"default-config", 0x7d0000, 0x10000}, 260 {"default-config", 0x7d0000, 0x10000},
271 {"log", 0x7e0000, 0x10000}, 261 {"log", 0x7e0000, 0x10000},
272 {"radio", 0x7f0000, 0x10000}, 262 {"radio", 0x7f0000, 0x10000},
273 {NULL, 0, 0} 263 {NULL, 0, 0}
274 }, 264 },
275   265  
276 .first_sysupgrade_partition = "os-image", 266 .first_sysupgrade_partition = "os-image",
277 .last_sysupgrade_partition = "support-list", 267 .last_sysupgrade_partition = "support-list",
278 }, 268 },
279   269  
280 { 270 {
281 .id = "WBS510", 271 .id = "WBS510",
282 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n", 272 .vendor = "CPE510(TP-LINK|UN|N300-5):1.0\r\n",
283 .support_list = 273 .support_list =
284 "SupportList:\r\n" 274 "SupportList:\r\n"
285 "WBS510(TP-LINK|UN|N300-5):1.20\r\n" 275 "WBS510(TP-LINK|UN|N300-5):1.20\r\n"
286 "WBS510(TP-LINK|US|N300-5):1.20\r\n" 276 "WBS510(TP-LINK|US|N300-5):1.20\r\n"
287 "WBS510(TP-LINK|EU|N300-5):1.20\r\n", 277 "WBS510(TP-LINK|EU|N300-5):1.20\r\n",
288 .support_trail = '\xff', 278 .support_trail = '\xff',
289 .soft_ver = NULL, 279 .soft_ver = NULL,
290   280  
291 .partitions = { 281 .partitions = {
292 {"fs-uboot", 0x00000, 0x20000}, 282 {"fs-uboot", 0x00000, 0x20000},
293 {"partition-table", 0x20000, 0x02000}, 283 {"partition-table", 0x20000, 0x02000},
294 {"default-mac", 0x30000, 0x00020}, 284 {"default-mac", 0x30000, 0x00020},
295 {"product-info", 0x31100, 0x00100}, 285 {"product-info", 0x31100, 0x00100},
296 {"signature", 0x32000, 0x00400}, 286 {"signature", 0x32000, 0x00400},
297 {"os-image", 0x40000, 0x1c0000}, 287 {"os-image", 0x40000, 0x1c0000},
298 {"file-system", 0x200000, 0x5b0000}, 288 {"file-system", 0x200000, 0x5b0000},
299 {"soft-version", 0x7b0000, 0x00100}, 289 {"soft-version", 0x7b0000, 0x00100},
300 {"support-list", 0x7b1000, 0x00400}, 290 {"support-list", 0x7b1000, 0x00400},
301 {"user-config", 0x7c0000, 0x10000}, 291 {"user-config", 0x7c0000, 0x10000},
302 {"default-config", 0x7d0000, 0x10000}, 292 {"default-config", 0x7d0000, 0x10000},
303 {"log", 0x7e0000, 0x10000}, 293 {"log", 0x7e0000, 0x10000},
304 {"radio", 0x7f0000, 0x10000}, 294 {"radio", 0x7f0000, 0x10000},
305 {NULL, 0, 0} 295 {NULL, 0, 0}
306 }, 296 },
307   297  
308 .first_sysupgrade_partition = "os-image", 298 .first_sysupgrade_partition = "os-image",
309 .last_sysupgrade_partition = "support-list", 299 .last_sysupgrade_partition = "support-list",
310 }, 300 },
311   301  
312 /** Firmware layout for the C2600 */ 302 /** Firmware layout for the C2600 */
313 { 303 {
314 .id = "C2600", 304 .id = "C2600",
315 .vendor = "", 305 .vendor = "",
316 .support_list = 306 .support_list =
317 "SupportList:\r\n" 307 "SupportList:\r\n"
318 "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n", 308 "{product_name:Archer C2600,product_ver:1.0.0,special_id:00000000}\r\n",
319 .support_trail = '\x00', 309 .support_trail = '\x00',
320 .soft_ver = NULL, 310 .soft_ver = NULL,
321   311  
322 /** 312 /**
323 We use a bigger os-image partition than the stock images (and thus 313 We use a bigger os-image partition than the stock images (and thus
324 smaller file-system), as our kernel doesn't fit in the stock firmware's 314 smaller file-system), as our kernel doesn't fit in the stock firmware's
325 2 MB os-image since kernel 4.14. 315 2 MB os-image since kernel 4.14.
326 */ 316 */
327 .partitions = { 317 .partitions = {
328 {"SBL1", 0x00000, 0x20000}, 318 {"SBL1", 0x00000, 0x20000},
329 {"MIBIB", 0x20000, 0x20000}, 319 {"MIBIB", 0x20000, 0x20000},
330 {"SBL2", 0x40000, 0x20000}, 320 {"SBL2", 0x40000, 0x20000},
331 {"SBL3", 0x60000, 0x30000}, 321 {"SBL3", 0x60000, 0x30000},
332 {"DDRCONFIG", 0x90000, 0x10000}, 322 {"DDRCONFIG", 0x90000, 0x10000},
333 {"SSD", 0xa0000, 0x10000}, 323 {"SSD", 0xa0000, 0x10000},
334 {"TZ", 0xb0000, 0x30000}, 324 {"TZ", 0xb0000, 0x30000},
335 {"RPM", 0xe0000, 0x20000}, 325 {"RPM", 0xe0000, 0x20000},
336 {"fs-uboot", 0x100000, 0x70000}, 326 {"fs-uboot", 0x100000, 0x70000},
337 {"uboot-env", 0x170000, 0x40000}, 327 {"uboot-env", 0x170000, 0x40000},
338 {"radio", 0x1b0000, 0x40000}, 328 {"radio", 0x1b0000, 0x40000},
339 {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */ 329 {"os-image", 0x1f0000, 0x400000}, /* Stock: base 0x1f0000 size 0x200000 */
340 {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */ 330 {"file-system", 0x5f0000, 0x1900000}, /* Stock: base 0x3f0000 size 0x1b00000 */
341 {"default-mac", 0x1ef0000, 0x00200}, 331 {"default-mac", 0x1ef0000, 0x00200},
342 {"pin", 0x1ef0200, 0x00200}, 332 {"pin", 0x1ef0200, 0x00200},
343 {"product-info", 0x1ef0400, 0x0fc00}, 333 {"product-info", 0x1ef0400, 0x0fc00},
344 {"partition-table", 0x1f00000, 0x10000}, 334 {"partition-table", 0x1f00000, 0x10000},
345 {"soft-version", 0x1f10000, 0x10000}, 335 {"soft-version", 0x1f10000, 0x10000},
346 {"support-list", 0x1f20000, 0x10000}, 336 {"support-list", 0x1f20000, 0x10000},
347 {"profile", 0x1f30000, 0x10000}, 337 {"profile", 0x1f30000, 0x10000},
348 {"default-config", 0x1f40000, 0x10000}, 338 {"default-config", 0x1f40000, 0x10000},
349 {"user-config", 0x1f50000, 0x40000}, 339 {"user-config", 0x1f50000, 0x40000},
350 {"qos-db", 0x1f90000, 0x40000}, 340 {"qos-db", 0x1f90000, 0x40000},
351 {"usb-config", 0x1fd0000, 0x10000}, 341 {"usb-config", 0x1fd0000, 0x10000},
352 {"log", 0x1fe0000, 0x20000}, 342 {"log", 0x1fe0000, 0x20000},
353 {NULL, 0, 0} 343 {NULL, 0, 0}
354 }, 344 },
355   345  
356 .first_sysupgrade_partition = "os-image", 346 .first_sysupgrade_partition = "os-image",
357 .last_sysupgrade_partition = "file-system" 347 .last_sysupgrade_partition = "file-system"
358 }, 348 },
359   -  
360 /** Firmware layout for the A7-V5 */ -  
361 { -  
362 .id = "ARCHER-A7-V5", -  
363 .support_list = -  
364 "SupportList:\n" -  
365 "{product_name:Archer A7,product_ver:5.0.0,special_id:45550000}\n" -  
366 "{product_name:Archer A7,product_ver:5.0.0,special_id:55530000}\n" -  
367 "{product_name:Archer A7,product_ver:5.0.0,special_id:43410000}\n" -  
368 "{product_name:Archer A7,product_ver:5.0.0,special_id:4A500000}\n" -  
369 "{product_name:Archer A7,product_ver:5.0.0,special_id:54570000}\n", -  
370 .support_trail = '\x00', -  
371 .soft_ver = "soft_ver:1.0.0\n", -  
372   -  
373 /* We're using a dynamic kernel/rootfs split here */ -  
374 .partitions = { -  
375 {"factory-boot", 0x00000, 0x20000}, -  
376 {"fs-uboot", 0x20000, 0x20000}, -  
377 {"firmware", 0x40000, 0xec0000}, /* Stock: name os-image base 0x40000 size 0x120000 */ -  
378 /* Stock: name file-system base 0x160000 size 0xda0000 */ -  
379 {"default-mac", 0xf40000, 0x00200}, -  
380 {"pin", 0xf40200, 0x00200}, -  
381 {"device-id", 0xf40400, 0x00100}, -  
382 {"product-info", 0xf40500, 0x0fb00}, -  
383 {"soft-version", 0xf50000, 0x00100}, -  
384 {"extra-para", 0xf51000, 0x01000}, -  
385 {"support-list", 0xf52000, 0x0a000}, -  
386 {"profile", 0xf5c000, 0x04000}, -  
387 {"default-config", 0xf60000, 0x10000}, -  
388 {"user-config", 0xf70000, 0x40000}, -  
389 {"certificate", 0xfb0000, 0x10000}, -  
390 {"partition-table", 0xfc0000, 0x10000}, -  
391 {"log", 0xfd0000, 0x20000}, -  
392 {"radio", 0xff0000, 0x10000}, -  
393 {NULL, 0, 0} -  
394 }, -  
395   -  
396 .first_sysupgrade_partition = "os-image", -  
397 .last_sysupgrade_partition = "file-system", -  
398 }, -  
399   -  
400 /** Firmware layout for the C2v3 */ -  
401 { -  
402 .id = "ARCHER-C2-V3", -  
403 .support_list = -  
404 "SupportList:\n" -  
405 "{product_name:ArcherC2,product_ver:3.0.0,special_id:00000000}\n" -  
406 "{product_name:ArcherC2,product_ver:3.0.0,special_id:55530000}\n" -  
407 "{product_name:ArcherC2,product_ver:3.0.0,special_id:45550000}\n", -  
408 .support_trail = '\x00', -  
409 .soft_ver = "soft_ver:3.0.1\n", -  
410   -  
411 /** We're using a dynamic kernel/rootfs split here */ -  
412   -  
413 .partitions = { -  
414 {"factory-boot", 0x00000, 0x20000}, -  
415 {"fs-uboot", 0x20000, 0x10000}, -  
416 {"firmware", 0x30000, 0x7a0000}, -  
417 {"user-config", 0x7d0000, 0x04000}, -  
418 {"default-mac", 0x7e0000, 0x00100}, -  
419 {"device-id", 0x7e0100, 0x00100}, -  
420 {"extra-para", 0x7e0200, 0x00100}, -  
421 {"pin", 0x7e0300, 0x00100}, -  
422 {"support-list", 0x7e0400, 0x00400}, -  
423 {"soft-version", 0x7e0800, 0x00400}, -  
424 {"product-info", 0x7e0c00, 0x01400}, -  
425 {"partition-table", 0x7e2000, 0x01000}, -  
426 {"profile", 0x7e3000, 0x01000}, -  
427 {"default-config", 0x7e4000, 0x04000}, -  
428 {"merge-config", 0x7ec000, 0x02000}, -  
429 {"qos-db", 0x7ee000, 0x02000}, -  
430 {"radio", 0x7f0000, 0x10000}, -  
431 {NULL, 0, 0} -  
432 }, -  
433   -  
434 .first_sysupgrade_partition = "os-image", -  
435 .last_sysupgrade_partition = "file-system", -  
436 }, -  
437   349  
438 /** Firmware layout for the C25v1 */ 350 /** Firmware layout for the C25v1 */
439 { 351 {
440 .id = "ARCHER-C25-V1", 352 .id = "ARCHER-C25-V1",
441 .support_list = 353 .support_list =
442 "SupportList:\n" 354 "SupportList:\n"
443 "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n" 355 "{product_name:ArcherC25,product_ver:1.0.0,special_id:00000000}\n"
444 "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n" 356 "{product_name:ArcherC25,product_ver:1.0.0,special_id:55530000}\n"
445 "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n", 357 "{product_name:ArcherC25,product_ver:1.0.0,special_id:45550000}\n",
446 .support_trail = '\x00', 358 .support_trail = '\x00',
447 .soft_ver = "soft_ver:1.0.0\n", 359 .soft_ver = "soft_ver:1.0.0\n",
-   360  
448   361 /**
-   362 We use a bigger os-image partition than the stock images (and thus
-   363 smaller file-system), as our kernel doesn't fit in the stock firmware's
-   364 1MB os-image.
449 /* We're using a dynamic kernel/rootfs split here */ 365 */
450 .partitions = { 366 .partitions = {
451 {"factory-boot", 0x00000, 0x20000}, 367 {"factory-boot", 0x00000, 0x20000},
452 {"fs-uboot", 0x20000, 0x10000}, 368 {"fs-uboot", 0x20000, 0x10000},
453 {"firmware", 0x30000, 0x7a0000}, /* Stock: name os-image base 0x30000 size 0x100000 */ 369 {"os-image", 0x30000, 0x180000}, /* Stock: base 0x30000 size 0x100000 */
454 /* Stock: name file-system base 0x130000 size 0x6a0000 */ 370 {"file-system", 0x1b0000, 0x620000}, /* Stock: base 0x130000 size 0x6a0000 */
455 {"user-config", 0x7d0000, 0x04000}, 371 {"user-config", 0x7d0000, 0x04000},
456 {"default-mac", 0x7e0000, 0x00100}, 372 {"default-mac", 0x7e0000, 0x00100},
457 {"device-id", 0x7e0100, 0x00100}, 373 {"device-id", 0x7e0100, 0x00100},
458 {"extra-para", 0x7e0200, 0x00100}, 374 {"extra-para", 0x7e0200, 0x00100},
459 {"pin", 0x7e0300, 0x00100}, 375 {"pin", 0x7e0300, 0x00100},
460 {"support-list", 0x7e0400, 0x00400}, 376 {"support-list", 0x7e0400, 0x00400},
461 {"soft-version", 0x7e0800, 0x00400}, 377 {"soft-version", 0x7e0800, 0x00400},
462 {"product-info", 0x7e0c00, 0x01400}, 378 {"product-info", 0x7e0c00, 0x01400},
463 {"partition-table", 0x7e2000, 0x01000}, 379 {"partition-table", 0x7e2000, 0x01000},
464 {"profile", 0x7e3000, 0x01000}, 380 {"profile", 0x7e3000, 0x01000},
465 {"default-config", 0x7e4000, 0x04000}, 381 {"default-config", 0x7e4000, 0x04000},
466 {"merge-config", 0x7ec000, 0x02000}, 382 {"merge-config", 0x7ec000, 0x02000},
467 {"qos-db", 0x7ee000, 0x02000}, 383 {"qos-db", 0x7ee000, 0x02000},
468 {"radio", 0x7f0000, 0x10000}, 384 {"radio", 0x7f0000, 0x10000},
469 {NULL, 0, 0} 385 {NULL, 0, 0}
470 }, 386 },
471   387  
472 .first_sysupgrade_partition = "os-image", 388 .first_sysupgrade_partition = "os-image",
473 .last_sysupgrade_partition = "file-system", 389 .last_sysupgrade_partition = "file-system",
474 }, 390 },
475   391  
476 /** Firmware layout for the C58v1 */ 392 /** Firmware layout for the C58v1 */
477 { 393 {
478 .id = "ARCHER-C58-V1", 394 .id = "ARCHER-C58-V1",
479 .vendor = "", 395 .vendor = "",
480 .support_list = 396 .support_list =
481 "SupportList:\r\n" 397 "SupportList:\r\n"
482 "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n" 398 "{product_name:Archer C58,product_ver:1.0.0,special_id:00000000}\r\n"
483 "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n" 399 "{product_name:Archer C58,product_ver:1.0.0,special_id:45550000}\r\n"
484 "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n", 400 "{product_name:Archer C58,product_ver:1.0.0,special_id:55530000}\r\n",
485 .support_trail = '\x00', 401 .support_trail = '\x00',
486 .soft_ver = "soft_ver:1.0.0\n", 402 .soft_ver = "soft_ver:1.0.0\n",
487   403  
488 .partitions = { 404 .partitions = {
489 {"fs-uboot", 0x00000, 0x10000}, 405 {"fs-uboot", 0x00000, 0x10000},
490 {"default-mac", 0x10000, 0x00200}, 406 {"default-mac", 0x10000, 0x00200},
491 {"pin", 0x10200, 0x00200}, 407 {"pin", 0x10200, 0x00200},
492 {"product-info", 0x10400, 0x00100}, 408 {"product-info", 0x10400, 0x00100},
493 {"partition-table", 0x10500, 0x00800}, 409 {"partition-table", 0x10500, 0x00800},
494 {"soft-version", 0x11300, 0x00200}, 410 {"soft-version", 0x11300, 0x00200},
495 {"support-list", 0x11500, 0x00100}, 411 {"support-list", 0x11500, 0x00100},
496 {"device-id", 0x11600, 0x00100}, 412 {"device-id", 0x11600, 0x00100},
497 {"profile", 0x11700, 0x03900}, 413 {"profile", 0x11700, 0x03900},
498 {"default-config", 0x15000, 0x04000}, 414 {"default-config", 0x15000, 0x04000},
499 {"user-config", 0x19000, 0x04000}, 415 {"user-config", 0x19000, 0x04000},
500 {"firmware", 0x20000, 0x7c8000}, 416 {"os-image", 0x20000, 0x180000},
-   417 {"file-system", 0x1a0000, 0x648000},
501 {"certyficate", 0x7e8000, 0x08000}, 418 {"certyficate", 0x7e8000, 0x08000},
502 {"radio", 0x7f0000, 0x10000}, 419 {"radio", 0x7f0000, 0x10000},
503 {NULL, 0, 0} 420 {NULL, 0, 0}
504 }, 421 },
505   422  
506 .first_sysupgrade_partition = "os-image", 423 .first_sysupgrade_partition = "os-image",
507 .last_sysupgrade_partition = "file-system", 424 .last_sysupgrade_partition = "file-system",
508 }, 425 },
509   426  
510 /** Firmware layout for the C59v1 */ 427 /** Firmware layout for the C59v1 */
511 { 428 {
512 .id = "ARCHER-C59-V1", 429 .id = "ARCHER-C59-V1",
513 .vendor = "", 430 .vendor = "",
514 .support_list = 431 .support_list =
515 "SupportList:\r\n" 432 "SupportList:\r\n"
516 "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n" 433 "{product_name:Archer C59,product_ver:1.0.0,special_id:00000000}\r\n"
517 "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n" 434 "{product_name:Archer C59,product_ver:1.0.0,special_id:45550000}\r\n"
518 "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n" 435 "{product_name:Archer C59,product_ver:1.0.0,special_id:52550000}\r\n"
519 "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n", 436 "{product_name:Archer C59,product_ver:1.0.0,special_id:55530000}\r\n",
520 .support_trail = '\x00', 437 .support_trail = '\x00',
521 .soft_ver = "soft_ver:1.0.0\n", 438 .soft_ver = "soft_ver:1.0.0\n",
522   -  
523 /* We're using a dynamic kernel/rootfs split here */ 439  
524 .partitions = { 440 .partitions = {
525 {"fs-uboot", 0x00000, 0x10000}, 441 {"fs-uboot", 0x00000, 0x10000},
526 {"default-mac", 0x10000, 0x00200}, 442 {"default-mac", 0x10000, 0x00200},
527 {"pin", 0x10200, 0x00200}, 443 {"pin", 0x10200, 0x00200},
528 {"device-id", 0x10400, 0x00100}, 444 {"device-id", 0x10400, 0x00100},
529 {"product-info", 0x10500, 0x0fb00}, 445 {"product-info", 0x10500, 0x0fb00},
530 {"firmware", 0x20000, 0xe30000}, 446 {"os-image", 0x20000, 0x180000},
-   447 {"file-system", 0x1a0000, 0xcb0000},
531 {"partition-table", 0xe50000, 0x10000}, 448 {"partition-table", 0xe50000, 0x10000},
532 {"soft-version", 0xe60000, 0x10000}, 449 {"soft-version", 0xe60000, 0x10000},
533 {"support-list", 0xe70000, 0x10000}, 450 {"support-list", 0xe70000, 0x10000},
534 {"profile", 0xe80000, 0x10000}, 451 {"profile", 0xe80000, 0x10000},
535 {"default-config", 0xe90000, 0x10000}, 452 {"default-config", 0xe90000, 0x10000},
536 {"user-config", 0xea0000, 0x40000}, 453 {"user-config", 0xea0000, 0x40000},
537 {"usb-config", 0xee0000, 0x10000}, 454 {"usb-config", 0xee0000, 0x10000},
538 {"certificate", 0xef0000, 0x10000}, 455 {"certificate", 0xef0000, 0x10000},
539 {"qos-db", 0xf00000, 0x40000}, 456 {"qos-db", 0xf00000, 0x40000},
540 {"log", 0xfe0000, 0x10000}, 457 {"log", 0xfe0000, 0x10000},
541 {"radio", 0xff0000, 0x10000}, 458 {"radio", 0xff0000, 0x10000},
542 {NULL, 0, 0} 459 {NULL, 0, 0}
543 }, 460 },
544   461  
545 .first_sysupgrade_partition = "os-image", 462 .first_sysupgrade_partition = "os-image",
546 .last_sysupgrade_partition = "file-system", 463 .last_sysupgrade_partition = "file-system",
547 }, 464 },
548   -  
549 /** Firmware layout for the C59v2 */ -  
550 { -  
551 .id = "ARCHER-C59-V2", -  
552 .vendor = "", -  
553 .support_list = -  
554 "SupportList:\r\n" -  
555 "{product_name:Archer C59,product_ver:2.0.0,special_id:00000000}\r\n" -  
556 "{product_name:Archer C59,product_ver:2.0.0,special_id:45550000}\r\n" -  
557 "{product_name:Archer C59,product_ver:2.0.0,special_id:55530000}\r\n", -  
558 .support_trail = '\x00', -  
559 .soft_ver = "soft_ver:2.0.0 Build 20161206 rel.7303\n", -  
560   -  
561 /** We're using a dynamic kernel/rootfs split here */ -  
562 .partitions = { -  
563 {"factory-boot", 0x00000, 0x20000}, -  
564 {"fs-uboot", 0x20000, 0x10000}, -  
565 {"default-mac", 0x30000, 0x00200}, -  
566 {"pin", 0x30200, 0x00200}, -  
567 {"device-id", 0x30400, 0x00100}, -  
568 {"product-info", 0x30500, 0x0fb00}, -  
569 {"firmware", 0x40000, 0xe10000}, -  
570 {"partition-table", 0xe50000, 0x10000}, -  
571 {"soft-version", 0xe60000, 0x10000}, -  
572 {"support-list", 0xe70000, 0x10000}, -  
573 {"profile", 0xe80000, 0x10000}, -  
574 {"default-config", 0xe90000, 0x10000}, -  
575 {"user-config", 0xea0000, 0x40000}, -  
576 {"usb-config", 0xee0000, 0x10000}, -  
577 {"certificate", 0xef0000, 0x10000}, -  
578 {"extra-para", 0xf00000, 0x10000}, -  
579 {"qos-db", 0xf10000, 0x30000}, -  
580 {"log", 0xfe0000, 0x10000}, -  
581 {"radio", 0xff0000, 0x10000}, -  
582 {NULL, 0, 0} -  
583 }, -  
584   -  
585 .first_sysupgrade_partition = "os-image", -  
586 .last_sysupgrade_partition = "file-system", -  
587 }, -  
588   -  
589 /** Firmware layout for the C6v2 */ -  
590 { -  
591 .id = "ARCHER-C6-V2", -  
592 .vendor = "", -  
593 .support_list = -  
594 "SupportList:\r\n" -  
595 "{product_name:Archer C6,product_ver:2.0.0,special_id:45550000}\r\n" -  
596 "{product_name:Archer C6,product_ver:2.0.0,special_id:52550000}\r\n" -  
597 "{product_name:Archer C6,product_ver:2.0.0,special_id:4A500000}\r\n", -  
598 .support_trail = '\x00', -  
599 .soft_ver = "soft_ver:1.0.0\n", -  
600   -  
601 .partitions = { -  
602 {"fs-uboot", 0x00000, 0x20000}, -  
603 {"default-mac", 0x20000, 0x00200}, -  
604 {"pin", 0x20200, 0x00100}, -  
605 {"product-info", 0x20300, 0x00200}, -  
606 {"device-id", 0x20500, 0x0fb00}, -  
607 {"firmware", 0x30000, 0x7a9400}, -  
608 {"soft-version", 0x7d9400, 0x00100}, -  
609 {"extra-para", 0x7d9500, 0x00100}, -  
610 {"support-list", 0x7d9600, 0x00200}, -  
611 {"profile", 0x7d9800, 0x03000}, -  
612 {"default-config", 0x7dc800, 0x03000}, -  
613 {"partition-table", 0x7df800, 0x00800}, -  
614 {"user-config", 0x7e0000, 0x0c000}, -  
615 {"certificate", 0x7ec000, 0x04000}, -  
616 {"radio", 0x7f0000, 0x10000}, -  
617 {NULL, 0, 0} -  
618 }, -  
619   -  
620 .first_sysupgrade_partition = "os-image", -  
621 .last_sysupgrade_partition = "file-system", -  
622 }, -  
623   -  
624   465  
625 /** Firmware layout for the C60v1 */ 466 /** Firmware layout for the C60v1 */
626 { 467 {
627 .id = "ARCHER-C60-V1", 468 .id = "ARCHER-C60-V1",
628 .vendor = "", 469 .vendor = "",
629 .support_list = 470 .support_list =
630 "SupportList:\r\n" 471 "SupportList:\r\n"
631 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n" 472 "{product_name:Archer C60,product_ver:1.0.0,special_id:00000000}\r\n"
632 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n" 473 "{product_name:Archer C60,product_ver:1.0.0,special_id:45550000}\r\n"
633 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n", 474 "{product_name:Archer C60,product_ver:1.0.0,special_id:55530000}\r\n",
634 .support_trail = '\x00', 475 .support_trail = '\x00',
635 .soft_ver = "soft_ver:1.0.0\n", 476 .soft_ver = "soft_ver:1.0.0\n",
636   477  
637 .partitions = { 478 .partitions = {
638 {"fs-uboot", 0x00000, 0x10000}, 479 {"fs-uboot", 0x00000, 0x10000},
639 {"default-mac", 0x10000, 0x00200}, 480 {"default-mac", 0x10000, 0x00200},
640 {"pin", 0x10200, 0x00200}, 481 {"pin", 0x10200, 0x00200},
641 {"product-info", 0x10400, 0x00100}, 482 {"product-info", 0x10400, 0x00100},
642 {"partition-table", 0x10500, 0x00800}, 483 {"partition-table", 0x10500, 0x00800},
643 {"soft-version", 0x11300, 0x00200}, 484 {"soft-version", 0x11300, 0x00200},
644 {"support-list", 0x11500, 0x00100}, 485 {"support-list", 0x11500, 0x00100},
645 {"device-id", 0x11600, 0x00100}, 486 {"device-id", 0x11600, 0x00100},
646 {"profile", 0x11700, 0x03900}, 487 {"profile", 0x11700, 0x03900},
647 {"default-config", 0x15000, 0x04000}, 488 {"default-config", 0x15000, 0x04000},
648 {"user-config", 0x19000, 0x04000}, 489 {"user-config", 0x19000, 0x04000},
649 {"firmware", 0x20000, 0x7c8000}, 490 {"os-image", 0x20000, 0x180000},
-   491 {"file-system", 0x1a0000, 0x648000},
650 {"certyficate", 0x7e8000, 0x08000}, 492 {"certyficate", 0x7e8000, 0x08000},
651 {"radio", 0x7f0000, 0x10000}, 493 {"radio", 0x7f0000, 0x10000},
652 {NULL, 0, 0} 494 {NULL, 0, 0}
653 }, 495 },
654   496  
655 .first_sysupgrade_partition = "os-image", 497 .first_sysupgrade_partition = "os-image",
656 .last_sysupgrade_partition = "file-system", 498 .last_sysupgrade_partition = "file-system",
657 }, 499 },
658   500  
659 /** Firmware layout for the C60v2 */ 501 /** Firmware layout for the C60v2 */
660 { 502 {
661 .id = "ARCHER-C60-V2", 503 .id = "ARCHER-C60-V2",
662 .vendor = "", 504 .vendor = "",
663 .support_list = 505 .support_list =
664 "SupportList:\r\n" 506 "SupportList:\r\n"
665 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n" 507 "{product_name:Archer C60,product_ver:2.0.0,special_id:42520000}\r\n"
666 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n" 508 "{product_name:Archer C60,product_ver:2.0.0,special_id:45550000}\r\n"
667 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n", 509 "{product_name:Archer C60,product_ver:2.0.0,special_id:55530000}\r\n",
668 .support_trail = '\x00', 510 .support_trail = '\x00',
669 .soft_ver = "soft_ver:2.0.0\n", 511 .soft_ver = "soft_ver:2.0.0\n",
670   512  
671 .partitions = { 513 .partitions = {
672 {"factory-boot", 0x00000, 0x1fb00}, 514 {"factory-boot", 0x00000, 0x1fb00},
673 {"default-mac", 0x1fb00, 0x00200}, 515 {"default-mac", 0x1fb00, 0x00200},
674 {"pin", 0x1fd00, 0x00100}, 516 {"pin", 0x1fd00, 0x00100},
675 {"product-info", 0x1fe00, 0x00100}, 517 {"product-info", 0x1fe00, 0x00100},
676 {"device-id", 0x1ff00, 0x00100}, 518 {"device-id", 0x1ff00, 0x00100},
677 {"fs-uboot", 0x20000, 0x10000}, 519 {"fs-uboot", 0x20000, 0x10000},
678 {"firmware", 0x30000, 0x7a0000}, 520 {"os-image", 0x30000, 0x180000},
-   521 {"file-system", 0x1b0000, 0x620000},
679 {"soft-version", 0x7d9500, 0x00100}, 522 {"soft-version", 0x7d9500, 0x00100},
680 {"support-list", 0x7d9600, 0x00100}, 523 {"support-list", 0x7d9600, 0x00100},
681 {"extra-para", 0x7d9700, 0x00100}, 524 {"extra-para", 0x7d9700, 0x00100},
682 {"profile", 0x7d9800, 0x03000}, 525 {"profile", 0x7d9800, 0x03000},
683 {"default-config", 0x7dc800, 0x03000}, 526 {"default-config", 0x7dc800, 0x03000},
684 {"partition-table", 0x7df800, 0x00800}, 527 {"partition-table", 0x7df800, 0x00800},
685 {"user-config", 0x7e0000, 0x0c000}, 528 {"user-config", 0x7e0000, 0x0c000},
686 {"certificate", 0x7ec000, 0x04000}, 529 {"certificate", 0x7ec000, 0x04000},
687 {"radio", 0x7f0000, 0x10000}, 530 {"radio", 0x7f0000, 0x10000},
688 {NULL, 0, 0} 531 {NULL, 0, 0}
689 }, 532 },
690   533  
691 .first_sysupgrade_partition = "os-image", 534 .first_sysupgrade_partition = "os-image",
692 .last_sysupgrade_partition = "file-system", 535 .last_sysupgrade_partition = "file-system",
693 }, 536 },
694   537  
695 /** Firmware layout for the C5 */ 538 /** Firmware layout for the C5 */
696 { 539 {
697 .id = "ARCHER-C5-V2", 540 .id = "ARCHER-C5-V2",
698 .vendor = "", 541 .vendor = "",
699 .support_list = 542 .support_list =
700 "SupportList:\r\n" 543 "SupportList:\r\n"
701 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n" 544 "{product_name:ArcherC5,product_ver:2.0.0,special_id:00000000}\r\n"
702 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n" 545 "{product_name:ArcherC5,product_ver:2.0.0,special_id:55530000}\r\n"
703 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */ 546 "{product_name:ArcherC5,product_ver:2.0.0,special_id:4A500000}\r\n", /* JP version */
704 .support_trail = '\x00', 547 .support_trail = '\x00',
705 .soft_ver = NULL, 548 .soft_ver = NULL,
706   549  
707 .partitions = { 550 .partitions = {
708 {"fs-uboot", 0x00000, 0x40000}, 551 {"fs-uboot", 0x00000, 0x40000},
709 {"os-image", 0x40000, 0x200000}, 552 {"os-image", 0x40000, 0x200000},
710 {"file-system", 0x240000, 0xc00000}, 553 {"file-system", 0x240000, 0xc00000},
711 {"default-mac", 0xe40000, 0x00200}, 554 {"default-mac", 0xe40000, 0x00200},
712 {"pin", 0xe40200, 0x00200}, 555 {"pin", 0xe40200, 0x00200},
713 {"product-info", 0xe40400, 0x00200}, 556 {"product-info", 0xe40400, 0x00200},
714 {"partition-table", 0xe50000, 0x10000}, 557 {"partition-table", 0xe50000, 0x10000},
715 {"soft-version", 0xe60000, 0x00200}, 558 {"soft-version", 0xe60000, 0x00200},
716 {"support-list", 0xe61000, 0x0f000}, 559 {"support-list", 0xe61000, 0x0f000},
717 {"profile", 0xe70000, 0x10000}, 560 {"profile", 0xe70000, 0x10000},
718 {"default-config", 0xe80000, 0x10000}, 561 {"default-config", 0xe80000, 0x10000},
719 {"user-config", 0xe90000, 0x50000}, 562 {"user-config", 0xe90000, 0x50000},
720 {"log", 0xee0000, 0x100000}, 563 {"log", 0xee0000, 0x100000},
721 {"radio_bk", 0xfe0000, 0x10000}, 564 {"radio_bk", 0xfe0000, 0x10000},
722 {"radio", 0xff0000, 0x10000}, 565 {"radio", 0xff0000, 0x10000},
723 {NULL, 0, 0} 566 {NULL, 0, 0}
724 }, 567 },
725   568  
726 .first_sysupgrade_partition = "os-image", 569 .first_sysupgrade_partition = "os-image",
727 .last_sysupgrade_partition = "file-system" 570 .last_sysupgrade_partition = "file-system"
728 }, 571 },
729   572  
730 /** Firmware layout for the C7 */ 573 /** Firmware layout for the C7 */
731 { 574 {
732 .id = "ARCHER-C7-V4", 575 .id = "ARCHER-C7-V4",
733 .support_list = 576 .support_list =
734 "SupportList:\n" 577 "SupportList:\n"
735 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n" 578 "{product_name:Archer C7,product_ver:4.0.0,special_id:00000000}\n"
736 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n" 579 "{product_name:Archer C7,product_ver:4.0.0,special_id:41550000}\n"
737 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n" 580 "{product_name:Archer C7,product_ver:4.0.0,special_id:45550000}\n"
738 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n" 581 "{product_name:Archer C7,product_ver:4.0.0,special_id:4B520000}\n"
739 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n" 582 "{product_name:Archer C7,product_ver:4.0.0,special_id:42520000}\n"
740 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n" 583 "{product_name:Archer C7,product_ver:4.0.0,special_id:4A500000}\n"
741 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n" 584 "{product_name:Archer C7,product_ver:4.0.0,special_id:52550000}\n"
742 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n" 585 "{product_name:Archer C7,product_ver:4.0.0,special_id:54570000}\n"
743 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n" 586 "{product_name:Archer C7,product_ver:4.0.0,special_id:55530000}\n"
744 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n", 587 "{product_name:Archer C7,product_ver:4.0.0,special_id:43410000}\n",
745 .support_trail = '\x00', 588 .support_trail = '\x00',
746 .soft_ver = "soft_ver:1.0.0\n", 589 .soft_ver = "soft_ver:1.0.0\n",
-   590  
747   591 /**
-   592 We use a bigger os-image partition than the stock images (and thus
-   593 smaller file-system), as our kernel doesn't fit in the stock firmware's
-   594 1MB os-image.
748 /* We're using a dynamic kernel/rootfs split here */ 595 */
749 .partitions = { 596 .partitions = {
750 {"factory-boot", 0x00000, 0x20000}, 597 {"factory-boot", 0x00000, 0x20000},
751 {"fs-uboot", 0x20000, 0x20000}, 598 {"fs-uboot", 0x20000, 0x20000},
752 {"firmware", 0x40000, 0xEC0000}, /* Stock: name os-image base 0x40000 size 0x120000 */ 599 {"os-image", 0x40000, 0x180000}, /* Stock: base 0x40000 size 0x120000 */
753 /* Stock: name file-system base 0x160000 size 0xda0000 */ 600 {"file-system", 0x1c0000, 0xd40000}, /* Stock: base 0x160000 size 0xda0000 */
754 {"default-mac", 0xf00000, 0x00200}, 601 {"default-mac", 0xf00000, 0x00200},
755 {"pin", 0xf00200, 0x00200}, 602 {"pin", 0xf00200, 0x00200},
756 {"device-id", 0xf00400, 0x00100}, 603 {"device-id", 0xf00400, 0x00100},
757 {"product-info", 0xf00500, 0x0fb00}, 604 {"product-info", 0xf00500, 0x0fb00},
758 {"soft-version", 0xf10000, 0x00100}, 605 {"soft-version", 0xf10000, 0x00100},
759 {"extra-para", 0xf11000, 0x01000}, 606 {"extra-para", 0xf11000, 0x01000},
760 {"support-list", 0xf12000, 0x0a000}, 607 {"support-list", 0xf12000, 0x0a000},
761 {"profile", 0xf1c000, 0x04000}, 608 {"profile", 0xf1c000, 0x04000},
762 {"default-config", 0xf20000, 0x10000}, 609 {"default-config", 0xf20000, 0x10000},
763 {"user-config", 0xf30000, 0x40000}, 610 {"user-config", 0xf30000, 0x40000},
764 {"qos-db", 0xf70000, 0x40000}, 611 {"qos-db", 0xf70000, 0x40000},
765 {"certificate", 0xfb0000, 0x10000}, 612 {"certificate", 0xfb0000, 0x10000},
766 {"partition-table", 0xfc0000, 0x10000}, 613 {"partition-table", 0xfc0000, 0x10000},
767 {"log", 0xfd0000, 0x20000}, 614 {"log", 0xfd0000, 0x20000},
768 {"radio", 0xff0000, 0x10000}, 615 {"radio", 0xff0000, 0x10000},
769 {NULL, 0, 0} 616 {NULL, 0, 0}
770 }, 617 },
771   618  
772 .first_sysupgrade_partition = "os-image", 619 .first_sysupgrade_partition = "os-image",
773 .last_sysupgrade_partition = "file-system", 620 .last_sysupgrade_partition = "file-system",
774 }, 621 },
775   622  
776 /** Firmware layout for the C7 v5*/ 623 /** Firmware layout for the C7 v5*/
777 { 624 {
778 .id = "ARCHER-C7-V5", 625 .id = "ARCHER-C7-V5",
779 .support_list = 626 .support_list =
780 "SupportList:\n" 627 "SupportList:\n"
781 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n" 628 "{product_name:Archer C7,product_ver:5.0.0,special_id:00000000}\n"
782 "{product_name:Archer C7,product_ver:5.0.0,special_id:45550000}\n" -  
783 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n" 629 "{product_name:Archer C7,product_ver:5.0.0,special_id:55530000}\n",
784 "{product_name:Archer C7,product_ver:5.0.0,special_id:43410000}\n" -  
785 "{product_name:Archer C7,product_ver:5.0.0,special_id:4A500000}\n" -  
786 "{product_name:Archer C7,product_ver:5.0.0,special_id:54570000}\n" -  
787 "{product_name:Archer C7,product_ver:5.0.0,special_id:52550000}\n", -  
788   630  
789 .support_trail = '\x00', 631 .support_trail = '\x00',
790 .soft_ver = "soft_ver:1.0.0\n", 632 .soft_ver = "soft_ver:1.0.0\n",
-   633  
791   634 /**
-   635 We use a bigger os-image partition than the stock images (and thus
-   636 smaller file-system), as our kernel doesn't fit in the stock firmware's
-   637 1MB os-image.
792 /* We're using a dynamic kernel/rootfs split here */ 638 */
793 .partitions = { 639 .partitions = {
794 {"factory-boot", 0x00000, 0x20000}, 640 {"factory-boot", 0x00000, 0x20000},
795 {"fs-uboot", 0x20000, 0x20000}, 641 {"fs-uboot", 0x20000, 0x20000},
796 {"partition-table", 0x40000, 0x10000}, 642 {"partition-table", 0x40000, 0x10000},
797 {"radio", 0x50000, 0x10000}, 643 {"radio", 0x50000, 0x10000},
798 {"default-mac", 0x60000, 0x00200}, 644 {"default-mac", 0x60000, 0x00200},
799 {"pin", 0x60200, 0x00200}, 645 {"pin", 0x60200, 0x00200},
800 {"device-id", 0x60400, 0x00100}, 646 {"device-id", 0x60400, 0x00100},
801 {"product-info", 0x60500, 0x0fb00}, 647 {"product-info", 0x60500, 0x0fb00},
802 {"soft-version", 0x70000, 0x01000}, 648 {"soft-version", 0x70000, 0x01000},
803 {"extra-para", 0x71000, 0x01000}, 649 {"extra-para", 0x71000, 0x01000},
804 {"support-list", 0x72000, 0x0a000}, 650 {"support-list", 0x72000, 0x0a000},
805 {"profile", 0x7c000, 0x04000}, 651 {"profile", 0x7c000, 0x04000},
806 {"user-config", 0x80000, 0x40000}, 652 {"user-config", 0x80000, 0x40000},
807   653  
808   654  
809 {"firmware", 0xc0000, 0xf00000}, /* Stock: name os-image base 0xc0000 size 0x120000 */ 655 {"os-image", 0xc0000, 0x180000}, /* Stock: base 0xc0000 size 0x120000 */
810 /* Stock: name file-system base 0x1e0000 size 0xde0000 */ 656 {"file-system", 0x240000, 0xd80000}, /* Stock: base 0x1e0000 size 0xde0000 */
811   657  
812 {"log", 0xfc0000, 0x20000}, 658 {"log", 0xfc0000, 0x20000},
813 {"certificate", 0xfe0000, 0x10000}, 659 {"certificate", 0xfe0000, 0x10000},
814 {"default-config", 0xff0000, 0x10000}, 660 {"default-config", 0xff0000, 0x10000},
815 {NULL, 0, 0} 661 {NULL, 0, 0}
816   662  
817 }, 663 },
818   664  
819 .first_sysupgrade_partition = "os-image", 665 .first_sysupgrade_partition = "os-image",
820 .last_sysupgrade_partition = "file-system", 666 .last_sysupgrade_partition = "file-system",
821 }, 667 },
822   668  
823 /** Firmware layout for the C9 */ 669 /** Firmware layout for the C9 */
824 { 670 {
825 .id = "ARCHERC9", 671 .id = "ARCHERC9",
826 .vendor = "", 672 .vendor = "",
827 .support_list = 673 .support_list =
828 "SupportList:\n" 674 "SupportList:\n"
829 "{product_name:ArcherC9," 675 "{product_name:ArcherC9,"
830 "product_ver:1.0.0," 676 "product_ver:1.0.0,"
831 "special_id:00000000}\n", 677 "special_id:00000000}\n",
832 .support_trail = '\x00', 678 .support_trail = '\x00',
833 .soft_ver = NULL, 679 .soft_ver = NULL,
834   680  
835 .partitions = { 681 .partitions = {
836 {"fs-uboot", 0x00000, 0x40000}, 682 {"fs-uboot", 0x00000, 0x40000},
837 {"os-image", 0x40000, 0x200000}, 683 {"os-image", 0x40000, 0x200000},
838 {"file-system", 0x240000, 0xc00000}, 684 {"file-system", 0x240000, 0xc00000},
839 {"default-mac", 0xe40000, 0x00200}, 685 {"default-mac", 0xe40000, 0x00200},
840 {"pin", 0xe40200, 0x00200}, 686 {"pin", 0xe40200, 0x00200},
841 {"product-info", 0xe40400, 0x00200}, 687 {"product-info", 0xe40400, 0x00200},
842 {"partition-table", 0xe50000, 0x10000}, 688 {"partition-table", 0xe50000, 0x10000},
843 {"soft-version", 0xe60000, 0x00200}, 689 {"soft-version", 0xe60000, 0x00200},
844 {"support-list", 0xe61000, 0x0f000}, 690 {"support-list", 0xe61000, 0x0f000},
845 {"profile", 0xe70000, 0x10000}, 691 {"profile", 0xe70000, 0x10000},
846 {"default-config", 0xe80000, 0x10000}, 692 {"default-config", 0xe80000, 0x10000},
847 {"user-config", 0xe90000, 0x50000}, 693 {"user-config", 0xe90000, 0x50000},
848 {"log", 0xee0000, 0x100000}, 694 {"log", 0xee0000, 0x100000},
849 {"radio_bk", 0xfe0000, 0x10000}, 695 {"radio_bk", 0xfe0000, 0x10000},
850 {"radio", 0xff0000, 0x10000}, 696 {"radio", 0xff0000, 0x10000},
851 {NULL, 0, 0} 697 {NULL, 0, 0}
852 }, 698 },
853   699  
854 .first_sysupgrade_partition = "os-image", 700 .first_sysupgrade_partition = "os-image",
855 .last_sysupgrade_partition = "file-system" 701 .last_sysupgrade_partition = "file-system"
856 }, 702 },
857   703  
858 /** Firmware layout for the EAP120 */ 704 /** Firmware layout for the EAP120 */
859 { 705 {
860 .id = "EAP120", 706 .id = "EAP120",
861 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n", 707 .vendor = "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
862 .support_list = 708 .support_list =
863 "SupportList:\r\n" 709 "SupportList:\r\n"
864 "EAP120(TP-LINK|UN|N300-2):1.0\r\n", 710 "EAP120(TP-LINK|UN|N300-2):1.0\r\n",
865 .support_trail = '\xff', 711 .support_trail = '\xff',
866 .soft_ver = NULL, 712 .soft_ver = NULL,
867   713  
868 .partitions = { 714 .partitions = {
869 {"fs-uboot", 0x00000, 0x20000}, 715 {"fs-uboot", 0x00000, 0x20000},
870 {"partition-table", 0x20000, 0x02000}, 716 {"partition-table", 0x20000, 0x02000},
871 {"default-mac", 0x30000, 0x00020}, 717 {"default-mac", 0x30000, 0x00020},
872 {"support-list", 0x31000, 0x00100}, 718 {"support-list", 0x31000, 0x00100},
873 {"product-info", 0x31100, 0x00100}, 719 {"product-info", 0x31100, 0x00100},
874 {"soft-version", 0x32000, 0x00100}, 720 {"soft-version", 0x32000, 0x00100},
875 {"os-image", 0x40000, 0x180000}, 721 {"os-image", 0x40000, 0x180000},
876 {"file-system", 0x1c0000, 0x600000}, 722 {"file-system", 0x1c0000, 0x600000},
877 {"user-config", 0x7c0000, 0x10000}, 723 {"user-config", 0x7c0000, 0x10000},
878 {"backup-config", 0x7d0000, 0x10000}, 724 {"backup-config", 0x7d0000, 0x10000},
879 {"log", 0x7e0000, 0x10000}, 725 {"log", 0x7e0000, 0x10000},
880 {"radio", 0x7f0000, 0x10000}, 726 {"radio", 0x7f0000, 0x10000},
881 {NULL, 0, 0} 727 {NULL, 0, 0}
882 }, 728 },
883   729  
884 .first_sysupgrade_partition = "os-image", 730 .first_sysupgrade_partition = "os-image",
885 .last_sysupgrade_partition = "file-system" 731 .last_sysupgrade_partition = "file-system"
886 }, 732 },
887   733  
888 /** Firmware layout for the TL-WA850RE v2 */ 734 /** Firmware layout for the TL-WA850RE v2 */
889 { 735 {
890 .id = "TLWA850REV2", 736 .id = "TLWA850REV2",
891 .vendor = "", 737 .vendor = "",
892 .support_list = 738 .support_list =
893 "SupportList:\n" 739 "SupportList:\n"
894 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n" 740 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55530000}\n"
895 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n" 741 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:00000000}\n"
896 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n" 742 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:55534100}\n"
897 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n" 743 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:45550000}\n"
898 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n" 744 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4B520000}\n"
899 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n" 745 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:42520000}\n"
900 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n" 746 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:4A500000}\n"
901 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n" 747 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:43410000}\n"
902 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n" 748 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:41550000}\n"
903 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n", 749 "{product_name:TL-WA850RE,product_ver:2.0.0,special_id:52550000}\n",
904 .support_trail = '\x00', 750 .support_trail = '\x00',
905 .soft_ver = NULL, 751 .soft_ver = NULL,
906   752  
907 /** 753 /**
908 576KB were moved from file-system to os-image 754 576KB were moved from file-system to os-image
909 in comparison to the stock image 755 in comparison to the stock image
910 */ 756 */
911 .partitions = { 757 .partitions = {
912 {"fs-uboot", 0x00000, 0x20000}, 758 {"fs-uboot", 0x00000, 0x20000},
913 {"os-image", 0x20000, 0x150000}, 759 {"os-image", 0x20000, 0x150000},
914 {"file-system", 0x170000, 0x240000}, 760 {"file-system", 0x170000, 0x240000},
915 {"partition-table", 0x3b0000, 0x02000}, 761 {"partition-table", 0x3b0000, 0x02000},
916 {"default-mac", 0x3c0000, 0x00020}, 762 {"default-mac", 0x3c0000, 0x00020},
917 {"pin", 0x3c0100, 0x00020}, 763 {"pin", 0x3c0100, 0x00020},
918 {"product-info", 0x3c1000, 0x01000}, 764 {"product-info", 0x3c1000, 0x01000},
919 {"soft-version", 0x3c2000, 0x00100}, 765 {"soft-version", 0x3c2000, 0x00100},
920 {"support-list", 0x3c3000, 0x01000}, 766 {"support-list", 0x3c3000, 0x01000},
921 {"profile", 0x3c4000, 0x08000}, 767 {"profile", 0x3c4000, 0x08000},
922 {"user-config", 0x3d0000, 0x10000}, 768 {"user-config", 0x3d0000, 0x10000},
923 {"default-config", 0x3e0000, 0x10000}, 769 {"default-config", 0x3e0000, 0x10000},
924 {"radio", 0x3f0000, 0x10000}, 770 {"radio", 0x3f0000, 0x10000},
925 {NULL, 0, 0} 771 {NULL, 0, 0}
926 }, 772 },
927   773  
928 .first_sysupgrade_partition = "os-image", 774 .first_sysupgrade_partition = "os-image",
929 .last_sysupgrade_partition = "file-system" 775 .last_sysupgrade_partition = "file-system"
930 }, 776 },
931   777  
932 /** Firmware layout for the TL-WA855RE v1 */ 778 /** Firmware layout for the TL-WA855RE v1 */
933 { 779 {
934 .id = "TLWA855REV1", 780 .id = "TLWA855REV1",
935 .vendor = "", 781 .vendor = "",
936 .support_list = 782 .support_list =
937 "SupportList:\n" 783 "SupportList:\n"
938 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n" 784 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:00000000}\n"
939 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n" 785 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:55530000}\n"
940 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n" 786 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:45550000}\n"
941 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n" 787 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4B520000}\n"
942 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n" 788 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:42520000}\n"
943 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n" 789 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:4A500000}\n"
944 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n" 790 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:43410000}\n"
945 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n" 791 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:41550000}\n"
946 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n", 792 "{product_name:TL-WA855RE,product_ver:1.0.0,special_id:52550000}\n",
947 .support_trail = '\x00', 793 .support_trail = '\x00',
948 .soft_ver = NULL, 794 .soft_ver = NULL,
949   795  
950 .partitions = { 796 .partitions = {
951 {"fs-uboot", 0x00000, 0x20000}, 797 {"fs-uboot", 0x00000, 0x20000},
952 {"os-image", 0x20000, 0x150000}, 798 {"os-image", 0x20000, 0x150000},
953 {"file-system", 0x170000, 0x240000}, 799 {"file-system", 0x170000, 0x240000},
954 {"partition-table", 0x3b0000, 0x02000}, 800 {"partition-table", 0x3b0000, 0x02000},
955 {"default-mac", 0x3c0000, 0x00020}, 801 {"default-mac", 0x3c0000, 0x00020},
956 {"pin", 0x3c0100, 0x00020}, 802 {"pin", 0x3c0100, 0x00020},
957 {"product-info", 0x3c1000, 0x01000}, 803 {"product-info", 0x3c1000, 0x01000},
958 {"soft-version", 0x3c2000, 0x00100}, 804 {"soft-version", 0x3c2000, 0x00100},
959 {"support-list", 0x3c3000, 0x01000}, 805 {"support-list", 0x3c3000, 0x01000},
960 {"profile", 0x3c4000, 0x08000}, 806 {"profile", 0x3c4000, 0x08000},
961 {"user-config", 0x3d0000, 0x10000}, 807 {"user-config", 0x3d0000, 0x10000},
962 {"default-config", 0x3e0000, 0x10000}, 808 {"default-config", 0x3e0000, 0x10000},
963 {"radio", 0x3f0000, 0x10000}, 809 {"radio", 0x3f0000, 0x10000},
964 {NULL, 0, 0} 810 {NULL, 0, 0}
965 }, 811 },
966   812  
967 .first_sysupgrade_partition = "os-image", 813 .first_sysupgrade_partition = "os-image",
968 .last_sysupgrade_partition = "file-system" 814 .last_sysupgrade_partition = "file-system"
969 }, 815 },
970   816  
971 /** Firmware layout for the TL-WR1043 v5 */ 817 /** Firmware layout for the TL-WR1043 v5 */
972 { 818 {
973 .id = "TLWR1043NV5", 819 .id = "TLWR1043NV5",
974 .vendor = "", 820 .vendor = "",
975 .support_list = 821 .support_list =
976 "SupportList:\n" 822 "SupportList:\n"
977 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n" 823 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:45550000}\n"
978 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n", 824 "{product_name:TL-WR1043N,product_ver:5.0.0,special_id:55530000}\n",
979 .support_trail = '\x00', 825 .support_trail = '\x00',
980 .soft_ver = "soft_ver:1.0.0\n", 826 .soft_ver = "soft_ver:1.0.0\n",
981 .partitions = { 827 .partitions = {
982 {"factory-boot", 0x00000, 0x20000}, 828 {"factory-boot", 0x00000, 0x20000},
983 {"fs-uboot", 0x20000, 0x20000}, 829 {"fs-uboot", 0x20000, 0x20000},
984 {"firmware", 0x40000, 0xec0000}, 830 {"os-image", 0x40000, 0x180000},
-   831 {"file-system", 0x1c0000, 0xd40000},
985 {"default-mac", 0xf00000, 0x00200}, 832 {"default-mac", 0xf00000, 0x00200},
986 {"pin", 0xf00200, 0x00200}, 833 {"pin", 0xf00200, 0x00200},
987 {"device-id", 0xf00400, 0x00100}, 834 {"device-id", 0xf00400, 0x00100},
988 {"product-info", 0xf00500, 0x0fb00}, 835 {"product-info", 0xf00500, 0x0fb00},
989 {"soft-version", 0xf10000, 0x01000}, 836 {"soft-version", 0xf10000, 0x01000},
990 {"extra-para", 0xf11000, 0x01000}, 837 {"extra-para", 0xf11000, 0x01000},
991 {"support-list", 0xf12000, 0x0a000}, 838 {"support-list", 0xf12000, 0x0a000},
992 {"profile", 0xf1c000, 0x04000}, 839 {"profile", 0xf1c000, 0x04000},
993 {"default-config", 0xf20000, 0x10000}, 840 {"default-config", 0xf20000, 0x10000},
994 {"user-config", 0xf30000, 0x40000}, 841 {"user-config", 0xf30000, 0x40000},
995 {"qos-db", 0xf70000, 0x40000}, 842 {"qos-db", 0xf70000, 0x40000},
996 {"certificate", 0xfb0000, 0x10000}, 843 {"certificate", 0xfb0000, 0x10000},
997 {"partition-table", 0xfc0000, 0x10000}, 844 {"partition-table", 0xfc0000, 0x10000},
998 {"log", 0xfd0000, 0x20000}, 845 {"log", 0xfd0000, 0x20000},
999 {"radio", 0xff0000, 0x10000}, 846 {"radio", 0xff0000, 0x10000},
1000 {NULL, 0, 0} 847 {NULL, 0, 0}
1001 }, 848 },
1002 .first_sysupgrade_partition = "os-image", 849 .first_sysupgrade_partition = "os-image",
1003 .last_sysupgrade_partition = "file-system" 850 .last_sysupgrade_partition = "file-system"
1004 }, 851 },
1005   852  
1006 /** Firmware layout for the TL-WR1043 v4 */ 853 /** Firmware layout for the TL-WR1043 v4 */
1007 { 854 {
1008 .id = "TLWR1043NDV4", 855 .id = "TLWR1043NDV4",
1009 .vendor = "", 856 .vendor = "",
1010 .support_list = 857 .support_list =
1011 "SupportList:\n" 858 "SupportList:\n"
1012 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n", 859 "{product_name:TL-WR1043ND,product_ver:4.0.0,special_id:45550000}\n",
1013 .support_trail = '\x00', 860 .support_trail = '\x00',
1014 .soft_ver = NULL, 861 .soft_ver = NULL,
-   862  
1015   863 /**
-   864 We use a bigger os-image partition than the stock images (and thus
-   865 smaller file-system), as our kernel doesn't fit in the stock firmware's
-   866 1MB os-image.
1016 /* We're using a dynamic kernel/rootfs split here */ 867 */
1017 .partitions = { 868 .partitions = {
1018 {"fs-uboot", 0x00000, 0x20000}, 869 {"fs-uboot", 0x00000, 0x20000},
-   870 {"os-image", 0x20000, 0x180000},
1019 {"firmware", 0x20000, 0xf30000}, 871 {"file-system", 0x1a0000, 0xdb0000},
1020 {"default-mac", 0xf50000, 0x00200}, 872 {"default-mac", 0xf50000, 0x00200},
1021 {"pin", 0xf50200, 0x00200}, 873 {"pin", 0xf50200, 0x00200},
1022 {"product-info", 0xf50400, 0x0fc00}, 874 {"product-info", 0xf50400, 0x0fc00},
1023 {"soft-version", 0xf60000, 0x0b000}, 875 {"soft-version", 0xf60000, 0x0b000},
1024 {"support-list", 0xf6b000, 0x04000}, 876 {"support-list", 0xf6b000, 0x04000},
1025 {"profile", 0xf70000, 0x04000}, 877 {"profile", 0xf70000, 0x04000},
1026 {"default-config", 0xf74000, 0x0b000}, 878 {"default-config", 0xf74000, 0x0b000},
1027 {"user-config", 0xf80000, 0x40000}, 879 {"user-config", 0xf80000, 0x40000},
1028 {"partition-table", 0xfc0000, 0x10000}, 880 {"partition-table", 0xfc0000, 0x10000},
1029 {"log", 0xfd0000, 0x20000}, 881 {"log", 0xfd0000, 0x20000},
1030 {"radio", 0xff0000, 0x10000}, 882 {"radio", 0xff0000, 0x10000},
1031 {NULL, 0, 0} 883 {NULL, 0, 0}
1032 }, 884 },
1033   885  
1034 .first_sysupgrade_partition = "os-image", 886 .first_sysupgrade_partition = "os-image",
1035 .last_sysupgrade_partition = "file-system" 887 .last_sysupgrade_partition = "file-system"
1036 }, 888 },
1037   889  
1038 /** Firmware layout for the TL-WR902AC v1 */ 890 /** Firmware layout for the TL-WR902AC v1 */
1039 { 891 {
1040 .id = "TL-WR902AC-V1", 892 .id = "TL-WR902AC-V1",
1041 .vendor = "", 893 .vendor = "",
1042 .support_list = 894 .support_list =
1043 "SupportList:\n" 895 "SupportList:\n"
1044 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n" 896 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:45550000}\n"
1045 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n", 897 "{product_name:TL-WR902AC,product_ver:1.0.0,special_id:55530000}\n",
1046 .support_trail = '\x00', 898 .support_trail = '\x00',
1047 .soft_ver = NULL, 899 .soft_ver = NULL,
1048   900  
1049 /** 901 /**
1050 384KB were moved from file-system to os-image 902 384KB were moved from file-system to os-image
1051 in comparison to the stock image 903 in comparison to the stock image
1052 */ 904 */
1053 .partitions = { 905 .partitions = {
1054 {"fs-uboot", 0x00000, 0x20000}, 906 {"fs-uboot", 0x00000, 0x20000},
1055 {"firmware", 0x20000, 0x730000}, 907 {"os-image", 0x20000, 0x180000},
-   908 {"file-system", 0x1a0000, 0x5b0000},
1056 {"default-mac", 0x750000, 0x00200}, 909 {"default-mac", 0x750000, 0x00200},
1057 {"pin", 0x750200, 0x00200}, 910 {"pin", 0x750200, 0x00200},
1058 {"product-info", 0x750400, 0x0fc00}, 911 {"product-info", 0x750400, 0x0fc00},
1059 {"soft-version", 0x760000, 0x0b000}, 912 {"soft-version", 0x760000, 0x0b000},
1060 {"support-list", 0x76b000, 0x04000}, 913 {"support-list", 0x76b000, 0x04000},
1061 {"profile", 0x770000, 0x04000}, 914 {"profile", 0x770000, 0x04000},
1062 {"default-config", 0x774000, 0x0b000}, 915 {"default-config", 0x774000, 0x0b000},
1063 {"user-config", 0x780000, 0x40000}, 916 {"user-config", 0x780000, 0x40000},
1064 {"partition-table", 0x7c0000, 0x10000}, 917 {"partition-table", 0x7c0000, 0x10000},
1065 {"log", 0x7d0000, 0x20000}, 918 {"log", 0x7d0000, 0x20000},
1066 {"radio", 0x7f0000, 0x10000}, 919 {"radio", 0x7f0000, 0x10000},
1067 {NULL, 0, 0} 920 {NULL, 0, 0}
1068 }, 921 },
1069   922  
1070 .first_sysupgrade_partition = "os-image", 923 .first_sysupgrade_partition = "os-image",
1071 .last_sysupgrade_partition = "file-system", 924 .last_sysupgrade_partition = "file-system",
1072 }, 925 },
1073   926  
1074 /** Firmware layout for the TL-WR942N V1 */ 927 /** Firmware layout for the TL-WR942N V1 */
1075 { 928 {
1076 .id = "TLWR942NV1", 929 .id = "TLWR942NV1",
1077 .vendor = "", 930 .vendor = "",
1078 .support_list = 931 .support_list =
1079 "SupportList:\r\n" 932 "SupportList:\r\n"
1080 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n" 933 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:00000000}\r\n"
1081 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n", 934 "{product_name:TL-WR942N,product_ver:1.0.0,special_id:52550000}\r\n",
1082 .support_trail = '\x00', 935 .support_trail = '\x00',
1083 .soft_ver = NULL, 936 .soft_ver = NULL,
1084   937  
1085 .partitions = { 938 .partitions = {
1086 {"fs-uboot", 0x00000, 0x20000}, 939 {"fs-uboot", 0x00000, 0x20000},
1087 {"firmware", 0x20000, 0xe20000}, 940 {"os-image", 0x20000, 0x180000},
-   941 {"file-system", 0x1a0000, 0xca0000},
1088 {"default-mac", 0xe40000, 0x00200}, 942 {"default-mac", 0xe40000, 0x00200},
1089 {"pin", 0xe40200, 0x00200}, 943 {"pin", 0xe40200, 0x00200},
1090 {"product-info", 0xe40400, 0x0fc00}, 944 {"product-info", 0xe40400, 0x0fc00},
1091 {"partition-table", 0xe50000, 0x10000}, 945 {"partition-table", 0xe50000, 0x10000},
1092 {"soft-version", 0xe60000, 0x10000}, 946 {"soft-version", 0xe60000, 0x10000},
1093 {"support-list", 0xe70000, 0x10000}, 947 {"support-list", 0xe70000, 0x10000},
1094 {"profile", 0xe80000, 0x10000}, 948 {"profile", 0xe80000, 0x10000},
1095 {"default-config", 0xe90000, 0x10000}, 949 {"default-config", 0xe90000, 0x10000},
1096 {"user-config", 0xea0000, 0x40000}, 950 {"user-config", 0xea0000, 0x40000},
1097 {"qos-db", 0xee0000, 0x40000}, 951 {"qos-db", 0xee0000, 0x40000},
1098 {"certificate", 0xf20000, 0x10000}, 952 {"certificate", 0xf20000, 0x10000},
1099 {"usb-config", 0xfb0000, 0x10000}, 953 {"usb-config", 0xfb0000, 0x10000},
1100 {"log", 0xfc0000, 0x20000}, 954 {"log", 0xfc0000, 0x20000},
1101 {"radio-bk", 0xfe0000, 0x10000}, 955 {"radio-bk", 0xfe0000, 0x10000},
1102 {"radio", 0xff0000, 0x10000}, 956 {"radio", 0xff0000, 0x10000},
1103 {NULL, 0, 0} 957 {NULL, 0, 0}
1104 }, 958 },
1105   959  
1106 .first_sysupgrade_partition = "os-image", 960 .first_sysupgrade_partition = "os-image",
1107 .last_sysupgrade_partition = "file-system", 961 .last_sysupgrade_partition = "file-system",
1108 }, 962 },
1109   963  
1110 /** Firmware layout for the RE350 v1 */ 964 /** Firmware layout for the RE350 v1 */
1111 { 965 {
1112 .id = "RE350-V1", 966 .id = "RE350-V1",
1113 .vendor = "", 967 .vendor = "",
1114 .support_list = 968 .support_list =
1115 "SupportList:\n" 969 "SupportList:\n"
1116 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n" 970 "{product_name:RE350,product_ver:1.0.0,special_id:45550000}\n"
1117 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n" 971 "{product_name:RE350,product_ver:1.0.0,special_id:00000000}\n"
1118 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n" 972 "{product_name:RE350,product_ver:1.0.0,special_id:41550000}\n"
1119 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n" 973 "{product_name:RE350,product_ver:1.0.0,special_id:55530000}\n"
1120 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n" 974 "{product_name:RE350,product_ver:1.0.0,special_id:43410000}\n"
1121 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n" 975 "{product_name:RE350,product_ver:1.0.0,special_id:4b520000}\n"
1122 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n", 976 "{product_name:RE350,product_ver:1.0.0,special_id:4a500000}\n",
1123 .support_trail = '\x00', 977 .support_trail = '\x00',
1124 .soft_ver = NULL, 978 .soft_ver = NULL,
-   979  
1125   980 /**
-   981 The original os-image partition is too small,
-   982 so we enlarge it to 1.75M
1126 /** We're using a dynamic kernel/rootfs split here */ 983 */
1127 .partitions = { 984 .partitions = {
1128 {"fs-uboot", 0x00000, 0x20000}, 985 {"fs-uboot", 0x00000, 0x20000},
-   986 {"os-image", 0x20000, 0x1c0000},
1129 {"firmware", 0x20000, 0x5e0000}, 987 {"file-system", 0x1e0000, 0x420000},
1130 {"partition-table", 0x600000, 0x02000}, 988 {"partition-table", 0x600000, 0x02000},
1131 {"default-mac", 0x610000, 0x00020}, 989 {"default-mac", 0x610000, 0x00020},
1132 {"pin", 0x610100, 0x00020}, 990 {"pin", 0x610100, 0x00020},
1133 {"product-info", 0x611100, 0x01000}, 991 {"product-info", 0x611100, 0x01000},
1134 {"soft-version", 0x620000, 0x01000}, 992 {"soft-version", 0x620000, 0x01000},
1135 {"support-list", 0x621000, 0x01000}, 993 {"support-list", 0x621000, 0x01000},
1136 {"profile", 0x622000, 0x08000}, 994 {"profile", 0x622000, 0x08000},
1137 {"user-config", 0x630000, 0x10000}, 995 {"user-config", 0x630000, 0x10000},
1138 {"default-config", 0x640000, 0x10000}, 996 {"default-config", 0x640000, 0x10000},
1139 {"radio", 0x7f0000, 0x10000}, 997 {"radio", 0x7f0000, 0x10000},
1140 {NULL, 0, 0} 998 {NULL, 0, 0}
1141 }, 999 },
1142   1000  
1143 .first_sysupgrade_partition = "os-image", 1001 .first_sysupgrade_partition = "os-image",
1144 .last_sysupgrade_partition = "file-system" 1002 .last_sysupgrade_partition = "file-system"
1145 }, 1003 },
1146   1004  
1147 /** Firmware layout for the RE355 */ 1005 /** Firmware layout for the RE355 */
1148 { 1006 {
1149 .id = "RE355", 1007 .id = "RE355",
1150 .vendor = "", 1008 .vendor = "",
1151 .support_list = 1009 .support_list =
1152 "SupportList:\r\n" 1010 "SupportList:\r\n"
1153 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n" 1011 "{product_name:RE355,product_ver:1.0.0,special_id:00000000}\r\n"
1154 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n" 1012 "{product_name:RE355,product_ver:1.0.0,special_id:55530000}\r\n"
1155 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n" 1013 "{product_name:RE355,product_ver:1.0.0,special_id:45550000}\r\n"
1156 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n" 1014 "{product_name:RE355,product_ver:1.0.0,special_id:4A500000}\r\n"
1157 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n" 1015 "{product_name:RE355,product_ver:1.0.0,special_id:43410000}\r\n"
1158 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n" 1016 "{product_name:RE355,product_ver:1.0.0,special_id:41550000}\r\n"
1159 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n" 1017 "{product_name:RE355,product_ver:1.0.0,special_id:4B520000}\r\n"
1160 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n", 1018 "{product_name:RE355,product_ver:1.0.0,special_id:55534100}\r\n",
1161 .support_trail = '\x00', 1019 .support_trail = '\x00',
1162 .soft_ver = NULL, 1020 .soft_ver = NULL,
-   1021  
-   1022 /**
1163   1023 The flash partition table for RE355;
-   1024 it is almost the same as the one used by the stock images,
-   1025 576KB were moved from file-system to os-image.
1164 /* We're using a dynamic kernel/rootfs split here */ 1026 */
1165 .partitions = { 1027 .partitions = {
1166 {"fs-uboot", 0x00000, 0x20000}, 1028 {"fs-uboot", 0x00000, 0x20000},
-   1029 {"os-image", 0x20000, 0x180000},
1167 {"firmware", 0x20000, 0x5e0000}, 1030 {"file-system", 0x1a0000, 0x460000},
1168 {"partition-table", 0x600000, 0x02000}, 1031 {"partition-table", 0x600000, 0x02000},
1169 {"default-mac", 0x610000, 0x00020}, 1032 {"default-mac", 0x610000, 0x00020},
1170 {"pin", 0x610100, 0x00020}, 1033 {"pin", 0x610100, 0x00020},
1171 {"product-info", 0x611100, 0x01000}, 1034 {"product-info", 0x611100, 0x01000},
1172 {"soft-version", 0x620000, 0x01000}, 1035 {"soft-version", 0x620000, 0x01000},
1173 {"support-list", 0x621000, 0x01000}, 1036 {"support-list", 0x621000, 0x01000},
1174 {"profile", 0x622000, 0x08000}, 1037 {"profile", 0x622000, 0x08000},
1175 {"user-config", 0x630000, 0x10000}, 1038 {"user-config", 0x630000, 0x10000},
1176 {"default-config", 0x640000, 0x10000}, 1039 {"default-config", 0x640000, 0x10000},
1177 {"radio", 0x7f0000, 0x10000}, 1040 {"radio", 0x7f0000, 0x10000},
1178 {NULL, 0, 0} 1041 {NULL, 0, 0}
1179 }, 1042 },
1180   1043  
1181 .first_sysupgrade_partition = "os-image", 1044 .first_sysupgrade_partition = "os-image",
1182 .last_sysupgrade_partition = "file-system" 1045 .last_sysupgrade_partition = "file-system"
1183 }, 1046 },
1184   1047  
1185 /** Firmware layout for the RE450 */ 1048 /** Firmware layout for the RE450 */
1186 { 1049 {
1187 .id = "RE450", 1050 .id = "RE450",
1188 .vendor = "", 1051 .vendor = "",
1189 .support_list = 1052 .support_list =
1190 "SupportList:\r\n" 1053 "SupportList:\r\n"
1191 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n" 1054 "{product_name:RE450,product_ver:1.0.0,special_id:00000000}\r\n"
1192 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n" 1055 "{product_name:RE450,product_ver:1.0.0,special_id:55530000}\r\n"
1193 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n" 1056 "{product_name:RE450,product_ver:1.0.0,special_id:45550000}\r\n"
1194 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n" 1057 "{product_name:RE450,product_ver:1.0.0,special_id:4A500000}\r\n"
1195 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n" 1058 "{product_name:RE450,product_ver:1.0.0,special_id:43410000}\r\n"
1196 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n" 1059 "{product_name:RE450,product_ver:1.0.0,special_id:41550000}\r\n"
1197 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n" 1060 "{product_name:RE450,product_ver:1.0.0,special_id:4B520000}\r\n"
1198 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n", 1061 "{product_name:RE450,product_ver:1.0.0,special_id:55534100}\r\n",
1199 .support_trail = '\x00', 1062 .support_trail = '\x00',
1200 .soft_ver = NULL, 1063 .soft_ver = NULL,
1201   -  
1202 /** We're using a dynamic kernel/rootfs split here */ -  
1203 .partitions = { -  
1204 {"fs-uboot", 0x00000, 0x20000}, -  
1205 {"firmware", 0x20000, 0x5e0000}, -  
1206 {"partition-table", 0x600000, 0x02000}, -  
1207 {"default-mac", 0x610000, 0x00020}, -  
1208 {"pin", 0x610100, 0x00020}, -  
1209 {"product-info", 0x611100, 0x01000}, -  
1210 {"soft-version", 0x620000, 0x01000}, -  
1211 {"support-list", 0x621000, 0x01000}, -  
1212 {"profile", 0x622000, 0x08000}, -  
1213 {"user-config", 0x630000, 0x10000}, -  
1214 {"default-config", 0x640000, 0x10000}, -  
1215 {"radio", 0x7f0000, 0x10000}, -  
1216 {NULL, 0, 0} 1064  
1217 }, -  
1218   1065 /**
1219 .first_sysupgrade_partition = "os-image", 1066 The flash partition table for RE450;
1220 .last_sysupgrade_partition = "file-system" -  
1221 }, -  
1222   1067 it is almost the same as the one used by the stock images,
1223 /** Firmware layout for the RE450 v2 */ 1068 576KB were moved from file-system to os-image.
1224 { -  
1225 .id = "RE450-V2", -  
1226 .vendor = "", -  
1227 .support_list = -  
1228 "SupportList:\r\n" -  
1229 "{product_name:RE450,product_ver:2.0.0,special_id:00000000}\r\n" -  
1230 "{product_name:RE450,product_ver:2.0.0,special_id:55530000}\r\n" -  
1231 "{product_name:RE450,product_ver:2.0.0,special_id:45550000}\r\n" -  
1232 "{product_name:RE450,product_ver:2.0.0,special_id:4A500000}\r\n" -  
1233 "{product_name:RE450,product_ver:2.0.0,special_id:43410000}\r\n" -  
1234 "{product_name:RE450,product_ver:2.0.0,special_id:41550000}\r\n" -  
1235 "{product_name:RE450,product_ver:2.0.0,special_id:41530000}\r\n" -  
1236 "{product_name:RE450,product_ver:2.0.0,special_id:4B520000}\r\n" -  
1237 "{product_name:RE450,product_ver:2.0.0,special_id:42520000}\r\n", -  
1238 .support_trail = '\x00', -  
1239 .soft_ver = NULL, -  
1240   -  
1241 /* We're using a dynamic kernel/rootfs split here */ 1069 */
1242 .partitions = { 1070 .partitions = {
1243 {"fs-uboot", 0x00000, 0x20000}, 1071 {"fs-uboot", 0x00000, 0x20000},
-   1072 {"os-image", 0x20000, 0x180000},
1244 {"firmware", 0x20000, 0x5e0000}, 1073 {"file-system", 0x1a0000, 0x460000},
1245 {"partition-table", 0x600000, 0x02000}, 1074 {"partition-table", 0x600000, 0x02000},
1246 {"default-mac", 0x610000, 0x00020}, 1075 {"default-mac", 0x610000, 0x00020},
1247 {"pin", 0x610100, 0x00020}, 1076 {"pin", 0x610100, 0x00020},
1248 {"product-info", 0x611100, 0x01000}, 1077 {"product-info", 0x611100, 0x01000},
1249 {"soft-version", 0x620000, 0x01000}, 1078 {"soft-version", 0x620000, 0x01000},
1250 {"support-list", 0x621000, 0x01000}, 1079 {"support-list", 0x621000, 0x01000},
1251 {"profile", 0x622000, 0x08000}, 1080 {"profile", 0x622000, 0x08000},
1252 {"user-config", 0x630000, 0x10000}, 1081 {"user-config", 0x630000, 0x10000},
1253 {"default-config", 0x640000, 0x10000}, 1082 {"default-config", 0x640000, 0x10000},
1254 {"radio", 0x7f0000, 0x10000}, 1083 {"radio", 0x7f0000, 0x10000},
1255   -  
1256 {NULL, 0, 0} 1084 {NULL, 0, 0}
1257 }, 1085 },
1258   1086  
1259 .first_sysupgrade_partition = "os-image", 1087 .first_sysupgrade_partition = "os-image",
1260 .last_sysupgrade_partition = "file-system" 1088 .last_sysupgrade_partition = "file-system"
1261 }, 1089 },
1262   1090  
1263 {} 1091 {}
1264 }; 1092 };
1265   1093  
1266 #define error(_ret, _errno, _str, ...) \ 1094 #define error(_ret, _errno, _str, ...) \
1267 do { \ 1095 do { \
1268 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \ 1096 fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \
1269 strerror(_errno)); \ 1097 strerror(_errno)); \
1270 if (_ret) \ 1098 if (_ret) \
1271 exit(_ret); \ 1099 exit(_ret); \
1272 } while (0) 1100 } while (0)
1273   1101  
1274   1102  
1275 /** Stores a uint32 as big endian */ 1103 /** Stores a uint32 as big endian */
1276 static inline void put32(uint8_t *buf, uint32_t val) { 1104 static inline void put32(uint8_t *buf, uint32_t val) {
1277 buf[0] = val >> 24; 1105 buf[0] = val >> 24;
1278 buf[1] = val >> 16; 1106 buf[1] = val >> 16;
1279 buf[2] = val >> 8; 1107 buf[2] = val >> 8;
1280 buf[3] = val; 1108 buf[3] = val;
1281 } 1109 }
1282   1110  
1283 /** Allocates a new image partition */ 1111 /** Allocates a new image partition */
1284 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) { 1112 static struct image_partition_entry alloc_image_partition(const char *name, size_t len) {
1285 struct image_partition_entry entry = {name, len, malloc(len)}; 1113 struct image_partition_entry entry = {name, len, malloc(len)};
1286 if (!entry.data) 1114 if (!entry.data)
1287 error(1, errno, "malloc"); 1115 error(1, errno, "malloc");
1288   1116  
1289 return entry; 1117 return entry;
1290 } 1118 }
1291   1119  
1292 /** Frees an image partition */ 1120 /** Frees an image partition */
1293 static void free_image_partition(struct image_partition_entry entry) { 1121 static void free_image_partition(struct image_partition_entry entry) {
1294 free(entry.data); 1122 free(entry.data);
1295 } 1123 }
1296   1124  
1297 static time_t source_date_epoch = -1; 1125 static time_t source_date_epoch = -1;
1298 static void set_source_date_epoch() { 1126 static void set_source_date_epoch() {
1299 char *env = getenv("SOURCE_DATE_EPOCH"); 1127 char *env = getenv("SOURCE_DATE_EPOCH");
1300 char *endptr = env; 1128 char *endptr = env;
1301 errno = 0; 1129 errno = 0;
1302 if (env && *env) { 1130 if (env && *env) {
1303 source_date_epoch = strtoull(env, &endptr, 10); 1131 source_date_epoch = strtoull(env, &endptr, 10);
1304 if (errno || (endptr && *endptr != '\0')) { 1132 if (errno || (endptr && *endptr != '\0')) {
1305 fprintf(stderr, "Invalid SOURCE_DATE_EPOCH"); 1133 fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
1306 exit(1); 1134 exit(1);
1307 } 1135 }
1308 } 1136 }
1309 } 1137 }
1310   1138  
1311 /** Generates the partition-table partition */ 1139 /** Generates the partition-table partition */
1312 static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) { 1140 static struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) {
1313 struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800); 1141 struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800);
1314   1142  
1315 char *s = (char *)entry.data, *end = (char *)(s+entry.size); 1143 char *s = (char *)entry.data, *end = (char *)(s+entry.size);
1316   1144  
1317 *(s++) = 0x00; 1145 *(s++) = 0x00;
1318 *(s++) = 0x04; 1146 *(s++) = 0x04;
1319 *(s++) = 0x00; 1147 *(s++) = 0x00;
1320 *(s++) = 0x00; 1148 *(s++) = 0x00;
1321   1149  
1322 size_t i; 1150 size_t i;
1323 for (i = 0; p[i].name; i++) { 1151 for (i = 0; p[i].name; i++) {
1324 size_t len = end-s; 1152 size_t len = end-s;
1325 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size); 1153 size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size);
1326   1154  
1327 if (w > len-1) 1155 if (w > len-1)
1328 error(1, 0, "flash partition table overflow?"); 1156 error(1, 0, "flash partition table overflow?");
1329   1157  
1330 s += w; 1158 s += w;
1331 } 1159 }
1332   1160  
1333 s++; 1161 s++;
1334   1162  
1335 memset(s, 0xff, end-s); 1163 memset(s, 0xff, end-s);
1336   1164  
1337 return entry; 1165 return entry;
1338 } 1166 }
1339   1167  
1340   1168  
1341 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */ 1169 /** Generates a binary-coded decimal representation of an integer in the range [0, 99] */
1342 static inline uint8_t bcd(uint8_t v) { 1170 static inline uint8_t bcd(uint8_t v) {
1343 return 0x10 * (v/10) + v%10; 1171 return 0x10 * (v/10) + v%10;
1344 } 1172 }
1345   1173  
1346   1174  
1347 /** Generates the soft-version partition */ 1175 /** Generates the soft-version partition */
1348 static struct image_partition_entry make_soft_version(uint32_t rev) { 1176 static struct image_partition_entry make_soft_version(uint32_t rev) {
1349 struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version)); 1177 struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version));
1350 struct soft_version *s = (struct soft_version *)entry.data; 1178 struct soft_version *s = (struct soft_version *)entry.data;
1351   1179  
1352 time_t t; 1180 time_t t;
1353   1181  
1354 if (source_date_epoch != -1) 1182 if (source_date_epoch != -1)
1355 t = source_date_epoch; 1183 t = source_date_epoch;
1356 else if (time(&t) == (time_t)(-1)) 1184 else if (time(&t) == (time_t)(-1))
1357 error(1, errno, "time"); 1185 error(1, errno, "time");
1358   1186  
1359 struct tm *tm = localtime(&t); 1187 struct tm *tm = localtime(&t);
1360   1188  
1361 s->magic = htonl(0x0000000c); 1189 s->magic = htonl(0x0000000c);
1362 s->zero = 0; 1190 s->zero = 0;
1363 s->pad1 = 0xff; 1191 s->pad1 = 0xff;
1364   1192  
1365 s->version_major = 0; 1193 s->version_major = 0;
1366 s->version_minor = 0; 1194 s->version_minor = 0;
1367 s->version_patch = 0; 1195 s->version_patch = 0;
1368   1196  
1369 s->year_hi = bcd((1900+tm->tm_year)/100); 1197 s->year_hi = bcd((1900+tm->tm_year)/100);
1370 s->year_lo = bcd(tm->tm_year%100); 1198 s->year_lo = bcd(tm->tm_year%100);
1371 s->month = bcd(tm->tm_mon+1); 1199 s->month = bcd(tm->tm_mon+1);
1372 s->day = bcd(tm->tm_mday); 1200 s->day = bcd(tm->tm_mday);
1373 s->rev = htonl(rev); 1201 s->rev = htonl(rev);
1374   1202  
1375 s->pad2 = 0xff; 1203 s->pad2 = 0xff;
1376   1204  
1377 return entry; 1205 return entry;
1378 } 1206 }
1379   1207  
1380 static struct image_partition_entry make_soft_version_from_string(const char *soft_ver) { 1208 static struct image_partition_entry make_soft_version_from_string(const char *soft_ver) {
1381 /** String length _including_ the terminating zero byte */ 1209 /** String length _including_ the terminating zero byte */
1382 uint32_t ver_len = strlen(soft_ver) + 1; 1210 uint32_t ver_len = strlen(soft_ver) + 1;
1383 /** Partition contains 64 bit header, the version string, and one additional null byte */ 1211 /** Partition contains 64 bit header, the version string, and one additional null byte */
1384 size_t partition_len = 2*sizeof(uint32_t) + ver_len + 1; 1212 size_t partition_len = 2*sizeof(uint32_t) + ver_len + 1;
1385 struct image_partition_entry entry = alloc_image_partition("soft-version", partition_len); 1213 struct image_partition_entry entry = alloc_image_partition("soft-version", partition_len);
1386   1214  
1387 uint32_t *len = (uint32_t *)entry.data; 1215 uint32_t *len = (uint32_t *)entry.data;
1388 len[0] = htonl(ver_len); 1216 len[0] = htonl(ver_len);
1389 len[1] = 0; 1217 len[1] = 0;
1390 memcpy(&len[2], soft_ver, ver_len); 1218 memcpy(&len[2], soft_ver, ver_len);
1391   1219  
1392 entry.data[partition_len - 1] = 0; 1220 entry.data[partition_len - 1] = 0;
1393   1221  
1394 return entry; 1222 return entry;
1395 } 1223 }
1396   1224  
1397 /** Generates the support-list partition */ 1225 /** Generates the support-list partition */
1398 static struct image_partition_entry make_support_list(struct device_info *info) { 1226 static struct image_partition_entry make_support_list(const struct device_info *info) {
1399 size_t len = strlen(info->support_list); 1227 size_t len = strlen(info->support_list);
1400 struct image_partition_entry entry = alloc_image_partition("support-list", len + 9); 1228 struct image_partition_entry entry = alloc_image_partition("support-list", len + 9);
1401   1229  
1402 put32(entry.data, len); 1230 put32(entry.data, len);
1403 memset(entry.data+4, 0, 4); 1231 memset(entry.data+4, 0, 4);
1404 memcpy(entry.data+8, info->support_list, len); 1232 memcpy(entry.data+8, info->support_list, len);
1405 entry.data[len+8] = info->support_trail; 1233 entry.data[len+8] = info->support_trail;
1406   1234  
1407 return entry; 1235 return entry;
1408 } 1236 }
1409   1237  
1410 /** Creates a new image partition with an arbitrary name from a file */ 1238 /** Creates a new image partition with an arbitrary name from a file */
1411 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) { 1239 static struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof) {
1412 struct stat statbuf; 1240 struct stat statbuf;
1413   1241  
1414 if (stat(filename, &statbuf) < 0) 1242 if (stat(filename, &statbuf) < 0)
1415 error(1, errno, "unable to stat file `%s'", filename); 1243 error(1, errno, "unable to stat file `%s'", filename);
1416   1244  
1417 size_t len = statbuf.st_size; 1245 size_t len = statbuf.st_size;
1418   1246  
1419 if (add_jffs2_eof) 1247 if (add_jffs2_eof)
1420 if (file_system_partition) -  
1421 len = ALIGN(len + file_system_partition->base, 0x10000) + sizeof(jffs2_eof_mark) - file_system_partition->base; -  
1422 else -  
1423 len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark); 1248 len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark);
1424   1249  
1425 struct image_partition_entry entry = alloc_image_partition(part_name, len); 1250 struct image_partition_entry entry = alloc_image_partition(part_name, len);
1426   1251  
1427 FILE *file = fopen(filename, "rb"); 1252 FILE *file = fopen(filename, "rb");
1428 if (!file) 1253 if (!file)
1429 error(1, errno, "unable to open file `%s'", filename); 1254 error(1, errno, "unable to open file `%s'", filename);
1430   1255  
1431 if (fread(entry.data, statbuf.st_size, 1, file) != 1) 1256 if (fread(entry.data, statbuf.st_size, 1, file) != 1)
1432 error(1, errno, "unable to read file `%s'", filename); 1257 error(1, errno, "unable to read file `%s'", filename);
1433   1258  
1434 if (add_jffs2_eof) { 1259 if (add_jffs2_eof) {
1435 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size; 1260 uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size;
1436   1261  
1437 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark)); 1262 memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark));
1438 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark)); 1263 memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark));
1439 } 1264 }
1440   1265  
1441 fclose(file); 1266 fclose(file);
1442   1267  
1443 return entry; 1268 return entry;
1444 } 1269 }
1445   1270  
1446 /** Creates a new image partition from arbitrary data */ 1271 /** Creates a new image partition from arbitrary data */
1447 static struct image_partition_entry put_data(const char *part_name, const char *datain, size_t len) { 1272 static struct image_partition_entry put_data(const char *part_name, const char *datain, size_t len) {
1448   1273  
1449 struct image_partition_entry entry = alloc_image_partition(part_name, len); 1274 struct image_partition_entry entry = alloc_image_partition(part_name, len);
1450   1275  
1451 memcpy(entry.data, datain, len); 1276 memcpy(entry.data, datain, len);
1452   1277  
1453 return entry; 1278 return entry;
1454 } 1279 }
1455   1280  
1456 /** 1281 /**
1457 Copies a list of image partitions into an image buffer and generates the image partition table while doing so 1282 Copies a list of image partitions into an image buffer and generates the image partition table while doing so
1458   1283  
1459 Example image partition table: 1284 Example image partition table:
1460   1285  
1461 fwup-ptn partition-table base 0x00800 size 0x00800 1286 fwup-ptn partition-table base 0x00800 size 0x00800
1462 fwup-ptn os-image base 0x01000 size 0x113b45 1287 fwup-ptn os-image base 0x01000 size 0x113b45
1463 fwup-ptn file-system base 0x114b45 size 0x1d0004 1288 fwup-ptn file-system base 0x114b45 size 0x1d0004
1464 fwup-ptn support-list base 0x2e4b49 size 0x000d1 1289 fwup-ptn support-list base 0x2e4b49 size 0x000d1
1465   1290  
1466 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"), 1291 Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"),
1467 the end of the partition table is marked with a zero byte. 1292 the end of the partition table is marked with a zero byte.
1468   1293  
1469 The firmware image must contain at least the partition-table and support-list partitions 1294 The firmware image must contain at least the partition-table and support-list partitions
1470 to be accepted. There aren't any alignment constraints for the image partitions. 1295 to be accepted. There aren't any alignment constraints for the image partitions.
1471   1296  
1472 The partition-table partition contains the actual flash layout; partitions 1297 The partition-table partition contains the actual flash layout; partitions
1473 from the image partition table are mapped to the corresponding flash partitions during 1298 from the image partition table are mapped to the corresponding flash partitions during
1474 the firmware upgrade. The support-list partition contains a list of devices supported by 1299 the firmware upgrade. The support-list partition contains a list of devices supported by
1475 the firmware image. 1300 the firmware image.
1476   1301  
1477 The base offsets in the firmware partition table are relative to the end 1302 The base offsets in the firmware partition table are relative to the end
1478 of the vendor information block, so the partition-table partition will 1303 of the vendor information block, so the partition-table partition will
1479 actually start at offset 0x1814 of the image. 1304 actually start at offset 0x1814 of the image.
1480   1305  
1481 I think partition-table must be the first partition in the firmware image. 1306 I think partition-table must be the first partition in the firmware image.
1482 */ 1307 */
1483 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) { 1308 static void put_partitions(uint8_t *buffer, const struct flash_partition_entry *flash_parts, const struct image_partition_entry *parts) {
1484 size_t i, j; 1309 size_t i, j;
1485 char *image_pt = (char *)buffer, *end = image_pt + 0x800; 1310 char *image_pt = (char *)buffer, *end = image_pt + 0x800;
1486   1311  
1487 size_t base = 0x800; 1312 size_t base = 0x800;
1488 for (i = 0; parts[i].name; i++) { 1313 for (i = 0; parts[i].name; i++) {
1489 for (j = 0; flash_parts[j].name; j++) { 1314 for (j = 0; flash_parts[j].name; j++) {
1490 if (!strcmp(flash_parts[j].name, parts[i].name)) { 1315 if (!strcmp(flash_parts[j].name, parts[i].name)) {
1491 if (parts[i].size > flash_parts[j].size) 1316 if (parts[i].size > flash_parts[j].size)
1492 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size); 1317 error(1, 0, "%s partition too big (more than %u bytes)", flash_parts[j].name, (unsigned)flash_parts[j].size);
1493 break; 1318 break;
1494 } 1319 }
1495 } 1320 }
1496   1321  
1497 assert(flash_parts[j].name); 1322 assert(flash_parts[j].name);
1498   1323  
1499 memcpy(buffer + base, parts[i].data, parts[i].size); 1324 memcpy(buffer + base, parts[i].data, parts[i].size);
1500   1325  
1501 size_t len = end-image_pt; 1326 size_t len = end-image_pt;
1502 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); 1327 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);
1503   1328  
1504 if (w > len-1) 1329 if (w > len-1)
1505 error(1, 0, "image partition table overflow?"); 1330 error(1, 0, "image partition table overflow?");
1506   1331  
1507 image_pt += w; 1332 image_pt += w;
1508   1333  
1509 base += parts[i].size; 1334 base += parts[i].size;
1510 } 1335 }
1511 } 1336 }
1512   1337  
1513 /** Generates and writes the image MD5 checksum */ 1338 /** Generates and writes the image MD5 checksum */
1514 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) { 1339 static void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) {
1515 MD5_CTX ctx; 1340 MD5_CTX ctx;
1516   1341  
1517 MD5_Init(&ctx); 1342 MD5_Init(&ctx);
1518 MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt)); 1343 MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt));
1519 MD5_Update(&ctx, buffer, len); 1344 MD5_Update(&ctx, buffer, len);
1520 MD5_Final(md5, &ctx); 1345 MD5_Final(md5, &ctx);
1521 } 1346 }
1522   1347  
1523   1348  
1524 /** 1349 /**
1525 Generates the firmware image in factory format 1350 Generates the firmware image in factory format
1526   1351  
1527 Image format: 1352 Image format:
1528   1353  
1529 Bytes (hex) Usage 1354 Bytes (hex) Usage
1530 ----------- ----- 1355 ----------- -----
1531 0000-0003 Image size (4 bytes, big endian) 1356 0000-0003 Image size (4 bytes, big endian)
1532 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14) 1357 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14)
1533 0014-0017 Vendor information length (without padding) (4 bytes, big endian) 1358 0014-0017 Vendor information length (without padding) (4 bytes, big endian)
1534 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older 1359 0018-1013 Vendor information (4092 bytes, padded with 0xff; there seem to be older
1535 (VxWorks-based) TP-LINK devices which use a smaller vendor information block) 1360 (VxWorks-based) TP-LINK devices which use a smaller vendor information block)
1536 1014-1813 Image partition table (2048 bytes, padded with 0xff) 1361 1014-1813 Image partition table (2048 bytes, padded with 0xff)
1537 1814-xxxx Firmware partitions 1362 1814-xxxx Firmware partitions
1538 */ 1363 */
1539 static void * generate_factory_image(struct device_info *info, const struct image_partition_entry *parts, size_t *len) { 1364 static void * generate_factory_image(const struct device_info *info, const struct image_partition_entry *parts, size_t *len) {
1540 *len = 0x1814; 1365 *len = 0x1814;
1541   1366  
1542 size_t i; 1367 size_t i;
1543 for (i = 0; parts[i].name; i++) 1368 for (i = 0; parts[i].name; i++)
1544 *len += parts[i].size; 1369 *len += parts[i].size;
1545   1370  
1546 uint8_t *image = malloc(*len); 1371 uint8_t *image = malloc(*len);
1547 if (!image) 1372 if (!image)
1548 error(1, errno, "malloc"); 1373 error(1, errno, "malloc");
1549   1374  
1550 memset(image, 0xff, *len); 1375 memset(image, 0xff, *len);
1551 put32(image, *len); 1376 put32(image, *len);
1552   1377  
1553 if (info->vendor) { 1378 if (info->vendor) {
1554 size_t vendor_len = strlen(info->vendor); 1379 size_t vendor_len = strlen(info->vendor);
1555 put32(image+0x14, vendor_len); 1380 put32(image+0x14, vendor_len);
1556 memcpy(image+0x18, info->vendor, vendor_len); 1381 memcpy(image+0x18, info->vendor, vendor_len);
1557 } 1382 }
1558   1383  
1559 put_partitions(image + 0x1014, info->partitions, parts); 1384 put_partitions(image + 0x1014, info->partitions, parts);
1560 put_md5(image+0x04, image+0x14, *len-0x14); 1385 put_md5(image+0x04, image+0x14, *len-0x14);
1561   1386  
1562 return image; 1387 return image;
1563 } 1388 }
1564   1389  
1565 /** 1390 /**
1566 Generates the firmware image in sysupgrade format 1391 Generates the firmware image in sysupgrade format
1567   1392  
1568 This makes some assumptions about the provided flash and image partition tables and 1393 This makes some assumptions about the provided flash and image partition tables and
1569 should be generalized when TP-LINK starts building its safeloader into hardware with 1394 should be generalized when TP-LINK starts building its safeloader into hardware with
1570 different flash layouts. 1395 different flash layouts.
1571 */ 1396 */
1572 static void * generate_sysupgrade_image(struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) { 1397 static void * generate_sysupgrade_image(const struct device_info *info, const struct image_partition_entry *image_parts, size_t *len) {
1573 size_t i, j; 1398 size_t i, j;
1574 size_t flash_first_partition_index = 0; 1399 size_t flash_first_partition_index = 0;
1575 size_t flash_last_partition_index = 0; 1400 size_t flash_last_partition_index = 0;
1576 const struct flash_partition_entry *flash_first_partition = NULL; 1401 const struct flash_partition_entry *flash_first_partition = NULL;
1577 const struct flash_partition_entry *flash_last_partition = NULL; 1402 const struct flash_partition_entry *flash_last_partition = NULL;
1578 const struct image_partition_entry *image_last_partition = NULL; 1403 const struct image_partition_entry *image_last_partition = NULL;
1579   1404  
1580 /** Find first and last partitions */ 1405 /** Find first and last partitions */
1581 for (i = 0; info->partitions[i].name; i++) { 1406 for (i = 0; info->partitions[i].name; i++) {
1582 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) { 1407 if (!strcmp(info->partitions[i].name, info->first_sysupgrade_partition)) {
1583 flash_first_partition = &info->partitions[i]; 1408 flash_first_partition = &info->partitions[i];
1584 flash_first_partition_index = i; 1409 flash_first_partition_index = i;
1585 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) { 1410 } else if (!strcmp(info->partitions[i].name, info->last_sysupgrade_partition)) {
1586 flash_last_partition = &info->partitions[i]; 1411 flash_last_partition = &info->partitions[i];
1587 flash_last_partition_index = i; 1412 flash_last_partition_index = i;
1588 } 1413 }
1589 } 1414 }
1590   1415  
1591 assert(flash_first_partition && flash_last_partition); 1416 assert(flash_first_partition && flash_last_partition);
1592 assert(flash_first_partition_index < flash_last_partition_index); 1417 assert(flash_first_partition_index < flash_last_partition_index);
1593   1418  
1594 /** Find last partition from image to calculate needed size */ 1419 /** Find last partition from image to calculate needed size */
1595 for (i = 0; image_parts[i].name; i++) { 1420 for (i = 0; image_parts[i].name; i++) {
1596 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) { 1421 if (!strcmp(image_parts[i].name, info->last_sysupgrade_partition)) {
1597 image_last_partition = &image_parts[i]; 1422 image_last_partition = &image_parts[i];
1598 break; 1423 break;
1599 } 1424 }
1600 } 1425 }
1601   1426  
1602 assert(image_last_partition); 1427 assert(image_last_partition);
1603   1428  
1604 *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size; 1429 *len = flash_last_partition->base - flash_first_partition->base + image_last_partition->size;
1605   1430  
1606 uint8_t *image = malloc(*len); 1431 uint8_t *image = malloc(*len);
1607 if (!image) 1432 if (!image)
1608 error(1, errno, "malloc"); 1433 error(1, errno, "malloc");
1609   1434  
1610 memset(image, 0xff, *len); 1435 memset(image, 0xff, *len);
1611   1436  
1612 for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) { 1437 for (i = flash_first_partition_index; i <= flash_last_partition_index; i++) {
1613 for (j = 0; image_parts[j].name; j++) { 1438 for (j = 0; image_parts[j].name; j++) {
1614 if (!strcmp(info->partitions[i].name, image_parts[j].name)) { 1439 if (!strcmp(info->partitions[i].name, image_parts[j].name)) {
1615 if (image_parts[j].size > info->partitions[i].size) 1440 if (image_parts[j].size > info->partitions[i].size)
1616 error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size); 1441 error(1, 0, "%s partition too big (more than %u bytes)", info->partitions[i].name, (unsigned)info->partitions[i].size);
1617 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size); 1442 memcpy(image + info->partitions[i].base - flash_first_partition->base, image_parts[j].data, image_parts[j].size);
1618 break; 1443 break;
1619 } 1444 }
1620   1445  
1621 assert(image_parts[j].name); 1446 assert(image_parts[j].name);
1622 } 1447 }
1623 } 1448 }
1624   1449  
1625 return image; 1450 return image;
1626 } 1451 }
1627   1452  
1628 /** Generates an image according to a given layout and writes it to a file */ 1453 /** Generates an image according to a given layout and writes it to a file */
1629 static void build_image(const char *output, 1454 static void build_image(const char *output,
1630 const char *kernel_image, 1455 const char *kernel_image,
1631 const char *rootfs_image, 1456 const char *rootfs_image,
1632 uint32_t rev, 1457 uint32_t rev,
1633 bool add_jffs2_eof, 1458 bool add_jffs2_eof,
1634 bool sysupgrade, 1459 bool sysupgrade,
1635 struct device_info *info) { 1460 const struct device_info *info) {
1636   -  
1637 size_t i; -  
1638   1461  
1639 struct image_partition_entry parts[7] = {}; 1462 struct image_partition_entry parts[7] = {};
1640   -  
1641 struct flash_partition_entry *firmware_partition = NULL; -  
1642 struct flash_partition_entry *os_image_partition = NULL; -  
1643 struct flash_partition_entry *file_system_partition = NULL; -  
1644 size_t firmware_partition_index = 0; -  
1645   -  
1646 for (i = 0; info->partitions[i].name; i++) { -  
1647 if (!strcmp(info->partitions[i].name, "firmware")) -  
1648 { -  
1649 firmware_partition = &info->partitions[i]; -  
1650 firmware_partition_index = i; -  
1651 } -  
1652 } -  
1653   -  
1654 if (firmware_partition) -  
1655 { -  
1656 os_image_partition = &info->partitions[firmware_partition_index]; -  
1657 file_system_partition = &info->partitions[firmware_partition_index + 1]; -  
1658   -  
1659 struct stat kernel; -  
1660 if (stat(kernel_image, &kernel) < 0) -  
1661 error(1, errno, "unable to stat file `%s'", kernel_image); -  
1662   -  
1663 if (kernel.st_size > firmware_partition->size) -  
1664 error(1, 0, "kernel overflowed firmware partition\n"); -  
1665   -  
1666 for (i = MAX_PARTITIONS-1; i >= firmware_partition_index + 1; i--) -  
1667 info->partitions[i+1] = info->partitions[i]; -  
1668   -  
1669 file_system_partition->name = "file-system"; -  
1670 file_system_partition->base = firmware_partition->base + kernel.st_size; -  
1671   -  
1672 /* Align partition start to erase blocks for factory images only */ -  
1673 if (!sysupgrade) -  
1674 file_system_partition->base = ALIGN(firmware_partition->base + kernel.st_size, 0x10000); -  
1675   -  
1676 file_system_partition->size = firmware_partition->size - file_system_partition->base; -  
1677   -  
1678 os_image_partition->name = "os-image"; -  
1679 os_image_partition->size = kernel.st_size; -  
1680 } -  
1681   1463  
1682 parts[0] = make_partition_table(info->partitions); 1464 parts[0] = make_partition_table(info->partitions);
1683 if (info->soft_ver) 1465 if (info->soft_ver)
1684 parts[1] = make_soft_version_from_string(info->soft_ver); 1466 parts[1] = make_soft_version_from_string(info->soft_ver);
1685 else 1467 else
1686 parts[1] = make_soft_version(rev); 1468 parts[1] = make_soft_version(rev);
1687   1469  
1688 parts[2] = make_support_list(info); 1470 parts[2] = make_support_list(info);
1689 parts[3] = read_file("os-image", kernel_image, false, NULL); 1471 parts[3] = read_file("os-image", kernel_image, false);
1690 parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof, file_system_partition); 1472 parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof);
1691   1473  
1692 /* Some devices need the extra-para partition to accept the firmware */ 1474 /* Some devices need the extra-para partition to accept the firmware */
1693 if (strcasecmp(info->id, "ARCHER-C2-V3") == 0 || -  
1694 strcasecmp(info->id, "ARCHER-C25-V1") == 0 || -  
1695 strcasecmp(info->id, "ARCHER-C59-V2") == 0 || 1475 if (strcasecmp(info->id, "ARCHER-C25-V1") == 0 ||
1696 strcasecmp(info->id, "ARCHER-C60-V2") == 0 || 1476 strcasecmp(info->id, "ARCHER-C60-V2") == 0 ||
1697 strcasecmp(info->id, "TLWR1043NV5") == 0) { 1477 strcasecmp(info->id, "TLWR1043NV5") == 0) {
1698 const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; 1478 const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};
1699 parts[5] = put_data("extra-para", mdat, 11); 1479 parts[5] = put_data("extra-para", mdat, 11);
1700 } else if (strcasecmp(info->id, "ARCHER-A7-V5") == 0 || strcasecmp(info->id, "ARCHER-C7-V4") == 0 || strcasecmp(info->id, "ARCHER-C7-V5") == 0) { 1480 } else if (strcasecmp(info->id, "ARCHER-C7-V4") == 0 || strcasecmp(info->id, "ARCHER-C7-V5") == 0) {
1701 const char mdat[11] = {0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x01, 0x00, 0x00}; 1481 const char mdat[11] = {0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0xca, 0x00, 0x01, 0x00, 0x00};
1702 parts[5] = put_data("extra-para", mdat, 11); 1482 parts[5] = put_data("extra-para", mdat, 11);
1703 } else if (strcasecmp(info->id, "ARCHER-C6-V2") == 0) { -  
1704 const char mdat[11] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; -  
1705 parts[5] = put_data("extra-para", mdat, 11); -  
1706 } 1483 }
1707   1484  
1708 size_t len; 1485 size_t len;
1709 void *image; 1486 void *image;
1710 if (sysupgrade) 1487 if (sysupgrade)
1711 image = generate_sysupgrade_image(info, parts, &len); 1488 image = generate_sysupgrade_image(info, parts, &len);
1712 else 1489 else
1713 image = generate_factory_image(info, parts, &len); 1490 image = generate_factory_image(info, parts, &len);
1714   1491  
1715 FILE *file = fopen(output, "wb"); 1492 FILE *file = fopen(output, "wb");
1716 if (!file) 1493 if (!file)
1717 error(1, errno, "unable to open output file"); 1494 error(1, errno, "unable to open output file");
1718   1495  
1719 if (fwrite(image, len, 1, file) != 1) 1496 if (fwrite(image, len, 1, file) != 1)
1720 error(1, 0, "unable to write output file"); 1497 error(1, 0, "unable to write output file");
1721   1498  
1722 fclose(file); 1499 fclose(file);
1723   1500  
1724 free(image); 1501 free(image);
-   1502  
1725   1503 size_t i;
1726 for (i = 0; parts[i].name; i++) 1504 for (i = 0; parts[i].name; i++)
1727 free_image_partition(parts[i]); 1505 free_image_partition(parts[i]);
1728 } 1506 }
1729   1507  
1730 /** Usage output */ 1508 /** Usage output */
1731 static void usage(const char *argv0) { 1509 static void usage(const char *argv0) {
1732 fprintf(stderr, 1510 fprintf(stderr,
1733 "Usage: %s [OPTIONS...]\n" 1511 "Usage: %s [OPTIONS...]\n"
1734 "\n" 1512 "\n"
1735 "Options:\n" 1513 "Options:\n"
1736 " -h show this help\n" 1514 " -h show this help\n"
1737 "\n" 1515 "\n"
1738 "Create a new image:\n" 1516 "Create a new image:\n"
1739 " -B <board> create image for the board specified with <board>\n" 1517 " -B <board> create image for the board specified with <board>\n"
1740 " -k <file> read kernel image from the file <file>\n" 1518 " -k <file> read kernel image from the file <file>\n"
1741 " -r <file> read rootfs image from the file <file>\n" 1519 " -r <file> read rootfs image from the file <file>\n"
1742 " -o <file> write output to the file <file>\n" 1520 " -o <file> write output to the file <file>\n"
1743 " -V <rev> sets the revision number to <rev>\n" 1521 " -V <rev> sets the revision number to <rev>\n"
1744 " -j add jffs2 end-of-filesystem markers\n" 1522 " -j add jffs2 end-of-filesystem markers\n"
1745 " -S create sysupgrade instead of factory image\n" 1523 " -S create sysupgrade instead of factory image\n"
1746 "Extract an old image:\n" 1524 "Extract an old image:\n"
1747 " -x <file> extract all oem firmware partition\n" 1525 " -x <file> extract all oem firmware partition\n"
1748 " -d <dir> destination to extract the firmware partition\n" 1526 " -d <dir> destination to extract the firmware partition\n"
1749 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n", 1527 " -z <file> convert an oem firmware into a sysupgade file. Use -o for output file\n",
1750 argv0 1528 argv0
1751 ); 1529 );
1752 }; 1530 };
1753   1531  
1754   1532  
1755 static struct device_info *find_board(const char *id) 1533 static const struct device_info *find_board(const char *id)
1756 { 1534 {
1757 struct device_info *board = NULL; 1535 struct device_info *board = NULL;
1758   1536  
1759 for (board = boards; board->id != NULL; board++) 1537 for (board = boards; board->id != NULL; board++)
1760 if (strcasecmp(id, board->id) == 0) 1538 if (strcasecmp(id, board->id) == 0)
1761 return board; 1539 return board;
1762   1540  
1763 return NULL; 1541 return NULL;
1764 } 1542 }
1765   1543  
1766 static int add_flash_partition( 1544 static int add_flash_partition(
1767 struct flash_partition_entry *part_list, 1545 struct flash_partition_entry *part_list,
1768 size_t max_entries, 1546 size_t max_entries,
1769 const char *name, 1547 const char *name,
1770 unsigned long base, 1548 unsigned long base,
1771 unsigned long size) 1549 unsigned long size)
1772 { 1550 {
1773 int ptr; 1551 int ptr;
1774 /* check if the list has a free entry */ 1552 /* check if the list has a free entry */
1775 for (ptr = 0; ptr < max_entries; ptr++, part_list++) { 1553 for (ptr = 0; ptr < max_entries; ptr++, part_list++) {
1776 if (part_list->name == NULL && 1554 if (part_list->name == NULL &&
1777 part_list->base == 0 && 1555 part_list->base == 0 &&
1778 part_list->size == 0) 1556 part_list->size == 0)
1779 break; 1557 break;
1780 } 1558 }
1781   1559  
1782 if (ptr == max_entries) { 1560 if (ptr == max_entries) {
1783 error(1, 0, "No free flash part entry available."); 1561 error(1, 0, "No free flash part entry available.");
1784 } 1562 }
1785   1563  
1786 part_list->name = calloc(1, strlen(name) + 1); 1564 part_list->name = calloc(1, strlen(name) + 1);
1787 if (!part_list->name) { -  
1788 error(1, 0, "Unable to allocate memory"); -  
1789 } -  
1790   -  
1791 memcpy((char *)part_list->name, name, strlen(name)); 1565 memcpy((char *)part_list->name, name, strlen(name));
1792 part_list->base = base; 1566 part_list->base = base;
1793 part_list->size = size; 1567 part_list->size = size;
1794   1568  
1795 return 0; 1569 return 0;
1796 } 1570 }
1797   1571  
1798 /** read the partition table into struct flash_partition_entry */ 1572 /** read the partition table into struct flash_partition_entry */
1799 static int read_partition_table( 1573 static int read_partition_table(
1800 FILE *file, long offset, 1574 FILE *file, long offset,
1801 struct flash_partition_entry *entries, size_t max_entries, 1575 struct flash_partition_entry *entries, size_t max_entries,
1802 int type) 1576 int type)
1803 { 1577 {
1804 char buf[2048]; 1578 char buf[2048];
1805 char *ptr, *end; 1579 char *ptr, *end;
1806 const char *parthdr = NULL; 1580 const char *parthdr = NULL;
1807 const char *fwuphdr = "fwup-ptn"; 1581 const char *fwuphdr = "fwup-ptn";
1808 const char *flashhdr = "partition"; 1582 const char *flashhdr = "partition";
1809   1583  
1810 /* TODO: search for the partition table */ 1584 /* TODO: search for the partition table */
1811   1585  
1812 switch(type) { 1586 switch(type) {
1813 case 0: 1587 case 0:
1814 parthdr = fwuphdr; 1588 parthdr = fwuphdr;
1815 break; 1589 break;
1816 case 1: 1590 case 1:
1817 parthdr = flashhdr; 1591 parthdr = flashhdr;
1818 break; 1592 break;
1819 default: 1593 default:
1820 error(1, 0, "Invalid partition table"); 1594 error(1, 0, "Invalid partition table");
1821 } 1595 }
1822   1596  
1823 if (fseek(file, offset, SEEK_SET) < 0) 1597 if (fseek(file, offset, SEEK_SET) < 0)
1824 error(1, errno, "Can not seek in the firmware"); 1598 error(1, errno, "Can not seek in the firmware");
1825   1599  
1826 if (fread(buf, 1, 2048, file) < 0) 1600 if (fread(buf, 1, 2048, file) < 0)
1827 error(1, errno, "Can not read fwup-ptn from the firmware"); 1601 error(1, errno, "Can not read fwup-ptn from the firmware");
1828   1602  
1829 buf[2047] = '\0'; 1603 buf[2047] = '\0';
1830   1604  
1831 /* look for the partition header */ 1605 /* look for the partition header */
1832 if (memcmp(buf, parthdr, strlen(parthdr)) != 0) { 1606 if (memcmp(buf, parthdr, strlen(parthdr)) != 0) {
1833 fprintf(stderr, "DEBUG: can not find fwuphdr\n"); 1607 fprintf(stderr, "DEBUG: can not find fwuphdr\n");
1834 return 1; 1608 return 1;
1835 } 1609 }
1836   1610  
1837 ptr = buf; 1611 ptr = buf;
1838 end = buf + sizeof(buf); 1612 end = buf + sizeof(buf);
1839 while ((ptr + strlen(parthdr)) < end && 1613 while ((ptr + strlen(parthdr)) < end &&
1840 memcmp(ptr, parthdr, strlen(parthdr)) == 0) { 1614 memcmp(ptr, parthdr, strlen(parthdr)) == 0) {
1841 char *end_part; 1615 char *end_part;
1842 char *end_element; 1616 char *end_element;
1843   1617  
1844 char name[32] = { 0 }; 1618 char name[32] = { 0 };
1845 int name_len = 0; 1619 int name_len = 0;
1846 unsigned long base = 0; 1620 unsigned long base = 0;
1847 unsigned long size = 0; 1621 unsigned long size = 0;
1848   1622  
1849 end_part = memchr(ptr, '\n', (end - ptr)); 1623 end_part = memchr(ptr, '\n', (end - ptr));
1850 if (end_part == NULL) { 1624 if (end_part == NULL) {
1851 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */ 1625 /* in theory this should never happen, because a partition always ends with 0x09, 0x0D, 0x0A */
1852 break; 1626 break;
1853 } 1627 }
1854   1628  
1855 for (int i = 0; i <= 4; i++) { 1629 for (int i = 0; i <= 4; i++) {
1856 if (end_part <= ptr) 1630 if (end_part <= ptr)
1857 break; 1631 break;
1858   1632  
1859 end_element = memchr(ptr, 0x20, (end_part - ptr)); 1633 end_element = memchr(ptr, 0x20, (end_part - ptr));
1860 if (end_element == NULL) { 1634 if (end_element == NULL) {
1861 error(1, errno, "Ignoring the rest of the partition entries."); 1635 error(1, errno, "Ignoring the rest of the partition entries.");
1862 break; 1636 break;
1863 } 1637 }
1864   1638  
1865 switch (i) { 1639 switch (i) {
1866 /* partition header */ 1640 /* partition header */
1867 case 0: 1641 case 0:
1868 ptr = end_element + 1; 1642 ptr = end_element + 1;
1869 continue; 1643 continue;
1870 /* name */ 1644 /* name */
1871 case 1: 1645 case 1:
1872 name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr); 1646 name_len = (end_element - ptr) > 31 ? 31 : (end_element - ptr);
1873 strncpy(name, ptr, name_len); 1647 strncpy(name, ptr, name_len);
1874 name[name_len] = '\0'; 1648 name[name_len] = '\0';
1875 ptr = end_element + 1; 1649 ptr = end_element + 1;
1876 continue; 1650 continue;
1877   1651  
1878 /* string "base" */ 1652 /* string "base" */
1879 case 2: 1653 case 2:
1880 ptr = end_element + 1; 1654 ptr = end_element + 1;
1881 continue; 1655 continue;
1882   1656  
1883 /* actual base */ 1657 /* actual base */
1884 case 3: 1658 case 3:
1885 base = strtoul(ptr, NULL, 16); 1659 base = strtoul(ptr, NULL, 16);
1886 ptr = end_element + 1; 1660 ptr = end_element + 1;
1887 continue; 1661 continue;
1888   1662  
1889 /* string "size" */ 1663 /* string "size" */
1890 case 4: 1664 case 4:
1891 ptr = end_element + 1; 1665 ptr = end_element + 1;
1892 /* actual size. The last element doesn't have a sepeartor */ 1666 /* actual size. The last element doesn't have a sepeartor */
1893 size = strtoul(ptr, NULL, 16); 1667 size = strtoul(ptr, NULL, 16);
1894 /* the part ends with 0x09, 0x0d, 0x0a */ 1668 /* the part ends with 0x09, 0x0d, 0x0a */
1895 ptr = end_part + 1; 1669 ptr = end_part + 1;
1896 add_flash_partition(entries, max_entries, name, base, size); 1670 add_flash_partition(entries, max_entries, name, base, size);
1897 continue; 1671 continue;
1898 } 1672 }
1899 } 1673 }
1900 } 1674 }
1901   1675  
1902 return 0; 1676 return 0;
1903 } 1677 }
1904   1678  
1905 static void write_partition( 1679 static void write_partition(
1906 FILE *input_file, 1680 FILE *input_file,
1907 size_t firmware_offset, 1681 size_t firmware_offset,
1908 struct flash_partition_entry *entry, 1682 struct flash_partition_entry *entry,
1909 FILE *output_file) 1683 FILE *output_file)
1910 { 1684 {
1911 char buf[4096]; 1685 char buf[4096];
1912 size_t offset; 1686 size_t offset;
1913   1687  
1914 fseek(input_file, entry->base + firmware_offset, SEEK_SET); 1688 fseek(input_file, entry->base + firmware_offset, SEEK_SET);
1915   1689  
1916 for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) { 1690 for (offset = 0; sizeof(buf) + offset <= entry->size; offset += sizeof(buf)) {
1917 if (fread(buf, sizeof(buf), 1, input_file) < 0) 1691 if (fread(buf, sizeof(buf), 1, input_file) < 0)
1918 error(1, errno, "Can not read partition from input_file"); 1692 error(1, errno, "Can not read partition from input_file");
1919   1693  
1920 if (fwrite(buf, sizeof(buf), 1, output_file) < 0) 1694 if (fwrite(buf, sizeof(buf), 1, output_file) < 0)
1921 error(1, errno, "Can not write partition to output_file"); 1695 error(1, errno, "Can not write partition to output_file");
1922 } 1696 }
1923 /* write last chunk smaller than buffer */ 1697 /* write last chunk smaller than buffer */
1924 if (offset < entry->size) { 1698 if (offset < entry->size) {
1925 offset = entry->size - offset; 1699 offset = entry->size - offset;
1926 if (fread(buf, offset, 1, input_file) < 0) 1700 if (fread(buf, offset, 1, input_file) < 0)
1927 error(1, errno, "Can not read partition from input_file"); 1701 error(1, errno, "Can not read partition from input_file");
1928 if (fwrite(buf, offset, 1, output_file) < 0) 1702 if (fwrite(buf, offset, 1, output_file) < 0)
1929 error(1, errno, "Can not write partition to output_file"); 1703 error(1, errno, "Can not write partition to output_file");
1930 } 1704 }
1931 } 1705 }
1932   1706  
1933 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory) 1707 static int extract_firmware_partition(FILE *input_file, size_t firmware_offset, struct flash_partition_entry *entry, const char *output_directory)
1934 { 1708 {
1935 FILE *output_file; 1709 FILE *output_file;
1936 char output[PATH_MAX]; 1710 char output[PATH_MAX];
1937   1711  
1938 snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name); 1712 snprintf(output, PATH_MAX, "%s/%s", output_directory, entry->name);
1939 output_file = fopen(output, "wb+"); 1713 output_file = fopen(output, "wb+");
1940 if (output_file == NULL) { 1714 if (output_file == NULL) {
1941 error(1, errno, "Can not open output file %s", output); 1715 error(1, errno, "Can not open output file %s", output);
1942 } 1716 }
1943   1717  
1944 write_partition(input_file, firmware_offset, entry, output_file); 1718 write_partition(input_file, firmware_offset, entry, output_file);
1945   1719  
1946 fclose(output_file); 1720 fclose(output_file);
1947   1721  
1948 return 0; 1722 return 0;
1949 } 1723 }
1950   1724  
1951 /** extract all partitions from the firmware file */ 1725 /** extract all partitions from the firmware file */
1952 static int extract_firmware(const char *input, const char *output_directory) 1726 static int extract_firmware(const char *input, const char *output_directory)
1953 { 1727 {
1954 struct flash_partition_entry entries[16] = { 0 }; 1728 struct flash_partition_entry entries[16] = { 0 };
1955 size_t max_entries = 16; 1729 size_t max_entries = 16;
1956 size_t firmware_offset = 0x1014; 1730 size_t firmware_offset = 0x1014;
1957 FILE *input_file; 1731 FILE *input_file;
1958   1732  
1959 struct stat statbuf; 1733 struct stat statbuf;
1960   1734  
1961 /* check input file */ 1735 /* check input file */
1962 if (stat(input, &statbuf)) { 1736 if (stat(input, &statbuf)) {
1963 error(1, errno, "Can not read input firmware %s", input); 1737 error(1, errno, "Can not read input firmware %s", input);
1964 } 1738 }
1965   1739  
1966 /* check if output directory exists */ 1740 /* check if output directory exists */
1967 if (stat(output_directory, &statbuf)) { 1741 if (stat(output_directory, &statbuf)) {
1968 error(1, errno, "Failed to stat output directory %s", output_directory); 1742 error(1, errno, "Failed to stat output directory %s", output_directory);
1969 } 1743 }
1970   1744  
1971 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { 1745 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
1972 error(1, errno, "Given output directory is not a directory %s", output_directory); 1746 error(1, errno, "Given output directory is not a directory %s", output_directory);
1973 } 1747 }
1974   1748  
1975 input_file = fopen(input, "rb"); 1749 input_file = fopen(input, "rb");
1976   1750  
1977 if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) { 1751 if (read_partition_table(input_file, firmware_offset, entries, 16, 0) != 0) {
1978 error(1, 0, "Error can not read the partition table (fwup-ptn)"); 1752 error(1, 0, "Error can not read the partition table (fwup-ptn)");
1979 } 1753 }
1980   1754  
1981 for (int i = 0; i < max_entries; i++) { 1755 for (int i = 0; i < max_entries; i++) {
1982 if (entries[i].name == NULL && 1756 if (entries[i].name == NULL &&
1983 entries[i].base == 0 && 1757 entries[i].base == 0 &&
1984 entries[i].size == 0) 1758 entries[i].size == 0)
1985 continue; 1759 continue;
1986   1760  
1987 extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory); 1761 extract_firmware_partition(input_file, firmware_offset, &entries[i], output_directory);
1988 } 1762 }
1989   1763  
1990 return 0; 1764 return 0;
1991 } 1765 }
1992   1766  
1993 static struct flash_partition_entry *find_partition( 1767 static struct flash_partition_entry *find_partition(
1994 struct flash_partition_entry *entries, size_t max_entries, 1768 struct flash_partition_entry *entries, size_t max_entries,
1995 const char *name, const char *error_msg) 1769 const char *name, const char *error_msg)
1996 { 1770 {
1997 for (int i = 0; i < max_entries; i++, entries++) { 1771 for (int i = 0; i < max_entries; i++, entries++) {
1998 if (strcmp(entries->name, name) == 0) 1772 if (strcmp(entries->name, name) == 0)
1999 return entries; 1773 return entries;
2000 } 1774 }
2001   1775  
2002 error(1, 0, "%s", error_msg); 1776 error(1, 0, "%s", error_msg);
2003 return NULL; 1777 return NULL;
2004 } 1778 }
2005   1779  
2006 static void write_ff(FILE *output_file, size_t size) 1780 static void write_ff(FILE *output_file, size_t size)
2007 { 1781 {
2008 char buf[4096]; 1782 char buf[4096];
2009 int offset; 1783 int offset;
2010   1784  
2011 memset(buf, 0xff, sizeof(buf)); 1785 memset(buf, 0xff, sizeof(buf));
2012   1786  
2013 for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) { 1787 for (offset = 0; offset + sizeof(buf) < size ; offset += sizeof(buf)) {
2014 if (fwrite(buf, sizeof(buf), 1, output_file) < 0) 1788 if (fwrite(buf, sizeof(buf), 1, output_file) < 0)
2015 error(1, errno, "Can not write 0xff to output_file"); 1789 error(1, errno, "Can not write 0xff to output_file");
2016 } 1790 }
2017   1791  
2018 /* write last chunk smaller than buffer */ 1792 /* write last chunk smaller than buffer */
2019 if (offset < size) { 1793 if (offset < size) {
2020 offset = size - offset; 1794 offset = size - offset;
2021 if (fwrite(buf, offset, 1, output_file) < 0) 1795 if (fwrite(buf, offset, 1, output_file) < 0)
2022 error(1, errno, "Can not write partition to output_file"); 1796 error(1, errno, "Can not write partition to output_file");
2023 } 1797 }
2024 } 1798 }
2025   1799  
2026 static void convert_firmware(const char *input, const char *output) 1800 static void convert_firmware(const char *input, const char *output)
2027 { 1801 {
2028 struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 }; 1802 struct flash_partition_entry fwup[MAX_PARTITIONS] = { 0 };
2029 struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 }; 1803 struct flash_partition_entry flash[MAX_PARTITIONS] = { 0 };
2030 struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL; 1804 struct flash_partition_entry *fwup_os_image = NULL, *fwup_file_system = NULL;
2031 struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL; 1805 struct flash_partition_entry *flash_os_image = NULL, *flash_file_system = NULL;
2032 struct flash_partition_entry *fwup_partition_table = NULL; 1806 struct flash_partition_entry *fwup_partition_table = NULL;
2033 size_t firmware_offset = 0x1014; 1807 size_t firmware_offset = 0x1014;
2034 FILE *input_file, *output_file; 1808 FILE *input_file, *output_file;
2035   1809  
2036 struct stat statbuf; 1810 struct stat statbuf;
2037   1811  
2038 /* check input file */ 1812 /* check input file */
2039 if (stat(input, &statbuf)) { 1813 if (stat(input, &statbuf)) {
2040 error(1, errno, "Can not read input firmware %s", input); 1814 error(1, errno, "Can not read input firmware %s", input);
2041 } 1815 }
2042   1816  
2043 input_file = fopen(input, "rb"); 1817 input_file = fopen(input, "rb");
2044 if (!input_file) 1818 if (!input_file)
2045 error(1, 0, "Can not open input firmware %s", input); 1819 error(1, 0, "Can not open input firmware %s", input);
2046   1820  
2047 output_file = fopen(output, "wb"); 1821 output_file = fopen(output, "wb");
2048 if (!output_file) 1822 if (!output_file)
2049 error(1, 0, "Can not open output firmware %s", output); 1823 error(1, 0, "Can not open output firmware %s", output);
2050   1824  
2051 if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) { 1825 if (read_partition_table(input_file, firmware_offset, fwup, MAX_PARTITIONS, 0) != 0) {
2052 error(1, 0, "Error can not read the partition table (fwup-ptn)"); 1826 error(1, 0, "Error can not read the partition table (fwup-ptn)");
2053 } 1827 }
2054   1828  
2055 fwup_os_image = find_partition(fwup, MAX_PARTITIONS, 1829 fwup_os_image = find_partition(fwup, MAX_PARTITIONS,
2056 "os-image", "Error can not find os-image partition (fwup)"); 1830 "os-image", "Error can not find os-image partition (fwup)");
2057 fwup_file_system = find_partition(fwup, MAX_PARTITIONS, 1831 fwup_file_system = find_partition(fwup, MAX_PARTITIONS,
2058 "file-system", "Error can not find file-system partition (fwup)"); 1832 "file-system", "Error can not find file-system partition (fwup)");
2059 fwup_partition_table = find_partition(fwup, MAX_PARTITIONS, 1833 fwup_partition_table = find_partition(fwup, MAX_PARTITIONS,
2060 "partition-table", "Error can not find partition-table partition"); 1834 "partition-table", "Error can not find partition-table partition");
2061   1835  
2062 /* the flash partition table has a 0x00000004 magic haeder */ 1836 /* the flash partition table has a 0x00000004 magic haeder */
2063 if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0) 1837 if (read_partition_table(input_file, firmware_offset + fwup_partition_table->base + 4, flash, MAX_PARTITIONS, 1) != 0)
2064 error(1, 0, "Error can not read the partition table (flash)"); 1838 error(1, 0, "Error can not read the partition table (flash)");
2065   1839  
2066 flash_os_image = find_partition(flash, MAX_PARTITIONS, 1840 flash_os_image = find_partition(flash, MAX_PARTITIONS,
2067 "os-image", "Error can not find os-image partition (flash)"); 1841 "os-image", "Error can not find os-image partition (flash)");
2068 flash_file_system = find_partition(flash, MAX_PARTITIONS, 1842 flash_file_system = find_partition(flash, MAX_PARTITIONS,
2069 "file-system", "Error can not find file-system partition (flash)"); 1843 "file-system", "Error can not find file-system partition (flash)");
2070   1844  
2071 /* write os_image to 0x0 */ 1845 /* write os_image to 0x0 */
2072 write_partition(input_file, firmware_offset, fwup_os_image, output_file); 1846 write_partition(input_file, firmware_offset, fwup_os_image, output_file);
2073 write_ff(output_file, flash_os_image->size - fwup_os_image->size); 1847 write_ff(output_file, flash_os_image->size - fwup_os_image->size);
2074   1848  
2075 /* write file-system behind os_image */ 1849 /* write file-system behind os_image */
2076 fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET); 1850 fseek(output_file, flash_file_system->base - flash_os_image->base, SEEK_SET);
2077 write_partition(input_file, firmware_offset, fwup_file_system, output_file); 1851 write_partition(input_file, firmware_offset, fwup_file_system, output_file);
2078 write_ff(output_file, flash_file_system->size - fwup_file_system->size); 1852 write_ff(output_file, flash_file_system->size - fwup_file_system->size);
2079   1853  
2080 fclose(output_file); 1854 fclose(output_file);
2081 fclose(input_file); 1855 fclose(input_file);
2082 } 1856 }
2083   1857  
2084 int main(int argc, char *argv[]) { 1858 int main(int argc, char *argv[]) {
2085 const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL; 1859 const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL;
2086 const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL; 1860 const char *extract_image = NULL, *output_directory = NULL, *convert_image = NULL;
2087 bool add_jffs2_eof = false, sysupgrade = false; 1861 bool add_jffs2_eof = false, sysupgrade = false;
2088 unsigned rev = 0; 1862 unsigned rev = 0;
2089 struct device_info *info; 1863 const struct device_info *info;
2090 set_source_date_epoch(); 1864 set_source_date_epoch();
2091   1865  
2092 while (true) { 1866 while (true) {
2093 int c; 1867 int c;
2094   1868  
2095 c = getopt(argc, argv, "B:k:r:o:V:jSh:x:d:z:"); 1869 c = getopt(argc, argv, "B:k:r:o:V:jSh:x:d:z:");
2096 if (c == -1) 1870 if (c == -1)
2097 break; 1871 break;
2098   1872  
2099 switch (c) { 1873 switch (c) {
2100 case 'B': 1874 case 'B':
2101 board = optarg; 1875 board = optarg;
2102 break; 1876 break;
2103   1877  
2104 case 'k': 1878 case 'k':
2105 kernel_image = optarg; 1879 kernel_image = optarg;
2106 break; 1880 break;
2107   1881  
2108 case 'r': 1882 case 'r':
2109 rootfs_image = optarg; 1883 rootfs_image = optarg;
2110 break; 1884 break;
2111   1885  
2112 case 'o': 1886 case 'o':
2113 output = optarg; 1887 output = optarg;
2114 break; 1888 break;
2115   1889  
2116 case 'V': 1890 case 'V':
2117 sscanf(optarg, "r%u", &rev); 1891 sscanf(optarg, "r%u", &rev);
2118 break; 1892 break;
2119   1893  
2120 case 'j': 1894 case 'j':
2121 add_jffs2_eof = true; 1895 add_jffs2_eof = true;
2122 break; 1896 break;
2123   1897  
2124 case 'S': 1898 case 'S':
2125 sysupgrade = true; 1899 sysupgrade = true;
2126 break; 1900 break;
2127   1901  
2128 case 'h': 1902 case 'h':
2129 usage(argv[0]); 1903 usage(argv[0]);
2130 return 0; 1904 return 0;
2131   1905  
2132 case 'd': 1906 case 'd':
2133 output_directory = optarg; 1907 output_directory = optarg;
2134 break; 1908 break;
2135   1909  
2136 case 'x': 1910 case 'x':
2137 extract_image = optarg; 1911 extract_image = optarg;
2138 break; 1912 break;
2139   1913  
2140 case 'z': 1914 case 'z':
2141 convert_image = optarg; 1915 convert_image = optarg;
2142 break; 1916 break;
2143   1917  
2144 default: 1918 default:
2145 usage(argv[0]); 1919 usage(argv[0]);
2146 return 1; 1920 return 1;
2147 } 1921 }
2148 } 1922 }
2149   1923  
2150 if (extract_image || output_directory) { 1924 if (extract_image || output_directory) {
2151 if (!extract_image) 1925 if (!extract_image)
2152 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x"); 1926 error(1, 0, "No factory/oem image given via -x <file>. Output directory is only valid with -x");
2153 if (!output_directory) 1927 if (!output_directory)
2154 error(1, 0, "Can not extract an image without output directory. Use -d <dir>"); 1928 error(1, 0, "Can not extract an image without output directory. Use -d <dir>");
2155 extract_firmware(extract_image, output_directory); 1929 extract_firmware(extract_image, output_directory);
2156 } else if (convert_image) { 1930 } else if (convert_image) {
2157 if (!output) 1931 if (!output)
2158 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>"); 1932 error(1, 0, "Can not convert a factory/oem image into sysupgrade image without output file. Use -o <file>");
2159 convert_firmware(convert_image, output); 1933 convert_firmware(convert_image, output);
2160 } else { 1934 } else {
2161 if (!board) 1935 if (!board)
2162 error(1, 0, "no board has been specified"); 1936 error(1, 0, "no board has been specified");
2163 if (!kernel_image) 1937 if (!kernel_image)
2164 error(1, 0, "no kernel image has been specified"); 1938 error(1, 0, "no kernel image has been specified");
2165 if (!rootfs_image) 1939 if (!rootfs_image)
2166 error(1, 0, "no rootfs image has been specified"); 1940 error(1, 0, "no rootfs image has been specified");
2167 if (!output) 1941 if (!output)
2168 error(1, 0, "no output filename has been specified"); 1942 error(1, 0, "no output filename has been specified");
2169   1943  
2170 info = find_board(board); 1944 info = find_board(board);
2171   1945  
2172 if (info == NULL) 1946 if (info == NULL)
2173 error(1, 0, "unsupported board %s", board); 1947 error(1, 0, "unsupported board %s", board);
2174   1948  
2175 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info); 1949 build_image(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade, info);
2176 } 1950 }
2177   1951  
2178 return 0; 1952 return 0;
2179 } 1953 }
2180   1954