Codebase list 0xffff / 4e9ae47
New upstream release. Debian Janitor 2 years ago
15 changed file(s) with 826 addition(s) and 262 deletion(s). Raw diff Collapse all Expand all
44 * Detect device from asic id
55
66 disk:
7 * Support for flashing mmc images
87 * Badblock checking
98
109 fiasco:
1413 * Support for Harmattan images
1514
1615 local:
17 * Support for flashing (on device)
1816 * Write versions
1917 * Badblock checking
2018
0 VERSION = 0.9
0 VERSION = 0.10
11 PREFIX = /usr/local
22
33 # NetBSD stuff
0 0xffff (0.10-1) UNRELEASED; urgency=low
1
2 * New upstream release.
3
4 -- Debian Janitor <janitor@jelmer.uk> Sat, 29 Jan 2022 02:53:30 -0000
5
06 0xffff (0.9-1) unstable; urgency=medium
17
28 [ Debian Janitor ]
2929 For dumping mtd partition is used tool nanddump. Here is example how to dump
3030 kernel image without padding to file zImage:
3131
32 $ nanddump -o -b -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
32 $ nanddump --omitoob -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
3333
3434 Params means:
35 -o - "Omit oob data"
36 -b - "Omit bad blocks"
35 --omitoob - "Omit oob data"
3736 -s - "Start address"
3837 -l - "Length"
3938 -f - "Output file"
3737
3838 1 byte = 0x54 -- signature
3939 1 byte -- number of subsection blocks
40 (start of data block)
41 1 byte -- type of subsection block (data - always 0x2e)
42 1 byte -- length of subsection block (data - always 25)
43 3 bytes -- unknown (always 0x01 0x01 0x00)
40 block {
41 1 byte -- type of subsection block
42 0x2E - file data
43 0x2F - partition info
44 0x31 - version
45 0x32 - device & hw revisions (size of device is 16, hw revision 8)
46 0x33 - layout
47 0x34 - image data part block (one block for one data part)
48 1 byte -- length of subsection block
49 N bytes -- subsection block data
50 }
51 1 byte -- checksum of subsection data without signature (0xFF - xorpair)
52 N bytes -- image data
53
54
55 FILE DATA BLOCK
56
57 1 byte -- asic index (always APE - 0x01)
58 1 byte -- device type (always NAND - 0x01)
59 1 byte -- device index (always 0x00)
4460 2 bytes -- checksum for the image contents (xorpair) (big endian)
4561 12 bytes -- image name type (first byte is FF if is the last image)
4662 4 bytes -- length of image data (big endian)
63 4 bytes -- load address of image data (big endian, unused always zero)
64
65
66 PARTITION INFO BLOCK
67
68 N bytes -- unknown
69
70
71 IMAGE DATA PART BLOCK
72
4773 4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
48 (end of data block)
49 block {
50 1 byte -- type of subsection block
51 '1' - version
52 '2' - device & hw revisions (size of device is 16, hw revision 8)
53 '3' - layout
54 '4' - unknown
55 '/' - unknown
56 1 byte -- length of subsection block
57 N bytes -- subsection block data
58 }
59 1 byte -- unknown (0x00 is accepted, maybe end of subsections?)
60 N bytes -- image data
74 4 bytes -- offset (big endian)
75 4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
76 4 bytes -- size (big endian)
77 N bytes -- partition name (prefix) in layout (may be omitted)
78
79
80 LAYOUT DATA BLOCK
81
82 N bytes of text data, e.g.:
83
84 mmc {
85 name = "internal";
86 partition {
87 fs_type = "vfat";
88 prefix = "mydocs";
89 no_create = true;
90 }
91 partition {
92 size = 2048;
93 fs_type = "ext3";
94 prefix = "home";
95 }
96 partition {
97 size = 768;
98 fs_type = "swap";
99 }
100 }
183183 continue;
184184 }
185185
186 for ( i = 0; device_first->hwrevs[i] != -1; ++i )
187 if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
188 ++local;
186 if ( device_first->hwrevs ) {
187 for ( i = 0; device_first->hwrevs[i] != -1; ++i )
188 if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
189 ++local;
190 }
189191
190192 size += (1+16+(MAX_HWREVS+1)*8)*(local/MAX_HWREVS+1);
191193 count += local/MAX_HWREVS;
214216 continue;
215217 }
216218
217 while ( device_first->hwrevs[i+1] != -1 ) {
219 do {
218220
219221 uint8_t len = 0;
220222 ret[j] = ++last_ptr;
227229
228230 for ( k = 0; k < MAX_HWREVS; ++k ) {
229231
230 if ( device_first->hwrevs[i+1] == -1 )
232 if ( ! device_first->hwrevs || device_first->hwrevs[i+1] == -1 )
231233 break;
232234
233235 ++i;
245247
246248 ++j;
247249
248 }
250 } while ( device_first->hwrevs && device_first->hwrevs[i+1] != -1 );
249251
250252 device_first = device_first->next;
251253
117117
118118 blkdev[len] = 0;
119119
120 fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
120 fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
121121 if ( fd < 0 ) {
122122 ERROR_INFO("Cannot open block device %s", blkdev);
123123 return -1;
143143 ERROR("Block device name is too long");
144144 return -1;
145145 }
146 fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
146 fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
147147 if ( fd < 0 && errno == ENOENT ) {
148148 if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) {
149149 ERROR("Block device name is too long");
150150 return -1;
151151 }
152 fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
152 fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
153153 }
154154 if ( fd < 0 && errno == ENOENT ) {
155155 blkdev[len] = 0;
200200
201201 int disk_dump_dev(int fd, const char * file) {
202202
203 int fd2;
203 int fd2 = -1;
204204 int ret;
205205 char * path;
206206 uint64_t blksize;
252252 return -1;
253253 }
254254
255 fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
256
257 if ( fd2 < 0 ) {
258 ERROR_INFO("Cannot create file %s", file);
259 return -1;
255 if ( ! simulate ) {
256
257 fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
258
259 if ( fd2 < 0 ) {
260 ERROR_INFO("Cannot create file %s", file);
261 return -1;
262 }
263
260264 }
261265
262266 sent = 0;
271275 break;
272276 if ( size < 0 ) {
273277 PRINTF_ERROR("Reading from block device failed");
274 close(fd2);
275 return -1;
276 }
277 if ( write(fd2, global_buf, size) != size ) {
278 PRINTF_ERROR("Dumping image failed");
279 close(fd2);
280 return -1;
278 if ( ! simulate )
279 close(fd2);
280 return -1;
281 }
282 if ( ! simulate ) {
283 if ( write(fd2, global_buf, size) != size ) {
284 PRINTF_ERROR("Dumping image failed");
285 close(fd2);
286 return -1;
287 }
281288 }
282289 sent += size;
283290 printf_progressbar(sent, blksize);
284291 }
285292
286 close(fd2);
293 if ( ! simulate )
294 close(fd2);
287295 return 0;
288296
289297 }
290298
291 int disk_flash_dev(int fd, const char * file) {
292
293 ERROR("Not implemented yet");
294 (void)fd;
295 (void)file;
296 return -1;
299 int disk_flash_dev(int fd, struct image * image) {
300
301 uint64_t blksize;
302 size_t need, sent;
303 ssize_t size;
304
305 if ( image->type != IMAGE_MMC )
306 ERROR_RETURN("Only mmc images are supported", -1);
307
308 printf("Writing image to block device...\n");
309
310 #ifdef __linux__
311
312 if ( ioctl(fd, BLKGETSIZE64, &blksize) != 0 ) {
313 ERROR_INFO("Cannot get size of block device");
314 return -1;
315 }
316
317 #else
318
319 blksize = lseek(fd, 0, SEEK_END);
320 if ( (off_t)blksize == (off_t)-1 ) {
321 ERROR_INFO("Cannot get size of block device");
322 return -1;
323 }
324
325 if ( lseek(fd, 0, SEEK_SET) == (off_t)-1 ) {
326 ERROR_INFO("Cannot seek to begin of block device");
327 return -1;
328 }
329
330 #endif
331
332 if ( blksize == 0 )
333 ERROR_RETURN("Block device has zero size", -1);
334
335 if ( image->size > blksize )
336 ERROR_RETURN("Image is too big", -1);
337
338 sent = 0;
339 printf_progressbar(0, image->size);
340
341 while ( sent < image->size ) {
342 need = image->size - sent;
343 if ( need > sizeof(global_buf) )
344 need = sizeof(global_buf);
345 size = image_read(image, global_buf, need);
346 if ( size == 0 ) {
347 PRINTF_ERROR("Failed to read image");
348 return -1;
349 }
350 if ( ! simulate ) {
351 if ( write(fd, global_buf, size) != size ) {
352 PRINTF_ERROR("Writing image failed");
353 return -1;
354 }
355 }
356 sent += size;
357 printf_progressbar(sent, image->size);
358 }
359
360 return 0;
297361
298362 }
299363
411475 maj2 = tmp;
412476 }
413477
414 /* TODO: change 1 to 0 when disk_flash_dev will be implemented */
415
416478 /* RX-51, RM-680 and RM-696 export MyDocs in first usb device and just first partion, so host system see whole device without MBR table */
417479 if ( dev->device == DEVICE_RX_51 || dev->device == DEVICE_RM_680 || dev->device == DEVICE_RM_696 )
418 fd = disk_open_dev(maj1, min1, -1, 1);
480 fd = disk_open_dev(maj1, min1, -1, simulate ? 1 : 0);
419481 /* Other devices can export SD card as first partition and export whole mmc device, so host system will see MBR table */
420482 else if ( maj2 != -1 && min2 != -1 )
421 fd = disk_open_dev(maj2, min2, 1, 1);
483 fd = disk_open_dev(maj2, min2, 1, simulate ? 1 : 0);
422484 else
423 fd = disk_open_dev(maj1, min1, 1, 1);
485 fd = disk_open_dev(maj1, min1, 1, simulate ? 1 : 0);
424486
425487 if ( fd < 0 )
426488 return -1;
453515
454516 int disk_flash_image(struct usb_device_info * dev, struct image * image) {
455517
456 ERROR("Not implemented yet");
457 (void)dev;
458 (void)image;
459 return -1;
518 int ret;
519
520 printf("Flash image:\n");
521 image_print_info(image);
522
523 ret = disk_flash_dev(dev->data, image);
524 if ( ret == 0 )
525 printf("Done\n");
526
527 return ret;
460528
461529 }
462530
2929
3030 int disk_open_dev(int maj, int min, int partition, int readonly);
3131 int disk_dump_dev(int fd, const char * file);
32 int disk_flash_dev(int fd, const char * file);
32 int disk_flash_dev(int fd, struct image * image);
3333
3434 int disk_flash_image(struct usb_device_info * dev, struct image * image);
3535 int disk_dump_image(struct usb_device_info * dev, enum image_type image, const char * file);
3333 #include "image.h"
3434 #include "fiasco.h"
3535
36 #define CHECKSUM(checksum, buf, size) do { size_t _i; for ( _i = 0; _i < size; _i++ ) checksum += ((unsigned char *)buf)[_i]; } while (0)
3637 #define FIASCO_READ_ERROR(fiasco, ...) do { ERROR_INFO(__VA_ARGS__); fiasco_free(fiasco); return NULL; } while (0)
3738 #define FIASCO_WRITE_ERROR(file, fd, ...) do { ERROR_INFO_STR(file, __VA_ARGS__); if ( fd >= 0 ) close(fd); return -1; } while (0)
3839 #define READ_OR_FAIL(fiasco, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) { FIASCO_READ_ERROR(fiasco, "Cannot read %d bytes", size); } } while (0)
39 #define READ_OR_RETURN(fiasco, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; } while (0)
40 #define READ_OR_RETURN(fiasco, checksum, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; CHECKSUM(checksum, buf, size); } while (0)
4041 #define WRITE_OR_FAIL_FREE(file, fd, buf, size, var) do { if ( ! simulate ) { if ( write(fd, buf, size) != (ssize_t)size ) { free(var); FIASCO_WRITE_ERROR(file, fd, "Cannot write %d bytes", size); } } } while (0)
4142 #define WRITE_OR_FAIL(file, fd, buf, size) WRITE_OR_FAIL_FREE(file, fd, buf, size, NULL)
4243
6465 char hwrevs[1024];
6566 char version[257];
6667 char layout[257];
68 uint8_t asicidx;
69 uint8_t devicetype;
70 uint8_t deviceidx;
71 uint8_t checksum;
72 uint32_t address;
6773 uint16_t hash;
6874 off_t offset;
6975 struct image * image;
76 struct image_part * image_part;
77 struct image_part * image_parts;
7078
7179 char hwrev[9];
7280 unsigned char buf[512];
119127 while ( 1 ) {
120128
121129 /* If end of file, return fiasco image */
122 READ_OR_RETURN(fiasco, buf, 7);
123
124 /* Header of next image */
125 if ( ! ( buf[0] == 0x54 && buf[2] == 0x2E && buf[3] == 0x19 && buf[4] == 0x01 && buf[5] == 0x01 && buf[6] == 0x00 ) ) {
130 checksum = 0x00;
131 READ_OR_RETURN(fiasco, checksum, buf, 1);
132
133 /* Header of next image (0x54) */
134 if ( buf[0] != 0x54 ) {
126135 ERROR("Invalid next image header");
127136 return fiasco;
128137 }
129138
130 count8 = buf[1];
131 if ( count8 > 0 )
132 --count8;
133
134 READ_OR_RETURN(fiasco, &hash, 2);
139 checksum = 0x00;
140
141 READ_OR_RETURN(fiasco, checksum, &count8, 1);
142
143 if ( count8 == 0 ) {
144 ERROR("No section in image header");
145 return fiasco;
146 }
147
148 READ_OR_RETURN(fiasco, checksum, buf, 2);
149
150 /* File data section (0x2E) with length of 25 bytes */
151 if ( buf[0] != 0x2E || buf[1] != 25 ) {
152 ERROR("First section in image header is not file data with length of 25 bytes");
153 return fiasco;
154 }
155
156 READ_OR_RETURN(fiasco, checksum, &asicidx, 1);
157 READ_OR_RETURN(fiasco, checksum, &devicetype, 1);
158 READ_OR_RETURN(fiasco, checksum, &deviceidx, 1);
159
160 READ_OR_RETURN(fiasco, checksum, &hash, 2);
135161 hash = ntohs(hash);
136162
137163 memset(type, 0, sizeof(type));
138 READ_OR_RETURN(fiasco, type, 12);
164 READ_OR_RETURN(fiasco, checksum, type, 12);
139165
140166 byte = type[0];
141167 if ( byte == 0xFF )
143169
144170 VERBOSE(" %s\n", type);
145171
146 READ_OR_RETURN(fiasco, &length, 4);
172 READ_OR_RETURN(fiasco, checksum, &length, 4);
147173 length = ntohl(length);
148174
149 /* unknown */
150 READ_OR_RETURN(fiasco, buf, 4);
175 /* load address (unused) */
176 READ_OR_RETURN(fiasco, checksum, &address, 4);
177
178 /* end of file data section */
179 --count8;
151180
152181 VERBOSE(" size: %d bytes\n", length);
153 VERBOSE(" hash: %#04x\n", hash);
182 VERBOSE(" address: 0x%04x\n", address);
183 VERBOSE(" hash: 0x%04x\n", hash);
184 VERBOSE(" asic idx: %d\n", asicidx);
185 VERBOSE(" device type: %d\n", devicetype);
186 VERBOSE(" device idx: %d\n", deviceidx);
154187 VERBOSE(" subsections: %d\n", count8);
155188
156189 memset(device, 0, sizeof(device));
157190 memset(hwrevs, 0, sizeof(hwrevs));
158191 memset(version, 0, sizeof(version));
159192 memset(layout, 0, sizeof(layout));
193 image_part = NULL;
194 image_parts = NULL;
160195
161196 while ( count8 > 0 ) {
162197
163 READ_OR_RETURN(fiasco, &byte, 1);
164 READ_OR_RETURN(fiasco, &length8, 1);
165 READ_OR_RETURN(fiasco, buf, length8);
198 READ_OR_RETURN(fiasco, checksum, &byte, 1);
199 READ_OR_RETURN(fiasco, checksum, &length8, 1);
200 READ_OR_RETURN(fiasco, checksum, buf, length8);
166201
167202 VERBOSE(" subinfo\n");
168203 VERBOSE(" length: %d\n", length8);
206241 memset(layout, 0, sizeof(layout));
207242 strncpy(layout, (char *)buf, length8);
208243 VERBOSE("layout\n");
244 } else if ( byte == '4' ) {
245 VERBOSE("data part\n");
246 if ( length8 < 16 ) {
247 VERBOSE(" (damaged)\n");
248 } else {
249 if ( image_parts ) {
250 image_part->next = calloc(1, sizeof(struct image_part));
251 if ( ! image_part->next )
252 FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
253 image_part = image_part->next;
254 } else {
255 image_parts = calloc(1, sizeof(struct image_part));
256 if ( ! image_parts )
257 FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
258 image_part = image_parts;
259 }
260 image_part->offset = ntohl(*(uint32_t *)&buf[4]);
261 image_part->size = ntohl(*(uint32_t *)&buf[12]);
262 if ( length8 > 16 ) {
263 image_part->name = calloc(1, length8-16+1);
264 if ( image_part->name )
265 memcpy(image_part->name, &buf[16], length8-16);
266 }
267 VERBOSE(" unknown: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[0], buf[1], buf[2], buf[3]);
268 VERBOSE(" offset: %u bytes\n", image_part->offset);
269 VERBOSE(" unknown: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[8], buf[9], buf[10], buf[11]);
270 VERBOSE(" size: %u bytes\n", image_part->size);
271 if ( image_part->name )
272 VERBOSE(" partition name: %s\n", image_part->name);
273 }
209274 } else {
210 VERBOSE("unknown ('%c':%#x)\n", byte, byte);
275 int i;
276 VERBOSE("unknown (%#x)\n", byte);
277 VERBOSE(" hexdump:");
278 for ( i = 0; i < length8; i++ ) VERBOSE(" 0x%02x", buf[i]);
279 VERBOSE("\n");
211280 }
212281
213282 --count8;
214283 }
215284
216 /* unknown */
217 READ_OR_RETURN(fiasco, buf, 1);
285 /* checksum */
286 READ_OR_RETURN(fiasco, checksum, buf, 1);
287 VERBOSE(" subinfo checksum: 0x%02x\n", buf[0]);
288
289 if ( ! noverify && buf[0] != 0x00 && checksum != 0xFF ) {
290 ERROR("Image header subinfo checksum mishmash (counted 0x%02x, got 0x%02x)", (0xFF - checksum + buf[0]) & 0xFF, buf[0]);
291 return fiasco;
292 }
218293
219294 offset = lseek(fiasco->fd, 0, SEEK_CUR);
220295 if ( offset == (off_t)-1 )
225300 VERBOSE(" hwrevs: %s\n", hwrevs);
226301 VERBOSE(" data at: %#08x\n", (unsigned int)offset);
227302
228 image = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout);
303 image = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout, image_parts);
229304
230305 if ( ! image )
231306 FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
273348 uint32_t length;
274349 uint16_t hash;
275350 uint8_t length8;
351 uint8_t checksum;
276352 char ** device_hwrevs_bufs;
277353 const char * str;
278354 const char * type;
279355 struct image_list * image_list;
356 struct image_part * image_part;
280357 struct image * image;
281358 unsigned char buf[4096];
282359
374451 /* signature */
375452 WRITE_OR_FAIL_FREE(file, fd, "T", 1, device_hwrevs_bufs);
376453
454 checksum = 0x00;
455
377456 /* number of subsections */
378 length8 = device_count+1;
457 length8 = device_count+2;
379458 if ( image->version )
380459 ++length8;
381460 if ( image->layout )
382461 ++length8;
383462 WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
384
385 /* unknown */
463 CHECKSUM(checksum, &length8, 1);
464
465 /* file data: asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
386466 WRITE_OR_FAIL_FREE(file, fd, "\x2e\x19\x01\x01\x00", 5, device_hwrevs_bufs);
467 CHECKSUM(checksum, "\x2e\x19\x01\x01\x00", 5);
387468
388469 /* checksum */
389470 hash = htons(image->hash);
390471 WRITE_OR_FAIL_FREE(file, fd, &hash, 2, device_hwrevs_bufs);
472 CHECKSUM(checksum, &hash, 2);
391473
392474 /* image type name */
393475 memset(buf, 0, 12);
394476 strncpy((char *)buf, type, 12);
395477 WRITE_OR_FAIL_FREE(file, fd, buf, 12, device_hwrevs_bufs);
478 CHECKSUM(checksum, buf, 12);
396479
397480 /* image size */
398481 size = htonl(image->size);
399482 WRITE_OR_FAIL_FREE(file, fd, &size, 4, device_hwrevs_bufs);
400
401 /* unknown */
483 CHECKSUM(checksum, &size, 4);
484
485 /* image load address (unused always zero) */
402486 WRITE_OR_FAIL_FREE(file, fd, "\x00\x00\x00\x00", 4, device_hwrevs_bufs);
487 CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
403488
404489 /* append version subsection */
405490 if ( image->version ) {
407492 length8 = strlen(image->version)+1; /* +1 for NULL term */
408493 WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
409494 WRITE_OR_FAIL_FREE(file, fd, image->version, length8, device_hwrevs_bufs);
495 CHECKSUM(checksum, "1", 1);
496 CHECKSUM(checksum, &length8, 1);
497 CHECKSUM(checksum, image->version, length8);
410498 }
411499
412500 /* append device & hwrevs subsection */
415503 length8 = ((uint8_t *)(device_hwrevs_bufs[i]))[0];
416504 WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
417505 WRITE_OR_FAIL_FREE(file, fd, device_hwrevs_bufs[i]+1, length8, device_hwrevs_bufs);
506 CHECKSUM(checksum, "2", 1);
507 CHECKSUM(checksum, &length8, 1);
508 CHECKSUM(checksum, device_hwrevs_bufs[i]+1, length8);
418509 }
419510 free(device_hwrevs_bufs);
420511
424515 length8 = strlen(image->layout);
425516 WRITE_OR_FAIL(file, fd, &length8, 1);
426517 WRITE_OR_FAIL(file, fd, image->layout, length8);
427 }
428
429 /* dummy byte - end of all subsections */
430 WRITE_OR_FAIL(file, fd, "\x00", 1);
518 CHECKSUM(checksum, "3", 1);
519 CHECKSUM(checksum, &length8, 1);
520 CHECKSUM(checksum, image->layout, length8);
521 }
522
523 if ( image->parts ) {
524 /* for each image part append subsection */
525 for ( image_part = image->parts; image_part; image_part = image_part->next ) {
526 WRITE_OR_FAIL(file, fd, "4", 1); /* 4 - image data part */
527 CHECKSUM(checksum, "4", 1);
528 length = 16 + (image_part->name ? strlen(image_part->name) : 0);
529 length8 = length <= UINT8_MAX ? length : UINT8_MAX;
530 WRITE_OR_FAIL(file, fd, &length8, 1);
531 CHECKSUM(checksum, &length8, 1);
532 WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4); /* unknown */
533 CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
534 size = htonl(image_part->offset);
535 WRITE_OR_FAIL(file, fd, &size, 4);
536 CHECKSUM(checksum, &size, 4);
537 WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4); /* unknown */
538 CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
539 size = htonl(image_part->size);
540 WRITE_OR_FAIL(file, fd, &size, 4);
541 CHECKSUM(checksum, &size, 4);
542 if ( image_part->name ) {
543 WRITE_OR_FAIL(file, fd, image_part->name, length-16);
544 CHECKSUM(checksum, image_part->name, length-16);
545 }
546 }
547 } else {
548 /* append one image data part subsection */;
549 WRITE_OR_FAIL(file, fd, "4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 14);
550 CHECKSUM(checksum, "4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 14);
551 size = htonl(image->size);
552 WRITE_OR_FAIL(file, fd, &size, 4);
553 CHECKSUM(checksum, &size, 4);
554 }
555
556 /* checksum of header */
557 checksum = 0xFF - checksum;
558 WRITE_OR_FAIL(file, fd, &checksum, 1);
431559
432560 printf("Writing image data...\n");
433561
460588 char * name;
461589 char * layout_name;
462590 struct image * image;
591 struct image_part * image_part;
463592 struct image_list * image_list;
464 uint32_t size;
593 uint32_t offset, size, need, total_size, written;
594 int part_num;
465595 char cwd[256];
466596 unsigned char buf[4096];
467597
488618 while ( image_list ) {
489619
490620 fd = -1;
491 name = NULL;
492 layout_name = NULL;
493621
494622 image = image_list->image;
495
496 name = image_name_alloc_from_values(image);
497 if ( ! name )
498 return -1;
499623
500624 printf("\n");
501625 printf("Unpacking image...\n");
503627
504628 if ( image->layout ) {
505629
506 layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1);
630 name = image_name_alloc_from_values(image, -1);
631 if ( ! name )
632 ALLOC_ERROR_RETURN(-1);
633
634 layout_name = calloc(1, strlen(name) + sizeof("_layout")-1 + 1);
507635 if ( ! layout_name ) {
508636 free(name);
509637 ALLOC_ERROR_RETURN(-1);
510638 }
511639
512 sprintf(layout_name, "%s.layout", name);
640 sprintf(layout_name, "%s_layout", name);
641 free(name);
513642
514643 printf(" Layout file: %s\n", layout_name);
515
516 }
517
518 printf(" Output file: %s\n", name);
519
520 if ( ! simulate ) {
521 fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
522 if ( fd < 0 ) {
523 ERROR_INFO("Cannot create output file %s", name);
524 free(name);
525 free(layout_name);
526 return -1;
527 }
528 }
529
530 image_seek(image, 0);
531 while ( 1 ) {
532 size = image_read(image, buf, sizeof(buf));
533 if ( size == 0 )
534 break;
535 if ( ! simulate ) {
536 if ( write(fd, buf, size) != (ssize_t)size ) {
537 ERROR_INFO_STR(name, "Cannot write %d bytes", size);
538 close(fd);
539 free(name);
540 free(layout_name);
541 return -1;
542 }
543 }
544 }
545
546 free(name);
547
548 if ( ! simulate )
549 close(fd);
550
551 if ( image->layout ) {
552644
553645 if ( ! simulate ) {
554646 fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644);
570662
571663 free(layout_name);
572664
573 if ( ! simulate )
665 if ( ! simulate ) {
574666 close(fd);
575
576 }
667 fd = -1;
668 }
669
670 }
671
672 part_num = 0;
673 image_part = image->parts;
674
675 do {
676
677 offset = image_part ? image_part->offset : 0;
678 total_size = image_part ? image_part->size : image->size;
679
680 name = image_name_alloc_from_values(image, image_part ? part_num : -1);
681 if ( ! name )
682 ALLOC_ERROR_RETURN(-1);
683
684 if ( image_part && ( part_num > 0 || image_part->next ) )
685 printf(" Output file part %d: %s\n", part_num+1, name);
686 else
687 printf(" Output file: %s\n", name);
688
689 if ( ! simulate ) {
690 fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
691 if ( fd < 0 ) {
692 ERROR_INFO("Cannot create output file %s", name);
693 free(name);
694 return -1;
695 }
696 }
697
698 written = 0;
699 image_seek(image, offset);
700 while ( written < total_size ) {
701 need = total_size - written;
702 if ( need > sizeof(buf) )
703 need = sizeof(buf);
704 size = image_read(image, buf, need);
705 if ( size == 0 )
706 break;
707 if ( ! simulate ) {
708 if ( write(fd, buf, size) != (ssize_t)size ) {
709 ERROR_INFO_STR(name, "Cannot write %d bytes", size);
710 close(fd);
711 free(name);
712 return -1;
713 }
714 }
715 written += size;
716 }
717
718 free(name);
719
720 if ( ! simulate ) {
721 close(fd);
722 fd = -1;
723 }
724
725 if ( image_part ) {
726 image_part = image_part->next;
727 part_num++;
728 }
729
730 } while ( image_part );
577731
578732 image_list = image_list->next;
579733
9999 }
100100
101101 /* format: type-device:hwrevs_version */
102 char * image_name_alloc_from_values(struct image * image) {
102 char * image_name_alloc_from_values(struct image * image, int part_num) {
103103
104104 char * name;
105105 char * ptr;
107107 size_t length;
108108 const char * type;
109109 const char * device;
110 struct image_part * part;
111 int i;
110112
111113 type = image_type_to_string(image->type);
112114
122124 hwrevs = hwrevs_alloc_to_string(image->devices->hwrevs);
123125 else
124126 hwrevs = NULL;
127
128 part = image->parts;
129
130 if ( part && ( !part->next || part_num < 0 ) )
131 part = NULL;
132
133 for ( i = 0; i < part_num && part; i++ )
134 part = part->next;
125135
126136 length = 1 + strlen(type);
127137
131141 length += 1 + strlen(hwrevs);
132142 if ( image->version )
133143 length += 1 + strlen(image->version);
144 if ( part )
145 length += 4 + 3; /* 3 <= strlen(part_num) */
146 if ( part && part->name )
147 length += 1 + strlen(part->name);
134148
135149 name = calloc(1, length);
136150 if ( ! name ) {
148162 if ( image->version )
149163 ptr += sprintf(ptr, "_%s", image->version);
150164
165 if ( part ) {
166 ptr += sprintf(ptr, "_part%d", part_num+1);
167 if ( part->name )
168 ptr += sprintf(ptr, "_%s", part->name);
169 }
170
151171 free(hwrevs);
152172
153173 return name;
154174
155175 }
156176
157 static int image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
177 static int image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
158178
159179 enum image_type detected_type;
160180
209229 else
210230 image->layout = NULL;
211231
232 image->parts = parts;
233
212234 return 0;
213235
214236 }
243265
244266 }
245267
246 struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
268 struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
247269
248270 int fd;
249271
253275 return NULL;
254276 }
255277
256 return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout);
257
258 }
259
260 struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
278 return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout, parts);
279
280 }
281
282 struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
261283
262284 off_t offset;
263285 struct image * image = image_alloc();
290312 return NULL;
291313 }
292314
293 if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
315 if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
294316 return NULL;
295317
296318 if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) )
302324
303325 }
304326
305 struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
327 struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts) {
306328
307329 struct image * image = image_alloc();
308330 if ( ! image )
314336 image->offset = offset;
315337 image->cur = 0;
316338
317 if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
339 if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
318340 return NULL;
319341
320342 if ( ! noverify && image->hash != hash ) {
344366 free(image->devices->hwrevs);
345367 free(image->devices);
346368 image->devices = next;
369 }
370
371 while ( image->parts ) {
372 struct image_part * next = image->parts->next;
373 free(image->parts->name);
374 free(image->parts);
375 image->parts = next;
347376 }
348377
349378 free(image->version);
515544 [IMAGE_CMT_2ND] = "cmt-2nd",
516545 [IMAGE_CMT_ALGO] = "cmt-algo",
517546 [IMAGE_CMT_MCUSW] = "cmt-mcusw",
547 [IMAGE_1ST] = "1st",
548 [IMAGE_CERT_SW] = "cert-sw",
549 [IMAGE_APE_ALGO] = "ape-algo",
518550 };
519551
520552 enum image_type image_type_from_data(struct image * image) {
3636 IMAGE_CMT_2ND,
3737 IMAGE_CMT_ALGO,
3838 IMAGE_CMT_MCUSW,
39 IMAGE_1ST,
40 IMAGE_CERT_SW,
41 IMAGE_APE_ALGO,
3942 IMAGE_COUNT,
43 };
44
45 struct image_part {
46 struct image_part * next;
47 uint32_t offset;
48 uint32_t size;
49 char * name;
4050 };
4151
4252 struct image {
4656 char * layout;
4757 uint16_t hash;
4858 uint32_t size;
59 struct image_part * parts;
4960
5061 int fd;
5162 int is_shared_fd;
6273 struct image_list * next;
6374 };
6475
65 struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout);
66 struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout);
67 struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout);
76 struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
77 struct image * image_alloc_from_fd(int fd, const char * orig_filename, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
78 struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, uint16_t hash, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout, struct image_part * parts);
6879 void image_free(struct image * image);
6980 void image_seek(struct image * image, size_t whence);
7081 size_t image_read(struct image * image, void * buf, size_t count);
7586
7687 uint16_t image_hash_from_data(struct image * image);
7788 enum image_type image_type_from_data(struct image * image);
78 char * image_name_alloc_from_values(struct image * image);
89 char * image_name_alloc_from_values(struct image * image, int part_num);
7990 enum image_type image_type_from_string(const char * type);
8091 const char * image_type_to_string(enum image_type type);
8192 int image_hwrev_is_valid(struct image * image, int16_t hwrev);
1818 #include <stdio.h>
1919 #include <stdlib.h>
2020 #include <string.h>
21 #include <signal.h>
2122
2223 #include <sys/statvfs.h>
2324 #include <sys/types.h>
197198
198199 }
199200
200 int local_flash_image(struct image * image) {
201
202 ERROR("Not implemented yet");
203 (void)image;
204 return -1;
205
206 }
207
208201 static int local_nanddump(const char * file, int mtd, int offset, int length) {
209202
210203 struct statvfs buf;
226219 return 1;
227220 }
228221
229 size = snprintf(NULL, 0, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
222 size = snprintf(NULL, 0, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd);
230223
231224 command = malloc(size+1);
232225 if ( ! command )
233226 return 1;
234227
235 snprintf(command, size+1, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
236
237 ret = system(command);
228 snprintf(command, size+1, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd);
229
230 if ( ! simulate )
231 ret = system(command);
232 else
233 ret = 0;
238234
239235 free(command);
240236
242238
243239 }
244240
245 struct nanddump_args {
246 int valid;
247 int mtd;
248 int offset;
249 int length;
241 static FILE * local_nandwrite(int mtd, int offset) {
242
243 char * command;
244 FILE * stream;
245 size_t size;
246
247 size = snprintf(NULL, 0, "nandwrite -a -s %d -p /dev/mtd%d -", offset, mtd);
248
249 command = malloc(size+1);
250 if ( ! command )
251 return NULL;
252
253 snprintf(command, size+1, "nandwrite -a -s %d -p /dev/mtd%d -", offset, mtd);
254
255 if ( ! simulate )
256 stream = popen(command, "w");
257 else
258 stream = NULL;
259
260 free(command);
261
262 return stream;
263
264 }
265
266 struct nandpart_args {
267 unsigned int mtd;
268 unsigned int offset;
269 unsigned int length;
270 unsigned int header;
250271 };
251272
252 static struct nanddump_args nanddump_rx51[] = {
253 [IMAGE_XLOADER] = { 1, 0, 0x00000000, 0x00004000 },
254 [IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
255 [IMAGE_KERNEL] = { 1, 3, 0x00000800, 0x001FF800 },
256 [IMAGE_INITFS] = { 1, 4, 0x00000000, 0x00200000 },
257 [IMAGE_ROOTFS] = { 1, 5, 0x00000000, 0x0fb40000 },
273 static struct nandpart_args nandpart_rx51[] = {
274 [IMAGE_XLOADER] = { 0, 0x00000000, 0x00004000, 0x00000000 },
275 [IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
276 [IMAGE_KERNEL] = { 3, 0x00000000, 0x00200000, 0x00000800 },
277 [IMAGE_INITFS] = { 4, 0x00000000, 0x00200000, 0x00000000 },
278 [IMAGE_ROOTFS] = { 5, 0x00000000, 0x0fb40000, 0x00000000 },
258279 };
259280
260281 /* FIXME: Is this table correct? */
261 static struct nanddump_args nanddump_rx4x[] = {
262 [IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
263 [IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
264 [IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x0021F800 },
265 [IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00400000 },
266 [IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0f960000 },
282 static struct nandpart_args nandpart_rx4x[] = {
283 [IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 },
284 [IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
285 [IMAGE_KERNEL] = { 2, 0x00000000, 0x00220000, 0x00000800 },
286 [IMAGE_INITFS] = { 3, 0x00000000, 0x00400000, 0x00000000 },
287 [IMAGE_ROOTFS] = { 4, 0x00000000, 0x0f960000, 0x00000000 },
267288 };
268289
269290 /* FIXME: Is this table correct? */
270 static struct nanddump_args nanddump_old[] = {
271 [IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
272 [IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
273 [IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x001FF800 },
274 [IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00200000 },
275 [IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0fb80000 },
291 static struct nandpart_args nandpart_old[] = {
292 [IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 },
293 [IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
294 [IMAGE_KERNEL] = { 2, 0x00000000, 0x00200000, 0x00000800 },
295 [IMAGE_INITFS] = { 3, 0x00000000, 0x00200000, 0x00000000 },
296 [IMAGE_ROOTFS] = { 4, 0x00000000, 0x0fb80000, 0x00000000 },
276297 };
277298
278 struct nanddump_device {
299 struct nand_device {
279300 size_t count;
280 struct nanddump_args * args;
301 struct nandpart_args * args;
281302 };
282303
283 #define NANDDUMP(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
284
285 static struct nanddump_device nanddump[] = {
286 NANDDUMP(DEVICE_SU_18, nanddump_old),
287 NANDDUMP(DEVICE_RX_34, nanddump_old),
288 NANDDUMP(DEVICE_RX_44, nanddump_rx4x),
289 NANDDUMP(DEVICE_RX_48, nanddump_rx4x),
290 NANDDUMP(DEVICE_RX_51, nanddump_rx51),
304 #define NAND_DEVICE(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
305
306 static struct nand_device nand_device[] = {
307 NAND_DEVICE(DEVICE_SU_18, nandpart_old),
308 NAND_DEVICE(DEVICE_RX_34, nandpart_old),
309 NAND_DEVICE(DEVICE_RX_44, nandpart_rx4x),
310 NAND_DEVICE(DEVICE_RX_48, nandpart_rx4x),
311 NAND_DEVICE(DEVICE_RX_51, nandpart_rx51),
291312 };
292313
293314 #undef NANDDUMP
379400
380401 int local_dump_image(enum image_type image, const char * file) {
381402
403 unsigned char buf[20];
382404 int ret = -1;
383405 int fd = -1;
406 int header = 0;
384407 unsigned char * addr = NULL;
385 off_t nlen, len;
408 off_t nlen = (off_t)-1;
409 off_t len;
386410 int align;
387411 int maj, min;
388412
414438
415439 } else {
416440
417 if ( device >= sizeof(nanddump)/sizeof(nanddump[0]) ) {
441 if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) ) {
418442 ERROR("Unsupported device");
419443 goto clean;
420444 }
421445
422 if ( image >= nanddump[device].count ) {
446 if ( image >= nand_device[device].count ) {
423447 ERROR("Unsupported image type: %s", image_type_to_string(image));
424448 goto clean;
425449 }
426450
427 ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset, nanddump[device].args[image].length);
451 header = nand_device[device].args[image].header;
452
453 if ( header > 0 ) {
454
455 ret = local_nanddump(file, nand_device[device].args[image].mtd, nand_device[device].args[image].offset, header);
456 if ( ret != 0 ) {
457 if ( ! simulate )
458 unlink(file);
459 ret = -1;
460 goto clean;
461 }
462
463 if ( ! simulate ) {
464
465 fd = open(file, O_RDONLY);
466 if ( fd >= 0 ) {
467 if ( read(fd, buf, 20) == 20 ) {
468 if ( memcmp(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16) == 0 )
469 nlen = ((unsigned int)buf[16] << 0) | ((unsigned int)buf[17] << 8) | ((unsigned int)buf[18] << 16) | ((unsigned int)buf[19] << 24);
470 else if ( memcmp(buf, "NOLO img", 8) == 0 )
471 nlen = ((unsigned int)buf[8] << 0) | ((unsigned int)buf[9] << 8) | ((unsigned int)buf[10] << 16) | ((unsigned int)buf[11] << 24);
472 }
473 close(fd);
474 fd = -1;
475 }
476
477 unlink(file);
478
479 }
480
481 }
482
483 ret = local_nanddump(file, nand_device[device].args[image].mtd, nand_device[device].args[image].offset + header, nand_device[device].args[image].length - header);
428484
429485 }
430486
433489 goto clean;
434490 }
435491
492 if ( simulate )
493 goto clean;
494
436495 fd = open(file, O_RDWR);
437496 if ( fd < 0 )
438497 goto clean;
441500 if ( len == (off_t)-1 || len == 0 )
442501 goto clean;
443502
444 addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
445
446 if ( addr == MAP_FAILED )
447 addr = NULL;
448
449 if ( ! addr )
450 goto clean;
451
452 for ( nlen = len; nlen > 0; --nlen )
453 if ( addr[nlen-1] != 0xFF )
454 break;
455
456 for ( ; nlen > 0; --nlen )
457 if ( addr[nlen-1] != 0x00 )
458 break;
459
460 if ( image == IMAGE_MMC )
461 align = 8;
462 else
463 align = 7;
464
465 if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
466 nlen = ((nlen >> align) + 1) << align;
467
468 if ( nlen == 0 ) {
503 if ( header <= 0 || nlen == (off_t)-1 ) {
504
505 addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
506
507 if ( addr == MAP_FAILED )
508 addr = NULL;
509
510 if ( ! addr )
511 goto clean;
512
513 for ( nlen = len; nlen > 0; --nlen )
514 if ( addr[nlen-1] != 0xFF )
515 break;
516
517 for ( ; nlen > 0; --nlen )
518 if ( addr[nlen-1] != 0x00 )
519 break;
520
521 if ( image == IMAGE_MMC )
522 align = 8;
523 else
524 align = 7;
525
526 if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
527 nlen = ((nlen >> align) + 1) << align;
528
529 }
530
531 if ( header <= 0 && nlen == 0 ) {
469532 printf("File %s is empty, removing it...\n", file);
470533 unlink(file);
471534 } else if ( nlen != len ) {
486549
487550 }
488551
552 int local_flash_image(struct image * image) {
553
554 unsigned char buf[0x20000];
555 unsigned int remaining, size;
556 void (*sighandler)(int);
557 int min, maj, fd;
558 FILE * stream;
559 int ret;
560
561 printf("Flash image:\n");
562 image_print_info(image);
563
564 if ( image->type == IMAGE_MMC ) {
565
566 maj = -1;
567 min = -1;
568
569 local_find_internal_mydocs(&maj, &min);
570 if ( maj == -1 || min == -1 )
571 ERROR_RETURN("Cannot find MyDocs mmc device: Slot 'internal' was not found", -1);
572
573 VERBOSE("Detected internal MyDocs mmc device: major=%d minor=%d\n", maj, min);
574
575 fd = disk_open_dev(maj, min, 1, simulate ? 1 : 0);
576 if ( fd < 0 )
577 ERROR_RETURN("Cannot open MyDocs mmc device in /dev/", -1);
578
579 ret = disk_flash_dev(fd, image);
580
581 close(fd);
582
583 } else {
584
585 if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) )
586 ERROR_RETURN("Unsupported device", -1);
587
588 if ( image->type >= nand_device[device].count ) {
589 ERROR("Unsupported image type: %s", image_type_to_string(image->type));
590 return -1;
591 }
592
593 if ( image->size > nand_device[device].args[image->type].length - nand_device[device].args[image->type].header )
594 ERROR_RETURN("Image is too big", -1);
595
596 printf("Using nandwrite for flashing %s image...\n", image_type_to_string(image->type));
597
598 stream = local_nandwrite(nand_device[device].args[image->type].mtd, nand_device[device].args[image->type].offset);
599 if ( ! simulate && ! stream )
600 ERROR_RETURN("Cannot start nandwrite process", -1);
601
602 ret = 0;
603 sighandler = signal(SIGPIPE, SIG_IGN);
604
605 /* Write NOLO!img or NOLO img header with size */
606 if ( nand_device[device].args[image->type].header > 0 ) {
607 if ( device == DEVICE_RX_51 ) {
608 memcpy(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16);
609 buf[16] = (image->size >> 0) & 0xFF;
610 buf[17] = (image->size >> 8) & 0xFF;
611 buf[18] = (image->size >> 16) & 0xFF;
612 buf[19] = (image->size >> 24) & 0xFF;
613 size = 20;
614 } else {
615 memcpy(buf, "NOLO img", 8);
616 buf[ 8] = (image->size >> 0) & 0xFF;
617 buf[ 9] = (image->size >> 8) & 0xFF;
618 buf[10] = (image->size >> 16) & 0xFF;
619 buf[11] = (image->size >> 24) & 0xFF;
620 size = 12;
621 }
622
623 if ( ! simulate ) {
624 if ( fwrite(buf, size, 1, stream) != 1 ) {
625 ret = -1;
626 goto clean;
627 }
628 }
629
630 memset(buf, 0, sizeof(buf));
631 remaining = nand_device[device].args[image->type].header - size;
632 while ( remaining > 0 ) {
633 size = remaining < sizeof(buf) ? remaining : sizeof(buf);
634 if ( ! simulate ) {
635 if ( fwrite(buf, size, 1, stream) != 1 ) {
636 ret = -1;
637 goto clean;
638 }
639 }
640 remaining -= size;
641 }
642 }
643
644 /* Write image data */
645 image_seek(image, 0);
646 remaining = image->size;
647 while ( remaining > 0 ) {
648 size = remaining < sizeof(buf) ? remaining : sizeof(buf);
649 size = image_read(image, buf, size);
650 if ( size == 0 ) {
651 ERROR("Failed to read image");
652 ret = -1;
653 goto clean;
654 }
655 if ( ! simulate ) {
656 if ( fwrite(buf, size, 1, stream) != 1 ) {
657 ret = -1;
658 goto clean;
659 }
660 }
661 remaining -= size;
662 }
663
664 /* Write filler zeros to clear previous data */
665 memset(buf, 0, sizeof(buf));
666 remaining = nand_device[device].args[image->type].length - (image->size + nand_device[device].args[image->type].header);
667 while ( remaining > 0 ) {
668 size = remaining < sizeof(buf) ? remaining : sizeof(buf);
669 if ( ! simulate ) {
670 if ( fwrite(buf, size, 1, stream) != 1 ) {
671 ret = -1;
672 goto clean;
673 }
674 }
675 remaining -= size;
676 }
677
678 clean:
679 if ( ! simulate ) {
680 if ( ret == 0 )
681 ret = pclose(stream);
682 else
683 pclose(stream);
684 }
685
686 signal(SIGPIPE, sighandler);
687
688 if ( ret != 0 )
689 ERROR("Flashing failed");
690 }
691
692 if ( ret == 0 )
693 printf("Done\n");
694
695 return ret;
696
697 }
698
489699 int local_check_badblocks(const char * device) {
490700
491701 ERROR("Not implemented yet");
142142 int noverify;
143143 int verbose;
144144
145 /* arg = [[[dev:[hw:]]ver:]type:]file[%%lay] */
145 /* arg = [[[dev:[hw:]]ver:]type:]file[%file2%file3...%lay] */
146146 static void parse_image_arg(char * arg, struct image_list ** image_first) {
147147
148148 struct stat st;
153153 char * hwrevs;
154154 char * version;
155155 char * layout;
156 char * parts;
156157 char * layout_file;
158 char * ptr;
157159 int fd;
158160
159161 /* First check if arg is file, then try to parse arg format */
160162 fd = open(arg, O_RDONLY);
161163 if ( fd >= 0 ) {
162164 if ( fstat(fd, &st) == 0 && !S_ISDIR(st.st_mode) ) {
163 image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL);
165 image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL, NULL);
164166 if ( ! image ) {
165167 ERROR("Cannot load image file %s", arg);
166168 exit(1);
174176 exit(1);
175177 }
176178
177 layout_file = strchr(arg, '%');
178 if ( layout_file )
179 *(layout_file++) = 0;
179 parts = strchr(arg, '%');
180 if ( parts )
181 *(parts++) = 0;
182
183 layout_file = parts;
184 if ( layout_file ) {
185 while ( ( ptr = strchr(layout_file, '%') ) )
186 layout_file = ptr+1;
187 }
180188
181189 type = NULL;
182190 device = NULL;
236244 close(fd);
237245 }
238246
239 image = image_alloc_from_file(file, type, device, hwrevs, version, layout);
247 /* TODO: alloc parts */
248
249 image = image_alloc_from_file(file, type, device, hwrevs, version, layout, NULL);
240250
241251 if ( layout )
242252 free(layout);
425435 int i;
426436 char buf[512];
427437 char * ptr = NULL;
438 char * ptr1 = NULL;
439 char * ptr2 = NULL;
428440 char * tmp = NULL;
429441
430442 char nolo_ver[512];
10351047 /* filter images by device & hwrev */
10361048 if ( detected_device )
10371049 filter_images_by_device(dev->detected_device, &image_first);
1038 if ( detected_hwrev )
1050 if ( detected_hwrev > 0 )
10391051 filter_images_by_hwrev(dev->detected_hwrev, &image_first);
1040 if ( fiasco_in && ( detected_device || detected_hwrev ) )
1052 if ( fiasco_in && ( detected_device || detected_hwrev > 0 ) )
10411053 fiasco_in->first = image_first;
10421054
10431055 /* set kernel and initfs images for loading */
10951107 if ( dev_load ) {
10961108 if ( image_kernel ) {
10971109 ret = dev_load_image(dev, image_kernel->image);
1098 if ( ret < 0 )
1110 if ( ret == -EAGAIN )
10991111 goto again;
11001112
11011113 if ( image_kernel == image_first )
11091121
11101122 if ( image_initfs ) {
11111123 ret = dev_load_image(dev, image_initfs->image);
1112 if ( ret < 0 )
1124 if ( ret == -EAGAIN )
11131125 goto again;
11141126
11151127 if ( image_initfs == image_first )
11281140 while ( image_ptr ) {
11291141 struct image_list * next = image_ptr->next;
11301142 ret = dev_flash_image(dev, image_ptr->image);
1131 if ( ret < 0 )
1143 if ( ret == -EAGAIN )
11321144 goto again;
11331145
11341146 if ( image_ptr == image_first )
12641276 continue;
12651277
12661278 buf[0] = 0;
1267 snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
1279 if ( dev->detected_hwrev > 0 )
1280 snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
12681281
12691282 switch ( i ) {
12701283 case IMAGE_2ND:
12941307 break;
12951308 }
12961309
1297 image_dump = image_alloc_from_file(image_tmp_name(i), image_type_to_string(i), device_to_string(dev->detected_device), buf, ptr, NULL);
1310 /* TODO: add support for dumping mmc layout and also other mmc partitions as image data parts */
1311
1312 image_dump = image_alloc_from_file(image_tmp_name(i), image_type_to_string(i), device_to_string(dev->detected_device), buf, ptr, NULL, NULL);
12981313
12991314 if ( ! image_dump )
13001315 continue;
13651380 }
13661381
13671382 buf[0] = 0;
1368 snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr);
1383 snprintf(buf, sizeof(buf), "%s", image_type_to_string(i));
1384 ptr1 = buf + strlen(buf);
1385
1386 if ( dev->detected_device ) {
1387 snprintf(ptr1, sizeof(buf)-(ptr1-buf), "-%s", device_to_string(dev->detected_device));
1388 ptr1 += strlen(ptr1);
1389 }
1390
1391 if ( dev->detected_hwrev > 0 )
1392 snprintf(ptr1, sizeof(buf)-(ptr1-buf), ":%hd", dev->detected_hwrev);
1393 ptr2 = ptr1 + strlen(ptr1);
1394
1395 if ( ptr && ptr[0] )
1396 snprintf(ptr2, sizeof(buf)-(ptr2-buf), "_%s", ptr);
13691397
13701398 rename_ret = rename(image_tmp_name(i), buf);
13711399 rename_errno = errno;
13801408 errno = rename_errno;
13811409 ERROR_INFO("Renaming failed");
13821410
1383 buf[0] = 0;
1384 snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr);
1411 *ptr2 = 0;
13851412 printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
13861413
1387 if ( rename(image_tmp_name(i), buf) < 0 )
1414 if ( rename(image_tmp_name(i), buf) < 0 ) {
1415
13881416 ERROR_INFO("Renaming failed");
1417
1418 *ptr1 = 0;
1419 printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
1420
1421 if ( rename(image_tmp_name(i), buf) < 0 )
1422 ERROR_INFO("Renaming failed");
1423
1424 }
13891425
13901426 }
13911427
212212 msg1 = (struct mkii_message *)buf1;
213213 ptr = msg->data;
214214
215 /* Signature */
216 memcpy(ptr, "\x2E\x19\x01\x01", 4);
217 ptr += 4;
218
219 /* Space */
220 memcpy(ptr, "\x00", 1);
215 /* File data header */
216 memcpy(ptr, "\x2E", 1);
221217 ptr += 1;
218
219 /* Length of file data */
220 memcpy(ptr, "\x19", 1);
221 ptr += 1;
222
223 /* File data (ignored): asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
224 memcpy(ptr, "\x01\x01\x00", 3);
225 ptr += 3;
222226
223227 /* Hash */
224228 hash = htons(image->hash);
238242 memcpy(ptr, &size, 4);
239243 ptr += 4;
240244
241 /* Space */
245 /* Load address (ignored) */
242246 memcpy(ptr, "\x00\x00\x00\x00", 4);
243247 ptr += 4;
244248
268268
269269 ptr = buf;
270270
271 /* Signature */
272 memcpy(ptr, "\x2E\x19\x01\x01", 4);
273 ptr += 4;
274
275 /* Space */
276 memcpy(ptr, "\x00", 1);
271 /* File data header */
272 memcpy(ptr, "\x2E", 1);
277273 ptr += 1;
274
275 /* Length of file data */
276 memcpy(ptr, "\x19", 1);
277 ptr += 1;
278
279 /* File data (ignored by NOLO): asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
280 memcpy(ptr, "\x01\x01\x00", 3);
281 ptr += 3;
278282
279283 /* Hash */
280284 hash = htons(image->hash);
294298 memcpy(ptr, &size, 4);
295299 ptr += 4;
296300
297 /* Space */
301 /* Load address (ignored by NOLO) */
298302 memcpy(ptr, "\x00\x00\x00\x00", 4);
299303 ptr += 4;
300304