diff --git a/common/bootm.c b/common/bootm.c index 6842029..07ae0f5 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -240,6 +240,23 @@ static int bootm_find_fdt(int flag, int argc, char * const argv[]) } #endif +#if defined(CONFIG_FIT) +static int bootm_find_loadables(int flag, int argc, char * const argv[]) +{ + int ret; + + /* find all of the loadables */ + ret = boot_get_loadable(argc, argv, &images, IH_ARCH_DEFAULT, + NULL, NULL); + if (ret) { + printf("Loadable(s) is corrupt or invalid\n"); + return 1; + } + + return 0; +} +#endif + int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]) { if (bootm_find_ramdisk(flag, argc, argv)) @@ -250,6 +267,11 @@ int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]) return 1; #endif +#if defined(CONFIG_FIT) + if (bootm_find_loadables(flag, argc, argv)) + return 1; +#endif + return 0; } diff --git a/common/image-fit.c b/common/image-fit.c index fc9ea1f..4bd8fea 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1544,6 +1544,8 @@ static const char *fit_get_image_type_property(int type) return FIT_RAMDISK_PROP; case IH_TYPE_X86_SETUP: return FIT_SETUP_PROP; + case IH_TYPE_LOADABLE: + return FIT_LOADABLE_PROP; } return "unknown"; @@ -1661,7 +1663,13 @@ int fit_image_load(bootm_headers_t *images, ulong addr, os_ok = image_type == IH_TYPE_FLATDT || fit_image_check_os(fit, noffset, IH_OS_LINUX) || fit_image_check_os(fit, noffset, IH_OS_OPENRTOS); - if (!type_ok || !os_ok) { + + /* + * If either of the checks fail, we should report an error, but + * if the image type is coming from the "loadables" field, we + * don't care what it is + */ + if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) { fit_image_get_os(fit, noffset, &os); printf("No %s %s %s Image\n", genimg_get_os_name(os), diff --git a/common/image.c b/common/image.c index fdec496..0f5274f 100644 --- a/common/image.c +++ b/common/image.c @@ -1165,6 +1165,77 @@ int boot_get_setup(bootm_headers_t *images, uint8_t arch, #endif } +#if defined(CONFIG_FIT) +int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images, + uint8_t arch, const ulong *ld_start, ulong * const ld_len) +{ + /* + * These variables are used to hold the current image location + * in system memory. + */ + ulong tmp_img_addr; + /* + * These two variables are requirements for fit_image_load, but + * their values are not used + */ + ulong img_data, img_len; + void *buf; + int loadables_index; + int conf_noffset; + int fit_img_result; + char *uname; + + /* Check to see if the images struct has a FIT configuration */ + if (!genimg_has_config(images)) { + debug("## FIT configuration was not specified\n"); + return 0; + } + + /* + * Obtain the os FIT header from the images struct + * copy from dataflash if needed + */ + tmp_img_addr = map_to_sysmem(images->fit_hdr_os); + tmp_img_addr = genimg_get_image(tmp_img_addr); + buf = map_sysmem(tmp_img_addr, 0); + /* + * Check image type. For FIT images get FIT node + * and attempt to locate a generic binary. + */ + switch (genimg_get_format(buf)) { + case IMAGE_FORMAT_FIT: + conf_noffset = fit_conf_get_node(buf, images->fit_uname_cfg); + + for (loadables_index = 0; + !fdt_get_string_index(buf, conf_noffset, + FIT_LOADABLE_PROP, + loadables_index, + (const char **)&uname) > 0; + loadables_index++) + { + fit_img_result = fit_image_load(images, + tmp_img_addr, + (const char **)&uname, + &(images->fit_uname_cfg), arch, + IH_TYPE_LOADABLE, + BOOTSTAGE_ID_FIT_LOADABLE_START, + FIT_LOAD_OPTIONAL_NON_ZERO, + &img_data, &img_len); + if (fit_img_result < 0) { + /* Something went wrong! */ + return fit_img_result; + } + } + break; + default: + printf("The given image format is not supported (corrupt?)\n"); + return 1; + } + + return 0; +} +#endif + #ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline diff --git a/include/bootstage.h b/include/bootstage.h index fe30ab6..9765360 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -168,6 +168,7 @@ enum bootstage_id { BOOTSTAGE_ID_NAND_FIT_READ = 150, BOOTSTAGE_ID_NAND_FIT_READ_OK, + BOOTSTAGE_ID_FIT_LOADABLE_START = 160, /* for Loadable Images */ /* * These boot stages are new, higher level, and not directly related * to the old boot progress numbers. They are useful for recording diff --git a/include/image.h b/include/image.h index 97b96b3..b6eb57e 100644 --- a/include/image.h +++ b/include/image.h @@ -244,6 +244,7 @@ struct lmb; #define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */ #define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */ #define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */ +#define IH_TYPE_LOADABLE 22 /* A list of typeless images */ /* * Compression Types @@ -455,7 +456,31 @@ ulong genimg_get_image(ulong img_addr); int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images, uint8_t arch, ulong *rd_start, ulong *rd_end); -#endif + +/** + * boot_get_loadable - routine to load a list of binaries to memory + * @argc: Ignored Argument + * @argv: Ignored Argument + * @images: pointer to the bootm images structure + * @arch: expected architecture for the image + * @ld_start: Ignored Argument + * @ld_len: Ignored Argument + * + * boot_get_loadable() will take the given FIT configuration, and look + * for a field named "loadables". Loadables, is a list of elements in + * the FIT given as strings. exe: + * loadables = "linux_kernel@1", "fdt@2"; + * this function will attempt to parse each string, and load the + * corresponding element from the FIT into memory. Once placed, + * no aditional actions are taken. + * + * @return: + * 0, if only valid images or no images are found + * error code, if an error occurs during fit_image_load + */ +int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images, + uint8_t arch, const ulong *ld_start, ulong * const ld_len); +#endif /* !USE_HOSTCC */ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, ulong *setup_start, ulong *setup_len);