OpenWrt – Diff between revs 2 and 3
?pathlinks?
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 | |