OpenWrt – Diff between revs 2 and 3
?pathlinks?
Rev 2 | Rev 3 | |||
---|---|---|---|---|
Line 27... | Line 27... | |||
27 | #include <sys/mman.h> |
27 | #include <sys/mman.h> |
|
28 | #include <netinet/in.h> |
28 | #include <netinet/in.h> |
|
29 | #include <stdio.h> |
29 | #include <stdio.h> |
|
30 | #include <stdlib.h> |
30 | #include <stdlib.h> |
|
31 | #include <limits.h> |
31 | #include <limits.h> |
|
32 | #include <stdbool.h> |
- | ||
33 | #include "fw.h" |
32 | #include "fw.h" |
|
Line 34... | Line 33... | |||
34 | |
33 | |
|
- | 34 | typedef struct fw_layout_data { |
||
35 | typedef struct fw_layout_data { |
35 | char name[PATH_MAX]; |
|
36 | u_int32_t kern_start; |
36 | u_int32_t kern_start; |
|
37 | u_int32_t kern_entry; |
37 | u_int32_t kern_entry; |
|
38 | u_int32_t firmware_max_length; |
38 | u_int32_t firmware_max_length; |
|
Line 39... | Line -... | |||
39 | } fw_layout_t; |
- | ||
40 | |
- | ||
41 | struct fw_info { |
39 | } fw_layout_t; |
|
42 | char name[PATH_MAX]; |
- | ||
43 | struct fw_layout_data fw_layout; |
- | ||
44 | bool sign; |
- | ||
45 | }; |
- | ||
46 | |
40 | |
|
47 | struct fw_info fw_info[] = { |
41 | fw_layout_t fw_layout_data[] = { |
|
48 | { |
- | ||
49 | .name = "XS2", |
42 | { |
|
50 | .fw_layout = { |
43 | .name = "XS2", |
|
51 | .kern_start = 0xbfc30000, |
44 | .kern_start = 0xbfc30000, |
|
52 | .kern_entry = 0x80041000, |
- | ||
53 | .firmware_max_length= 0x00390000, |
- | ||
54 | }, |
45 | .kern_entry = 0x80041000, |
|
55 | .sign = false, |
46 | .firmware_max_length= 0x00390000, |
|
56 | }, |
47 | }, |
|
57 | { |
- | ||
58 | .name = "XS5", |
48 | { |
|
59 | .fw_layout = { |
49 | .name = "XS5", |
|
60 | .kern_start = 0xbe030000, |
50 | .kern_start = 0xbe030000, |
|
61 | .kern_entry = 0x80041000, |
- | ||
62 | .firmware_max_length= 0x00390000, |
- | ||
63 | }, |
51 | .kern_entry = 0x80041000, |
|
64 | .sign = false, |
52 | .firmware_max_length= 0x00390000, |
|
65 | }, |
53 | }, |
|
66 | { |
- | ||
67 | .name = "RS", |
54 | { |
|
68 | .fw_layout = { |
55 | .name = "RS", |
|
69 | .kern_start = 0xbf030000, |
56 | .kern_start = 0xbf030000, |
|
70 | .kern_entry = 0x80060000, |
- | ||
71 | .firmware_max_length= 0x00B00000, |
- | ||
72 | }, |
57 | .kern_entry = 0x80060000, |
|
73 | .sign = false, |
58 | .firmware_max_length= 0x00B00000, |
|
74 | }, |
59 | }, |
|
75 | { |
- | ||
76 | .name = "RSPRO", |
60 | { |
|
77 | .fw_layout = { |
61 | .name = "RSPRO", |
|
78 | .kern_start = 0xbf030000, |
62 | .kern_start = 0xbf030000, |
|
79 | .kern_entry = 0x80060000, |
- | ||
80 | .firmware_max_length= 0x00F00000, |
- | ||
81 | }, |
63 | .kern_entry = 0x80060000, |
|
82 | .sign = false, |
64 | .firmware_max_length= 0x00F00000, |
|
83 | }, |
65 | }, |
|
84 | { |
- | ||
85 | .name = "LS-SR71", |
66 | { |
|
86 | .fw_layout = { |
67 | .name = "LS-SR71", |
|
87 | .kern_start = 0xbf030000, |
68 | .kern_start = 0xbf030000, |
|
88 | .kern_entry = 0x80060000, |
- | ||
89 | .firmware_max_length= 0x00640000, |
- | ||
90 | }, |
69 | .kern_entry = 0x80060000, |
|
91 | .sign = false, |
70 | .firmware_max_length= 0x00640000, |
|
92 | }, |
71 | }, |
|
93 | { |
- | ||
94 | .name = "XS2-8", |
72 | { |
|
95 | .fw_layout = { |
73 | .name = "XS2-8", |
|
96 | .kern_start = 0xa8030000, |
74 | .kern_start = 0xa8030000, |
|
97 | .kern_entry = 0x80041000, |
- | ||
98 | .firmware_max_length= 0x006C0000, |
- | ||
99 | }, |
- | ||
100 | .sign = false, |
75 | .kern_entry = 0x80041000, |
|
101 | |
76 | .firmware_max_length= 0x006C0000, |
|
102 | }, |
77 | }, |
|
103 | { |
- | ||
104 | .name = "XM", |
78 | { |
|
105 | .fw_layout = { |
79 | .name = "XM", |
|
106 | .kern_start = 0x9f050000, |
80 | .kern_start = 0x9f050000, |
|
107 | .kern_entry = 0x80002000, |
- | ||
108 | .firmware_max_length= 0x00760000, |
- | ||
109 | }, |
81 | .kern_entry = 0x80002000, |
|
110 | .sign = false, |
82 | .firmware_max_length= 0x00760000, |
|
111 | }, |
83 | }, |
|
112 | { |
- | ||
113 | .name = "UBDEV01", |
84 | { |
|
114 | .fw_layout = { |
85 | .name = "UBDEV01", |
|
115 | .kern_start = 0x9f050000, |
86 | .kern_start = 0x9f050000, |
|
116 | .kern_entry = 0x80002000, |
- | ||
117 | .firmware_max_length= 0x006A0000, |
- | ||
118 | }, |
87 | .kern_entry = 0x80002000, |
|
119 | .sign = false, |
- | ||
120 | }, |
- | ||
121 | { |
- | ||
122 | .name = "WA", |
- | ||
123 | .fw_layout = { |
- | ||
124 | .kern_start = 0x9f050000, |
- | ||
125 | .kern_entry = 0x80002000, |
- | ||
126 | .firmware_max_length= 0x00F60000, |
- | ||
127 | }, |
- | ||
128 | .sign = true, |
- | ||
129 | }, |
88 | .firmware_max_length= 0x006A0000, |
|
130 | { |
89 | }, |
|
131 | .name = "", |
90 | { .name = "", |
|
Line 132... | Line 91... | |||
132 | }, |
91 | }, |
|
133 | }; |
92 | }; |
|
Line 155... | Line 114... | |||
155 | char magic[16]; |
114 | char magic[16]; |
|
156 | char version[256]; |
115 | char version[256]; |
|
157 | char outputfile[PATH_MAX]; |
116 | char outputfile[PATH_MAX]; |
|
158 | u_int32_t part_count; |
117 | u_int32_t part_count; |
|
159 | part_data_t parts[MAX_SECTIONS]; |
118 | part_data_t parts[MAX_SECTIONS]; |
|
160 | struct fw_info* fwinfo; |
- | ||
161 | } image_info_t; |
119 | } image_info_t; |
|
Line 162... | Line -... | |||
162 | |
- | ||
163 | static struct fw_info* get_fwinfo(char* board_name) { |
- | ||
164 | struct fw_info *fwinfo = fw_info; |
- | ||
165 | while(strlen(fwinfo->name)) { |
- | ||
166 | if(strcmp(fwinfo->name, board_name) == 0) { |
- | ||
167 | return fwinfo; |
- | ||
168 | } |
- | ||
169 | fwinfo++; |
- | ||
170 | } |
- | ||
171 | return NULL; |
- | ||
172 | } |
- | ||
173 | |
120 | |
|
174 | static void write_header(void* mem, const char *magic, const char* version) |
121 | static void write_header(void* mem, const char *magic, const char* version) |
|
175 | { |
122 | { |
|
176 | header_t* header = mem; |
123 | header_t* header = mem; |
|
Line 193... | Line 140... | |||
193 | memcpy(sign->magic, MAGIC_END, MAGIC_LENGTH); |
140 | memcpy(sign->magic, MAGIC_END, MAGIC_LENGTH); |
|
194 | sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); |
141 | sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); |
|
195 | sign->pad = 0L; |
142 | sign->pad = 0L; |
|
196 | } |
143 | } |
|
Line 197... | Line -... | |||
197 | |
- | ||
198 | static void write_signature_rsa(void* mem, u_int32_t sig_offset) |
- | ||
199 | { |
- | ||
200 | /* write signature */ |
- | ||
201 | signature_rsa_t* sign = (signature_rsa_t*)(mem + sig_offset); |
- | ||
202 | memset(sign, 0, sizeof(signature_rsa_t)); |
- | ||
203 | |
- | ||
204 | memcpy(sign->magic, MAGIC_ENDS, MAGIC_LENGTH); |
- | ||
205 | // sign->crc = htonl(crc32(0L,(unsigned char *)mem, sig_offset)); |
- | ||
206 | sign->pad = 0L; |
- | ||
207 | } |
- | ||
208 | |
144 | |
|
209 | static int write_part(void* mem, part_data_t* d) |
145 | static int write_part(void* mem, part_data_t* d) |
|
210 | { |
146 | { |
|
211 | char* addr; |
147 | char* addr; |
|
212 | int fd; |
148 | int fd; |
|
Line 299... | Line 235... | |||
299 | static int create_image_layout(const char* kernelfile, const char* rootfsfile, char* board_name, image_info_t* im) |
235 | static int create_image_layout(const char* kernelfile, const char* rootfsfile, char* board_name, image_info_t* im) |
|
300 | { |
236 | { |
|
301 | part_data_t* kernel = &im->parts[0]; |
237 | part_data_t* kernel = &im->parts[0]; |
|
302 | part_data_t* rootfs = &im->parts[1]; |
238 | part_data_t* rootfs = &im->parts[1]; |
|
Line 303... | Line 239... | |||
303 | |
239 | |
|
Line -... | Line 240... | |||
- | 240 | fw_layout_t* p; |
||
- | 241 | |
||
- | 242 | p = &fw_layout_data[0]; |
||
- | 243 | while (*p->name && (strcmp(p->name, board_name) != 0)) |
||
- | 244 | p++; |
||
- | 245 | if (!*p->name) { |
||
- | 246 | printf("BUG! Unable to find default fw layout!\n"); |
||
- | 247 | exit(-1); |
||
304 | fw_layout_t* p = &im->fwinfo->fw_layout; |
248 | } |
|
305 | |
249 | |
|
306 | printf("board = %s\n", im->fwinfo->name); |
250 | printf("board = %s\n", p->name); |
|
307 | strcpy(kernel->partition_name, "kernel"); |
251 | strcpy(kernel->partition_name, "kernel"); |
|
308 | kernel->partition_index = 1; |
252 | kernel->partition_index = 1; |
|
309 | kernel->partition_baseaddr = p->kern_start; |
253 | kernel->partition_baseaddr = p->kern_start; |
|
Line 384... | Line 328... | |||
384 | u_int32_t mem_size; |
328 | u_int32_t mem_size; |
|
385 | FILE* f; |
329 | FILE* f; |
|
386 | int i; |
330 | int i; |
|
Line 387... | Line 331... | |||
387 | |
331 | |
|
388 | // build in-memory buffer |
- | ||
389 | mem_size = sizeof(header_t); |
- | ||
390 | if(im->fwinfo->sign) { |
- | ||
391 | mem_size += sizeof(signature_rsa_t); |
- | ||
392 | } else { |
332 | // build in-memory buffer |
|
393 | mem_size += sizeof(signature_t); |
- | ||
394 | } |
333 | mem_size = sizeof(header_t) + sizeof(signature_t); |
|
395 | for (i = 0; i < im->part_count; ++i) |
334 | for (i = 0; i < im->part_count; ++i) |
|
396 | { |
335 | { |
|
397 | part_data_t* d = &im->parts[i]; |
336 | part_data_t* d = &im->parts[i]; |
|
398 | mem_size += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); |
337 | mem_size += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); |
|
Line 418... | Line 357... | |||
418 | ERROR("ERROR: failed writing part %u '%s'\n", i, d->partition_name); |
357 | ERROR("ERROR: failed writing part %u '%s'\n", i, d->partition_name); |
|
419 | } |
358 | } |
|
420 | ptr += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); |
359 | ptr += sizeof(part_t) + d->stats.st_size + sizeof(part_crc_t); |
|
421 | } |
360 | } |
|
422 | // write signature |
361 | // write signature |
|
423 | if(im->fwinfo->sign) { |
- | ||
424 | write_signature_rsa(mem, mem_size - sizeof(signature_rsa_t)); |
- | ||
425 | } else { |
- | ||
426 | write_signature(mem, mem_size - sizeof(signature_t)); |
362 | write_signature(mem, mem_size - sizeof(signature_t)); |
|
427 | } |
- | ||
Line 428... | Line 363... | |||
428 | |
363 | |
|
429 | // write in-memory buffer into file |
364 | // write in-memory buffer into file |
|
430 | if ((f = fopen(im->outputfile, "w")) == NULL) |
365 | if ((f = fopen(im->outputfile, "w")) == NULL) |
|
431 | { |
366 | { |
|
Line 451... | Line 386... | |||
451 | char kernelfile[PATH_MAX]; |
386 | char kernelfile[PATH_MAX]; |
|
452 | char rootfsfile[PATH_MAX]; |
387 | char rootfsfile[PATH_MAX]; |
|
453 | char board_name[PATH_MAX]; |
388 | char board_name[PATH_MAX]; |
|
454 | int o, rc; |
389 | int o, rc; |
|
455 | image_info_t im; |
390 | image_info_t im; |
|
456 | struct fw_info *fwinfo; |
- | ||
Line 457... | Line 391... | |||
457 | |
391 | |
|
458 | memset(&im, 0, sizeof(im)); |
392 | memset(&im, 0, sizeof(im)); |
|
459 | memset(kernelfile, 0, sizeof(kernelfile)); |
393 | memset(kernelfile, 0, sizeof(kernelfile)); |
|
460 | memset(rootfsfile, 0, sizeof(rootfsfile)); |
394 | memset(rootfsfile, 0, sizeof(rootfsfile)); |
|
Line 511... | Line 445... | |||
511 | ERROR("Root FS file is not specified, cannot continue\n"); |
445 | ERROR("Root FS file is not specified, cannot continue\n"); |
|
512 | usage(argv[0]); |
446 | usage(argv[0]); |
|
513 | return -2; |
447 | return -2; |
|
514 | } |
448 | } |
|
Line 515... | Line -... | |||
515 | |
- | ||
516 | if ((fwinfo = get_fwinfo(board_name)) == NULL) { |
- | ||
517 | ERROR("Invalid baord name '%s'\n", board_name); |
- | ||
518 | usage(argv[0]); |
- | ||
519 | return -2; |
- | ||
520 | } |
- | ||
521 | |
- | ||
522 | im.fwinfo = fwinfo; |
- | ||
523 | |
449 | |
|
524 | if ((rc = create_image_layout(kernelfile, rootfsfile, board_name, &im)) != 0) |
450 | if ((rc = create_image_layout(kernelfile, rootfsfile, board_name, &im)) != 0) |
|
525 | { |
451 | { |
|
526 | ERROR("Failed creating firmware layout description - error code: %d\n", rc); |
452 | ERROR("Failed creating firmware layout description - error code: %d\n", rc); |
|
527 | return -3; |
453 | return -3; |