44 Commits
Author SHA1 Message Date
Pali Rohár f6b0a7be3a Release version 0.10 2022-01-04 17:29:07 +01:00
Pali Rohár 8a9e2759d4 device: Fix 0xFFFF crash when generating fiasco image without hwrev 2021-05-02 18:44:22 +02:00
Pali Rohár bacbb0165b fiasco: Mute warning about uninitialized variables fs and checksum 2021-05-02 17:56:24 +02:00
Pali Rohár df2340e48d main: Fix NULL pointer derefernce 2021-05-02 17:48:49 +02:00
Pali Rohár a5279bffaf local: Fix flashing and dumping kernel images with "NOLO img" header
"NOLO img" header (instead of "NOLO!img" header) is used on older devices.
2021-05-02 17:35:09 +02:00
Pali Rohár b46e4a6ad5 image: Define 1st, cert-sw and ape-algo Harmattan images
This change allows 0xFFFF to unpack Harmattan fiasco images.
2021-05-02 17:19:56 +02:00
Pali Rohár e65d7d1636 fiasco: Show verbose hexdump information about unknown section 2021-05-02 17:06:20 +02:00
Pali Rohár 1f466936cb fiasco: When generating fiasco image append image data part sections
Nokia's fiasco-gen writes data part section even if there is only one part.
So do the same thing in 0xFFFF.
2021-05-02 17:04:27 +02:00
Pali Rohár df8e50a824 fiasco: Add support for unpacking multiple parts of one image
Fiasco mmc image contains layout and two parts in one data section. First
part is FAT32 partition (MyDocs) and second part is tar archive for second
ext3 partition (/home). This change extends fiasco parser to load all parts
from one data section and correctly unpack all parts.
2021-05-02 17:01:48 +02:00
Pali Rohár 4f45b045c3 fiasco: Implement subsection checksum verification during parsing fiasco image
When checksum is set to 0x00 then skip verification due to backward
compatibility with 0xFFFF version 0.9 and earlier.
2021-05-02 14:24:51 +02:00
Pali Rohár 3c4943340b fiasco: Write correct subsection checksum when generating fiasco image
Previously 0xFFFF written fixed value 0x00 instead of correct checksum.
Apparently both NOLO and Nokia's flasher-3.5 ignored checksum value
verification when checksum was set to 0x00.

Also Nokia's fiasco-gen writes correct checksum (not 0x00) to final fiasco
image file.
2021-05-02 14:22:55 +02:00
Pali Rohár ce67a58983 fiasco: Update comments about unknown bytes and parsing of fiasco images
Allow to parse also fiasco images which do not have common parameters:
* asic index: APE (0x01)
* device type: NAND (0x01)
* device index: 0
2021-05-02 14:19:38 +02:00
Pali Rohár a6b6b71ded doc: Update fiasco documenation 2021-05-02 14:09:53 +02:00
Pali Rohár 580f1de0fe mkii: Update comments about unknown bytes in flashing protocol 2021-05-02 13:43:21 +02:00
Pali Rohár f9e88d6f91 nolo: Update comments about unknown bytes in flashing protocol 2021-05-02 13:42:36 +02:00
Pali Rohár ca035e2ec1 main: Fix renaming of dumped images
Some information (device, hwrev or version string) does not have to be available.
2021-05-02 13:36:56 +02:00
Pali Rohár 5c0720da32 local: Fix reading kernel size when dumping image 2021-05-01 21:06:37 +02:00
Pali Rohár 374fd1be01 TODO: Update implemented parts 2021-05-01 20:41:40 +02:00
Pali Rohár f144067634 local: Respect -s (simulate) flag for dump -e operation 2021-05-01 20:39:44 +02:00
Pali Rohár bbf438e1a8 disk: Respect -s (simulate) flag for dump -e operation 2021-05-01 20:38:26 +02:00
Pali Rohár 670db0d169 main: Retry load and flash operations only on -EAGAIN error 2021-05-01 20:10:21 +02:00
Pali Rohár 6eb58dcccb local: Implement local flashing via nandwrite 2021-05-01 20:09:40 +02:00
Pali Rohár b090564a85 disk: Implement flashing mmc images 2021-05-01 20:07:49 +02:00
Pali Rohár 38f83f8db4 local: Rename nanddump structures to just nand
They can be used also for other nand commands like nandwrite.
2021-05-01 18:27:32 +02:00
Pali Rohár 342dc610b3 local: Parse real kernel size from NOLO!img header when dumping kernel image
Kernel image is prepended with 2kB header with NOLO!img magic and contains
size of the kernel image. 0xFFFF until now just skipped this header. With
this change is reads from it real kernel image size and correctly truncate
final dumped image for 0xFFFF -e/-E dump operation.
2021-05-01 18:20:13 +02:00
Pali Rohár 67427daf17 local: Fix calling nanddump
In last 15 years nanddump changed its command line arguments. Argument -b
(omit bad blocks) was completely removed and argument -o (omit oob data)
changed its meaning to "include" oob data. So for compatibility with all
nanddump versions, do not use argument -b and instead of -o use argument
--omitoob which is present in all nanddump versions and has same meaning
to omit oob data.

This change should fix dumping firmware files on devices with recent
versions of nanddump.
2021-05-01 15:34:22 +02:00
Pali Rohár bf24ca2345 Release version 0.9 2021-01-05 19:16:39 +01:00
Pali Rohár 5c845a947e usb-device: Specify alternate id for cold flashing 2021-01-05 15:51:10 +01:00
Pali Rohár 673ccaf71d usb-device: Add N900 U-Boot mode (TTY via USB) to device list 2021-01-05 15:32:20 +01:00
Pali Rohár 9bc4b8c26f usb-device: Check that usb device provides required interface/alternate settings 2021-01-05 15:04:31 +01:00
Pali Rohár e6422cf5a2 usb-device: Remove dead usb_set_configuration() code
It is on worng place, must be called prior usb_claim_interface() and currently no device use it.
2021-01-05 14:38:02 +01:00
Pali Rohár a6effa8f62 usb-device: Remove 0x0421/0x3f00 from list
It was some internal Nokia development board with just temporary device id. Not a real RX-34 device.
2021-01-05 13:45:01 +01:00
Pali Rohár e16a79f75e usb-device: Fix interface id for Nokia N9 Sync mode and disable it as it use unsupported ADL protocol 2021-01-05 13:28:29 +01:00
Pali Rohár 93bd73d451 usb-device: Fix iterating over supported list of devices 2021-01-05 12:35:40 +01:00
Pali Rohár 0e5ceffa42 disk: Fix detecting Nokia N9 device 2021-01-05 12:32:34 +01:00
Pali Rohár ca080dd33f usb-device: Add device ids for Nokia N950 and Nokia N9 2020-12-26 01:40:57 +01:00
Pali Rohár 4ae1f13624 usb-device: Fix range or printable characters 2020-11-29 21:56:29 +01:00
Pali Rohár 69a7c2705e usb-device: Fix error message for usb_set_altinterface 2020-11-29 21:55:17 +01:00
Devendranath Thadi 8d053c9074 Travis-ci: added support for ppc64le
Signed-off-by: Devendranath Thadi <devendranath.thadi3@gmail.com>
2020-11-17 09:02:09 +00:00
Pali Rohár f37c2cd7e8 all: Fix delays for all operations 2020-04-25 20:04:51 +02:00
Pali Rohár e94279eecb local: Do not show error message about missing dump files which were skipped 2020-01-15 23:38:29 +01:00
Pali Rohár 52793b733d disk: Check if reading from block device failed 2019-09-30 17:42:16 +02:00
Sevan Janiyan 4bd0a47b22 Rewrap 2019-09-30 00:39:24 +01:00
Sevan Janiyan adeca0dd45 Grammar 2019-09-30 00:38:57 +01:00
20 changed files with 872 additions and 290 deletions

No files matched your search

+4
View File
@@ -2,6 +2,10 @@ sudo: false
language: c
arch:
- AMD64
- ppc64le
compiler:
- gcc
- clang
+13 -13
View File
@@ -10,24 +10,24 @@
_/ ___|_.|__|
'`
0xFFFF is Open Free Fiasco Firmware Flasher for Maemo devices. It support
generating and unpacking FIASCO images on local computer. Useful for editing
Maemo firmware package for future flash. It support via USB flashing any image
type to Maemo device and also \"cold\" flashing which means flashing dead device
with erased bootloader. There is support for booting kernel via USB without
flashing to NAND and also changing configuration of Maemo device (enable/disable
R&D mode, changing HW revision strings, ...).
0xFFFF is the Open Free Fiasco Firmware Flasher for Maemo devices. It supports
generating and unpacking FIASCO images. It is useful for editing Maemo firmware
packages before flashing. It supports flashing via USB any image type to a
Maemo device and also \"cold\" flashing which means flashing dead device with
erased bootloader. There is support for booting kernel via USB without flashing
to NAND and also changing configuration of Maemo device (enable/disable R&D
mode, changing HW revision strings, ...).
0xFFFF is alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen.
0xFFFF generate compatible FIASCO images and also accept FIASCO images generated
by Nokia fiasco-gen.
0xFFFF is an alternative tool to proprietary Nokia flasher-3.5 and fiasco-gen.
0xFFFF generates compatible FIASCO images and also accepts FIASCO images
generated by Nokia fiasco-gen.
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.
PLEASE. Read carefully all the documentation inside doc/* for more information
before building or using the flasher to avoid questions, problems or so.
PLEASE. Read all the documentation inside doc/* carefully before building or
using the flasher to avoid questions, problems or so.
https://github.com/pali/0xFFFF
-2
View File
@@ -5,7 +5,6 @@ cold-flash:
* Detect device from asic id
disk:
* Support for flashing mmc images
* Badblock checking
fiasco:
@@ -15,7 +14,6 @@ image:
* Support for Harmattan images
local:
* Support for flashing (on device)
* Write versions
* Badblock checking
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION = 0.8
VERSION = 0.10
PREFIX = /usr/local
# NetBSD stuff
+2 -3
View File
@@ -30,11 +30,10 @@ Technical details:
For dumping mtd partition is used tool nanddump. Here is example how to dump
kernel image without padding to file zImage:
$ nanddump -o -b -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
$ nanddump --omitoob -s 0x00000800 -l 0x001FF800 -f zImage /dev/mtd2
Params means:
-o - "Omit oob data"
-b - "Omit bad blocks"
--omitoob - "Omit oob data"
-s - "Start address"
-l - "Length"
-f - "Output file"
+55 -15
View File
@@ -38,24 +38,64 @@ IMAGE
1 byte = 0x54 -- signature
1 byte -- number of subsection blocks
(start of data block)
1 byte -- type of subsection block (data - always 0x2e)
1 byte -- length of subsection block (data - always 25)
3 bytes -- unknown (always 0x01 0x01 0x00)
2 bytes -- checksum for the image contents (xorpair) (big endian)
12 bytes -- image name type (first byte is FF if is the last image)
4 bytes -- length of image data (big endian)
4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
(end of data block)
block {
1 byte -- type of subsection block
'1' - version
'2' - device & hw revisions (size of device is 16, hw revision 8)
'3' - layout
'4' - unknown
'/' - unknown
0x2E - file data
0x2F - partition info
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 -- unknown (0x00 is accepted, maybe end of subsections?)
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)
12 bytes -- image name type (first byte is FF if is the last image)
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 -- offset (big endian)
4 bytes -- unknown (always 0x00 0x00 0x00 0x00)
4 bytes -- size (big endian)
N bytes -- partition name (prefix) in layout (may be omitted)
LAYOUT DATA BLOCK
N bytes of text data, e.g.:
mmc {
name = "internal";
partition {
fs_type = "vfat";
prefix = "mydocs";
no_create = true;
}
partition {
size = 2048;
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) )
ERROR_RETURN("Sending OMAP peripheral boot message failed", -1);
SLEEP(5000);
MSLEEP(5);
printf("Sending 2nd X-Loader image size...\n");
ret = usb_bulk_write(udev, USB_WRITE_EP, (char *)&image->size, 4, WRITE_TIMEOUT);
if ( ret != 4 )
ERROR_RETURN("Sending 2nd X-Loader image size failed", -1);
SLEEP(5000);
MSLEEP(5);
printf("Sending 2nd X-Loader image...\n");
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);
}
SLEEP(50000);
MSLEEP(50);
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);
printf("Waiting for X-Loader response...\n");
SLEEP(5000);
MSLEEP(5);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 )
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");
SLEEP(5000);
MSLEEP(5);
ret = usb_bulk_read(udev, USB_READ_EP, (char *)&buffer, 4, READ_TIMEOUT); /* 4 bytes - dummy value */
if ( ret != 4 )
ERROR_RETURN("No response", -1);
@@ -296,7 +296,7 @@ static int ping_timeout(usb_dev_handle * udev) {
break;
}
SLEEP(5000);
MSLEEP(5);
--try_read;
}
@@ -413,7 +413,7 @@ int leave_cold_flash(struct usb_device_info * dev) {
if ( ret != sizeof(omap_memory_msg) )
ERROR_RETURN("Sending OMAP memory boot message failed", -1);
SLEEP(1000000);
MSLEEP(250);
return 0;
}
+8 -6
View File
@@ -184,9 +184,11 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
continue;
}
for ( i = 0; device_first->hwrevs[i] != -1; ++i )
if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
++local;
if ( device_first->hwrevs ) {
for ( i = 0; device_first->hwrevs[i] != -1; ++i )
if ( device_first->hwrevs[i] >= 0 && device_first->hwrevs[i] <= 9999 )
++local;
}
size += (1+16+(MAX_HWREVS+1)*8)*(local/MAX_HWREVS+1);
count += local/MAX_HWREVS;
@@ -215,7 +217,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
continue;
}
while ( device_first->hwrevs[i+1] != -1 ) {
do {
uint8_t len = 0;
ret[j] = ++last_ptr;
@@ -228,7 +230,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
for ( k = 0; k < MAX_HWREVS; ++k ) {
if ( device_first->hwrevs[i+1] == -1 )
if ( ! device_first->hwrevs || device_first->hwrevs[i+1] == -1 )
break;
++i;
@@ -246,7 +248,7 @@ char ** device_list_alloc_to_bufs(const struct device_list * device_list) {
++j;
}
} while ( device_first->hwrevs && device_first->hwrevs[i+1] != -1 );
device_first = device_first->next;
+101 -28
View File
@@ -118,7 +118,7 @@ int disk_open_dev(int maj, int min, int partition, int readonly) {
blkdev[len] = 0;
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL | O_NONBLOCK);
if ( fd < 0 ) {
ERROR_INFO("Cannot open block device %s", blkdev);
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");
return -1;
}
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
if ( fd < 0 && errno == ENOENT ) {
if ( snprintf(blkdev+len, sizeof(blkdev)-len, "%d", partition) >= (int)(sizeof(blkdev)-len) ) {
ERROR("Block device name is too long");
return -1;
}
fd = open(blkdev, (readonly ? O_RDONLY : O_RDWR) | O_EXCL);
fd = open(blkdev, ((simulate || readonly) ? O_RDONLY : O_RDWR) | O_EXCL);
}
if ( fd < 0 && errno == ENOENT ) {
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 fd2;
int fd2 = -1;
int ret;
char * path;
uint64_t blksize;
@@ -253,11 +253,15 @@ int disk_dump_dev(int fd, const char * file) {
return -1;
}
fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ( ! simulate ) {
fd2 = creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if ( fd2 < 0 ) {
ERROR_INFO("Cannot create file %s", file);
return -1;
}
if ( fd2 < 0 ) {
ERROR_INFO("Cannot create file %s", file);
return -1;
}
sent = 0;
@@ -270,26 +274,91 @@ int disk_dump_dev(int fd, const char * file) {
size = read(fd, global_buf, need);
if ( size == 0 )
break;
if ( write(fd2, global_buf, size) != size ) {
PRINTF_ERROR("Dumping image failed");
close(fd2);
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 ) {
PRINTF_ERROR("Dumping image failed");
close(fd2);
return -1;
}
}
sent += size;
printf_progressbar(sent, blksize);
}
close(fd2);
if ( ! simulate )
close(fd2);
return 0;
}
int disk_flash_dev(int fd, const char * file) {
int disk_flash_dev(int fd, struct image * image) {
ERROR("Not implemented yet");
(void)fd;
(void)file;
return -1;
uint64_t blksize;
size_t need, sent;
ssize_t size;
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;
}
#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;
}
@@ -407,16 +476,14 @@ int disk_init(struct usb_device_info * dev) {
maj2 = tmp;
}
/* TODO: change 1 to 0 when disk_flash_dev will be implemented */
/* 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);
/* 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 */
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);
/* 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 )
fd = disk_open_dev(maj2, min2, 1, 1);
fd = disk_open_dev(maj2, min2, 1, simulate ? 1 : 0);
else
fd = disk_open_dev(maj1, min1, 1, 1);
fd = disk_open_dev(maj1, min1, 1, simulate ? 1 : 0);
if ( fd < 0 )
return -1;
@@ -449,10 +516,16 @@ enum device disk_get_device(struct usb_device_info * dev) {
int disk_flash_image(struct usb_device_info * dev, struct image * image) {
ERROR("Not implemented yet");
(void)dev;
(void)image;
return -1;
int ret;
printf("Flash image:\n");
image_print_info(image);
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_dump_dev(int fd, const char * file);
int disk_flash_dev(int fd, const char * file);
int disk_flash_dev(int fd, 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);
+226 -72
View File
@@ -34,10 +34,11 @@
#include "image.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_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_RETURN(fiasco, buf, size) do { if ( read(fiasco->fd, buf, size) != size ) return fiasco; } 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 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)
@@ -65,9 +66,16 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
char hwrevs[1024];
char version[257];
char layout[257];
uint8_t asicidx;
uint8_t devicetype;
uint8_t deviceidx;
uint8_t checksum;
uint32_t address;
uint16_t hash;
off_t offset;
struct image * image;
struct image_part * image_part;
struct image_part * image_parts;
char hwrev[9];
unsigned char buf[512];
@@ -120,23 +128,41 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
while ( 1 ) {
/* If end of file, return fiasco image */
READ_OR_RETURN(fiasco, buf, 7);
checksum = 0x00;
READ_OR_RETURN(fiasco, checksum, buf, 1);
/* Header of next image */
if ( ! ( buf[0] == 0x54 && buf[2] == 0x2E && buf[3] == 0x19 && buf[4] == 0x01 && buf[5] == 0x01 && buf[6] == 0x00 ) ) {
/* Header of next image (0x54) */
if ( buf[0] != 0x54 ) {
ERROR("Invalid next image header");
return fiasco;
}
count8 = buf[1];
if ( count8 > 0 )
--count8;
checksum = 0x00;
READ_OR_RETURN(fiasco, &hash, 2);
READ_OR_RETURN(fiasco, checksum, &count8, 1);
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);
memset(type, 0, sizeof(type));
READ_OR_RETURN(fiasco, type, 12);
READ_OR_RETURN(fiasco, checksum, type, 12);
byte = type[0];
if ( byte == 0xFF )
@@ -144,26 +170,35 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
VERBOSE(" %s\n", type);
READ_OR_RETURN(fiasco, &length, 4);
READ_OR_RETURN(fiasco, checksum, &length, 4);
length = ntohl(length);
/* unknown */
READ_OR_RETURN(fiasco, buf, 4);
/* load address (unused) */
READ_OR_RETURN(fiasco, checksum, &address, 4);
/* end of file data section */
--count8;
VERBOSE(" size: %d bytes\n", length);
VERBOSE(" hash: %#04x\n", hash);
VERBOSE(" address: 0x%04x\n", address);
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);
memset(device, 0, sizeof(device));
memset(hwrevs, 0, sizeof(hwrevs));
memset(version, 0, sizeof(version));
memset(layout, 0, sizeof(layout));
image_part = NULL;
image_parts = NULL;
while ( count8 > 0 ) {
READ_OR_RETURN(fiasco, &byte, 1);
READ_OR_RETURN(fiasco, &length8, 1);
READ_OR_RETURN(fiasco, buf, length8);
READ_OR_RETURN(fiasco, checksum, &byte, 1);
READ_OR_RETURN(fiasco, checksum, &length8, 1);
READ_OR_RETURN(fiasco, checksum, buf, length8);
VERBOSE(" subinfo\n");
VERBOSE(" length: %d\n", length8);
@@ -207,15 +242,55 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
memset(layout, 0, sizeof(layout));
strncpy(layout, (char *)buf, length8);
VERBOSE("layout\n");
} else if ( byte == '4' ) {
VERBOSE("data part\n");
if ( length8 < 16 ) {
VERBOSE(" (damaged)\n");
} else {
if ( image_parts ) {
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 {
VERBOSE("unknown ('%c':%#x)\n", byte, byte);
int i;
VERBOSE("unknown (%#x)\n", byte);
VERBOSE(" hexdump:");
for ( i = 0; i < length8; i++ ) VERBOSE(" 0x%02x", buf[i]);
VERBOSE("\n");
}
--count8;
}
/* unknown */
READ_OR_RETURN(fiasco, buf, 1);
/* checksum */
READ_OR_RETURN(fiasco, checksum, 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);
if ( offset == (off_t)-1 )
@@ -226,7 +301,7 @@ struct fiasco * fiasco_alloc_from_file(const char * file) {
VERBOSE(" hwrevs: %s\n", hwrevs);
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 = image_alloc_from_shared_fd(fiasco->fd, length, offset, hash, type, device, hwrevs, version, layout, image_parts);
if ( ! image )
FIASCO_READ_ERROR(fiasco, "Cannot allocate image");
@@ -274,10 +349,12 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
uint32_t length;
uint16_t hash;
uint8_t length8;
uint8_t checksum;
char ** device_hwrevs_bufs;
const char * str;
const char * type;
struct image_list * image_list;
struct image_part * image_part;
struct image * image;
unsigned char buf[4096];
@@ -375,32 +452,40 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
/* signature */
WRITE_OR_FAIL_FREE(file, fd, "T", 1, device_hwrevs_bufs);
checksum = 0x00;
/* number of subsections */
length8 = device_count+1;
length8 = device_count+2;
if ( image->version )
++length8;
if ( image->layout )
++length8;
WRITE_OR_FAIL_FREE(file, fd, &length8, 1, device_hwrevs_bufs);
CHECKSUM(checksum, &length8, 1);
/* unknown */
/* file data: asic index: APE (0x01), device type: NAND (0x01), device index: 0 */
WRITE_OR_FAIL_FREE(file, fd, "\x2e\x19\x01\x01\x00", 5, device_hwrevs_bufs);
CHECKSUM(checksum, "\x2e\x19\x01\x01\x00", 5);
/* checksum */
hash = htons(image->hash);
WRITE_OR_FAIL_FREE(file, fd, &hash, 2, device_hwrevs_bufs);
CHECKSUM(checksum, &hash, 2);
/* image type name */
memset(buf, 0, 12);
strncpy((char *)buf, type, 12);
WRITE_OR_FAIL_FREE(file, fd, buf, 12, device_hwrevs_bufs);
CHECKSUM(checksum, buf, 12);
/* image size */
size = htonl(image->size);
WRITE_OR_FAIL_FREE(file, fd, &size, 4, device_hwrevs_bufs);
CHECKSUM(checksum, &size, 4);
/* unknown */
/* image load address (unused always zero) */
WRITE_OR_FAIL_FREE(file, fd, "\x00\x00\x00\x00", 4, device_hwrevs_bufs);
CHECKSUM(checksum, "\x00\x00\x00\x00", 4);
/* append version subsection */
if ( image->version ) {
@@ -408,6 +493,9 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
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, image->version, length8, device_hwrevs_bufs);
CHECKSUM(checksum, "1", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, image->version, length8);
}
/* append device & hwrevs subsection */
@@ -416,6 +504,9 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
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, 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);
@@ -425,10 +516,47 @@ int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {
length8 = strlen(image->layout);
WRITE_OR_FAIL(file, fd, &length8, 1);
WRITE_OR_FAIL(file, fd, image->layout, length8);
CHECKSUM(checksum, "3", 1);
CHECKSUM(checksum, &length8, 1);
CHECKSUM(checksum, image->layout, length8);
}
/* dummy byte - end of all subsections */
WRITE_OR_FAIL(file, fd, "\x00", 1);
if ( image->parts ) {
/* for each image part append subsection */
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");
@@ -461,8 +589,10 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
char * name;
char * layout_name;
struct image * image;
struct image_part * image_part;
struct image_list * image_list;
uint32_t size;
uint32_t offset, size, need, total_size, written;
int part_num;
char cwd[256];
unsigned char buf[4096];
@@ -489,68 +619,30 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
while ( image_list ) {
fd = -1;
name = NULL;
layout_name = NULL;
image = image_list->image;
name = image_name_alloc_from_values(image);
if ( ! name )
return -1;
printf("\n");
printf("Unpacking image...\n");
image_print_info(image);
if ( image->layout ) {
layout_name = calloc(1, strlen(name) + sizeof(".layout")-1 + 1);
name = image_name_alloc_from_values(image, -1);
if ( ! name )
ALLOC_ERROR_RETURN(-1);
layout_name = calloc(1, strlen(name) + sizeof("_layout")-1 + 1);
if ( ! layout_name ) {
free(name);
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(" 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 ) {
fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644);
if ( fd < 0 ) {
@@ -571,11 +663,73 @@ int fiasco_unpack(struct fiasco * fiasco, const char * dir) {
free(layout_name);
if ( ! simulate )
if ( ! simulate ) {
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;
}
+1 -1
View File
@@ -22,7 +22,7 @@ extern int verbose;
#define ALLOC_ERROR() do { ERROR("Cannot allocate memory"); } while (0)
#define ALLOC_ERROR_RETURN(...) do { ALLOC_ERROR(); return __VA_ARGS__; } while (0)
#define SLEEP(usec) do { struct timespec _t = { 0, (usec) }; nanosleep(&_t, NULL); } while (0)
#define MSLEEP(msec) do { nanosleep(&(struct timespec){ (msec / 1000), (1000L * 1000L * (msec % 1000)) }, NULL); } while (0)
static inline void * MEMMEM(void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
for ( size_t i = 0; i < haystacklen; ++i ) {
+40 -8
View File
@@ -100,7 +100,7 @@ static void image_missing_values_from_name(struct image * image, const char * na
}
/* format: type-device:hwrevs_version */
char * image_name_alloc_from_values(struct image * image) {
char * image_name_alloc_from_values(struct image * image, int part_num) {
char * name;
char * ptr;
@@ -108,6 +108,8 @@ char * image_name_alloc_from_values(struct image * image) {
size_t length;
const char * type;
const char * device;
struct image_part * part;
int i;
type = image_type_to_string(image->type);
@@ -124,6 +126,14 @@ char * image_name_alloc_from_values(struct image * image) {
else
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);
if ( device )
@@ -132,6 +142,10 @@ char * image_name_alloc_from_values(struct image * image) {
length += 1 + strlen(hwrevs);
if ( 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);
if ( ! name ) {
@@ -149,13 +163,19 @@ char * image_name_alloc_from_values(struct image * image) {
if ( 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);
return name;
}
static int image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) {
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) {
enum image_type detected_type;
@@ -210,6 +230,8 @@ static int image_append(struct image * image, const char * type, const char * de
else
image->layout = NULL;
image->parts = parts;
return 0;
}
@@ -244,7 +266,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 * 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) {
int fd;
@@ -254,11 +276,11 @@ struct image * image_alloc_from_file(const char * file, const char * type, const
return NULL;
}
return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout);
return image_alloc_from_fd(fd, file, type, device, hwrevs, version, layout, 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_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) {
off_t offset;
struct image * image = image_alloc();
@@ -291,7 +313,7 @@ struct image * image_alloc_from_fd(int fd, const char * orig_filename, const cha
return NULL;
}
if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
return NULL;
if ( ( ! type || ! type[0] ) && ( ! device || ! device[0] ) && ( ! hwrevs || ! hwrevs[0] ) && ( ! version || ! version[0] ) )
@@ -303,7 +325,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 * 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 = image_alloc();
if ( ! image )
@@ -315,7 +337,7 @@ struct image * image_alloc_from_shared_fd(int fd, size_t size, size_t offset, ui
image->offset = offset;
image->cur = 0;
if ( image_append(image, type, device, hwrevs, version, layout) < 0 )
if ( image_append(image, type, device, hwrevs, version, layout, parts) < 0 )
return NULL;
if ( ! noverify && image->hash != hash ) {
@@ -347,6 +369,13 @@ void image_free(struct image * image) {
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->layout);
free(image->orig_filename);
@@ -516,6 +545,9 @@ static const char * image_types[] = {
[IMAGE_CMT_2ND] = "cmt-2nd",
[IMAGE_CMT_ALGO] = "cmt-algo",
[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) {
+15 -4
View File
@@ -37,9 +37,19 @@ enum image_type {
IMAGE_CMT_2ND,
IMAGE_CMT_ALGO,
IMAGE_CMT_MCUSW,
IMAGE_1ST,
IMAGE_CERT_SW,
IMAGE_APE_ALGO,
IMAGE_COUNT,
};
struct image_part {
struct image_part * next;
uint32_t offset;
uint32_t size;
char * name;
};
struct image {
enum image_type type;
struct device_list * devices;
@@ -47,6 +57,7 @@ struct image {
char * layout;
uint16_t hash;
uint32_t size;
struct image_part * parts;
int fd;
int is_shared_fd;
@@ -63,9 +74,9 @@ struct image_list {
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 * 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 * 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_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_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);
void image_free(struct image * image);
void image_seek(struct image * image, size_t whence);
size_t image_read(struct image * image, void * buf, size_t count);
@@ -76,7 +87,7 @@ void image_list_unlink(struct image_list * list);
uint16_t image_hash_from_data(struct image * image);
enum image_type image_type_from_data(struct image * image);
char * image_name_alloc_from_values(struct image * image);
char * image_name_alloc_from_values(struct image * image, int part_num);
enum image_type image_type_from_string(const char * type);
const char * image_type_to_string(enum image_type type);
int image_hwrev_is_valid(struct image * image, int16_t hwrev);
+275 -65
View File
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/statvfs.h>
#include <sys/types.h>
@@ -198,14 +199,6 @@ 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) {
struct statvfs buf;
@@ -227,15 +220,18 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
return 1;
}
size = snprintf(NULL, 0, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
size = snprintf(NULL, 0, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd);
command = malloc(size+1);
if ( ! command )
return 1;
snprintf(command, size+1, "nanddump -o -b -s %d -l %d -f %s /dev/mtd%dro", offset, length, file, mtd);
snprintf(command, size+1, "nanddump --omitoob -s %d -l %d -f %s /dev/mtd%d", offset, length, file, mtd);
ret = system(command);
if ( ! simulate )
ret = system(command);
else
ret = 0;
free(command);
@@ -243,52 +239,77 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
}
struct nanddump_args {
int valid;
int mtd;
int offset;
int length;
static FILE * local_nandwrite(int mtd, int offset) {
char * command;
FILE * stream;
size_t size;
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 nanddump_args nanddump_rx51[] = {
[IMAGE_XLOADER] = { 1, 0, 0x00000000, 0x00004000 },
[IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 1, 3, 0x00000800, 0x001FF800 },
[IMAGE_INITFS] = { 1, 4, 0x00000000, 0x00200000 },
[IMAGE_ROOTFS] = { 1, 5, 0x00000000, 0x0fb40000 },
static struct nandpart_args nandpart_rx51[] = {
[IMAGE_XLOADER] = { 0, 0x00000000, 0x00004000, 0x00000000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
[IMAGE_KERNEL] = { 3, 0x00000000, 0x00200000, 0x00000800 },
[IMAGE_INITFS] = { 4, 0x00000000, 0x00200000, 0x00000000 },
[IMAGE_ROOTFS] = { 5, 0x00000000, 0x0fb40000, 0x00000000 },
};
/* FIXME: Is this table correct? */
static struct nanddump_args nanddump_rx4x[] = {
[IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
[IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x0021F800 },
[IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00400000 },
[IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0f960000 },
static struct nandpart_args nandpart_rx4x[] = {
[IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
[IMAGE_KERNEL] = { 2, 0x00000000, 0x00220000, 0x00000800 },
[IMAGE_INITFS] = { 3, 0x00000000, 0x00400000, 0x00000000 },
[IMAGE_ROOTFS] = { 4, 0x00000000, 0x0f960000, 0x00000000 },
};
/* FIXME: Is this table correct? */
static struct nanddump_args nanddump_old[] = {
[IMAGE_XLOADER] = { 1, 0, 0x00000200, 0x00003E00 },
[IMAGE_SECONDARY] = { 1, 0, 0x00004000, 0x0001C000 },
[IMAGE_KERNEL] = { 1, 2, 0x00000800, 0x001FF800 },
[IMAGE_INITFS] = { 1, 3, 0x00000000, 0x00200000 },
[IMAGE_ROOTFS] = { 1, 4, 0x00000000, 0x0fb80000 },
static struct nandpart_args nandpart_old[] = {
[IMAGE_XLOADER] = { 0, 0x00000200, 0x00003E00, 0x00000000 },
[IMAGE_SECONDARY] = { 0, 0x00004000, 0x0001C000, 0x00000000 },
[IMAGE_KERNEL] = { 2, 0x00000000, 0x00200000, 0x00000800 },
[IMAGE_INITFS] = { 3, 0x00000000, 0x00200000, 0x00000000 },
[IMAGE_ROOTFS] = { 4, 0x00000000, 0x0fb80000, 0x00000000 },
};
struct nanddump_device {
struct nand_device {
size_t count;
struct nanddump_args * args;
struct nandpart_args * args;
};
#define NANDDUMP(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
#define NAND_DEVICE(device, array) [device] = { .count = sizeof(array)/sizeof(array[0]), .args = array }
static struct nanddump_device nanddump[] = {
NANDDUMP(DEVICE_SU_18, nanddump_old),
NANDDUMP(DEVICE_RX_34, nanddump_old),
NANDDUMP(DEVICE_RX_44, nanddump_rx4x),
NANDDUMP(DEVICE_RX_48, nanddump_rx4x),
NANDDUMP(DEVICE_RX_51, nanddump_rx51),
static struct nand_device nand_device[] = {
NAND_DEVICE(DEVICE_SU_18, nandpart_old),
NAND_DEVICE(DEVICE_RX_34, nandpart_old),
NAND_DEVICE(DEVICE_RX_44, nandpart_rx4x),
NAND_DEVICE(DEVICE_RX_48, nandpart_rx4x),
NAND_DEVICE(DEVICE_RX_51, nandpart_rx51),
};
#undef NANDDUMP
@@ -380,10 +401,13 @@ static void local_find_internal_mydocs(int * maj, int * min) {
int local_dump_image(enum image_type image, const char * file) {
unsigned char buf[20];
int ret = -1;
int fd = -1;
int header = 0;
unsigned char * addr = NULL;
off_t nlen, len;
off_t nlen = (off_t)-1;
off_t len;
int align;
int maj, min;
@@ -415,17 +439,49 @@ int local_dump_image(enum image_type image, const char * file) {
} else {
if ( device >= sizeof(nanddump)/sizeof(nanddump[0]) ) {
if ( device >= sizeof(nand_device)/sizeof(nand_device[0]) ) {
ERROR("Unsupported device");
goto clean;
}
if ( image >= nanddump[device].count ) {
if ( image >= nand_device[device].count ) {
ERROR("Unsupported image type: %s", image_type_to_string(image));
goto clean;
}
ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset, nanddump[device].args[image].length);
header = nand_device[device].args[image].header;
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);
}
@@ -434,6 +490,9 @@ int local_dump_image(enum image_type image, const char * file) {
goto clean;
}
if ( simulate )
goto clean;
fd = open(file, O_RDWR);
if ( fd < 0 )
goto clean;
@@ -442,31 +501,35 @@ int local_dump_image(enum image_type image, const char * file) {
if ( len == (off_t)-1 || len == 0 )
goto clean;
addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
if ( header <= 0 || nlen == (off_t)-1 ) {
if ( addr == MAP_FAILED )
addr = NULL;
addr = (unsigned char *)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
if ( ! addr )
goto clean;
if ( addr == MAP_FAILED )
addr = NULL;
for ( nlen = len; nlen > 0; --nlen )
if ( addr[nlen-1] != 0xFF )
break;
if ( ! addr )
goto clean;
for ( ; nlen > 0; --nlen )
if ( addr[nlen-1] != 0x00 )
break;
for ( nlen = len; nlen > 0; --nlen )
if ( addr[nlen-1] != 0xFF )
break;
if ( image == IMAGE_MMC )
align = 8;
else
align = 7;
for ( ; nlen > 0; --nlen )
if ( addr[nlen-1] != 0x00 )
break;
if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
nlen = ((nlen >> align) + 1) << align;
if ( image == IMAGE_MMC )
align = 8;
else
align = 7;
if ( nlen == 0 ) {
if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
nlen = ((nlen >> align) + 1) << align;
}
if ( header <= 0 && nlen == 0 ) {
printf("File %s is empty, removing it...\n", file);
unlink(file);
} else if ( nlen != len ) {
@@ -487,6 +550,153 @@ 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) {
ERROR("Not implemented yet");
+56 -18
View File
@@ -143,7 +143,7 @@ int simulate;
int noverify;
int verbose;
/* arg = [[[dev:[hw:]]ver:]type:]file[%%lay] */
/* arg = [[[dev:[hw:]]ver:]type:]file[%file2%file3...%lay] */
static void parse_image_arg(char * arg, struct image_list ** image_first) {
struct stat st;
@@ -154,14 +154,16 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
char * hwrevs;
char * version;
char * layout;
char * parts;
char * layout_file;
char * ptr;
int fd;
/* First check if arg is file, then try to parse arg format */
fd = open(arg, O_RDONLY);
if ( fd >= 0 ) {
if ( fstat(fd, &st) == 0 && !S_ISDIR(st.st_mode) ) {
image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL);
image = image_alloc_from_fd(fd, arg, NULL, NULL, NULL, NULL, NULL, NULL);
if ( ! image ) {
ERROR("Cannot load image file %s", arg);
exit(1);
@@ -175,9 +177,15 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
exit(1);
}
layout_file = strchr(arg, '%');
if ( layout_file )
*(layout_file++) = 0;
parts = strchr(arg, '%');
if ( parts )
*(parts++) = 0;
layout_file = parts;
if ( layout_file ) {
while ( ( ptr = strchr(layout_file, '%') ) )
layout_file = ptr+1;
}
type = NULL;
device = NULL;
@@ -237,7 +245,9 @@ static void parse_image_arg(char * arg, struct image_list ** image_first) {
close(fd);
}
image = image_alloc_from_file(file, type, device, hwrevs, version, layout);
/* TODO: alloc parts */
image = image_alloc_from_file(file, type, device, hwrevs, version, layout, NULL);
if ( layout )
free(layout);
@@ -421,9 +431,13 @@ int main(int argc, char **argv) {
enum device detected_device = DEVICE_UNKNOWN;
int16_t detected_hwrev = -1;
struct stat st;
int i;
char buf[512];
char * ptr = NULL;
char * ptr1 = NULL;
char * ptr2 = NULL;
char * tmp = NULL;
char nolo_ver[512];
@@ -1034,9 +1048,9 @@ int main(int argc, char **argv) {
/* filter images by device & hwrev */
if ( detected_device )
filter_images_by_device(dev->detected_device, &image_first);
if ( detected_hwrev )
if ( detected_hwrev > 0 )
filter_images_by_hwrev(dev->detected_hwrev, &image_first);
if ( fiasco_in && ( detected_device || detected_hwrev ) )
if ( fiasco_in && ( detected_device || detected_hwrev > 0 ) )
fiasco_in->first = image_first;
/* set kernel and initfs images for loading */
@@ -1094,7 +1108,7 @@ int main(int argc, char **argv) {
if ( dev_load ) {
if ( image_kernel ) {
ret = dev_load_image(dev, image_kernel->image);
if ( ret < 0 )
if ( ret == -EAGAIN )
goto again;
if ( image_kernel == image_first )
@@ -1108,7 +1122,7 @@ int main(int argc, char **argv) {
if ( image_initfs ) {
ret = dev_load_image(dev, image_initfs->image);
if ( ret < 0 )
if ( ret == -EAGAIN )
goto again;
if ( image_initfs == image_first )
@@ -1127,7 +1141,7 @@ int main(int argc, char **argv) {
while ( image_ptr ) {
struct image_list * next = image_ptr->next;
ret = dev_flash_image(dev, image_ptr->image);
if ( ret < 0 )
if ( ret == -EAGAIN )
goto again;
if ( image_ptr == image_first )
@@ -1259,11 +1273,12 @@ int main(int argc, char **argv) {
for ( i = 0; i < IMAGE_COUNT; ++i ) {
if ( ! image_tmp_name(i) )
if ( ! image_tmp_name(i) || ( stat(image_tmp_name(i), &st) < 0 && errno == ENOENT ) )
continue;
buf[0] = 0;
snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
if ( dev->detected_hwrev > 0 )
snprintf(buf, sizeof(buf), "%hd", dev->detected_hwrev);
switch ( i ) {
case IMAGE_2ND:
@@ -1293,7 +1308,9 @@ int main(int argc, char **argv) {
break;
}
image_dump = image_alloc_from_file(image_tmp_name(i), image_type_to_string(i), device_to_string(dev->detected_device), buf, ptr, NULL);
/* 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, NULL);
if ( ! image_dump )
continue;
@@ -1364,7 +1381,20 @@ int main(int argc, char **argv) {
}
buf[0] = 0;
snprintf(buf, sizeof(buf), "%s-%s:%hd_%s", image_type_to_string(i), device_to_string(dev->detected_device), dev->detected_hwrev, ptr);
snprintf(buf, sizeof(buf), "%s", image_type_to_string(i));
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_errno = errno;
@@ -1379,13 +1409,21 @@ int main(int argc, char **argv) {
errno = rename_errno;
ERROR_INFO("Renaming failed");
buf[0] = 0;
snprintf(buf, sizeof(buf), "%s-%s_%s", image_type_to_string(i), device_to_string(dev->detected_device), ptr);
*ptr2 = 0;
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 ) {
ERROR_INFO("Renaming failed");
*ptr1 = 0;
printf("Trying to rename %s image file to %s...\n", image_type_to_string(i), buf);
if ( rename(image_tmp_name(i), buf) < 0 )
ERROR_INFO("Renaming failed");
}
}
}
+16 -7
View File
@@ -213,14 +213,18 @@ int mkii_flash_image(struct usb_device_info * dev, struct image * image) {
msg1 = (struct mkii_message *)buf1;
ptr = msg->data;
/* Signature */
memcpy(ptr, "\x2E\x19\x01\x01", 4);
ptr += 4;
/* Space */
memcpy(ptr, "\x00", 1);
/* File data header */
memcpy(ptr, "\x2E", 1);
ptr += 1;
/* Length of file data */
memcpy(ptr, "\x19", 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 = htons(image->hash);
memcpy(ptr, &hash, 2);
@@ -239,7 +243,7 @@ int mkii_flash_image(struct usb_device_info * dev, struct image * image) {
memcpy(ptr, &size, 4);
ptr += 4;
/* Space */
/* Load address (ignored) */
memcpy(ptr, "\x00\x00\x00\x00", 4);
ptr += 4;
@@ -361,6 +365,11 @@ int mkii_reboot_device(struct usb_device_info * dev, int update) {
if ( ret != 1 || msg->data[0] != 0 )
ERROR_RETURN("Cannot send reboot command", -1);
if (dev->data & MKII_UPDATE_MODE)
MSLEEP(100);
else
MSLEEP(3000);
return 0;
}
+12 -8
View File
@@ -269,14 +269,18 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
ptr = buf;
/* Signature */
memcpy(ptr, "\x2E\x19\x01\x01", 4);
ptr += 4;
/* Space */
memcpy(ptr, "\x00", 1);
/* File data header */
memcpy(ptr, "\x2E", 1);
ptr += 1;
/* Length of file data */
memcpy(ptr, "\x19", 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 = htons(image->hash);
memcpy(ptr, &hash, 2);
@@ -295,7 +299,7 @@ static int nolo_send_image(struct usb_device_info * dev, struct image * image, i
memcpy(ptr, &size, 4);
ptr += 4;
/* Space */
/* Load address (ignored by NOLO) */
memcpy(ptr, "\x00\x00\x00\x00", 4);
ptr += 4;
@@ -541,7 +545,7 @@ int nolo_flash_image(struct usb_device_info * dev, struct image * image) {
}
SLEEP(0xc350); // 0.5s
MSLEEP(50);
}
+39 -30
View File
@@ -46,16 +46,21 @@
#endif
static struct usb_flash_device usb_devices[] = {
{ 0x0421, 0x0096, -1, -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, 0x0106, 0, -1, -1, FLASH_COLD, { DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0189, -1, -1, -1, FLASH_DISK, { DEVICE_RX_48, 0 } },
{ 0x0421, 0x01c7, -1, -1, -1, FLASH_DISK, { DEVICE_RX_51, 0 } },
{ 0x0421, 0x01c8, 1, 1, -1, FLASH_MKII, { DEVICE_RX_51, DEVICE_RM_680, 0 } },
{ 0x0421, 0x03d1, -1, -1, -1, FLASH_DISK, { DEVICE_RM_680, 0 } },
{ 0x0421, 0x0431, -1, -1, -1, FLASH_DISK, { DEVICE_SU_18, DEVICE_RX_34, 0 } },
{ 0x0421, 0x04c3, -1, -1, -1, FLASH_DISK, { DEVICE_RX_34, 0 } },
{ 0x0421, 0x3f00, 2, 1, -1, FLASH_NOLO, { DEVICE_RX_34, 0 } },
/* vend prod i a protocol devices */
{ 0x0421, 0x0096, -1, -1, FLASH_DISK, { DEVICE_RX_44, 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, 0, FLASH_COLD, { DEVICE_RX_51, DEVICE_RM_680, DEVICE_RM_696, 0 } },
{ 0x0421, 0x0189, -1, -1, FLASH_DISK, { DEVICE_RX_48, 0 } },
{ 0x0421, 0x01c7, -1, -1, FLASH_DISK, { DEVICE_RX_51, 0 } },
{ 0x0421, 0x01c8, 1, 1, FLASH_MKII, { DEVICE_RX_51, DEVICE_RM_680, 0 } },
{ 0x0421, 0x01c8, 1, 0, FLASH_UNKN, { DEVICE_RX_51, 0 } }, /* U-Boot mode (TTY via USB) */
{ 0x0421, 0x03d1, -1, -1, FLASH_DISK, { DEVICE_RM_680, 0 } },
{ 0x0421, 0x03d2, 1, 1, FLASH_MKII, { DEVICE_RM_680, 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[] = {
@@ -134,7 +139,7 @@ static void usb_descriptor_info_print(usb_dev_handle * udev, struct usb_device *
buf[0] = 0;
for ( i = 0; i < ret; i+=2 ) {
sscanf(buf+i, "%2x", &x);
if ( x > 32 && x < 128 )
if ( x > 31 && x < 127 )
buf2[i/2] = x;
else {
buf2[0] = 0;
@@ -150,14 +155,29 @@ 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) {
int i;
size_t i;
char product[1024];
struct usb_device_info * ret = NULL;
for ( i = 0; usb_devices[i].vendor; ++i ) {
for ( i = 0; i < sizeof(usb_devices)/sizeof(usb_devices[0]); ++i ) {
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_END();
PRINTF_ADD("Found ");
@@ -195,18 +215,7 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
if ( usb_devices[i].alternate >= 0 ) {
PRINTF_LINE("Setting alternate USB interface...");
if ( usb_set_altinterface(udev, usb_devices[i].alternate) < 0 ) {
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");
PRINTF_ERROR("usb_set_altinterface failed");
fprintf(stderr, "\n");
usb_reattach_kernel_driver(udev, usb_devices[i].interface);
usb_close(udev);
@@ -230,13 +239,13 @@ static struct usb_device_info * usb_device_is_valid(struct usb_device * dev) {
ret->device = DEVICE_RX_44;
else if ( strcmp(product, "Nokia N810 Internet Tablet WiMAX Edition") == 0 || strcmp(product, "Nokia-RX48 (Update mode)") == 0 )
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 )
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 )
ret->device = DEVICE_RX_51;
else if ( strcmp(product, "Nokia N950") == 0 || strcmp(product, "Sync Mode") == 0 || strcmp(product, "N950 (Update mode)") == 0 )
else if ( strcmp(product, "Nokia N950") == 0 || strcmp(product, "N950 (Update mode)") == 0 )
ret->device = DEVICE_RM_680;
else if ( strcmp(product, "N9 (Update mode)") == 0 || strcmp(product, "Nxy (Update mode)") == 0 )
else if ( strcmp(product, "Nokia N9") == 0 || strcmp(product, "N9 (Update mode)") == 0 || strcmp(product, "Nokia N9 RNDIS/Ethernet") == 0 )
ret->device = DEVICE_RM_696;
else if ( strcmp(product, "Nokia USB ROM") == 0 )
else if ( strcmp(product, "Nokia USB ROM") == 0 || strcmp(product, "Sync Mode") == 0 || strcmp(product, "Nxy (Update mode)") == 0 )
ret->device = DEVICE_ANY;
else
ret->device = DEVICE_UNKNOWN;
@@ -361,7 +370,7 @@ struct usb_device_info * usb_open_and_wait_for_device(void) {
if ( ret )
break;
SLEEP(0xc350); // 0.5s
MSLEEP(50);
}
-1
View File
@@ -49,7 +49,6 @@ struct usb_flash_device {
uint16_t product;
int interface;
int alternate;
int configuration;
enum usb_flash_protocol protocol;
enum device devices[DEVICE_COUNT];
};