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 <cascardo@cascardo.eti.br>
int main(int argc, char **argv)
{
int fd;
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;
char buffer[4096];
char *p;
int r;
off_t offset;
- 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;
}
if (fd < 0) {
return 2;
}
if (strncmp(buffer, "ANDROID!", 8)) {
return 4;
}
if (strncmp(buffer, "ANDROID!", 8)) {
return 4;
}
- kernel = *(uint32_t *) p;
+ kernel = (uint32_t *) p;
- initrd = *(uint32_t *) p;
+ initrd = (uint32_t *) p;
- second = *(uint32_t *) p;
+ second = (uint32_t *) p;
p += 12;
pgsz = *(uint32_t *) p;
offset = pgsz;
p += 12;
pgsz = *(uint32_t *) p;
offset = pgsz;
+ if (!is_load && *kernel > 0) {
+ lseek(fd, offset, SEEK_SET);
+ dump(fd, *kernel, pgsz, "kernel");
+ } else {
lseek(fd, offset, SEEK_SET);
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);
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);
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);