summaryrefslogtreecommitdiffstats
path: root/commands/bootm.c
diff options
context:
space:
mode:
Diffstat (limited to 'commands/bootm.c')
-rw-r--r--commands/bootm.c116
1 files changed, 38 insertions, 78 deletions
diff --git a/commands/bootm.c b/commands/bootm.c
index e5ffacb022..755932b505 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -95,16 +95,28 @@ fixup_silent_linux ()
}
#endif /* CONFIG_SILENT_CONSOLE */
+struct image_handle_data* image_handle_data_get_by_num(struct image_handle* handle, int num)
+{
+ if (!handle || num < 0 || num >= handle->nb_data_entries)
+ return NULL;
+
+ return &handle->data_entries[num];
+}
+
int relocate_image(struct image_handle *handle, void *load_address)
{
image_header_t *hdr = &handle->header;
unsigned long len = image_get_size(hdr);
- unsigned long data = (unsigned long)(handle->data);
+ struct image_handle_data *iha;
+ unsigned long data;
#if defined CONFIG_CMD_BOOTM_ZLIB || defined CONFIG_CMD_BOOTM_BZLIB
uint unc_len = CFG_BOOTM_LEN;
#endif
+ iha = image_handle_data_get_by_num(handle, 0);
+ data = (unsigned long)(iha->data);
+
switch (image_get_comp(hdr)) {
case IH_COMP_NONE:
if(image_get_load(hdr) == data) {
@@ -146,91 +158,32 @@ int relocate_image(struct image_handle *handle, void *load_address)
}
EXPORT_SYMBOL(relocate_image);
-struct image_handle *map_image(const char *filename, int verify)
+static LIST_HEAD(handler_list);
+
+int register_image_handler(struct image_handler *handler)
+{
+ list_add_tail(&handler->list, &handler_list);
+ return 0;
+}
+
+/*
+ * generate a image_handle from a multi_image
+ * this image_handle can be free by unmap_image
+ */
+static struct image_handle *get_fake_image_handle(struct image_data *data, int num)
{
- int fd;
- uint32_t checksum, len;
struct image_handle *handle;
+ struct image_handle_data* iha;
image_header_t *header;
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- printf("could not open: %s\n", errno_str());
- return NULL;
- }
+ iha = image_handle_data_get_by_num(data->os, num);
handle = xzalloc(sizeof(struct image_handle));
header = &handle->header;
-
- if (read(fd, header, image_get_header_size()) < 0) {
- printf("could not read: %s\n", errno_str());
- goto err_out;
- }
-
- if (image_get_magic(header) != IH_MAGIC) {
- puts ("Bad Magic Number\n");
- goto err_out;
- }
-
- checksum = image_get_hcrc(header);
- header->ih_hcrc = 0;
-
- if (crc32 (0, (uchar *)header, image_get_header_size()) != checksum) {
- puts ("Bad Header Checksum\n");
- goto err_out;
- }
- len = image_get_size(header);
-
- handle->data = memmap(fd, PROT_READ);
- if (handle->data == (void *)-1) {
- 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 +
- image_get_header_size());
- }
-
- if (verify) {
- puts (" Verifying Checksum ... ");
- if (crc32 (0, handle->data, len) != image_get_dcrc(header)) {
- printf ("Bad Data CRC\n");
- goto err_out;
- }
- puts ("OK\n");
- }
-
- image_print_contents(header);
-
- close(fd);
+ handle->data_entries = gen_image_handle_data(iha->data, iha->len);
+ handle->data = handle->data_entries[0].data;
return handle;
-err_out:
- close(fd);
- if (handle->flags & IH_MALLOC)
- free(handle->data);
- free(handle);
- return NULL;
-}
-EXPORT_SYMBOL(map_image);
-
-void unmap_image(struct image_handle *handle)
-{
- if (handle->flags & IH_MALLOC)
- free(handle->data);
- free(handle);
-}
-EXPORT_SYMBOL(unmap_image);
-
-static LIST_HEAD(handler_list);
-
-int register_image_handler(struct image_handler *handler)
-{
- list_add_tail(&handler->list, &handler_list);
- return 0;
}
static int initrd_handler_parse_options(struct image_data *data, int opt,
@@ -239,7 +192,14 @@ static int initrd_handler_parse_options(struct image_data *data, int opt,
switch(opt) {
case 'r':
printf("use initrd %s\n", optarg);
- data->initrd = map_image(optarg, data->verify);
+ /* check for multi image @<num> */
+ if (optarg[0] == '@') {
+ int num = simple_strtol(optarg + 1, NULL, 0);
+
+ data->initrd = get_fake_image_handle(data, num);
+ } else {
+ data->initrd = map_image(optarg, data->verify);
+ }
if (!data->initrd)
return -1;
return 0;