summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/lib/armlinux.c10
-rw-r--r--arch/ppc/lib/ppclinux.c26
-rw-r--r--commands/bootm.c79
-rw-r--r--include/boot.h14
-rw-r--r--include/image.h11
5 files changed, 77 insertions, 63 deletions
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index be950f00a7..78a14a3783 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 c75b842039..dcd40c2257 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 ec6e11c280..8dac4da4f6 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 09d4ce6314..889773bc2c 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 5d744beb6b..648e9d6bed 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__ */