/** * boot_get_kernel - find kernel image * @os_data: pointer to a ulong variable, will hold os data start address * @os_len: pointer to a ulong variable, will hold os data length * * boot_get_kernel() tries to find a kernel image, verifies its integrity * and locates kernel data. * * returns: * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len) { image_header_t *hdr; ulong img_addr; const void *buf; #if defined(CONFIG_FIT) const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; int os_noffset; #endif /* find out kernel image address */ if (argc < 2) { img_addr = load_addr; debug("* kernel: default image load address = 0x%08lx\n", load_addr); #if defined(CONFIG_FIT) } else if (fit_parse_conf(argv[1], load_addr, &img_addr, &fit_uname_config)) { debug("* kernel: config '%s' from image at 0x%08lx\n", fit_uname_config, img_addr); } else if (fit_parse_subimage(argv[1], load_addr, &img_addr, &fit_uname_kernel)) { debug("* kernel: subimage '%s' from image at 0x%08lx\n", fit_uname_kernel, img_addr); #endif } else { img_addr = simple_strtoul(argv[1], NULL, 16); debug("* kernel: cmdline image address = 0x%08lx\n", img_addr); } bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC); /* copy from dataflash if needed */ img_addr = genimg_get_image(img_addr); /* check image type, for FIT images get FIT kernel node */ *os_data = *os_len = 0; buf = map_sysmem(img_addr, 0); switch (genimg_get_format(buf)) { case IMAGE_FORMAT_LEGACY: printf("## Booting kernel from Legacy Image at %08lx ...\n", img_addr); hdr = image_get_kernel(img_addr, images->verify); if (!hdr) return NULL; bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE); /* get os_data and os_len */ switch (image_get_type(hdr)) { case IH_TYPE_KERNEL: case IH_TYPE_KERNEL_NOLOAD: *os_data = image_get_data(hdr); *os_len = image_get_data_size(hdr); break; case IH_TYPE_MULTI: image_multi_getimg(hdr, 0, os_data, os_len); break; case IH_TYPE_STANDALONE: *os_data = image_get_data(hdr); *os_len = image_get_data_size(hdr); break; default: printf("Wrong Image Type for %s command\n", cmdtp->name); bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE); return NULL; } /* * copy image header to allow for image overwrites during * kernel decompression. */ memmove(&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t)); /* save pointer to image header */ images->legacy_hdr_os = hdr; images->legacy_hdr_valid = 1; bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: os_noffset = fit_image_load(images, FIT_KERNEL_PROP, img_addr, &fit_uname_kernel, fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_KERNEL, BOOTSTAGE_ID_FIT_KERNEL_START, FIT_LOAD_IGNORED, os_data, os_len); if (os_noffset < 0) return NULL; images->fit_hdr_os = map_sysmem(img_addr, 0); images->fit_uname_os = fit_uname_kernel; images->fit_noffset_os = os_noffset; break; #endif default: printf("Wrong Image Format for %s command\n", cmdtp->name); bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO); return NULL; } debug(" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", *os_data, *os_len, *os_len); return buf; }
/** * boot_get_kernel - find kernel image * @os_data: pointer to a ulong variable, will hold os data start address * @os_len: pointer to a ulong variable, will hold os data length * * boot_get_kernel() tries to find a kernel image, verifies its integrity * and locates kernel data. * * returns: * pointer to image header if valid image was found, plus kernel start * address and length, otherwise NULL */ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], bootm_headers_t *images, ulong *os_data, ulong *os_len) { image_header_t *hdr; ulong img_addr; #if defined(CONFIG_FIT) void *fit_hdr; const char *fit_uname_config = NULL; const char *fit_uname_kernel = NULL; const void *data; size_t len; int cfg_noffset; int os_noffset; #endif /* find out kernel image address */ if (argc < 2) { img_addr = load_addr; debug ("* kernel: default image load address = 0x%08lx\n", load_addr); #if defined(CONFIG_FIT) } else if (fit_parse_conf (argv[1], load_addr, &img_addr, &fit_uname_config)) { debug ("* kernel: config '%s' from image at 0x%08lx\n", fit_uname_config, img_addr); } else if (fit_parse_subimage (argv[1], load_addr, &img_addr, &fit_uname_kernel)) { debug ("* kernel: subimage '%s' from image at 0x%08lx\n", fit_uname_kernel, img_addr); #endif } else { img_addr = simple_strtoul(argv[1], NULL, 16); debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); } show_boot_progress (1); /* copy from dataflash if needed */ img_addr = genimg_get_image (img_addr); /* check image type, for FIT images get FIT kernel node */ *os_data = *os_len = 0; switch (genimg_get_format ((void *)img_addr)) { case IMAGE_FORMAT_LEGACY: printf ("## Booting kernel from Legacy Image at %08lx ...\n", img_addr); hdr = image_get_kernel (img_addr, images->verify); if (!hdr) return NULL; show_boot_progress (5); /* get os_data and os_len */ switch (image_get_type (hdr)) { case IH_TYPE_KERNEL: *os_data = image_get_data (hdr); *os_len = image_get_data_size (hdr); break; case IH_TYPE_MULTI: image_multi_getimg (hdr, 0, os_data, os_len); break; case IH_TYPE_STANDALONE: if (argc >2) { hdr->ih_load = htonl(simple_strtoul(argv[2], NULL, 16)); } *os_data = image_get_data (hdr); *os_len = image_get_data_size (hdr); break; default: printf ("Wrong Image Type for %s command\n", cmdtp->name); show_boot_progress (-5); return NULL; } /* * copy image header to allow for image overwrites during kernel * decompression. */ memmove (&images->legacy_hdr_os_copy, hdr, sizeof(image_header_t)); /* save pointer to image header */ images->legacy_hdr_os = hdr; images->legacy_hdr_valid = 1; show_boot_progress (6); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (void *)img_addr; printf ("## Booting kernel from FIT Image at %08lx ...\n", img_addr); if (!fit_check_format (fit_hdr)) { puts ("Bad FIT kernel image format!\n"); show_boot_progress (-100); return NULL; } show_boot_progress (100); if (!fit_uname_kernel) { /* * no kernel image node unit name, try to get config * node first. If config unit node name is NULL * fit_conf_get_node() will try to find default config node */ show_boot_progress (101); cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); if (cfg_noffset < 0) { show_boot_progress (-101); return NULL; } /* save configuration uname provided in the first * bootm argument */ images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL); printf (" Using '%s' configuration\n", images->fit_uname_cfg); show_boot_progress (103); os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset); fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL); } else { /* get kernel component image node offset */ show_boot_progress (102); os_noffset = fit_image_get_node (fit_hdr, fit_uname_kernel); } if (os_noffset < 0) { show_boot_progress (-103); return NULL; } printf (" Trying '%s' kernel subimage\n", fit_uname_kernel); show_boot_progress (104); if (!fit_check_kernel (fit_hdr, os_noffset, images->verify)) return NULL; /* get kernel image data address and length */ if (fit_image_get_data (fit_hdr, os_noffset, &data, &len)) { puts ("Could not find kernel subimage data!\n"); show_boot_progress (-107); return NULL; } show_boot_progress (108); *os_len = len; *os_data = (ulong)data; images->fit_hdr_os = fit_hdr; images->fit_uname_os = fit_uname_kernel; images->fit_noffset_os = os_noffset; break; #endif default: printf ("Wrong Image Format for %s command\n", cmdtp->name); show_boot_progress (-108); return NULL; } debug (" kernel data at 0x%08lx, len = 0x%08lx (%ld)\n", *os_data, *os_len, *os_len); return (void *)img_addr; }
/** * boot_get_ramdisk - main ramdisk handling routine * @argc: command argument count * @argv: command argument list * @images: pointer to the bootm images structure * @arch: expected ramdisk architecture * @rd_start: pointer to a ulong variable, will hold ramdisk start address * @rd_end: pointer to a ulong variable, will hold ramdisk end * * boot_get_ramdisk() is responsible for finding a valid ramdisk image. * Curently supported are the following ramdisk sources: * - multicomponent kernel/ramdisk image, * - commandline provided address of decicated ramdisk image. * * returns: * 0, if ramdisk image was found and valid, or skiped * rd_start and rd_end are set to ramdisk start/end addresses if * ramdisk image is found and valid * * 1, if ramdisk image is found but corrupted, or invalid * rd_start and rd_end are set to 0 if no ramdisk exists */ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; ulong rd_data, rd_len; #if defined(CONFIG_IMAGE_FORMAT_LEGACY) const image_header_t *rd_hdr; #endif void *buf; #ifdef CONFIG_SUPPORT_RAW_INITRD char *end; #endif #if defined(CONFIG_FIT) const char *fit_uname_config = images->fit_uname_cfg; const char *fit_uname_ramdisk = NULL; ulong default_addr; int rd_noffset; #endif const char *select = NULL; *rd_start = 0; *rd_end = 0; #ifdef CONFIG_ANDROID_BOOT_IMAGE /* * Look for an Android boot image. */ buf = map_sysmem(images->os.start, 0); if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) select = argv[0]; #endif if (argc >= 2) select = argv[1]; /* * Look for a '-' which indicates to ignore the * ramdisk argument */ if (select && strcmp(select, "-") == 0) { debug("## Skipping init Ramdisk\n"); rd_len = rd_data = 0; } else if (select || genimg_has_config(images)) { #if defined(CONFIG_FIT) if (select) { /* * If the init ramdisk comes from the FIT image and * the FIT image address is omitted in the command * line argument, try to use os FIT image address or * default load address. */ if (images->fit_uname_os) default_addr = (ulong)images->fit_hdr_os; else default_addr = load_addr; if (fit_parse_conf(select, default_addr, &rd_addr, &fit_uname_config)) { debug("* ramdisk: config '%s' from image at " "0x%08lx\n", fit_uname_config, rd_addr); } else if (fit_parse_subimage(select, default_addr, &rd_addr, &fit_uname_ramdisk)) { debug("* ramdisk: subimage '%s' from image at " "0x%08lx\n", fit_uname_ramdisk, rd_addr); } else #endif { rd_addr = simple_strtoul(select, NULL, 16); debug("* ramdisk: cmdline image address = " "0x%08lx\n", rd_addr); } #if defined(CONFIG_FIT) } else { /* use FIT configuration provided in first bootm * command argument. If the property is not defined, * quit silently. */ rd_addr = map_to_sysmem(images->fit_hdr_os); rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP, rd_addr); if (rd_noffset == -ENOLINK) return 0; else if (rd_noffset < 0) return 1; } #endif /* copy from dataflash if needed */ rd_addr = genimg_get_image(rd_addr); /* * Check if there is an initrd image at the * address provided in the second bootm argument * check image type, for FIT images get FIT node. */ buf = map_sysmem(rd_addr, 0); switch (genimg_get_format(buf)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: printf("## Loading init Ramdisk from Legacy " "Image at %08lx ...\n", rd_addr); bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); rd_hdr = image_get_ramdisk(rd_addr, arch, images->verify); if (rd_hdr == NULL) return 1; rd_data = image_get_data(rd_hdr); rd_len = image_get_data_size(rd_hdr); rd_load = image_get_load(rd_hdr); break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: rd_noffset = fit_image_load(images, rd_addr, &fit_uname_ramdisk, &fit_uname_config, arch, IH_TYPE_RAMDISK, BOOTSTAGE_ID_FIT_RD_START, FIT_LOAD_OPTIONAL_NON_ZERO, &rd_data, &rd_len); if (rd_noffset < 0) return 1; images->fit_hdr_rd = map_sysmem(rd_addr, 0); images->fit_uname_rd = fit_uname_ramdisk; images->fit_noffset_rd = rd_noffset; break; #endif #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: android_image_get_ramdisk((void *)images->os.start, &rd_data, &rd_len); break; #endif default: #ifdef CONFIG_SUPPORT_RAW_INITRD end = NULL; if (select) end = strchr(select, ':'); if (end) { rd_len = simple_strtoul(++end, NULL, 16); rd_data = rd_addr; } else #endif { puts("Wrong Ramdisk Image Format\n"); rd_data = rd_len = rd_load = 0; return 1; } } } else if (images->legacy_hdr_valid && image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { /* * Now check if we have a legacy mult-component image, * get second entry data start address and len. */ bootstage_mark(BOOTSTAGE_ID_RAMDISK); printf("## Loading init Ramdisk from multi component " "Legacy Image at %08lx ...\n", (ulong)images->legacy_hdr_os); image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len); } else { /* * no initrd image */ bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK); rd_len = rd_data = 0; } if (!rd_data) { debug("## No init Ramdisk\n"); } else { *rd_start = rd_data; *rd_end = rd_data + rd_len; } debug(" ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n", *rd_start, *rd_end); return 0; }