summaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2012-08-07 14:00:50 +0200
committerPali Rohár <pali.rohar@gmail.com>2012-08-07 14:00:50 +0200
commit48fc14c9130e40ccd0e64acd8183c6803541270b (patch)
tree37172a402695b48a6198e9455f4f3441ce40c94d /src/image.c
parent37f5d069739fdc1d7db9eb7caac816cae0d69b9c (diff)
download0xFFFF-48fc14c9130e40ccd0e64acd8183c6803541270b.tar.bz2
Implement image functions
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c128
1 files changed, 115 insertions, 13 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];
+
+}