X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fimage.c;h=d218f2f88ba77397fd69b24e8e6f17cd9dde1954;hb=5e3dca577b7c1bf58bd2b48449b18b7e7dcd8e04;hp=9278ea92b3c48531b71855aada89225f64c5c389;hpb=5dfb52138688ccbf0146f62683fe6217b3ce1b05;p=oweals%2Fu-boot.git diff --git a/common/image.c b/common/image.c index 9278ea92b3..d218f2f88b 100644 --- a/common/image.c +++ b/common/image.c @@ -23,7 +23,6 @@ * MA 02111-1307 USA */ -#define DEBUG #ifndef USE_HOSTCC #include @@ -47,11 +46,18 @@ #include -#if defined(CONFIG_FIT) +#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT) #include #include #include +#endif + +#if defined(CONFIG_FIT) +#include #include + +static int fit_check_ramdisk (const void *fit, int os_noffset, + uint8_t arch, int verify); #endif #ifdef CONFIG_CMD_BDI @@ -60,11 +66,11 @@ extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); DECLARE_GLOBAL_DATA_PTR; -static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong rd_addr, uint8_t arch, int verify); +static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, + int verify); #else #include "mkimage.h" +#include #include #include #endif /* !USE_HOSTCC*/ @@ -373,10 +379,6 @@ inline void image_print_contents_noindent (image_header_t *hdr) #ifndef USE_HOSTCC /** * image_get_ramdisk - get and verify ramdisk image - * @cmdtp: command table pointer - * @flag: command flag - * @argc: command argument count - * @argv: command argument list * @rd_addr: ramdisk image start address * @arch: expected ramdisk architecture * @verify: checksum verification flag @@ -393,14 +395,10 @@ inline void image_print_contents_noindent (image_header_t *hdr) * pointer to a ramdisk image header, if image was found and valid * otherwise, return NULL */ -static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag, - int argc, char *argv[], - ulong rd_addr, uint8_t arch, int verify) +static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch, + int verify) { - image_header_t *rd_hdr; - - show_boot_progress (9); - rd_hdr = (image_header_t *)rd_addr; + image_header_t *rd_hdr = (image_header_t *)rd_addr; if (!image_check_magic (rd_hdr)) { puts ("Bad Magic Number\n"); @@ -466,8 +464,10 @@ ulong getenv_bootm_low(void) return tmp; } -#ifdef CFG_SDRAM_BASE +#if defined(CFG_SDRAM_BASE) return CFG_SDRAM_BASE; +#elif defined(CONFIG_ARM) + return gd->bd->bi_dram[0].start; #else return 0; #endif @@ -481,7 +481,11 @@ ulong getenv_bootm_size(void) return tmp; } +#if defined(CONFIG_ARM) + return gd->bd->bi_dram[0].size; +#else return gd->bd->bi_memsize; +#endif } void memmove_wd (void *to, void *from, size_t len, ulong chunksz) @@ -740,10 +744,28 @@ ulong genimg_get_image (ulong img_addr) return ram_addr; } +/** + * fit_has_config - check if there is a valid FIT configuration + * @images: pointer to the bootm command headers structure + * + * fit_has_config() checks if there is a FIT configuration in use + * (if FTI support is present). + * + * returns: + * 0, no FIT support or no configuration found + * 1, configuration found + */ +int genimg_has_config (bootm_headers_t *images) +{ +#if defined(CONFIG_FIT) + if (images->fit_uname_cfg) + return 1; +#endif + return 0; +} + /** * boot_get_ramdisk - main ramdisk handling routine - * @cmdtp: command table pointer - * @flag: command flag * @argc: command argument count * @argv: command argument list * @images: pointer to the bootm images structure @@ -757,14 +779,15 @@ ulong genimg_get_image (ulong img_addr) * - 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 * rd_start and rd_end are set to 0 if no ramdisk exists - * return 1 if ramdisk image is found but corrupted */ -int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], - bootm_headers_t *images, uint8_t arch, - ulong *rd_start, ulong *rd_end) +int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images, + uint8_t arch, ulong *rd_start, ulong *rd_end) { ulong rd_addr, rd_load; ulong rd_data, rd_len; @@ -774,8 +797,15 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], const char *fit_uname_config = NULL; const char *fit_uname_ramdisk = NULL; ulong default_addr; + int rd_noffset; + int cfg_noffset; + const void *data; + size_t size; #endif + *rd_start = 0; + *rd_end = 0; + /* * Look for a '-' which indicates to ignore the * ramdisk argument @@ -783,37 +813,65 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) { debug ("## Skipping init Ramdisk\n"); rd_len = rd_data = 0; - } else if (argc >= 3) { + } else if (argc >= 3 || genimg_has_config (images)) { #if defined(CONFIG_FIT) - /* - * 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 (argv[2], 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 (argv[2], default_addr, - &rd_addr, &fit_uname_ramdisk)) { - debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n", - fit_uname_ramdisk, rd_addr); - } else + if (argc >= 3) { + /* + * 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 (argv[2], 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 (argv[2], 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(argv[2], NULL, 16); - debug ("* ramdisk: cmdline image address = 0x%08lx\n", - rd_addr); + { + rd_addr = simple_strtoul(argv[2], 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 + */ + rd_addr = (ulong)images->fit_hdr_os; + fit_uname_config = images->fit_uname_cfg; + debug ("* ramdisk: using config '%s' from image at 0x%08lx\n", + fit_uname_config, rd_addr); + + /* + * Check whether configuration has ramdisk defined, + * if not, don't try to use it, quit silently. + */ + fit_hdr = (void *)rd_addr; + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + debug ("* ramdisk: no such config\n"); + return 0; + } + + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); + if (rd_noffset < 0) { + debug ("* ramdisk: no ramdisk in config\n"); + return 0; + } } +#endif /* copy from dataflash if needed */ - printf ("## Loading init Ramdisk Image at %08lx ...\n", - rd_addr); rd_addr = genimg_get_image (rd_addr); /* @@ -823,17 +881,15 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], */ switch (genimg_get_format ((void *)rd_addr)) { case IMAGE_FORMAT_LEGACY: + printf ("## Loading init Ramdisk from Legacy " + "Image at %08lx ...\n", rd_addr); - debug ("* ramdisk: legacy format image\n"); + show_boot_progress (9); + rd_hdr = image_get_ramdisk (rd_addr, arch, + images->verify); - rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv, - rd_addr, arch, images->verify); - - if (rd_hdr == NULL) { - *rd_start = 0; - *rd_end = 0; + if (rd_hdr == NULL) return 1; - } rd_data = image_get_data (rd_hdr); rd_len = image_get_data_size (rd_hdr); @@ -842,14 +898,78 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (void *)rd_addr; - debug ("* ramdisk: FIT format image\n"); - fit_unsupported_reset ("ramdisk"); - return 1; + printf ("## Loading init Ramdisk from FIT " + "Image at %08lx ...\n", rd_addr); + + show_boot_progress (120); + if (!fit_check_format (fit_hdr)) { + puts ("Bad FIT ramdisk image format!\n"); + show_boot_progress (-120); + return 0; + } + show_boot_progress (121); + + if (!fit_uname_ramdisk) { + /* + * no ramdisk 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 (122); + cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config); + if (cfg_noffset < 0) { + puts ("Could not find configuration node\n"); + show_boot_progress (-122); + return 0; + } + fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL); + printf (" Using '%s' configuration\n", fit_uname_config); + + rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset); + fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL); + } else { + /* get ramdisk component image node offset */ + show_boot_progress (123); + rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk); + } + if (rd_noffset < 0) { + puts ("Could not find subimage node\n"); + show_boot_progress (-124); + return 0; + } + + printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk); + + show_boot_progress (125); + if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify)) + return 0; + + /* get ramdisk image data address and length */ + if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) { + puts ("Could not find ramdisk subimage data!\n"); + show_boot_progress (-127); + return 0; + } + show_boot_progress (128); + + rd_data = (ulong)data; + rd_len = size; + + if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) { + puts ("Can't get ramdisk subimage load address!\n"); + show_boot_progress (-129); + return 0; + } + show_boot_progress (129); + + images->fit_hdr_rd = fit_hdr; + images->fit_uname_rd = fit_uname_ramdisk; + images->fit_noffset_rd = rd_noffset; + break; #endif default: - printf ("Wrong Image Format for %s command\n", - cmdtp->name); - rd_data = rd_len = 0; + puts ("Wrong Ramdisk Image Format\n"); + rd_data = rd_len = rd_load = 0; } #if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO) @@ -863,14 +983,14 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], #endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */ } else if (images->legacy_hdr_valid && - image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) { + 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. */ show_boot_progress (13); printf ("## Loading init Ramdisk from multi component " - "Image at %08lx ...\n", + "Legacy Image at %08lx ...\n", (ulong)images->legacy_hdr_os); image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len); @@ -884,8 +1004,6 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], if (!rd_data) { debug ("## No init Ramdisk\n"); - *rd_start = 0; - *rd_end = 0; } else { *rd_start = rd_data; *rd_end = rd_data + rd_len; @@ -896,7 +1014,7 @@ int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[], return 0; } -#if defined(CONFIG_PPC) || defined(CONFIG_M68K) +#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1823,8 +1941,8 @@ static int calculate_hash (const void *data, int data_len, const char *algo, (unsigned char *) value); *value_len = 20; } else if (strcmp (algo, "md5") == 0 ) { - printf ("MD5 not supported\n"); - *value_len = 0; + md5 ((unsigned char *)data, data_len, value); + *value_len = 16; } else { debug ("Unsupported hash alogrithm\n"); return -1; @@ -2337,7 +2455,7 @@ int fit_conf_get_fdt_node (const void *fit, int noffset) /** * fit_conf_print - prints out the FIT configuration details * @fit: pointer to the FIT format image header - * @conf_noffset: offset of the configuration node + * @noffset: offset of the configuration node * @p: pointer to prefix string * * fit_conf_print() lists all mandatory properies for the processed @@ -2376,4 +2494,48 @@ void fit_conf_print (const void *fit, int noffset, const char *p) if (uname) printf ("%s FDT: %s\n", p, uname); } + +/** + * fit_check_ramdisk - verify FIT format ramdisk subimage + * @fit_hdr: pointer to the FIT ramdisk header + * @rd_noffset: ramdisk subimage node offset within FIT image + * @arch: requested ramdisk image architecture type + * @verify: data CRC verification flag + * + * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from + * specified FIT image. + * + * returns: + * 1, on success + * 0, on failure + */ +#ifndef USE_HOSTCC +static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify) +{ + fit_image_print (fit, rd_noffset, " "); + + if (verify) { + puts (" Verifying Hash Integrity ... "); + if (!fit_image_check_hashes (fit, rd_noffset)) { + puts ("Bad Data Hash\n"); + show_boot_progress (-125); + return 0; + } + puts ("OK\n"); + } + + show_boot_progress (126); + if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) || + !fit_image_check_arch (fit, rd_noffset, arch) || + !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) { + printf ("No Linux %s Ramdisk Image\n", + genimg_get_arch_name(arch)); + show_boot_progress (-126); + return 0; + } + + show_boot_progress (127); + return 1; +} +#endif /* USE_HOSTCC */ #endif /* CONFIG_FIT */