Implement image functions

This commit is contained in:
Pali Rohár committed 2012-08-07 14:00:50 +02:00
1 parent 37f5d06973
commit 48fc14c913
2 files changed
+132 -16

No files matched your search

+115 -13
View File
@@ -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->hash = image_hash(image);
image->device = device;
IMAGE_CHECK(image);
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];
}
+17 -3
View File
@@ -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