summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2021-05-01 18:20:13 +0200
committerPali Rohár <pali.rohar@gmail.com>2021-05-01 18:20:13 +0200
commit342dc610b3008fe8d090a0abd587307a8c9f9880 (patch)
treea1e3563986c068d2e46cd862a5360a29f6583cd7
parent67427daf172ffbec429830ee97410c53095086d5 (diff)
download0xFFFF-342dc610b3008fe8d090a0abd587307a8c9f9880.tar.bz2
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.
-rw-r--r--src/local.c100
1 files changed, 64 insertions, 36 deletions
diff --git a/src/local.c b/src/local.c
index f9da146..b272aa0 100644
--- a/src/local.c
+++ b/src/local.c
@@ -244,36 +244,36 @@ static int local_nanddump(const char * file, int mtd, int offset, int length) {
}
struct nanddump_args {
- int valid;
int mtd;
int offset;
int length;
+ 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 },
+ [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 },
+ [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 },
+ [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 {
@@ -380,10 +380,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;
@@ -425,7 +428,28 @@ int local_dump_image(enum image_type image, const char * file) {
goto clean;
}
- ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset, nanddump[device].args[image].length);
+ header = nanddump[device].args[image].header;
+
+ if ( header > 0 ) {
+
+ ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset, header);
+ if ( ret != 0 ) {
+ unlink(file);
+ ret = -1;
+ goto clean;
+ }
+
+ fd = open(file, O_RDONLY);
+ if ( fd >= 0 ) {
+ if ( read(fd, buf, 20) == 20 && memcmp(buf, "NOLO!img\x02\x00\x00\x00\x00\x00\x00\x00", 16) == 0 )
+ nlen = (buf[16] << 0) | (buf[17] << 8) | (buf[18] << 16) | (buf[19] << 24);
+ close(fd);
+ }
+
+ unlink(file);
+ }
+
+ ret = local_nanddump(file, nanddump[device].args[image].mtd, nanddump[device].args[image].offset + header, nanddump[device].args[image].length - header);
}
@@ -442,31 +466,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 ( image == IMAGE_MMC )
+ align = 8;
+ else
+ align = 7;
- if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
- nlen = ((nlen >> align) + 1) << align;
+ if ( ( nlen & ( ( 1ULL << align ) - 1 ) ) != 0 )
+ nlen = ((nlen >> align) + 1) << align;
+
+ }
- if ( nlen == 0 ) {
+ if ( header <= 0 && nlen == 0 ) {
printf("File %s is empty, removing it...\n", file);
unlink(file);
} else if ( nlen != len ) {