From 8ce96b74e121a9eb786fb4f6a24e1206ebbf035d Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Thu, 27 Mar 2014 23:39:08 -0300 Subject: [PATCH] Load kernel and initrd into an existing image. This allows us to replace both kernel and initrd from an existing image and keep its command line, atags, and load addresses, just changing the kernel and initrd sizes. Signed-off-by: Thadeu Lima de Souza Cascardo --- bootimg.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/bootimg.c b/bootimg.c index b015c10..cacd658 100644 --- a/bootimg.c +++ b/bootimg.c @@ -105,14 +105,20 @@ static int load(int fd, size_t *len, int pgsz, char *fname) int main(int argc, char **argv) { int fd; - uint32_t kernel, initrd, second, pgsz; + uint32_t *kernel, *initrd, *second, pgsz; char buffer[4096]; char *p; int r; off_t offset; + int is_load; if (argc < 2) return 1; - fd = open(argv[1], O_RDONLY); + if (argc > 2) + is_load = 1; + if (is_load) + fd = open(argv[1], O_RDWR); + else + fd = open(argv[1], O_RDONLY); if (fd < 0) { return 2; } @@ -123,27 +129,40 @@ int main(int argc, char **argv) if (strncmp(buffer, "ANDROID!", 8)) { return 4; } - kernel = *(uint32_t *) p; + kernel = (uint32_t *) p; p += 8; - initrd = *(uint32_t *) p; + initrd = (uint32_t *) p; p += 8; - second = *(uint32_t *) p; + second = (uint32_t *) p; p += 12; pgsz = *(uint32_t *) p; offset = pgsz; - if (kernel > 0) { + if (!is_load && *kernel > 0) { + lseek(fd, offset, SEEK_SET); + dump(fd, *kernel, pgsz, "kernel"); + } else { lseek(fd, offset, SEEK_SET); - dump(fd, kernel, pgsz, "kernel"); + load(fd, kernel, pgsz, "kernel"); } - offset += ((kernel + pgsz - 1) / pgsz) * pgsz; - if (initrd > 0) { + offset += ((*kernel + pgsz - 1) / pgsz) * pgsz; + if (!is_load && *initrd > 0) { lseek(fd, offset, SEEK_SET); - dump(fd, initrd, pgsz, "initrd"); + dump(fd, *initrd, pgsz, "initrd"); + } else { + lseek(fd, offset, SEEK_SET); + load(fd, initrd, pgsz, "initrd"); } - offset += ((initrd + pgsz - 1) / pgsz) * pgsz; - if (second > 0) { + offset += ((*initrd + pgsz - 1) / pgsz) * pgsz; + if (!is_load && *second > 0) { lseek(fd, offset, SEEK_SET); - dump(fd, second, pgsz, "second"); + dump(fd, *second, pgsz, "second"); + } else { + /* For now, don't care about using second. */ + /* The header must be written back, and we may need to + * truncate the file. */ + ftruncate(fd, offset); + lseek(fd, 0, SEEK_SET); + write(fd, buffer, pgsz); } close(fd); return 0; -- 2.20.1