diff options
Diffstat (limited to 'commands/bootm.c')
-rw-r--r-- | commands/bootm.c | 116 |
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; |