8 Commits
28 changed files with 420 additions and 839 deletions

No files matched your search

-4
View File
@@ -2,10 +2,6 @@ sudo: false
language: c language: c
arch:
- AMD64
- ppc64le
compiler: compiler:
- gcc - gcc
- clang - clang
+13 -13
View File
@@ -10,24 +10,24 @@
_/ ___|_.|__| _/ ___|_.|__|
'` '`
0xFFFF is the Open Free Fiasco Firmware Flasher for Maemo devices. It supports 0xFFFF is Open Free Fiasco Firmware Flasher for Maemo devices. It support
generating and unpacking FIASCO images. It is useful for editing Maemo firmware generating and unpacking FIASCO images on local computer. Useful for editing
packages before flashing. It supports flashing via USB any image type to a Maemo firmware package for future flash. It support via USB flashing any image
Maemo device and also \"cold\" flashing which means flashing dead device with type to Maemo device and also \"cold\" flashing which means flashing dead device
erased bootloader. There is support for booting kernel via USB without flashing with erased bootloader. There is support for booting kernel via USB without
to NAND and also changing configuration of Maemo device (enable/disable R&D flashing to NAND and also changing configuration of Maemo device (enable/disable
mode, changing HW revision strings, ...). R&D mode, changing HW revision strings, ...).
0xFFFF is an alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen. 0xFFFF is alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen.
0xFFFF generates compatible FIASCO images and also accepts FIASCO images 0xFFFF generate compatible FIASCO images and also accept FIASCO images generated
generated by Nokia fiasco-gen. by Nokia fiasco-gen.
Use it with CARE. This is an experimental tool and it can brick your device. Use it with CARE. This is an experimental tool and it can brick your device.
It's not supposed to be stable, so Nokia will probably release incompatible It's not supposed to be stable, so nokia will probably release incompatible
bootloaders to break this tool. USE IT AT YOUR OWN RISK. bootloaders to break this tool. USE IT AT YOUR OWN RISK.
PLEASE. Read all the documentation inside doc/* carefully before building or PLEASE. Read carefully all the documentation inside doc/* for more information
using the flasher to avoid questions, problems or so. before building or using the flasher to avoid questions, problems or so.
https://github.com/pali/0xFFFF https://github.com/pali/0xFFFF
+2
View File
@@ -5,6 +5,7 @@ cold-flash:
* Detect device from asic id * Detect device from asic id
disk: disk:
* Support for flashing mmc images
* Badblock checking * Badblock checking
fiasco: fiasco:
@@ -14,6 +15,7 @@ image:
* Support for Harmattan images * Support for Harmattan images
local: local:
* Support for flashing (on device)
* Write versions * Write versions
* Badblock checking * Badblock checking
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION = 0.10 VERSION = 0.8
PREFIX = /usr/local PREFIX = /usr/local
# NetBSD stuff # NetBSD stuff
+27
View File
@@ -0,0 +1,27 @@
0xffff (0.8-1) fremantle; urgency=low
* New upstream version
-- Pali Rohár <pali.rohar@gmail.com> Sun, 08 Jul 2018 12:43:42 +0200
0xffff (0.7-1) fremantle; urgency=low
* New upstream version
-- Pali Rohár <pali.rohar@gmail.com> Sun, 25 Dec 2016 11:47:44 +0100
0xffff (0.6.1-1) experimental; urgency=medium
* New upstream release
- Contains a few security related fixes (memory corruptions & leaks)
- Support for -t (filter by type) for -e (dump images)
- reattach kernel driver
- minor fixes
-- Sebastian Reichel <sre@debian.org> Thu, 11 Dec 2014 21:52:53 +0100
0xffff (0.6-1) unstable; urgency=low
* This is new rewritten version of original 0xFFFF 0.5 tool
-- Pali Rohár <pali.rohar@gmail.com> Sun, 07 Apr 2013 15:01:50 +0200
+1
View File
@@ -0,0 +1 @@
7
+89
View File
@@ -0,0 +1,89 @@
Source: 0xffff
Section: user/system
Priority: extra
Maintainer: Pali Rohár <pali.rohar@gmail.com>
Standards-Version: 3.9.8
Build-Depends: debhelper (>= 7),
libusb-dev
Homepage: https://github.com/pali/0xFFFF
Vcs-Git: https://github.com/pali/0xFFFF.git
Vcs-Browser: https://github.com/pali/0xFFFF/tree/maemo
Package: 0xffff
Architecture: any
Depends: ${misc:Depends}, ${shlibs:Depends}, mtd-utils
Description: Open Free Fiasco Firmware Flasher
The ‘Open Free Fiasco Firmware Flasher’ aka 0xFFFF utility implements
a free userspace handler for the NOLO bootloader and extended features
for flashing, dumping and getting information for the Nokia Internet
Tablets. Thus it's a free alternative to Nokia's closed source flashing
utility called flasher.
.
Supported operations currently include, but are not limited to:
* generating and unpacking FIASCO images on local device
* editing Maemo firmware packages
* flashing any kind image type to Maemo devices via USB
* "cold" flashing for devices with bricked bootloaders
* direct kernel boot without flashing it to NAND
* changing configuration of Maemo device (R&D flags, HW revision strings, ...)
.
Supported are the Nokia 770, N800, N810, N810w, N900, N950 and N9.
XSBC-Maemo-Display-Name: 0xFFFF
XB-Maemo-Icon-26:
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
5l7y6xMAAAAASUVORK5CYII=
+31
View File
@@ -0,0 +1,31 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://github.com/pali/0xFFFF
Files: *
Copyright: 2007-2012 pancake <pancake@youterm.com>
2011 Michael Buesch <mb@bu3sch.de>
2011-2013 Pali Rohár <pali.rohar@gmail.com>
License: GPL-3+
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later
version.
.
On Debian systems, the complete text of the GPL-3 can be found in
/usr/share/common-licenses/GPL-3.
Files: debian/*
Copyright: Sebastian Reichel <sre@debian.org>
License: ISC
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Vendored
+3
View File
@@ -0,0 +1,3 @@
doc/
TODO
README
Vendored Executable
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:
dh_auto_install -- PREFIX=/usr
+1
View File
@@ -0,0 +1 @@
3.0 (quilt)
+4
View File
@@ -0,0 +1,4 @@
version=3
opts=filenamemangle=s/.+\/v?(\d\S+)\.tar\.gz/0xFFFF-$1\.tar\.gz/,pgpsigurlmangle=s/$/.asc/ \
https://github.com/pali/0xFFFF/releases .*/0xffff_(\d\S+)\.orig\.tar\.gz
+3 -2
View File
@@ -30,10 +30,11 @@ Technical details:
For dumping mtd partition is used tool nanddump. Here is example how to dump For dumping mtd partition is used tool nanddump. Here is example how to dump
kernel image without padding to file zImage: kernel image without padding to file zImage:
$ nanddump --omitoob -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2 $ nanddump -o -b -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
Params means: Params means:
--omitoob - "Omit oob data" -o - "Omit oob data"
-b - "Omit bad blocks"
-s - "Start address" -s - "Start address"
-l - "Length" -l - "Length"
-f - "Output file" -f - "Output file"
+16 -56
View File
@@ -38,64 +38,24 @@ IMAGE
1 byte = 0x54 -- signature 1 byte = 0x54 -- signature
1 byte -- number of subsection blocks 1 byte -- number of subsection blocks
block { (start of data block)
1 byte -- type of subsection block 1 byte -- type of subsection block (data - always 0x2e)
0x2E - file data 1 byte -- length of subsection block (data - always 25)
0x2F - partition info 3 bytes -- unknown (always 0x01 0x01 0x00)
0x31 - version
0x32 - device & hw revisions (size of device is 16, hw revision 8)
0x33 - layout
0x34 - image data part block (one block for one data part)
1 byte -- length of subsection block
N bytes -- subsection block data
}
1 byte -- checksum of subsection data without signature (0xFF - xorpair)
N bytes -- image data
FILE DATA BLOCK
1 byte -- asic index (always APE - 0x01)
1 byte -- device type (always NAND - 0x01)
1 byte -- device index (always 0x00)
2 bytes -- checksum for the image contents (xorpair) (big endian) 2 bytes -- checksum for the image contents (xorpair) (big endian)
12 bytes -- image name type (first byte is FF if is the last image) 12 bytes -- image name type (first byte is FF if is the last image)
4 bytes -- length of image data (big endian) 4 bytes -- length of image data (big endian)
4 bytes -- load address of image data (big endian, unused always zero)
PARTITION INFO BLOCK
N bytes -- unknown
IMAGE DATA PART BLOCK
4 bytes -- unknown (always 0x00 0x00 0x00 0x00) 4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
4 bytes -- offset (big endian) (end of data block)
4 bytes -- unknown (always 0x00 0x00 0x00 0x00) block {
4 bytes -- size (big endian) 1 byte -- type of subsection block
N bytes -- partition name (prefix) in layout (may be omitted) '1' - version
'2' - device & hw revisions (size of device is 16, hw revision 8)
'3' - layout
LAYOUT DATA BLOCK '4' - unknown
'/' - unknown
N bytes of text data, e.g.: 1 byte -- length of subsection block
N bytes -- subsection block data
mmc {
name = "internal";
partition {
fs_type = "vfat";
prefix = "mydocs";
no_create = true;
} }
partition { 1 byte -- unknown (0x00 is accepted, maybe end of subsections?)
size = 2048; N bytes -- image data
fs_type = "ext3";
prefix = "home";
}
partition {
size = 768;
fs_type = "swap";
}
}
+7 -7
View File
@@ -191,14 +191,14 @@ static int send_2nd(usb_dev_handle * udev, struct image * image) {
if ( ret != sizeof(omap_peripheral_msg) ) if ( ret != sizeof(omap_peripheral_msg) )
ERROR_RETURN("Sending OMAP peripheral boot message failed", -1); ERROR_RETURN("Sending OMAP peripheral boot message failed", -1);
MSLEEP(5); SLEEP(5000);
printf("Sending 2nd X-Loader image size...\n"); printf("Sending 2nd X-Loader image size...\n");
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&image->size, 4, WRITE_TIMEOUT); ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&image->size, 4, WRITE_TIMEOUT);
if ( ret != 4 ) if ( ret != 4 )
ERROR_RETURN("Sending 2nd X-Loader image size failed", -1); ERROR_RETURN("Sending 2nd X-Loader image size failed", -1);
MSLEEP(5); SLEEP(5000);
printf("Sending 2nd X-Loader image...\n"); printf("Sending 2nd X-Loader image...\n");
printf_progressbar(0, image->size); printf_progressbar(0, image->size);
@@ -217,7 +217,7 @@ static int send_2nd(usb_dev_handle * udev, struct image * image) {
printf_progressbar(sent, image->size); printf_progressbar(sent, image->size);
} }
MSLEEP(50); SLEEP(50000);
return 0; return 0;
} }
@@ -237,7 +237,7 @@ static int send_secondary(usb_dev_handle * udev, struct image * image) {
ERROR_RETURN("Sending X-Loader init message failed", -1); ERROR_RETURN("Sending X-Loader init message failed", -1);
printf("Waiting for X-Loader response...\n"); printf("Waiting for X-Loader response...\n");
MSLEEP(5); SLEEP(5000);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */ ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 ) if ( ret != 4 )
ERROR_RETURN("No response", -1); ERROR_RETURN("No response", -1);
@@ -260,7 +260,7 @@ static int send_secondary(usb_dev_handle * udev, struct image * image) {
} }
printf("Waiting for X-Loader response...\n"); printf("Waiting for X-Loader response...\n");
MSLEEP(5); SLEEP(5000);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */ ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 ) if ( ret != 4 )
ERROR_RETURN("No response", -1); ERROR_RETURN("No response", -1);
@@ -296,7 +296,7 @@ static int ping_timeout(usb_dev_handle * udev) {
break; break;
} }
MSLEEP(5); SLEEP(5000);
--try_read; --try_read;
} }
@@ -413,7 +413,7 @@ int leave_cold_flash(struct usb_device_info * dev) {
if ( ret != sizeof(omap_memory_msg) ) if ( ret != sizeof(omap_memory_msg) )
ERROR_RETURN("Sending OMAP memory boot message failed", -1); ERROR_RETURN("Sending OMAP memory boot message failed", -1);
MSLEEP(250); SLEEP(1000000);
return 0; return 0;
} }
+3 -5
View File
@@ -184,11 +184,9 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
continue; continue;
} }
if ( device_first->hwrevs ) {
for ( i = 0; device_first->hwrevs[i] != -1; ++i ) for ( i = 0; device_first->hwrevs[i] != -1; ++i )
if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 ) if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
++local; ++local;
}
size += (1+16+(MAX_HWREVS+1)*8)*(local/MAX_HWREVS+1); size += (1+16+(MAX_HWREVS+1)*8)*(local/MAX_HWREVS+1);
count += local/MAX_HWREVS; count += local/MAX_HWREVS;
@@ -217,7 +215,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
continue; continue;
} }
do { while ( device_first->hwrevs[i+1] != -1 ) {
uint8_t len = 0; uint8_t len = 0;
ret[j] = ++last_ptr; ret[j] = ++last_ptr;
@@ -230,7 +228,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
for ( k = 0; k < MAX_HWREVS; ++k ) { for ( k = 0; k < MAX_HWREVS; ++k ) {
if ( ! device_first->hwrevs || device_first->hwrevs[i+1] == -1 ) if ( device_first->hwrevs[i+1] == -1 )
break; break;
++i; ++i;
@@ -248,7 +246,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
++j; ++j;
} while ( device_first->hwrevs && device_first->hwrevs[i+1] != -1 ); }
device_first = device_first->next; device_first = device_first->next;
+19 -92
View File
@@ -118,7 +118,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
blkdev[len] = 0; blkdev[len] = 0;
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK); fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
if ( fd < 0 ) { if ( fd < 0 ) {
ERROR_INFO("Cannot open block device %s", blkdev); ERROR_INFO("Cannot open block device %s", blkdev);
return -1; return -1;
@@ -144,13 +144,13 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
ERROR("Block device name is too long"); ERROR("Block device name is too long");
return -1; return -1;
} }
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL); fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
if ( fd < 0 && errno == ENOENT ) { if ( fd < 0 && errno == ENOENT ) {
if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) { if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) {
ERROR("Block device name is too long"); ERROR("Block device name is too long");
return -1; return -1;
} }
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL); fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
} }
if ( fd < 0 && errno == ENOENT ) { if ( fd < 0 && errno == ENOENT ) {
blkdev[len] = 0; blkdev[len] = 0;
@@ -201,7 +201,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
int disk_dump_dev(int fd, const char * file) { int disk_dump_dev(int fd, const char * file) {
int fd2 = -1; int fd2;
int ret; int ret;
char * path; char * path;
uint64_t blksize; uint64_t blksize;
@@ -253,8 +253,6 @@ int disk_dump_dev(int fd, const char * file) {
return -1; return -1;
} }
if ( ! simulate ) {
fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ( fd2 < 0 ) { if ( fd2 < 0 ) {
@@ -262,8 +260,6 @@ int disk_dump_dev(int fd, const char * file) {
return -1; return -1;
} }
}
sent = 0; sent = 0;
printf_progressbar(0, blksize); printf_progressbar(0, blksize);
@@ -274,91 +270,26 @@ int disk_dump_dev(int fd, const char * file) {
size = read(fd, global_buf, need); size = read(fd, global_buf, need);
if ( size == 0 ) if ( size == 0 )
break; break;
if ( size < 0 ) {
PRINTF_ERROR("Reading from block device failed");
if ( ! simulate )
close(fd2);
return -1;
}
if ( ! simulate ) {
if ( write(fd2, global_buf, size) != size ) { if ( write(fd2, global_buf, size) != size ) {
PRINTF_ERROR("Dumping image failed"); PRINTF_ERROR("Dumping image failed");
close(fd2); close(fd2);
return -1; return -1;
} }
}
sent += size; sent += size;
printf_progressbar(sent, blksize); printf_progressbar(sent, blksize);
} }
if ( ! simulate )
close(fd2); close(fd2);
return 0; return 0;
} }
int disk_flash_dev(int fd, struct image * image) { int disk_flash_dev(int fd, const char * file) {
uint64_t blksize; ERROR("Not implemented yet");
size_t need, sent; (void)fd;
ssize_t size; (void)file;
if ( image->type != IMAGE_MMC )
ERROR_RETURN("Only mmc images are supported", -1);
printf("Writing image to block device...\n");
#ifdef __linux__
if ( ioctl(fd, BLKGETSIZE64, &blksize) != 0 ) {
ERROR_INFO("Cannot get size of block device");
return -1; return -1;
}
#else
blksize = lseek(fd, 0, SEEK_END);
if ( (off_t)blksize == (off_t)-1 ) {
ERROR_INFO("Cannot get size of block device");
return -1;
}
if ( lseek(fd, 0, SEEK_SET) == (off_t)-1 ) {
ERROR_INFO("Cannot seek to begin of block device");
return -1;
}
#endif
if ( blksize == 0 )
ERROR_RETURN("Block device has zero size", -1);
if ( image->size > blksize )
ERROR_RETURN("Image is too big", -1);
sent = 0;
printf_progressbar(0, image->size);
while ( sent < image->size ) {
need = image->size - sent;
if ( need > sizeof(global_buf) )
need = sizeof(global_buf);
size = image_read(image, global_buf, need);
if ( size == 0 ) {
PRINTF_ERROR("Failed to read image");
return -1;
}
if ( ! simulate ) {
if ( write(fd, global_buf, size) != size ) {
PRINTF_ERROR("Writing image failed");
return -1;
}
}
sent += size;
printf_progressbar(sent, image->size);
}
return 0;
} }
@@ -476,14 +407,16 @@ int disk_init(struct usb_device_info * dev) {
maj2 = tmp; maj2 = tmp;
} }
/* 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 */ /* TODO: change 1 to 0 when disk_flash_dev will be implemented */
if ( dev->device == DEVICE_RX_51 || dev->device == DEVICE_RM_680 || dev->device == DEVICE_RM_696 )
fd = disk_open_dev(maj1, min1, -1, simulate ? 1 : 0); /* RX-51 and RM-680 export MyDocs in first usb device and just first partion, so host system see whole device without MBR table */
if ( dev->device == DEVICE_RX_51 || dev->device == DEVICE_RM_680 )
fd = disk_open_dev(maj1, min1, -1, 1);
/* Other devices can export SD card as first partition and export whole mmc device, so host system will see MBR table */ /* Other devices can export SD card as first partition and export whole mmc device, so host system will see MBR table */
else if ( maj2 != -1 && min2 != -1 ) else if ( maj2 != -1 && min2 != -1 )
fd = disk_open_dev(maj2, min2, 1, simulate ? 1 : 0); fd = disk_open_dev(maj2, min2, 1, 1);
else else
fd = disk_open_dev(maj1, min1, 1, simulate ? 1 : 0); fd = disk_open_dev(maj1, min1, 1, 1);
if ( fd < 0 ) if ( fd < 0 )
return -1; return -1;
@@ -516,16 +449,10 @@ enum device disk_get_device(struct usb_device_info * dev) {
int disk_flash_image(struct usb_device_info * dev, struct image * image) { int disk_flash_image(struct usb_device_info * dev, struct image * image) {
int ret; ERROR("Not implemented yet");
(void)dev;
printf("Flash image:\n"); (void)image;
image_print_info(image); return -1;
ret = disk_flash_dev(dev->data, image);
if ( ret == 0 )
printf("Done\n");
return ret;
} }
+1 -1
View File
@@ -30,7 +30,7 @@ enum device disk_get_device(struct usb_device_info * dev);
int disk_open_dev(int maj, int min, int partition, int readonly); int disk_open_dev(int maj, int min, int partition, int readonly);
int disk_dump_dev(int fd, const char * file); int disk_dump_dev(int fd, const char * file);
int disk_flash_dev(int fd, struct image * image); int disk_flash_dev(int fd, const char * file);
int disk_flash_image(struct usb_device_info * dev, struct image * image); int disk_flash_image(struct usb_device_info * dev, struct image * image);
int disk_dump_image(struct usb_device_info * dev, enum image_type image, const char * file); int disk_dump_image(struct usb_device_info * dev, enum image_type image, const char * file);
+72 -226
View File
@@ -34,11 +34,10 @@
#include "image.h" #include "image.h"
#include "fiasco.h" #include "fiasco.h"
#define CHECKSUM(checksum, buf, size) do { size_t _i; for ( _i = 0; _i < size; _i++ ) checksum += ((unsigned char *)buf)[_i]; } while (0)
#define FIASCO_READ_ERROR(fiasco, ...) do { ERROR_INFO(__VA_ARGS__); fiasco_free(fiasco); return NULL; } while (0) #define FIASCO_READ_ERROR(fiasco, ...) do { ERROR_INFO(__VA_ARGS__); fiasco_free(fiasco); return NULL; } while (0)
#define FIASCO_WRITE_ERROR(file, fd, ...) do { ERROR_INFO_STR(file, __VA_ARGS__); if ( fd >= 0 ) close(fd); return -1; } while (0) #define FIASCO_WRITE_ERROR(file, fd, ...) do { ERROR_INFO_STR(file, __VA_ARGS__); if ( fd >= 0 ) close(fd); return -1; } while (0)
#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) #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)
#define READ_OR_RETURN(fiasco, checksum, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; CHECKSUM(checksum, buf, size); } while (0) #define READ_OR_RETURN(fiasco, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; } while (0)
#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) #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)
#define WRITE_OR_FAIL(file, fd, buf, size) WRITE_OR_FAIL_FREE(file, fd, buf, size, NULL) #define WRITE_OR_FAIL(file, fd, buf, size) WRITE_OR_FAIL_FREE(file, fd, buf, size, NULL)
@@ -66,16 +65,9 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
char hwrevs[1024]; char hwrevs[1024];
char version[257]; char version[257];
char layout[257]; char layout[257];
uint8_t asicidx;
uint8_t devicetype;
uint8_t deviceidx;
uint8_t checksum;
uint32_t address;
uint16_t hash; uint16_t hash;
off_t offset; off_t offset;
struct image * image; struct image * image;
struct image_part * image_part;
struct image_part * image_parts;
char hwrev[9]; char hwrev[9];
unsigned char buf[512]; unsigned char buf[512];
@@ -128,41 +120,23 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
while ( 1 ) { while ( 1 ) {
/* If end of file, return fiasco image */ /* If end of file, return fiasco image */
checksum = 0x00; READ_OR_RETURN(fiasco, buf, 7);
READ_OR_RETURN(fiasco, checksum, buf, 1);
/* Header of next image (0x54) */ /* Header of next image */
if ( buf[0] != 0x54 ) { if ( ! ( buf[0] == 0x54 && buf[2] == 0x2E && buf[3] == 0x19 && buf[4] == 0x01 && buf[5] == 0x01 && buf[6] == 0x00 ) ) {
ERROR("Invalid next image header"); ERROR("Invalid next image header");
return fiasco; return fiasco;
} }
checksum = 0x00; count8 = buf[1];
if ( count8 > 0 )
--count8;
READ_OR_RETURN(fiasco, checksum, &count8, 1); READ_OR_RETURN(fiasco, &hash, 2);
if ( count8 == 0 ) {
ERROR("No section in image header");
return fiasco;
}
READ_OR_RETURN(fiasco, checksum, buf, 2);
/* File data section (0x2E) with length of 25 bytes */
if ( buf[0] != 0x2E || buf[1] != 25 ) {
ERROR("First section in image header is not file data with length of 25 bytes");
return fiasco;
}
READ_OR_RETURN(fiasco, checksum, &asicidx, 1);
READ_OR_RETURN(fiasco, checksum, &devicetype, 1);
READ_OR_RETURN(fiasco, checksum, &deviceidx, 1);
READ_OR_RETURN(fiasco, checksum, &hash, 2);
hash = ntohs(hash); hash = ntohs(hash);
memset(type, 0, sizeof(type)); memset(type, 0, sizeof(type));
READ_OR_RETURN(fiasco, checksum, type, 12); READ_OR_RETURN(fiasco, type, 12);
byte = type[0]; byte = type[0];
if ( byte == 0xFF ) if ( byte == 0xFF )
@@ -170,35 +144,26 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
VERBOSE(" %s\n", type); VERBOSE(" %s\n", type);
READ_OR_RETURN(fiasco, checksum, &length, 4); READ_OR_RETURN(fiasco, &length, 4);
length = ntohl(length); length = ntohl(length);
/* load address (unused) */ /* unknown */
READ_OR_RETURN(fiasco, checksum, &address, 4); READ_OR_RETURN(fiasco, buf, 4);
/* end of file data section */
--count8;
VERBOSE(" size: %d bytes\n", length); VERBOSE(" size: %d bytes\n", length);
VERBOSE(" address: 0x%04x\n", address); VERBOSE(" hash: %#04x\n", hash);
VERBOSE(" hash: 0x%04x\n", hash);
VERBOSE(" asic idx: %d\n", asicidx);
VERBOSE(" device type: %d\n", devicetype);
VERBOSE(" device idx: %d\n", deviceidx);
VERBOSE(" subsections: %d\n", count8); VERBOSE(" subsections: %d\n", count8);
memset(device, 0, sizeof(device)); memset(device, 0, sizeof(device));
memset(hwrevs, 0, sizeof(hwrevs)); memset(hwrevs, 0, sizeof(hwrevs));
memset(version, 0, sizeof(version)); memset(version, 0, sizeof(version));
memset(layout, 0, sizeof(layout)); memset(layout, 0, sizeof(layout));
image_part = NULL;
image_parts = NULL;
while ( count8 > 0 ) { while ( count8 > 0 ) {
READ_OR_RETURN(fiasco, checksum, &byte, 1); READ_OR_RETURN(fiasco, &byte, 1);
READ_OR_RETURN(fiasco, checksum, &length8, 1); READ_OR_RETURN(fiasco, &length8, 1);
READ_OR_RETURN(fiasco, checksum, buf, length8); READ_OR_RETURN(fiasco, buf, length8);
VERBOSE(" subinfo\n"); VERBOSE(" subinfo\n");
VERBOSE(" length: %d\n", length8); VERBOSE(" length: %d\n", length8);
@@ -242,55 +207,15 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
memset(layout, 0, sizeof(layout)); memset(layout, 0, sizeof(layout));
strncpy(layout, (char *)buf, length8); strncpy(layout, (char *)buf, length8);
VERBOSE("layout\n"); VERBOSE("layout\n");
} else if ( byte == '4' ) {
VERBOSE("data part\n");
if ( length8 < 16 ) {
VERBOSE(" (damaged)\n");
} else { } else {
if ( image_parts ) { VERBOSE("unknown ('%c':%#x)\n", byte, byte);
image_part->next = calloc(1, sizeof(struct image_part));
if ( ! image_part->next )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
image_part = image_part->next;
} else {
image_parts = calloc(1, sizeof(struct image_part));
if ( ! image_parts )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
image_part = image_parts;
}
image_part->offset = ntohl(*(uint32_t *)&buf[4]);
image_part->size = ntohl(*(uint32_t *)&buf[12]);
if ( length8 > 16 ) {
image_part->name = calloc(1, length8-16+1);
if ( image_part->name )
memcpy(image_part->name, &buf[16], length8-16);
}
VERBOSE(" unknown: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[0], buf[1], buf[2], buf[3]);
VERBOSE(" offset: %u bytes\n", image_part->offset);
VERBOSE(" unknown: 0x%02x 0x%02x 0x%02x 0x%02x\n", buf[8], buf[9], buf[10], buf[11]);
VERBOSE(" size: %u bytes\n", image_part->size);
if ( image_part->name )
VERBOSE(" partition name: %s\n", image_part->name);
}
} else {
int i;
VERBOSE("unknown (%#x)\n", byte);
VERBOSE(" hexdump:");
for ( i = 0; i < length8; i++ ) VERBOSE(" 0x%02x", buf[i]);
VERBOSE("\n");
} }
--count8; --count8;
} }
/* checksum */ /* unknown */
READ_OR_RETURN(fiasco, checksum, buf, 1); READ_OR_RETURN(fiasco, buf, 1);
VERBOSE(" subinfo checksum: 0x%02x\n", buf[0]);
if ( ! noverify && buf[0] != 0x00 && checksum != 0xFF ) {
ERROR("Image header subinfo checksum mishmash (counted 0x%02x, got 0x%02x)", (0xFF - checksum + buf[0]) & 0xFF, buf[0]);
return fiasco;
}
offset = lseek(fiasco->fd, 0, SEEK_CUR); offset = lseek(fiasco->fd, 0, SEEK_CUR);
if ( offset == (off_t)-1 ) if ( offset == (off_t)-1 )
@@ -301,7 +226,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
VERBOSE(" hwrevs: %s\n", hwrevs); VERBOSE(" hwrevs: %s\n", hwrevs);
VERBOSE(" data at: %#08x\n", (unsigned int)offset); VERBOSE(" data at: %#08x\n", (unsigned int)offset);
image = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout, image_parts); image = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout);
if ( ! image ) if ( ! image )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image"); FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
@@ -349,12 +274,10 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
uint32_t length; uint32_t length;
uint16_t hash; uint16_t hash;
uint8_t length8; uint8_t length8;
uint8_t checksum;
char ** device_hwrevs_bufs; char ** device_hwrevs_bufs;
const char * str; const char * str;
const char * type; const char * type;
struct image_list * image_list; struct image_list * image_list;
struct image_part * image_part;
struct image * image; struct image * image;
unsigned char buf[4096]; unsigned char buf[4096];
@@ -452,40 +375,32 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
/* signature */ /* signature */
WRITE_OR_FAIL_FREE(file, fd, "T", 1, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, "T", 1, device_hwrevs_bufs);
checksum = 0x00;
/* number of subsections */ /* number of subsections */
length8 = device_count+2; length8 = device_count+1;
if ( image->version ) if ( image->version )
++length8; ++length8;
if ( image->layout ) if ( image->layout )
++length8; ++length8;
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
CHECKSUM(checksum, &length8, 1);
/* file data: asic index: APE (0x01), device type: NAND (0x01), device index: 0 */ /* unknown */
WRITE_OR_FAIL_FREE(file, fd, "\x2e\x19\x01\x01\x00", 5, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, "\x2e\x19\x01\x01\x00", 5, device_hwrevs_bufs);
CHECKSUM(checksum, "\x2e\x19\x01\x01\x00", 5);
/* checksum */ /* checksum */
hash = htons(image->hash); hash = htons(image->hash);
WRITE_OR_FAIL_FREE(file, fd, &hash, 2, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, &hash, 2, device_hwrevs_bufs);
CHECKSUM(checksum, &hash, 2);
/* image type name */ /* image type name */
memset(buf, 0, 12); memset(buf, 0, 12);
strncpy((char *)buf, type, 12); strncpy((char *)buf, type, 12);
WRITE_OR_FAIL_FREE(file, fd, buf, 12, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, buf, 12, device_hwrevs_bufs);
CHECKSUM(checksum, buf, 12);
/* image size */ /* image size */
size = htonl(image->size); size = htonl(image->size);
WRITE_OR_FAIL_FREE(file, fd, &size, 4, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, &size, 4, device_hwrevs_bufs);
CHECKSUM(checksum, &size, 4);
/* image load address (unused always zero) */ /* unknown */
WRITE_OR_FAIL_FREE(file, fd, "\x00\x00\x00\x00", 4, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, "\x00\x00\x00\x00", 4, device_hwrevs_bufs);
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
/* append version subsection */ /* append version subsection */
if ( image->version ) { if ( image->version ) {
@@ -493,9 +408,6 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = strlen(image->version)+1; /* +1 for NULL term */ length8 = strlen(image->version)+1; /* +1 for NULL term */
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
WRITE_OR_FAIL_FREE(file, fd, image->version, length8, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, image->version, length8, device_hwrevs_bufs);
CHECKSUM(checksum, "1", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, image->version, length8);
} }
/* append device & hwrevs subsection */ /* append device & hwrevs subsection */
@@ -504,9 +416,6 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = ((uint8_t *)(device_hwrevs_bufs[i]))[0]; length8 = ((uint8_t *)(device_hwrevs_bufs[i]))[0];
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
WRITE_OR_FAIL_FREE(file, fd, device_hwrevs_bufs[i]+1, length8, device_hwrevs_bufs); WRITE_OR_FAIL_FREE(file, fd, device_hwrevs_bufs[i]+1, length8, device_hwrevs_bufs);
CHECKSUM(checksum, "2", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, device_hwrevs_bufs[i]+1, length8);
} }
free(device_hwrevs_bufs); free(device_hwrevs_bufs);
@@ -516,47 +425,10 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = strlen(image->layout); length8 = strlen(image->layout);
WRITE_OR_FAIL(file, fd, &length8, 1); WRITE_OR_FAIL(file, fd, &length8, 1);
WRITE_OR_FAIL(file, fd, image->layout, length8); WRITE_OR_FAIL(file, fd, image->layout, length8);
CHECKSUM(checksum, "3", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, image->layout, length8);
} }
if ( image->parts ) { /* dummy byte - end of all subsections */
/* for each image part append subsection */ WRITE_OR_FAIL(file, fd, "\x00", 1);
for ( image_part = image->parts; image_part; image_part = image_part->next ) {
WRITE_OR_FAIL(file, fd, "4", 1); /* 4 - image data part */
CHECKSUM(checksum, "4", 1);
length = 16 + (image_part->name ? strlen(image_part->name) : 0);
length8 = length <= UINT8_MAX ? length : UINT8_MAX;
WRITE_OR_FAIL(file, fd, &length8, 1);
CHECKSUM(checksum, &length8, 1);
WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4); /* unknown */
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
size = htonl(image_part->offset);
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4); /* unknown */
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
size = htonl(image_part->size);
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
if ( image_part->name ) {
WRITE_OR_FAIL(file, fd, image_part->name, length-16);
CHECKSUM(checksum, image_part->name, length-16);
}
}
} else {
/* append one image data part subsection */;
WRITE_OR_FAIL(file, fd, "4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 14);
CHECKSUM(checksum, "4\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 14);
size = htonl(image->size);
WRITE_OR_FAIL(file, fd, &size, 4);
CHECKSUM(checksum, &size, 4);
}
/* checksum of header */
checksum = 0xFF - checksum;
WRITE_OR_FAIL(file, fd, &checksum, 1);
printf("Writing image data...\n"); printf("Writing image data...\n");
@@ -589,10 +461,8 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
char * name; char * name;
char * layout_name; char * layout_name;
struct image * image; struct image * image;
struct image_part * image_part;
struct image_list * image_list; struct image_list * image_list;
uint32_t offset, size, need, total_size, written; uint32_t size;
int part_num;
char cwd[256]; char cwd[256];
unsigned char buf[4096]; unsigned char buf[4096];
@@ -619,30 +489,68 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
while ( image_list ) { while ( image_list ) {
fd = -1; fd = -1;
name = NULL;
layout_name = NULL;
image = image_list->image; image = image_list->image;
name = image_name_alloc_from_values(image);
if ( ! name )
return -1;
printf("\n"); printf("\n");
printf("Unpacking image...\n"); printf("Unpacking image...\n");
image_print_info(image); image_print_info(image);
if ( image->layout ) { if ( image->layout ) {
name = image_name_alloc_from_values(image, -1); layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1);
if ( ! name )
ALLOC_ERROR_RETURN(-1);
layout_name = calloc(1, strlen(name) + sizeof("_layout")-1 + 1);
if ( ! layout_name ) { if ( ! layout_name ) {
free(name); free(name);
ALLOC_ERROR_RETURN(-1); ALLOC_ERROR_RETURN(-1);
} }
sprintf(layout_name, "%s_layout", name); sprintf(layout_name, "%s.layout", name);
free(name);
printf(" Layout file: %s\n", layout_name); printf(" Layout file: %s\n", layout_name);
}
printf(" Output file: %s\n", name);
if ( ! simulate ) {
fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) {
ERROR_INFO("Cannot create output file %s", name);
free(name);
free(layout_name);
return -1;
}
}
image_seek(image, 0);
while ( 1 ) {
size = image_read(image, buf, sizeof(buf));
if ( size == 0 )
break;
if ( ! simulate ) {
if ( write(fd, buf, size) != (ssize_t)size ) {
ERROR_INFO_STR(name, "Cannot write %d bytes", size);
close(fd);
free(name);
free(layout_name);
return -1;
}
}
}
free(name);
if ( ! simulate )
close(fd);
if ( image->layout ) {
if ( ! simulate ) { if ( ! simulate ) {
fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644); fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) { if ( fd < 0 ) {
@@ -663,73 +571,11 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
free(layout_name); free(layout_name);
if ( ! simulate ) { if ( ! simulate )
close(fd); close(fd);
fd = -1;
}
} }
part_num = 0;
image_part = image->parts;
do {
offset = image_part ? image_part->offset : 0;
total_size = image_part ? image_part->size : image->size;
name = image_name_alloc_from_values(image, image_part ? part_num : -1);
if ( ! name )
ALLOC_ERROR_RETURN(-1);
if ( image_part && ( part_num > 0 || image_part->next ) )
printf(" Output file part %d: %s\n", part_num+1, name);
else
printf(" Output file: %s\n", name);
if ( ! simulate ) {
fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) {
ERROR_INFO("Cannot create output file %s", name);
free(name);
return -1;
}
}
written = 0;
image_seek(image, offset);
while ( written < total_size ) {
need = total_size - written;
if ( need > sizeof(buf) )
need = sizeof(buf);
size = image_read(image, buf, need);
if ( size == 0 )
break;
if ( ! simulate ) {
if ( write(fd, buf, size) != (ssize_t)size ) {
ERROR_INFO_STR(name, "Cannot write %d bytes", size);
close(fd);
free(name);
return -1;
}
}
written += size;
}
free(name);
if ( ! simulate ) {
close(fd);
fd = -1;
}
if ( image_part ) {
image_part = image_part->next;
part_num++;
}
} while ( image_part );
image_list = image_list->next; image_list = image_list->next;
} }
+1 -1
View File
@@ -22,7 +22,7 @@ extern int verbose;
#define ALLOC_ERROR() do { ERROR("Cannot allocate memory"); } while (0) #define ALLOC_ERROR() do { ERROR("Cannot allocate memory"); } while (0)
#define ALLOC_ERROR_RETURN(...) do { ALLOC_ERROR(); return __VA_ARGS__; } while (0) #define ALLOC_ERROR_RETURN(...) do { ALLOC_ERROR(); return __VA_ARGS__; } while (0)
#define MSLEEP(msec) do { nanosleep(&(struct timespec){ (msec / 1000), (1000L * 1000L * (msec % 1000)) }, NULL); } while (0) #define SLEEP(usec) do { struct timespec _t = { 0, (usec) }; nanosleep(&_t, NULL); } while (0)
static inline void * MEMMEM(void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { static inline void * MEMMEM(void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
for ( size_t i = 0; i < haystacklen; ++i ) { for ( size_t i = 0; i < haystacklen; ++i ) {
+8 -40
View File
@@ -100,7 +100,7 @@ static void image_missing_values_from_name(struct image * image, const char * na
} }
/* format: type-device:hwrevs_version */ /* format: type-device:hwrevs_version */
char * image_name_alloc_from_values(struct image * image, int part_num) { char * image_name_alloc_from_values(struct image * image) {
char * name; char * name;
char * ptr; char * ptr;
@@ -108,8 +108,6 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
size_t length; size_t length;
const char * type; const char * type;
const char * device; const char * device;
struct image_part * part;
int i;
type = image_type_to_string(image->type); type = image_type_to_string(image->type);
@@ -126,14 +124,6 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
else else
hwrevs = NULL; hwrevs = NULL;
part = image->parts;
if ( part && ( !part->next || part_num < 0 ) )
part = NULL;
for ( i = 0; i < part_num && part; i++ )
part = part->next;
length = 1 + strlen(type); length = 1 + strlen(type);
if ( device ) if ( device )
@@ -142,10 +132,6 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
length += 1 + strlen(hwrevs); length += 1 + strlen(hwrevs);
if ( image->version ) if ( image->version )
length += 1 + strlen(image->version); length += 1 + strlen(image->version);
if ( part )
length += 4 + 3; /* 3 <= strlen(part_num) */
if ( part && part->name )
length += 1 + strlen(part->name);
name = calloc(1, length); name = calloc(1, length);
if ( ! name ) { if ( ! name ) {
@@ -163,19 +149,13 @@ char * image_name_alloc_from_values(struct image * image, int part_num) {
if ( image->version ) if ( image->version )
ptr += sprintf(ptr, "_%s", image->version); ptr += sprintf(ptr, "_%s", image->version);
if ( part ) {
ptr += sprintf(ptr, "_part%d", part_num+1);
if ( part->name )
ptr += sprintf(ptr, "_%s", part->name);
}
free(hwrevs); free(hwrevs);
return name; return name;
} }
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) { static int image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
enum image_type detected_type; enum image_type detected_type;
@@ -230,8 +210,6 @@ static int image_append(struct image * image, const char * type, const char * de
else else
image->layout = NULL; image->layout = NULL;
image->parts = parts;
return 0; return 0;
} }
@@ -266,7 +244,7 @@ static struct image * image_alloc(void) {
} }
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) { struct image * image_alloc_from_file(const char * file, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
int fd; int fd;
@@ -276,11 +254,11 @@ struct image * image_alloc_from_file(const char * file, const char * type, const
return NULL; return NULL;
} }
return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout, parts); return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout);
} }
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) { 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) {
off_t offset; off_t offset;
struct image * image = image_alloc(); struct image * image = image_alloc();
@@ -313,7 +291,7 @@ struct image * image_alloc_from_fd(int fd, const char * orig_filename, const cha
return NULL; return NULL;
} }
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 ) if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
return NULL; return NULL;
if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) ) if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) )
@@ -325,7 +303,7 @@ struct image * image_alloc_from_fd(int fd, const char * orig_filename, const cha
} }
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) { 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 * image = image_alloc(); struct image * image = image_alloc();
if ( ! image ) if ( ! image )
@@ -337,7 +315,7 @@ struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, ui
image->offset = offset; image->offset = offset;
image->cur = 0; image->cur = 0;
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 ) if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
return NULL; return NULL;
if ( ! noverify && image->hash != hash ) { if ( ! noverify && image->hash != hash ) {
@@ -369,13 +347,6 @@ void image_free(struct image * image) {
image->devices = next; image->devices = next;
} }
while ( image->parts ) {
struct image_part * next = image->parts->next;
free(image->parts->name);
free(image->parts);
image->parts = next;
}
free(image->version); free(image->version);
free(image->layout); free(image->layout);
free(image->orig_filename); free(image->orig_filename);
@@ -545,9 +516,6 @@ static const char * image_types[] = {
[IMAGE_CMT_2ND] = "cmt-2nd", [IMAGE_CMT_2ND] = "cmt-2nd",
[IMAGE_CMT_ALGO] = "cmt-algo", [IMAGE_CMT_ALGO] = "cmt-algo",
[IMAGE_CMT_MCUSW] = "cmt-mcusw", [IMAGE_CMT_MCUSW] = "cmt-mcusw",
[IMAGE_1ST] = "1st",
[IMAGE_CERT_SW] = "cert-sw",
[IMAGE_APE_ALGO] = "ape-algo",
}; };
enum image_type image_type_from_data(struct image * image) { enum image_type image_type_from_data(struct image * image) {
+4 -15
View File
@@ -37,19 +37,9 @@ enum image_type {
IMAGE_CMT_2ND, IMAGE_CMT_2ND,
IMAGE_CMT_ALGO, IMAGE_CMT_ALGO,
IMAGE_CMT_MCUSW, IMAGE_CMT_MCUSW,
IMAGE_1ST,
IMAGE_CERT_SW,
IMAGE_APE_ALGO,
IMAGE_COUNT, IMAGE_COUNT,
}; };
struct image_part {
struct image_part * next;
uint32_t offset;
uint32_t size;
char * name;
};
struct image { struct image {
enum image_type type; enum image_type type;
struct device_list * devices; struct device_list * devices;
@@ -57,7 +47,6 @@ struct image {
char * layout; char * layout;
uint16_t hash; uint16_t hash;
uint32_t size; uint32_t size;
struct image_part * parts;
int fd; int fd;
int is_shared_fd; int is_shared_fd;
@@ -74,9 +63,9 @@ struct image_list {
struct image_list * next; struct image_list * next;
}; };
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); 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 * 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); 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 * 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); 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);
void image_free(struct image * image); void image_free(struct image * image);
void image_seek(struct image * image, size_t whence); void image_seek(struct image * image, size_t whence);
size_t image_read(struct image * image, void * buf, size_t count); size_t image_read(struct image * image, void * buf, size_t count);
@@ -87,7 +76,7 @@ void image_list_unlink(struct image_list * list);
uint16_t image_hash_from_data(struct image * image); uint16_t image_hash_from_data(struct image * image);
enum image_type image_type_from_data(struct image * image); enum image_type image_type_from_data(struct image * image);
char * image_name_alloc_from_values(struct image * image, int part_num); char * image_name_alloc_from_values(struct image * image);
enum image_type image_type_from_string(const char * type); enum image_type image_type_from_string(const char * type);
const char * image_type_to_string(enum image_type type); const char * image_type_to_string(enum image_type type);
int image_hwrev_is_valid(struct image * image, int16_t hwrev); int image_hwrev_is_valid(struct image * image, int16_t hwrev);
+47 -257
View File
@@ -19,7 +19,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include <sys/types.h> #include <sys/types.h>
@@ -199,6 +198,14 @@ enum device local_get_device(void) {
} }
int local_flash_image(struct image * image) {
ERROR("Not implemented yet");
(void)image;
return -1;
}
static int local_nanddump(const char * file, int mtd, int offset, int length) { static int local_nanddump(const char * file, int mtd, int offset, int length) {
struct statvfs buf; struct statvfs buf;
@@ -220,18 +227,15 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
return 1; return 1;
} }
size = snprintf(NULL, 0, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd); size = snprintf(NULL, 0, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
command = malloc(size+1); command = malloc(size+1);
if ( ! command ) if ( ! command )
return 1; return 1;
snprintf(command, size+1, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd); snprintf(command, size+1, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
if ( ! simulate )
ret = system(command); ret = system(command);
else
ret = 0;
free(command); free(command);
@@ -239,77 +243,52 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
} }
static FILE * local_nandwrite(int mtd, int offset) { struct nanddump_args {
int valid;
char * command; int mtd;
FILE * stream; int offset;
size_t size; int length;
size = snprintf(NULL, 0, "nandwrite -a -s %d -p /dev/mtd%d -", offset, mtd);
command = malloc(size+1);
if ( ! command )
return NULL;
snprintf(command, size+1, "nandwrite -a -s %d -p /dev/mtd%d -", offset, mtd);
if ( ! simulate )
stream = popen(command, "w");
else
stream = NULL;
free(command);
return stream;
}
struct nandpart_args {
unsigned int mtd;
unsigned int offset;
unsigned int length;
unsigned int header;
}; };
static struct nandpart_args nandpart_rx51[] = { static struct nanddump_args nanddump_rx51[] = {
[IMAGE_XLOADER] = { 0, 0x00000000, 0x00004000, 0x00000000 }, [IMAGE_XLOADER] = { 1, 0, 0x00000000, 0x00004000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 }, [IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 3, 0x00000000, 0x00200000, 0x00000800 }, [IMAGE_KERNEL] = { 1, 3, 0x00000800, 0x001FF800 },
[IMAGE_INITFS] = { 4, 0x00000000, 0x00200000, 0x00000000 }, [IMAGE_INITFS] = { 1, 4, 0x00000000, 0x00200000 },
[IMAGE_ROOTFS] = { 5, 0x00000000, 0x0fb40000, 0x00000000 }, [IMAGE_ROOTFS] = { 1, 5, 0x00000000, 0x0fb40000 },
}; };
/* FIXME: Is this table correct? */ /* FIXME: Is this table correct? */
static struct nandpart_args nandpart_rx4x[] = { static struct nanddump_args nanddump_rx4x[] = {
[IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 }, [IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 }, [IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 2, 0x00000000, 0x00220000, 0x00000800 }, [IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x0021F800 },
[IMAGE_INITFS] = { 3, 0x00000000, 0x00400000, 0x00000000 }, [IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00400000 },
[IMAGE_ROOTFS] = { 4, 0x00000000, 0x0f960000, 0x00000000 }, [IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0f960000 },
}; };
/* FIXME: Is this table correct? */ /* FIXME: Is this table correct? */
static struct nandpart_args nandpart_old[] = { static struct nanddump_args nanddump_old[] = {
[IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 }, [IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 }, [IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 2, 0x00000000, 0x00200000, 0x00000800 }, [IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x001FF800 },
[IMAGE_INITFS] = { 3, 0x00000000, 0x00200000, 0x00000000 }, [IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00200000 },
[IMAGE_ROOTFS] = { 4, 0x00000000, 0x0fb80000, 0x00000000 }, [IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0fb80000 },
}; };
struct nand_device { struct nanddump_device {
size_t count; size_t count;
struct nandpart_args * args; struct nanddump_args * args;
}; };
#define NAND_DEVICE(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array } #define NANDDUMP(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
static struct nand_device nand_device[] = { static struct nanddump_device nanddump[] = {
NAND_DEVICE(DEVICE_SU_18, nandpart_old), NANDDUMP(DEVICE_SU_18, nanddump_old),
NAND_DEVICE(DEVICE_RX_34, nandpart_old), NANDDUMP(DEVICE_RX_34, nanddump_old),
NAND_DEVICE(DEVICE_RX_44, nandpart_rx4x), NANDDUMP(DEVICE_RX_44, nanddump_rx4x),
NAND_DEVICE(DEVICE_RX_48, nandpart_rx4x), NANDDUMP(DEVICE_RX_48, nanddump_rx4x),
NAND_DEVICE(DEVICE_RX_51, nandpart_rx51), NANDDUMP(DEVICE_RX_51, nanddump_rx51),
}; };
#undef NANDDUMP #undef NANDDUMP
@@ -401,13 +380,10 @@ static void local_find_internal_mydocs(int * maj, int * min) {
int local_dump_image(enum image_type image, const char * file) { int local_dump_image(enum image_type image, const char * file) {
unsigned char buf[20];
int ret = -1; int ret = -1;
int fd = -1; int fd = -1;
int header = 0;
unsigned char * addr = NULL; unsigned char * addr = NULL;
off_t nlen = (off_t)-1; off_t nlen, len;
off_t len;
int align; int align;
int maj, min; int maj, min;
@@ -439,49 +415,17 @@ int local_dump_image(enum image_type image, const char * file) {
} else { } else {
if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) ) { if ( device >= sizeof(nanddump)/sizeof(nanddump[0]) ) {
ERROR("Unsupported device"); ERROR("Unsupported device");
goto clean; goto clean;
} }
if ( image >= nand_device[device].count ) { if ( image >= nanddump[device].count ) {
ERROR("Unsupported image type: %s", image_type_to_string(image)); ERROR("Unsupported image type: %s", image_type_to_string(image));
goto clean; goto clean;
} }
header = nand_device[device].args[image].header; ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset, nanddump[device].args[image].length);
if ( header > 0 ) {
ret = local_nanddump(file, nand_device[device].args[image].mtd, nand_device[device].args[image].offset, header);
if ( ret != 0 ) {
if ( ! simulate )
unlink(file);
ret = -1;
goto clean;
}
if ( ! simulate ) {
fd = open(file, O_RDONLY);
if ( fd >= 0 ) {
if ( read(fd, buf, 20) == 20 ) {
if ( memcmp(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16) == 0 )
nlen = ((unsigned int)buf[16] << 0) | ((unsigned int)buf[17] << 8) | ((unsigned int)buf[18] << 16) | ((unsigned int)buf[19] << 24);
else if ( memcmp(buf, "NOLO img", 8) == 0 )
nlen = ((unsigned int)buf[8] << 0) | ((unsigned int)buf[9] << 8) | ((unsigned int)buf[10] << 16) | ((unsigned int)buf[11] << 24);
}
close(fd);
fd = -1;
}
unlink(file);
}
}
ret = local_nanddump(file, nand_device[device].args[image].mtd, nand_device[device].args[image].offset + header, nand_device[device].args[image].length - header);
} }
@@ -490,9 +434,6 @@ int local_dump_image(enum image_type image, const char * file) {
goto clean; goto clean;
} }
if ( simulate )
goto clean;
fd = open(file, O_RDWR); fd = open(file, O_RDWR);
if ( fd < 0 ) if ( fd < 0 )
goto clean; goto clean;
@@ -501,8 +442,6 @@ int local_dump_image(enum image_type image, const char * file) {
if ( len == (off_t)-1 || len == 0 ) if ( len == (off_t)-1 || len == 0 )
goto clean; goto clean;
if ( header <= 0 || nlen == (off_t)-1 ) {
addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
if ( addr == MAP_FAILED ) if ( addr == MAP_FAILED )
@@ -527,9 +466,7 @@ int local_dump_image(enum image_type image, const char * file) {
if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 ) if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
nlen = ((nlen >> align) + 1) << align; nlen = ((nlen >> align) + 1) << align;
} if ( nlen == 0 ) {
if ( header <= 0 && nlen == 0 ) {
printf("File %s is empty, removing it...\n", file); printf("File %s is empty, removing it...\n", file);
unlink(file); unlink(file);
} else if ( nlen != len ) { } else if ( nlen != len ) {
@@ -550,153 +487,6 @@ clean:
} }
int local_flash_image(struct image * image) {
unsigned char buf[0x20000];
unsigned int remaining, size;
void (*sighandler)(int);
int min, maj, fd;
FILE * stream;
int ret;
printf("Flash image:\n");
image_print_info(image);
if ( image->type == IMAGE_MMC ) {
maj = -1;
min = -1;
local_find_internal_mydocs(&maj, &min);
if ( maj == -1 || min == -1 )
ERROR_RETURN("Cannot find MyDocs mmc device: Slot 'internal' was not found", -1);
VERBOSE("Detected internal MyDocs mmc device: major=%d minor=%d\n", maj, min);
fd = disk_open_dev(maj, min, 1, simulate ? 1 : 0);
if ( fd < 0 )
ERROR_RETURN("Cannot open MyDocs mmc device in /dev/", -1);
ret = disk_flash_dev(fd, image);
close(fd);
} else {
if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) )
ERROR_RETURN("Unsupported device", -1);
if ( image->type >= nand_device[device].count ) {
ERROR("Unsupported image type: %s", image_type_to_string(image->type));
return -1;
}
if ( image->size > nand_device[device].args[image->type].length - nand_device[device].args[image->type].header )
ERROR_RETURN("Image is too big", -1);
printf("Using nandwrite for flashing %s image...\n", image_type_to_string(image->type));
stream = local_nandwrite(nand_device[device].args[image->type].mtd, nand_device[device].args[image->type].offset);
if ( ! simulate && ! stream )
ERROR_RETURN("Cannot start nandwrite process", -1);
ret = 0;
sighandler = signal(SIGPIPE, SIG_IGN);
/* Write NOLO!img or NOLO img header with size */
if ( nand_device[device].args[image->type].header > 0 ) {
if ( device == DEVICE_RX_51 ) {
memcpy(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16);
buf[16] = (image->size >> 0) & 0xFF;
buf[17] = (image->size >> 8) & 0xFF;
buf[18] = (image->size >> 16) & 0xFF;
buf[19] = (image->size >> 24) & 0xFF;
size = 20;
} else {
memcpy(buf, "NOLO img", 8);
buf[ 8] = (image->size >> 0) & 0xFF;
buf[ 9] = (image->size >> 8) & 0xFF;
buf[10] = (image->size >> 16) & 0xFF;
buf[11] = (image->size >> 24) & 0xFF;
size = 12;
}
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
memset(buf, 0, sizeof(buf));
remaining = nand_device[device].args[image->type].header - size;
while ( remaining > 0 ) {
size = remaining < sizeof(buf) ? remaining : sizeof(buf);
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
remaining -= size;
}
}
/* Write image data */
image_seek(image, 0);
remaining = image->size;
while ( remaining > 0 ) {
size = remaining < sizeof(buf) ? remaining : sizeof(buf);
size = image_read(image, buf, size);
if ( size == 0 ) {
ERROR("Failed to read image");
ret = -1;
goto clean;
}
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
remaining -= size;
}
/* Write filler zeros to clear previous data */
memset(buf, 0, sizeof(buf));
remaining = nand_device[device].args[image->type].length - (image->size + nand_device[device].args[image->type].header);
while ( remaining > 0 ) {
size = remaining < sizeof(buf) ? remaining : sizeof(buf);
if ( ! simulate ) {
if ( fwrite(buf, size, 1, stream) != 1 ) {
ret = -1;
goto clean;
}
}
remaining -= size;
}
clean:
if ( ! simulate ) {
if ( ret == 0 )
ret = pclose(stream);
else
pclose(stream);
}
signal(SIGPIPE, sighandler);
if ( ret != 0 )
ERROR("Flashing failed");
}
if ( ret == 0 )
printf("Done\n");
return ret;
}
int local_check_badblocks(const char * device) { int local_check_badblocks(const char * device) {
ERROR("Not implemented yet"); ERROR("Not implemented yet");
+16 -54
View File
@@ -143,7 +143,7 @@ int simulate;
int noverify; int noverify;
int verbose; int verbose;
/* arg = [[[dev:[hw:]]ver:]type:]file[%file2%file3...%lay] */ /* arg = [[[dev:[hw:]]ver:]type:]file[%%lay] */
static void parse_image_arg(char * arg, struct image_list ** image_first) { static void parse_image_arg(char * arg, struct image_list ** image_first) {
struct stat st; struct stat st;
@@ -154,16 +154,14 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
char * hwrevs; char * hwrevs;
char * version; char * version;
char * layout; char * layout;
char * parts;
char * layout_file; char * layout_file;
char * ptr;
int fd; int fd;
/* First check if arg is file, then try to parse arg format */ /* First check if arg is file, then try to parse arg format */
fd = open(arg, O_RDONLY); fd = open(arg, O_RDONLY);
if ( fd >= 0 ) { if ( fd >= 0 ) {
if ( fstat(fd, &st) == 0 && !S_ISDIR(st.st_mode) ) { if ( fstat(fd, &st) == 0 && !S_ISDIR(st.st_mode) ) {
image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL, NULL); image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL);
if ( ! image ) { if ( ! image ) {
ERROR("Cannot load image file %s", arg); ERROR("Cannot load image file %s", arg);
exit(1); exit(1);
@@ -177,15 +175,9 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
exit(1); exit(1);
} }
parts = strchr(arg, '%'); layout_file = strchr(arg, '%');
if ( parts ) if ( layout_file )
*(parts++) = 0; *(layout_file++) = 0;
layout_file = parts;
if ( layout_file ) {
while ( ( ptr = strchr(layout_file, '%') ) )
layout_file = ptr+1;
}
type = NULL; type = NULL;
device = NULL; device = NULL;
@@ -245,9 +237,7 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
close(fd); close(fd);
} }
/* TODO: alloc parts */ image = image_alloc_from_file(file, type, device, hwrevs, version, layout);
image = image_alloc_from_file(file, type, device, hwrevs, version, layout, NULL);
if ( layout ) if ( layout )
free(layout); free(layout);
@@ -431,13 +421,9 @@ int main(int argc, char **argv) {
enum device detected_device = DEVICE_UNKNOWN; enum device detected_device = DEVICE_UNKNOWN;
int16_t detected_hwrev = -1; int16_t detected_hwrev = -1;
struct stat st;
int i; int i;
char buf[512]; char buf[512];
char * ptr = NULL; char * ptr = NULL;
char * ptr1 = NULL;
char * ptr2 = NULL;
char * tmp = NULL; char * tmp = NULL;
char nolo_ver[512]; char nolo_ver[512];
@@ -1048,9 +1034,9 @@ int main(int argc, char **argv) {
/* filter images by device & hwrev */ /* filter images by device & hwrev */
if ( detected_device ) if ( detected_device )
filter_images_by_device(dev->detected_device, &image_first); filter_images_by_device(dev->detected_device, &image_first);
if ( detected_hwrev > 0 ) if ( detected_hwrev )
filter_images_by_hwrev(dev->detected_hwrev, &image_first); filter_images_by_hwrev(dev->detected_hwrev, &image_first);
if ( fiasco_in && ( detected_device || detected_hwrev > 0 ) ) if ( fiasco_in && ( detected_device || detected_hwrev ) )
fiasco_in->first = image_first; fiasco_in->first = image_first;
/* set kernel and initfs images for loading */ /* set kernel and initfs images for loading */
@@ -1108,7 +1094,7 @@ int main(int argc, char **argv) {
if ( dev_load ) { if ( dev_load ) {
if ( image_kernel ) { if ( image_kernel ) {
ret = dev_load_image(dev, image_kernel->image); ret = dev_load_image(dev, image_kernel->image);
if ( ret == -EAGAIN ) if ( ret < 0 )
goto again; goto again;
if ( image_kernel == image_first ) if ( image_kernel == image_first )
@@ -1122,7 +1108,7 @@ int main(int argc, char **argv) {
if ( image_initfs ) { if ( image_initfs ) {
ret = dev_load_image(dev, image_initfs->image); ret = dev_load_image(dev, image_initfs->image);
if ( ret == -EAGAIN ) if ( ret < 0 )
goto again; goto again;
if ( image_initfs == image_first ) if ( image_initfs == image_first )
@@ -1141,7 +1127,7 @@ int main(int argc, char **argv) {
while ( image_ptr ) { while ( image_ptr ) {
struct image_list * next = image_ptr->next; struct image_list * next = image_ptr->next;
ret = dev_flash_image(dev, image_ptr->image); ret = dev_flash_image(dev, image_ptr->image);
if ( ret == -EAGAIN ) if ( ret < 0 )
goto again; goto again;
if ( image_ptr == image_first ) if ( image_ptr == image_first )
@@ -1273,11 +1259,10 @@ int main(int argc, char **argv) {
for ( i = 0; i < IMAGE_COUNT; ++i ) { for ( i = 0; i < IMAGE_COUNT; ++i ) {
if ( ! image_tmp_name(i) || ( stat(image_tmp_name(i), &st) < 0 && errno == ENOENT ) ) if ( ! image_tmp_name(i) )
continue; continue;
buf[0] = 0; buf[0] = 0;
if ( dev->detected_hwrev > 0 )
snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev); snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
switch ( i ) { switch ( i ) {
@@ -1308,9 +1293,7 @@ int main(int argc, char **argv) {
break; break;
} }
/* TODO: add support for dumping mmc layout and also other mmc partitions as image data parts */ image_dump = image_alloc_from_file(image_tmp_name(i), image_type_to_string(i), device_to_string(dev->detected_device), buf, ptr, NULL);
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);
if ( ! image_dump ) if ( ! image_dump )
continue; continue;
@@ -1381,20 +1364,7 @@ int main(int argc, char **argv) {
} }
buf[0] = 0; buf[0] = 0;
snprintf(buf, sizeof(buf), "%s", image_type_to_string(i)); snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr);
ptr1 = buf + strlen(buf);
if ( dev->detected_device ) {
snprintf(ptr1, sizeof(buf)-(ptr1-buf), "-%s", device_to_string(dev->detected_device));
ptr1 += strlen(ptr1);
}
if ( dev->detected_hwrev > 0 )
snprintf(ptr1, sizeof(buf)-(ptr1-buf), ":%hd", dev->detected_hwrev);
ptr2 = ptr1 + strlen(ptr1);
if ( ptr && ptr[0] )
snprintf(ptr2, sizeof(buf)-(ptr2-buf), "_%s", ptr);
rename_ret = rename(image_tmp_name(i), buf); rename_ret = rename(image_tmp_name(i), buf);
rename_errno = errno; rename_errno = errno;
@@ -1409,14 +1379,8 @@ int main(int argc, char **argv) {
errno = rename_errno; errno = rename_errno;
ERROR_INFO("Renaming failed"); ERROR_INFO("Renaming failed");
*ptr2 = 0; buf[0] = 0;
printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf); snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr);
if ( rename(image_tmp_name(i), buf) < 0 ) {
ERROR_INFO("Renaming failed");
*ptr1 = 0;
printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf); printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
if ( rename(image_tmp_name(i), buf) < 0 ) if ( rename(image_tmp_name(i), buf) < 0 )
@@ -1428,8 +1392,6 @@ int main(int argc, char **argv) {
} }
}
/* boot */ /* boot */
if ( dev_boot ) { if ( dev_boot ) {
dev_boot_device(dev, dev_boot_arg); dev_boot_device(dev, dev_boot_arg);
+6 -15
View File
@@ -213,18 +213,14 @@ int mkii_flash_image(struct usb_device_info * dev, struct image * image) {
msg1 = (struct mkii_message *)buf1; msg1 = (struct mkii_message *)buf1;
ptr = msg->data; ptr = msg->data;
/* File data header */ /* Signature */
memcpy(ptr, "\x2E", 1); memcpy(ptr, "\x2E\x19\x01\x01", 4);
ptr += 1; ptr += 4;
/* Length of file data */ /* Space */
memcpy(ptr, "\x19", 1); memcpy(ptr, "\x00", 1);
ptr += 1; ptr += 1;
/* File data (ignored): asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
memcpy(ptr, "\x01\x01\x00", 3);
ptr += 3;
/* Hash */ /* Hash */
hash = htons(image->hash); hash = htons(image->hash);
memcpy(ptr, &hash, 2); memcpy(ptr, &hash, 2);
@@ -243,7 +239,7 @@ int mkii_flash_image(struct usb_device_info * dev, struct image * image) {
memcpy(ptr, &size, 4); memcpy(ptr, &size, 4);
ptr += 4; ptr += 4;
/* Load address (ignored) */ /* Space */
memcpy(ptr, "\x00\x00\x00\x00", 4); memcpy(ptr, "\x00\x00\x00\x00", 4);
ptr += 4; ptr += 4;
@@ -365,11 +361,6 @@ int mkii_reboot_device(struct usb_device_info * dev, int update) {
if ( ret != 1 || msg->data[0] != 0 ) if ( ret != 1 || msg->data[0] != 0 )
ERROR_RETURN("Cannot send reboot command", -1); ERROR_RETURN("Cannot send reboot command", -1);
if (dev->data & MKII_UPDATE_MODE)
MSLEEP(100);
else
MSLEEP(3000);
return 0; return 0;
} }
+7 -11
View File
@@ -269,18 +269,14 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
ptr = buf; ptr = buf;
/* File data header */ /* Signature */
memcpy(ptr, "\x2E", 1); memcpy(ptr, "\x2E\x19\x01\x01", 4);
ptr += 1; ptr += 4;
/* Length of file data */ /* Space */
memcpy(ptr, "\x19", 1); memcpy(ptr, "\x00", 1);
ptr += 1; ptr += 1;
/* File data (ignored by NOLO): asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
memcpy(ptr, "\x01\x01\x00", 3);
ptr += 3;
/* Hash */ /* Hash */
hash = htons(image->hash); hash = htons(image->hash);
memcpy(ptr, &hash, 2); memcpy(ptr, &hash, 2);
@@ -299,7 +295,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
memcpy(ptr, &size, 4); memcpy(ptr, &size, 4);
ptr += 4; ptr += 4;
/* Load address (ignored by NOLO) */ /* Space */
memcpy(ptr, "\x00\x00\x00\x00", 4); memcpy(ptr, "\x00\x00\x00\x00", 4);
ptr += 4; ptr += 4;
@@ -545,7 +541,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
} }
MSLEEP(50); SLEEP(0xc350); // 0.5s
} }
+30 -39
View File
@@ -46,21 +46,16 @@
#endif #endif
static struct usb_flash_device usb_devices[] = { static struct usb_flash_device usb_devices[] = {
/* vend prod i a protocol devices */ { 0x0421, 0x0096, -1, -1, -1, FLASH_DISK, { DEVICE_RX_44, 0 } },
{ 0x0421, 0x0096, -1, -1, FLASH_DISK, { DEVICE_RX_44, 0 } }, { 0x0421, 0x0105, 2, 1, -1, FLASH_NOLO, { DEVICE_SU_18, DEVICE_RX_34, DEVICE_RX_44, DEVICE_RX_48, DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0105, 2, 1, FLASH_NOLO, { DEVICE_SU_18, DEVICE_RX_34, DEVICE_RX_44, DEVICE_RX_48, DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } }, { 0x0421, 0x0106, 0, -1, -1, FLASH_COLD, { DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0106, 0, 0, FLASH_COLD, { DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } }, { 0x0421, 0x0189, -1, -1, -1, FLASH_DISK, { DEVICE_RX_48, 0 } },
{ 0x0421, 0x0189, -1, -1, FLASH_DISK, { DEVICE_RX_48, 0 } }, { 0x0421, 0x01c7, -1, -1, -1, FLASH_DISK, { DEVICE_RX_51, 0 } },
{ 0x0421, 0x01c7, -1, -1, FLASH_DISK, { DEVICE_RX_51, 0 } }, { 0x0421, 0x01c8, 1, 1, -1, FLASH_MKII, { DEVICE_RX_51, DEVICE_RM_680, 0 } },
{ 0x0421, 0x01c8, 1, 1, FLASH_MKII, { DEVICE_RX_51, DEVICE_RM_680, 0 } }, { 0x0421, 0x03d1, -1, -1, -1, FLASH_DISK, { DEVICE_RM_680, 0 } },
{ 0x0421, 0x01c8, 1, 0, FLASH_UNKN, { DEVICE_RX_51, 0 } }, /* U-Boot mode (TTY via USB) */ { 0x0421, 0x0431, -1, -1, -1, FLASH_DISK, { DEVICE_SU_18, DEVICE_RX_34, 0 } },
{ 0x0421, 0x03d1, -1, -1, FLASH_DISK, { DEVICE_RM_680, 0 } }, { 0x0421, 0x04c3, -1, -1, -1, FLASH_DISK, { DEVICE_RX_34, 0 } },
{ 0x0421, 0x03d2, 1, 1, FLASH_MKII, { DEVICE_RM_680, 0 } }, { 0x0421, 0x3f00, 2, 1, -1, FLASH_NOLO, { DEVICE_RX_34, 0 } },
{ 0x0421, 0x0431, -1, -1, FLASH_DISK, { DEVICE_SU_18, DEVICE_RX_34, 0 } },
{ 0x0421, 0x04c3, -1, -1, FLASH_DISK, { DEVICE_RX_34, 0 } },
{ 0x0421, 0x0518, -1, -1, FLASH_DISK, { DEVICE_RM_696, 0 } },
{ 0x0421, 0x0519, -1, -1, FLASH_UNKN, { DEVICE_RM_696, 0 } }, /* RNDIS/Ethernet mode */
{ 0x0421, 0x051a, 2, 1, FLASH_UNKN, { DEVICE_RM_696, 0 } }, /* Sync mode (ADL protocol) */
}; };
static const char * usb_flash_protocols[] = { static const char * usb_flash_protocols[] = {
@@ -139,7 +134,7 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
buf[0] = 0; buf[0] = 0;
for ( i = 0; i < ret; i+=2 ) { for ( i = 0; i < ret; i+=2 ) {
sscanf(buf+i, "%2x", &x); sscanf(buf+i, "%2x", &x);
if ( x > 31 && x < 127 ) if ( x > 32 && x < 128 )
buf2[i/2] = x; buf2[i/2] = x;
else { else {
buf2[0] = 0; buf2[0] = 0;
@@ -155,29 +150,14 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) { static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
size_t i; int i;
char product[1024]; char product[1024];
struct usb_device_info * ret = NULL; struct usb_device_info * ret = NULL;
for ( i = 0; i < sizeof(usb_devices)/sizeof(usb_devices[0]); ++i ) { for ( i = 0; usb_devices[i].vendor; ++i ) {
if ( dev->descriptor.idVendor == usb_devices[i].vendor && dev->descriptor.idProduct == usb_devices[i].product ) { if ( dev->descriptor.idVendor == usb_devices[i].vendor && dev->descriptor.idProduct == usb_devices[i].product ) {
if ( usb_devices[i].protocol == FLASH_UNKN )
continue;
if ( dev->descriptor.bNumConfigurations < 1 )
continue;
if ( usb_devices[i].interface != -1 ) {
if ( usb_devices[i].interface >= dev->config[0].bNumInterfaces )
continue;
if ( usb_devices[i].alternate != -1 ) {
if ( usb_devices[i].alternate >= dev->config[0].interface[usb_devices[i].interface].num_altsetting )
continue;
}
}
printf("\b\b "); printf("\b\b ");
PRINTF_END(); PRINTF_END();
PRINTF_ADD("Found "); PRINTF_ADD("Found ");
@@ -215,7 +195,18 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
if ( usb_devices[i].alternate >= 0 ) { if ( usb_devices[i].alternate >= 0 ) {
PRINTF_LINE("Setting alternate USB interface..."); PRINTF_LINE("Setting alternate USB interface...");
if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) { if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) {
PRINTF_ERROR("usb_set_altinterface failed"); PRINTF_ERROR("usb_claim_interface failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
return NULL;
}
}
if ( usb_devices[i].configuration >= 0 ) {
PRINTF_LINE("Setting USB configuration...");
if ( usb_set_configuration(udev, usb_devices[i].configuration) < 0 ) {
PRINTF_ERROR("usb_set_configuration failed");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface); usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev); usb_close(udev);
@@ -239,13 +230,13 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
ret->device = DEVICE_RX_44; ret->device = DEVICE_RX_44;
else if ( strcmp(product, "Nokia N810 Internet Tablet WiMAX Edition") == 0 || strcmp(product, "Nokia-RX48 (Update mode)") == 0 ) else if ( strcmp(product, "Nokia N810 Internet Tablet WiMAX Edition") == 0 || strcmp(product, "Nokia-RX48 (Update mode)") == 0 )
ret->device = DEVICE_RX_48; ret->device = DEVICE_RX_48;
else if ( strcmp(product, "N900 (Storage Mode)") == 0 || strcmp(product, "Nokia N900 (Update mode)") == 0 || strcmp(product, "N900 (PC-Suite Mode)") == 0 || strcmp(product, "N900 (U-Boot)") == 0 ) else if ( strcmp(product, "N900 (Storage Mode)") == 0 || strcmp(product, "Nokia N900 (Update mode)") == 0 || strcmp(product, "N900 (PC-Suite Mode)") == 0 )
ret->device = DEVICE_RX_51; ret->device = DEVICE_RX_51;
else if ( strcmp(product, "Nokia N950") == 0 || strcmp(product, "N950 (Update mode)") == 0 ) else if ( strcmp(product, "Nokia N950") == 0 || strcmp(product, "Sync Mode") == 0 || strcmp(product, "N950 (Update mode)") == 0 )
ret->device = DEVICE_RM_680; ret->device = DEVICE_RM_680;
else if ( strcmp(product, "Nokia N9") == 0 || strcmp(product, "N9 (Update mode)") == 0 || strcmp(product, "Nokia N9 RNDIS/Ethernet") == 0 ) else if ( strcmp(product, "N9 (Update mode)") == 0 || strcmp(product, "Nxy (Update mode)") == 0 )
ret->device = DEVICE_RM_696; ret->device = DEVICE_RM_696;
else if ( strcmp(product, "Nokia USB ROM") == 0 || strcmp(product, "Sync Mode") == 0 || strcmp(product, "Nxy (Update mode)") == 0 ) else if ( strcmp(product, "Nokia USB ROM") == 0 )
ret->device = DEVICE_ANY; ret->device = DEVICE_ANY;
else else
ret->device = DEVICE_UNKNOWN; ret->device = DEVICE_UNKNOWN;
@@ -370,7 +361,7 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
if ( ret ) if ( ret )
break; break;
MSLEEP(50); SLEEP(0xc350); // 0.5s
} }
+1
View File
@@ -49,6 +49,7 @@ struct usb_flash_device {
uint16_t product; uint16_t product;
int interface; int interface;
int alternate; int alternate;
int configuration;
enum usb_flash_protocol protocol; enum usb_flash_protocol protocol;
enum device devices[DEVICE_COUNT]; enum device devices[DEVICE_COUNT];
}; };