diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c index be950f00a..78a14a378 100644 --- a/arch/arm/lib/armlinux.c +++ b/arch/arm/lib/armlinux.c @@ -67,10 +67,10 @@ static struct tag *params; #endif -int do_bootm_linux(image_header_t *os_header, image_header_t *initrd) +int do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd) { - ulong initrd_start, initrd_end; void (*theKernel)(int zero, int arch, uint params); + image_header_t *os_header = &os_handle->header; #ifdef CONFIG_CMDLINE_TAG const char *commandline = getenv ("bootargs"); #endif @@ -78,7 +78,9 @@ int do_bootm_linux(image_header_t *os_header, image_header_t *initrd) printf("Multifile images not handled at the moment\n"); return -1; } -printf("os header: 0x%p ep: %\n", os_header, os_header + 1); + + printf("commandline: %s\n", commandline); + theKernel = (void (*)(int, int, uint))ntohl((unsigned long)(os_header->ih_ep)); debug ("## Transferring control to Linux (at address %08lx) ...\n", @@ -113,7 +115,7 @@ printf("os header: 0x%p ep: %\n", os_header, os_header + 1); #endif setup_end_tag (); #endif - if (relocate_image(os_header, (void *)ntohl(os_header->ih_load))) + if (relocate_image(os_handle, (void *)ntohl(os_header->ih_load))) return -1; /* we assume that the kernel is in place */ diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c index c75b84203..dcd40c225 100644 --- a/arch/ppc/lib/ppclinux.c +++ b/arch/ppc/lib/ppclinux.c @@ -17,7 +17,7 @@ extern bd_t *bd; #define SHOW_BOOT_PROGRESS(x) int -do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const char *oftree) +do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handle, const char *oftree) { ulong sp; ulong initrd_end = 0; @@ -30,18 +30,23 @@ do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const c void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); #ifdef CONFIG_OF_FLAT_TREE char *of_flat_tree = NULL; -// ulong of_data = 0; #endif + image_header_t *os_header = &os_handle->header; + image_header_t *initrd_header = NULL; void *os_data = NULL; void *initrd_data = NULL; void *of_data = NULL; + struct image_handle *oftree_handle; unsigned long os_len, initrd_len; + if (initrd_handle) + initrd_header = &initrd_handle->header; + printf("entering %s: os_header: %p initrd_header: %p oftree: %p\n", __FUNCTION__, os_header, initrd_header, oftree); if (os_header->ih_type == IH_TYPE_MULTI) { - unsigned long *data = (unsigned long *)(os_header + 1); + unsigned long *data = (unsigned long *)(os_handle->data); unsigned long len1 = 0, len2 = 0; if (!*data) { @@ -83,22 +88,21 @@ do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const c initrd_len = len1; } } else { - os_data = (void *)(os_header + 1); + os_data = os_handle->data; printf("set os_data to %p\n", os_data); } - if (initrd_header) - initrd_data = (void *)(initrd_header + 1); + if (initrd_handle) + initrd_data = initrd_handle->data; #ifdef CONFIG_OF_FLAT_TREE if (oftree) { - image_header_t *oftree_header; /* The oftree can be given either as an uboot image or as a * binary blob. First try to read it as an image. */ - oftree_header = map_image(oftree, 1); - if (oftree_header) { - of_data = (void *)(oftree_header + 1); + oftree_handle = map_image(oftree, 1); + if (oftree_handle) { + of_data = oftree_handle->data; } else { of_data = read_file(oftree); if (!of_data) { @@ -197,7 +201,7 @@ do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const c kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(os_header->ih_ep); /* FIXME */ - if (relocate_image(os_header, (void *)ntohl(os_header->ih_load))) + if (relocate_image(os_handle, (void *)ntohl(os_header->ih_load))) return -1; #if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500) diff --git a/commands/bootm.c b/commands/bootm.c index ec6e11c28..8dac4da4f 100644 --- a/commands/bootm.c +++ b/commands/bootm.c @@ -167,10 +167,11 @@ print_type (image_header_t *hdr) } #endif -int relocate_image(image_header_t *hdr, void *load_address) +int relocate_image(struct image_handle *handle, void *load_address) { - unsigned long data = (unsigned long)(hdr + 1); + image_header_t *hdr = &handle->header; unsigned long len = ntohl(hdr->ih_size); + unsigned long data = (unsigned long)(handle->data); #if defined CONFIG_CMD_BOOTM_ZLIB || defined CONFIG_CMD_BOOTM_BZLIB uint unc_len = CFG_BOOTM_LEN; @@ -215,12 +216,12 @@ int relocate_image(image_header_t *hdr, void *load_address) return 0; } -image_header_t *map_image(const char *filename, int verify) +struct image_handle *map_image(const char *filename, int verify) { int fd; uint32_t checksum, len; - void *data; - image_header_t *header, *tmp_header; + struct image_handle *handle; + image_header_t *header; fd = open(filename, O_RDONLY); if (fd < 0) { @@ -228,7 +229,8 @@ image_header_t *map_image(const char *filename, int verify) return NULL; } - header = xmalloc(sizeof(image_header_t)); + handle = xzalloc(sizeof(struct image_handle)); + header = &handle->header; if (read(fd, header, sizeof(image_header_t)) < 0) { printf("could not read: %s\n", errno_str()); @@ -249,38 +251,47 @@ image_header_t *map_image(const char *filename, int verify) } len = ntohl(header->ih_size); - tmp_header = realloc(header, sizeof(image_header_t) + len); - if (!tmp_header) - goto err_out; - header = tmp_header; - - data = (void *)(header + 1); - - if (read(fd, data, len) < 0) { - printf("could not read: %s\n", errno_str()); - goto err_out; + handle->data = memmap(fd, PROT_READ); + if (!handle) { + handle->data = xmalloc(len); + handle->flags = IH_MALLOC; + if (read(fd, &handle->data, len) < 0) { + printf("could not read: %s\n", errno_str()); + goto err_out; + } + } else { + handle->data = (void *)((unsigned long)handle->data + sizeof(image_header_t)); } if (verify) { puts (" Verifying Checksum ... "); - if (crc32 (0, data, len) != ntohl(header->ih_dcrc)) { + if (crc32 (0, handle->data, len) != ntohl(header->ih_dcrc)) { printf ("Bad Data CRC\n"); goto err_out; } puts ("OK\n"); } - print_image_hdr (header); + print_image_hdr(header); close(fd); - return header; + return handle; err_out: close(fd); - free(header); + if (handle->flags & IH_MALLOC) + free(handle->data); + free(handle); return NULL; } +void unmap_image(struct image_handle *handle) +{ + if (handle->flags & IH_MALLOC) + free(handle->data); + free(handle); +} + #ifdef CONFIG_OF_FLAT_TREE #define OPT_OFTREE "o:" #else @@ -295,10 +306,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *initrd = NULL; image_header_t *os_header; image_header_t *initrd_header = NULL; + struct image_handle *os_handle, *initrd_handle = NULL; #ifdef CONFIG_OF_FLAT_TREE char *oftree = NULL; #endif - int ignore_load_address = 0; getopt_reset(); @@ -310,9 +321,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) case 'n': verify = 0; break; - case 'i': - ignore_load_address = 1; - break; #ifdef CONFIG_OF_FLAT_TREE case 'o': oftree = optarg; @@ -328,19 +336,22 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) return 1; } - os_header = map_image(argv[optind], verify); - if (!os_header) + os_handle = map_image(argv[optind], verify); + if (!os_handle) return 1; + os_header = &os_handle->header; + if (os_header->ih_arch != IH_CPU) { printf ("Unsupported Architecture 0x%x\n", os_header->ih_arch); goto err_out; } if (initrd) { - initrd_header = map_image(initrd, verify); - if (!initrd_header) + initrd_handle = map_image(initrd, verify); + if (!initrd_handle) goto err_out; + initrd_header = &initrd_handle->header; } #if 0 switch (os_header->ih_type) { @@ -383,9 +394,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) fixup_silent_linux(); #endif #ifdef CONFIG_OF_FLAT_TREE - do_bootm_linux(os_header, initrd_header, oftree); + do_bootm_linux(os_handle, initrd_handle, oftree); #else - do_bootm_linux(os_header, initrd_header); + do_bootm_linux(os_handle, initrd_handle); #endif break; #ifdef CONFIG_NETBSD @@ -434,10 +445,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) #endif err_out: - if (os_header) - free(os_header); - if (initrd_header) - free(initrd_header); + if (os_handle) + unmap_image(os_handle); + if (initrd_handle) + unmap_image(initrd_handle); return 1; } diff --git a/include/boot.h b/include/boot.h index 09d4ce631..889773bc2 100644 --- a/include/boot.h +++ b/include/boot.h @@ -2,21 +2,11 @@ #define __BOOT_H #ifdef CONFIG_OF_FLAT_TREE -int do_bootm_linux(image_header_t *os, image_header_t *initrd, +int do_bootm_linux(struct image_handle *os, struct image_handle *initrd, const char *oftree); #else -int do_bootm_linux(image_header_t *os, image_header_t *initrd); +int do_bootm_linux(struct image_handle *os, struct image_handle *initrd); #endif #endif /* __BOOT_H */ -#ifndef __BOOT_H -#define __BOOT_H -#ifdef CONFIG_OF_FLAT_TREE -int do_bootm_linux(image_header_t *os, image_header_t *initrd, - const char *oftree); -#else -int do_bootm_linux(image_header_t *os, image_header_t *initrd); -#endif - -#endif /* __BOOT_H */ diff --git a/include/image.h b/include/image.h index 5d744beb6..648e9d6be 100644 --- a/include/image.h +++ b/include/image.h @@ -180,6 +180,13 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; +struct image_handle { + image_header_t header; + void *data; +#define IH_MALLOC 1 + int flags; +}; + /* commamds/bootm.c */ void print_image_hdr (image_header_t *hdr); @@ -187,12 +194,12 @@ void print_image_hdr (image_header_t *hdr); * Load an image into memory. Returns a pointer to the loaded * image. */ -image_header_t *map_image(const char *filename, int verify); +struct image_handle *map_image(const char *filename, int verify); /* * Relocate an image to load_address by uncompressing * or just copying. */ -int relocate_image(image_header_t *hdr, void *load_address); +int relocate_image(struct image_handle *handle, void *load_address); #endif /* __IMAGE_H__ */