diff options
author | Pali Rohár <pali.rohar@gmail.com> | 2012-08-07 14:00:50 +0200 |
---|---|---|
committer | Pali Rohár <pali.rohar@gmail.com> | 2012-08-07 14:00:50 +0200 |
commit | 48fc14c9130e40ccd0e64acd8183c6803541270b (patch) | |
tree | 37172a402695b48a6198e9455f4f3441ce40c94d /src | |
parent | 37f5d069739fdc1d7db9eb7caac816cae0d69b9c (diff) | |
download | 0xFFFF-48fc14c9130e40ccd0e64acd8183c6803541270b.tar.bz2 |
Implement image functions
Diffstat (limited to 'src')
-rw-r--r-- | src/image.c | 128 | ||||
-rw-r--r-- | src/image.h | 20 |
2 files changed, 132 insertions, 16 deletions
diff --git a/src/image.c b/src/image.c index a99eb73..9f53640 100644 --- a/src/image.c +++ b/src/image.c @@ -1,17 +1,21 @@ +#include "image.h" + #define IMAGE_CHECK(image) do { if ( ! image || image->fd < 0 ) return; } while (0) #define IMAGE_STORE_CUR(image) do { if ( shared_fd ) image->cur = lseek(image->fd, 0, SEEK_CUR) - image->offset; } while (0) #define IMAGE_RESTORE_CUR(image) do { if ( shared_fd ) lseek(image->fd, image->offset + image->cur, SEEK_SET); } while (0) -static void image_append(struct image * image, enum image_type type, enum device device, const char * hwrevs, const char * version, const char * layout) { +static void image_append(struct image * image, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) { + + IMAGE_CHECK(image); - image->hash = image_hash(image); - image->device = device; + image->hash = image_hash_from_data(image); + image->device = device_from_string(device); if ( type ) - image->type = type; + image->type = image_type_from_string(type); else - image->type = image_type(image); + image->type = image_type_from_data(image); if ( hwrevs ) image->hwrevs = strdup(hwrevs); @@ -58,19 +62,26 @@ struct image * image_alloc_from_file(const char * file, const char * type, const } -struct image * image_alloc_from_fiasco(struct image * image, int fd, size_t size, size_t offset, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout) { +struct image * image_alloc_from_fiasco(struct fiasco * fiasco, 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(); if ( ! image ) return NULL; image->shared_fd = 1; - image->fd = fd; + image->fd = fiasco->fd; image->size = size; image->offset = offset; image->cur = 0; image_append(image, type, device, hwrevs, version, layout); + + if ( image->hash != hash ) { + fprintf(stderr, "Image hash mishmash"); + image_free(image); + return NULL; + } + return image; } @@ -79,13 +90,11 @@ void image_free(struct image * image) { IMAGE_CHECK(image); - if ( image->shared_fd ) { + if ( ! image->shared_fd ) { close(image->fd); image->fd = -1; } - free(image->type); - free(image->device); free(image->hwrevs); free(image->version); free(image->layout); @@ -107,8 +116,11 @@ size_t image_read(struct image * image, void * buf, size_t count) { IMAGE_CHECK(image); IMAGE_RESTORE_CUR(image); - if ( image->cur + count > image->size ) + if ( image->cur + count > image->size ) { + if ( image->size < image->cur ) + return 0; count = image->size - image->cur; + } count = read(image->fd, buf, count); @@ -117,7 +129,7 @@ size_t image_read(struct image * image, void * buf, size_t count) { } -size_t image_write(struct image * image, void * buf, size_t count) { +/*size_t image_write(struct image * image, void * buf, size_t count) { IMAGE_CHECK(image); IMAGE_RESTORE_CUR(image); @@ -125,11 +137,12 @@ size_t image_write(struct image * image, void * buf, size_t count) { IMAGE_STORE_CUR(image); return count; -} +}*/ void image_list_add(struct image_list ** list, struct image * image) { + IMAGE_CHECK(image); struct image_list * first = calloc(1, sizeof(struct image_list)); if ( ! next ) return; @@ -163,3 +176,92 @@ void image_list_del(struct image_list * list) { free(list); } + + +uint16_t image_hash_from_data(struct image * image) { + + /* TODO */ + +} + +static const char * image_types[] = { + [IMAGE_XLOADER] = "xloader", + [IMAGE_2ND] = "2nd", + [IMAGE_SECONDARY] = "secondary", + [IMAGE_KERNEL] = "kernel", + [IMAGE_INITFS] = "initfs", + [IMAGE_ROOTFS] = "rootfs", + [IMAGE_OMAP_NAND] = "omap-nand", + [IMAGE_MMC] = "mmc", + [IMAGE_CMT_2ND] = "cmt-2nd", + [IMAGE_CMT_ALGO] = "cmt-algo", + [IMAGE_CMT_MCUSW] = "cmt-mcusw", +}; + +enum image_type image_type_from_data(struct image * image) { + + IMAGE_CHECK(image); + unsigned char buf[512]; + + image_seek(image, 0); + image_read(image, buf, sizeof(buf)); + + // 2nd : +0x34 = 2NDAPE + // secondary: +0x04 = NOLOScnd + // x-loader : +0x14 = X-LOADER + // xloader8 : +0x0c = NOLOXldr + // kernel : +0x00 = 0000 a0e1 0000 a0e1 + // initfs : <2M...be sure with 3M 0x300000 + + if ( memcmp(buf+0x34, "2NDAPE", 6) == 0 ) + return IMAGE_2ND; + else if ( memcmp(buf+0x04, "NOLOScnd", 8) == 0 ) + return IMAGE_SECONDARY; + else if ( memcmp(buf+0x14, "X-LOADER", 8) == 0 ) + return IMAGE_XLOADER; + else if ( memcmp(buf+0x0c, "NOLOXldr", 8) == 0 ) + return IMAGE_XLOADER; + else if ( memcmp(buf+4, "NOLOXldr", 8) == 0 ) + // TODO: this is xloader800, not valid on 770? + return IMAGE_2ND; + else if ( memcmp(buf, "\x00\x00\xa0\xe1\x00\x00\xa0\xe1", 8) == 0 ) + return IMAGE_KERNEL; + else if ( memcmp(buf, "\x21\x01\x01", 3) == 0 ) + return IMAGE_KERNEL; + else if ( memcmp(b+0x00, "\x85\x19", 2) == 0 ) { + // JFFS2 MAGIC + if ( image->size < 0x300000 ) + return IMAGE_INITFS; + else + return IMAGE_ROOTFS; + } + + /* TODO: Add support for UBIFS rootfs and other types */ + + return IMAGE_UNKNOWN; + +} + +enum image_type image_type_from_string(const char * type) { + + size_t i; + + if ( ! type ) + return IMAGE_UNKNOWN; + + for ( i = 0; i < sizeof(image_types)/sizeof(image_types[0]); ++i ) + if ( image_types[i] && strcmp(image_types[i], type) == 0 ) + return i; + + return IMAGE_UNKNOWN; + +} + +const char * image_type_to_string(enum image_type type) { + + if ( type > sizeof(image_types) ) + return NULL; + + return image_types[type]; + +} diff --git a/src/image.h b/src/image.h index 60bcd58..24b29dc 100644 --- a/src/image.h +++ b/src/image.h @@ -1,4 +1,10 @@ + +#ifndef IMAGE_H +#define IMAGE_H + +#include <stdint.h> + enum image_type { IMAGE_UNKNOWN = 0, IMAGE_XLOADER, @@ -7,7 +13,7 @@ enum image_type { IMAGE_KERNEL, IMAGE_INITFS, IMAGE_ROOTFS, - IMAGE_OMAPNAND, + IMAGE_OMAP_NAND, IMAGE_MMC, IMAGE_CMT_2ND, IMAGE_CMT_ALGO, @@ -16,6 +22,7 @@ enum image_type { enum device { DEVICE_UNKNOWN = 0, + DEVICE_ANY, /* Unspecified / Any device */ DEVICE_SU_18, /* Nokia 770 */ DEVICE_RX_34, /* Nokia N800 */ DEVICE_RX_44, /* Nokia N810 */ @@ -45,10 +52,17 @@ struct image_list { } 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_fiasco(struct image * image, int fd, size_t size, size_t offset, const char * type, const char * device, const char * hwrevs, const char * version, const char * layout); +struct image * image_alloc_from_fiasco(struct fiasco * fiasco, 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_seek(struct image * image, whence); size_t image_read(struct image * image, void * buf, size_t count); -size_t image_write(struct image * image, void * buf, size_t count); +/*size_t image_write(struct image * image, void * buf, size_t count);*/ void image_list_add(struct image_list ** list, struct image * image); void image_list_del(struct image_list * list); + +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_string(const char * type); +const char * image_type_to_string(enum image_type type); + +#endif |