[U-Boot] [PATCH v3 0/4] New tag for Flattened Image Trees (FIT) - Booting Xen from a FIT.

The FIT config now supports a tag named "loadables:" which is a comma separated list. Users can add any number of images to the list, and u-boot will move the selected binaries to their listed load_addresses. This allows u-boot to boot xen from using an FIT configuration. Xen expects a kernel to be placed at a predetermined location, however the "kernel" field was already filled by xen itself. This change allows the user to move the required binary before xen boots, all within the FIT's configuration.
Changes in v3: - Moved the documentation about the loadables field from the commit message, to a new example.its file in doc/uImage.FIT/ doc/uImage.FIT/multi-with-loadables.its - Removed a couple zealous puts->printf conversions - Replaced an instance of puts I mistakenly included with printf - Moved the commit that adds the test to the end of patch-stack
Karl Apsite (4): mkimage will now report information about loadable add boot_get_loadables() to load listed images Combine bootm_find_<thing> functions together add test for two 'loadables'
common/bootm.c | 45 +++++++++-------- common/cmd_bootm.c | 4 +- common/image-fit.c | 25 ++++++++- common/image.c | 71 ++++++++++++++++++++++++++ doc/uImage.FIT/multi-with-loadables.its | 89 +++++++++++++++++++++++++++++++++ doc/uImage.FIT/source_file_format.txt | 4 ++ include/bootm.h | 2 +- include/bootstage.h | 1 + include/image.h | 28 ++++++++++- test/image/test-fit.py | 73 +++++++++++++++++++++++---- 10 files changed, 308 insertions(+), 34 deletions(-) create mode 100644 doc/uImage.FIT/multi-with-loadables.its

From: Karl Apsite karl.apsite@dornerworks.com
Added FIT_LOADABLE_PROP, so the user can identify an optional entry named "loadables" in their .its configuration. "loadables" is a comma separated list in the .its
Documentation can be found in doc/uImage.FIT/source_file_format.txt and doc/uImage.Fit/multi-with-loadables.its
Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com ---
Changes in v3: - Moved the documentation about the loadables field from the commit message, to a new example.its file in doc/uImage.FIT/ doc/uImage.FIT/multi-with-loadables.its
common/image-fit.c | 17 +++++++ doc/uImage.FIT/multi-with-loadables.its | 89 +++++++++++++++++++++++++++++++++ doc/uImage.FIT/source_file_format.txt | 4 ++ include/image.h | 1 + 4 files changed, 111 insertions(+) create mode 100644 doc/uImage.FIT/multi-with-loadables.its
diff --git a/common/image-fit.c b/common/image-fit.c index 4eb4d42..fc9ea1f 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1436,6 +1436,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p) char *desc; char *uname; int ret; + int loadables_index;
/* Mandatory properties */ ret = fit_get_desc(fit, noffset, &desc); @@ -1460,6 +1461,22 @@ void fit_conf_print(const void *fit, int noffset, const char *p) uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL); if (uname) printf("%s FDT: %s\n", p, uname); + + /* Print out all of the specified loadables */ + for (loadables_index = 0; + !fdt_get_string_index(fit, noffset, + FIT_LOADABLE_PROP, + loadables_index, + (const char **)&uname) > 0; + loadables_index++) + { + if (loadables_index == 0) { + printf("%s Loadables: ", p); + } else { + printf("%s ", p); + } + printf("%s\n", uname); + } }
static int fit_image_select(const void *fit, int rd_noffset, int verify) diff --git a/doc/uImage.FIT/multi-with-loadables.its b/doc/uImage.FIT/multi-with-loadables.its new file mode 100644 index 0000000..9baffa6 --- /dev/null +++ b/doc/uImage.FIT/multi-with-loadables.its @@ -0,0 +1,89 @@ +/* + * U-boot uImage source file with multiple kernels, ramdisks and FDT blobs + * This example makes use of the 'loadables' field + */ + +/dts-v1/; + +/ { + description = "Configuration to load a Xen Kernel"; + #address-cells = <1>; + + images { + xen_kernel@1 { + description = "xen binary"; + data = /incbin/("./xen"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "none"; + load = <0xa0000000>; + entry = <0xa0000000>; + hash@1 { + algo = "md5"; + }; + }; + + fdt@1 { + description = "xexpress-ca15 tree blob"; + data = /incbin/("./vexpress-v2p-ca15-tc1.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + load = <0xb0000000>; + hash@1 { + algo = "md5"; + }; + }; + + fdt@2 { + description = "xexpress-ca15 tree blob"; + data = /incbin/("./vexpress-v2p-ca15-tc1.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + load = <0xb0400000>; + hash@1 { + algo = "md5"; + }; + }; + + linux_kernel@1 { + description = "Linux Image"; + data = /incbin/("./Image"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "none"; + load = <0xa0000000>; + entry = <0xa0000000>; + hash@1 { + algo = "md5"; + }; + }; + }; + + configurations { + default = "config@2"; + + config@1 { + description = "Just plain Linux"; + kernel = "linux_kernel@1"; + fdt = "fdt@1"; + }; + + config@2 { + description = "Xen one loadable"; + kernel = "xen_kernel@1"; + fdt = "fdt@1"; + loadables = "linux_kernel@1"; + }; + + config@3 { + description = "Xen two loadables"; + kernel = "xen_kernel@1"; + fdt = "fdt@1"; + loadables = "linux_kernel@1", "fdt@2"; + }; + }; +}; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 427ea49..004acd1 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -235,6 +235,7 @@ o config@1 |- kernel = "kernel sub-node unit name" |- ramdisk = "ramdisk sub-node unit name" |- fdt = "fdt sub-node unit-name" + |- loadables = "loadables sub-node unit-name"
Mandatory properties: @@ -249,6 +250,9 @@ o config@1 "fdt type"). - setup : Unit name of the corresponding setup binary (used for booting an x86 kernel). This contains the setup.bin file built by the kernel. + - loadables : Unit name containing a list of additional binaries to be loaded at + their given locations. "loadables" is a comma-separated list of strings. + u-boot will load each binary at its given start-address.
The FDT blob is required to properly boot FDT based kernel, so the minimal configuration for 2.6 FDT kernel is (kernel, fdt) pair. diff --git a/include/image.h b/include/image.h index 60b924a..97b96b3 100644 --- a/include/image.h +++ b/include/image.h @@ -742,6 +742,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end); #define FIT_KERNEL_PROP "kernel" #define FIT_RAMDISK_PROP "ramdisk" #define FIT_FDT_PROP "fdt" +#define FIT_LOADABLE_PROP "loadables" #define FIT_DEFAULT_PROP "default" #define FIT_SETUP_PROP "setup"

Hi Karl,
On 18 May 2015 at 16:27, Karl Apsite Karl.Apsite@dornerworks.com wrote:
From: Karl Apsite karl.apsite@dornerworks.com
Added FIT_LOADABLE_PROP, so the user can identify an optional entry named "loadables" in their .its configuration. "loadables" is a comma separated list in the .its
Documentation can be found in doc/uImage.FIT/source_file_format.txt and doc/uImage.Fit/multi-with-loadables.its
Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com
Looks good, just a few nits from me.
Changes in v3:
- Moved the documentation about the loadables field from the commit message, to a new example.its file in doc/uImage.FIT/ doc/uImage.FIT/multi-with-loadables.its
common/image-fit.c | 17 +++++++ doc/uImage.FIT/multi-with-loadables.its | 89 +++++++++++++++++++++++++++++++++ doc/uImage.FIT/source_file_format.txt | 4 ++ include/image.h | 1 + 4 files changed, 111 insertions(+) create mode 100644 doc/uImage.FIT/multi-with-loadables.its
diff --git a/common/image-fit.c b/common/image-fit.c index 4eb4d42..fc9ea1f 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -1436,6 +1436,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p) char *desc; char *uname; int ret;
int loadables_index; /* Mandatory properties */ ret = fit_get_desc(fit, noffset, &desc);
@@ -1460,6 +1461,22 @@ void fit_conf_print(const void *fit, int noffset, const char *p) uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL); if (uname) printf("%s FDT: %s\n", p, uname);
/* Print out all of the specified loadables */
for (loadables_index = 0;
!fdt_get_string_index(fit, noffset,
FIT_LOADABLE_PROP,
loadables_index,
(const char **)&uname) > 0;
loadables_index++)
{
if (loadables_index == 0) {
printf("%s Loadables: ", p);
} else {
printf("%s ", p);
}
printf("%s\n", uname);
}
}
static int fit_image_select(const void *fit, int rd_noffset, int verify) diff --git a/doc/uImage.FIT/multi-with-loadables.its b/doc/uImage.FIT/multi-with-loadables.its new file mode 100644 index 0000000..9baffa6 --- /dev/null +++ b/doc/uImage.FIT/multi-with-loadables.its @@ -0,0 +1,89 @@ +/*
- U-boot uImage source file with multiple kernels, ramdisks and FDT blobs
U-Boot
- This example makes use of the 'loadables' field
- */
+/dts-v1/;
+/ {
description = "Configuration to load a Xen Kernel";
#address-cells = <1>;
images {
xen_kernel@1 {
description = "xen binary";
data = /incbin/("./xen");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0xa0000000>;
entry = <0xa0000000>;
hash@1 {
algo = "md5";
};
};
fdt@1 {
description = "xexpress-ca15 tree blob";
data = /incbin/("./vexpress-v2p-ca15-tc1.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
load = <0xb0000000>;
hash@1 {
algo = "md5";
};
};
fdt@2 {
description = "xexpress-ca15 tree blob";
data = /incbin/("./vexpress-v2p-ca15-tc1.dtb");
type = "flat_dt";
arch = "arm";
compression = "none";
load = <0xb0400000>;
hash@1 {
algo = "md5";
};
};
linux_kernel@1 {
description = "Linux Image";
data = /incbin/("./Image");
type = "kernel";
arch = "arm";
os = "linux";
compression = "none";
load = <0xa0000000>;
entry = <0xa0000000>;
hash@1 {
algo = "md5";
};
};
};
configurations {
default = "config@2";
config@1 {
description = "Just plain Linux";
kernel = "linux_kernel@1";
fdt = "fdt@1";
};
config@2 {
description = "Xen one loadable";
kernel = "xen_kernel@1";
fdt = "fdt@1";
loadables = "linux_kernel@1";
};
config@3 {
description = "Xen two loadables";
kernel = "xen_kernel@1";
fdt = "fdt@1";
loadables = "linux_kernel@1", "fdt@2";
};
};
+}; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 427ea49..004acd1 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -235,6 +235,7 @@ o config@1 |- kernel = "kernel sub-node unit name" |- ramdisk = "ramdisk sub-node unit name" |- fdt = "fdt sub-node unit-name"
|- loadables = "loadables sub-node unit-name"
Mandatory properties:
@@ -249,6 +250,9 @@ o config@1 "fdt type").
- setup : Unit name of the corresponding setup binary (used for booting an x86 kernel). This contains the setup.bin file built by the kernel.
- loadables : Unit name containing a list of additional binaries to be loaded at
try wrapping to 78 columns at most.
- their given locations. "loadables" is a comma-separated list of strings.
- u-boot will load each binary at its given start-address.
U-Boot
The FDT blob is required to properly boot FDT based kernel, so the minimal configuration for 2.6 FDT kernel is (kernel, fdt) pair. diff --git a/include/image.h b/include/image.h index 60b924a..97b96b3 100644 --- a/include/image.h +++ b/include/image.h @@ -742,6 +742,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end); #define FIT_KERNEL_PROP "kernel" #define FIT_RAMDISK_PROP "ramdisk" #define FIT_FDT_PROP "fdt" +#define FIT_LOADABLE_PROP "loadables" #define FIT_DEFAULT_PROP "default" #define FIT_SETUP_PROP "setup"
-- 2.3.7
Regards, Simon

From: Karl Apsite karl.apsite@dornerworks.com
Added a trimmed down instance of boot_get_<thing>() to satisfy the minimum requierments of the added feature. The function follows the normal patterns set by other boot_get<thing>'s, which should make it a bit easier to combine them all together into one boot_get_image() function in a later refactor.
Documentation for the new function can be found in source: include/image.h
Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com ---
Changes in v3: - Removed a couple zealous puts->printf conversions - Replaced an instance of puts I mistakenly included with printf
common/bootm.c | 22 +++++++++++++++++ common/image-fit.c | 8 +++++- common/image.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/bootstage.h | 1 + include/image.h | 27 +++++++++++++++++++- 5 files changed, 127 insertions(+), 2 deletions(-)
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..ecd3e67 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,11 @@ 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);

Hi Karl,
On 18 May 2015 at 16:27, Karl Apsite Karl.Apsite@dornerworks.com wrote:
From: Karl Apsite karl.apsite@dornerworks.com
Added a trimmed down instance of boot_get_<thing>() to satisfy the minimum requierments of the added feature. The function follows the normal patterns set by other boot_get<thing>'s, which should make it a bit easier to combine them all together into one boot_get_image() function in a later refactor.
Documentation for the new function can be found in source: include/image.h
Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com
Again some tiny nits.
Changes in v3:
- Removed a couple zealous puts->printf conversions
- Replaced an instance of puts I mistakenly included with printf
common/bootm.c | 22 +++++++++++++++++ common/image-fit.c | 8 +++++- common/image.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/bootstage.h | 1 + include/image.h | 27 +++++++++++++++++++- 5 files changed, 127 insertions(+), 2 deletions(-)
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..ecd3e67 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,11 @@ 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 */
Comment style:
/* * If either ... * ... * 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); -- 2.3.7
Regards, Simon

bootm_find_ramdisk_fdt() renamed to bootm_find_images() for readability.
The function bootm_find_ramdisk_fdt() appears to be a simple wrapper for bootm_find_ramdisk(), bootm_find_fdt(), and now bootm_find_loadables(). I didn't see any other callers entering a bootm_find<thing>, so removing the wrapper, and condensing these together hopefully makes the code a little simpler.
Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com ---
Changes in v3: None
common/bootm.c | 53 ++++++++++++++++++----------------------------------- common/cmd_bootm.c | 4 ++-- include/bootm.h | 2 +- 3 files changed, 21 insertions(+), 38 deletions(-)
diff --git a/common/bootm.c b/common/bootm.c index 07ae0f5..667c934 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -206,7 +206,23 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, return 0; }
-static int bootm_find_ramdisk(int flag, int argc, char * const argv[]) +/** + * bootm_find_images - wrapper to find and locate various images + * @flag: Ignored Argument + * @argc: command argument count + * @argv: command argument list + * + * boot_find_images() will attempt to load an available ramdisk, + * flattened device tree, as well as specifically marked + * "loadable" images (loadables are FIT only) + * + * Note: bootm_find_images will skip an image if it is not found + * + * @return: + * 0, if all existing images were loaded correctly + * 1, if an image is found but corrupted, or invalid + */ +int bootm_find_images(int flag, int argc, char * const argv[]) { int ret;
@@ -218,14 +234,7 @@ static int bootm_find_ramdisk(int flag, int argc, char * const argv[]) return 1; }
- return 0; -} - #if defined(CONFIG_OF_LIBFDT) -static int bootm_find_fdt(int flag, int argc, char * const argv[]) -{ - int ret; - /* find flattened device tree */ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images, &images.ft_addr, &images.ft_len); @@ -233,18 +242,10 @@ static int bootm_find_fdt(int flag, int argc, char * const argv[]) puts("Could not find a valid device tree\n"); return 1; } - set_working_fdt_addr((ulong)images.ft_addr); - - return 0; -} #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); @@ -252,24 +253,6 @@ static int bootm_find_loadables(int flag, int argc, char * const argv[]) 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)) - return 1; - -#if defined(CONFIG_OF_LIBFDT) - if (bootm_find_fdt(flag, argc, argv)) - return 1; -#endif - -#if defined(CONFIG_FIT) - if (bootm_find_loadables(flag, argc, argv)) - return 1; #endif
return 0; @@ -283,7 +266,7 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc, (images.os.type == IH_TYPE_MULTI)) && (images.os.os == IH_OS_LINUX || images.os.os == IH_OS_VXWORKS)) - return bootm_find_ramdisk_fdt(flag, argc, argv); + return bootm_find_images(flag, argc, argv);
return 0; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 6b6aca6..48738ac 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -580,7 +580,7 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_ramdisk_fdt(flag, argc, argv)) + if (bootm_find_images(flag, argc, argv)) return 1;
return 0; @@ -721,7 +721,7 @@ static int booti_start(cmd_tbl_t *cmdtp, int flag, int argc, * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not * have a header that provide this informaiton. */ - if (bootm_find_ramdisk_fdt(flag, argc, argv)) + if (bootm_find_images(flag, argc, argv)) return 1;
return 0; diff --git a/include/bootm.h b/include/bootm.h index 6181488..4981377 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -49,7 +49,7 @@ int boot_selected_os(int argc, char * const argv[], int state, ulong bootm_disable_interrupts(void);
/* This is a special function used by booti/bootz */ -int bootm_find_ramdisk_fdt(int flag, int argc, char * const argv[]); +int bootm_find_images(int flag, int argc, char * const argv[]);
int do_bootm_states(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], int states, bootm_headers_t *images, int boot_progress);

On 18 May 2015 at 16:27, Karl Apsite Karl.Apsite@dornerworks.com wrote:
bootm_find_ramdisk_fdt() renamed to bootm_find_images() for readability.
The function bootm_find_ramdisk_fdt() appears to be a simple wrapper for bootm_find_ramdisk(), bootm_find_fdt(), and now bootm_find_loadables(). I didn't see any other callers entering a bootm_find<thing>, so removing the wrapper, and condensing these together hopefully makes the code a little simpler.
Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com
Changes in v3: None
common/bootm.c | 53 ++++++++++++++++++----------------------------------- common/cmd_bootm.c | 4 ++-- include/bootm.h | 2 +- 3 files changed, 21 insertions(+), 38 deletions(-)
Acked-by: Simon Glass sjg@chromium.org

From: Karl Apsite karl.apsite@dornerworks.com
Nothing too fancy. A simple test that attmpts to load two loadables and verify that they are properly unpacked in the u-boot sandbox. Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com ---
Changes in v3: - Moved the commit that adds the test to the end of patch-stack
test/image/test-fit.py | 73 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 9 deletions(-)
diff --git a/test/image/test-fit.py b/test/image/test-fit.py index e9e756a..ef6b24f 100755 --- a/test/image/test-fit.py +++ b/test/image/test-fit.py @@ -48,6 +48,15 @@ base_its = ''' load = <0x40000>; entry = <0x8>; }; + kernel@2 { + data = /incbin/("%(loadables1)s"); + type = "kernel"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + %(loadables1_load)s + entry = <0x0>; + }; fdt@1 { description = "snow"; data = /incbin/("u-boot.dtb"); @@ -69,6 +78,15 @@ base_its = ''' %(ramdisk_load)s compression = "none"; }; + ramdisk@2 { + description = "snow"; + data = /incbin/("%(loadables2)s"); + type = "ramdisk"; + arch = "sandbox"; + os = "linux"; + %(loadables2_load)s + compression = "none"; + }; }; configurations { default = "conf@1"; @@ -76,6 +94,7 @@ base_its = ''' kernel = "kernel@1"; fdt = "fdt@1"; %(ramdisk_config)s + %(loadables_config)s }; }; }; @@ -103,6 +122,8 @@ bootm loados sb save hostfs 0 %(kernel_addr)x %(kernel_out)s %(kernel_size)x sb save hostfs 0 %(fdt_addr)x %(fdt_out)s %(fdt_size)x sb save hostfs 0 %(ramdisk_addr)x %(ramdisk_out)s %(ramdisk_size)x +sb save hostfs 0 %(loadables1_addr)x %(loadables1_out)s %(loadables1_size)x +sb save hostfs 0 %(loadables2_addr)x %(loadables2_out)s %(loadables2_size)x reset '''
@@ -188,30 +209,32 @@ def make_fit(mkimage, params): print >>fd, base_fdt return fit
-def make_kernel(): +def make_kernel(filename, text): """Make a sample kernel with test data
+ Args: + filename: the name of the file you want to create Returns: - Filename of kernel created + Full path and filename of the kernel it created """ - fname = make_fname('test-kernel.bin') + fname = make_fname(filename) data = '' for i in range(100): - data += 'this kernel %d is unlikely to boot\n' % i + data += 'this %s %d is unlikely to boot\n' % (text, i) with open(fname, 'w') as fd: print >>fd, data return fname
-def make_ramdisk(): +def make_ramdisk(filename, text): """Make a sample ramdisk with test data
Returns: Filename of ramdisk created """ - fname = make_fname('test-ramdisk.bin') + fname = make_fname(filename) data = '' for i in range(100): - data += 'ramdisk %d was seldom used in the middle ages\n' % i + data += '%s %d was seldom used in the middle ages\n' % (text, i) with open(fname, 'w') as fd: print >>fd, data return fname @@ -298,11 +321,15 @@ def run_fit_test(mkimage, u_boot):
# Set up invariant files control_dtb = make_dtb() - kernel = make_kernel() - ramdisk = make_ramdisk() + kernel = make_kernel('test-kernel.bin', 'kernel') + ramdisk = make_ramdisk('test-ramdisk.bin', 'ramdisk') + loadables1 = make_kernel('test-loadables1.bin', 'lenrek') + loadables2 = make_ramdisk('test-loadables2.bin', 'ksidmar') kernel_out = make_fname('kernel-out.bin') fdt_out = make_fname('fdt-out.dtb') ramdisk_out = make_fname('ramdisk-out.bin') + loadables1_out = make_fname('loadables1-out.bin') + loadables2_out = make_fname('loadables2-out.bin')
# Set up basic parameters with default values params = { @@ -324,6 +351,20 @@ def run_fit_test(mkimage, u_boot): 'ramdisk_size' : filesize(ramdisk), 'ramdisk_load' : '', 'ramdisk_config' : '', + + 'loadables1' : loadables1, + 'loadables1_out' : loadables1_out, + 'loadables1_addr' : 0x100000, + 'loadables1_size' : filesize(loadables1), + 'loadables1_load' : '', + + 'loadables2' : loadables2, + 'loadables2_out' : loadables2_out, + 'loadables2_addr' : 0x140000, + 'loadables2_size' : filesize(loadables2), + 'loadables2_load' : '', + + 'loadables_config' : '', }
# Make a basic FIT and a script to load it @@ -378,6 +419,19 @@ def run_fit_test(mkimage, u_boot): if read_file(ramdisk) != read_file(ramdisk_out): fail('Ramdisk not loaded', stdout)
+ # Configuration with some Loadables + set_test('Kernel + FDT + Ramdisk load + Loadables') + params['loadables_config'] = 'loadables = "kernel@2", "ramdisk@2";' + params['loadables1_load'] = 'load = <%#x>;' % params['loadables1_addr'] + params['loadables2_load'] = 'load = <%#x>;' % params['loadables2_addr'] + fit = make_fit(mkimage, params) + stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd) + debug_stdout(stdout) + if read_file(loadables1) != read_file(loadables1_out): + fail('Loadables1 (kernel) not loaded', stdout) + if read_file(loadables2) != read_file(loadables2_out): + fail('Loadables2 (ramdisk) not loaded', stdout) + def run_tests(): """Parse options, run the FIT tests and print the result""" global base_path, base_dir @@ -406,6 +460,7 @@ def run_tests(): title = 'FIT Tests' print title, '\n', '=' * len(title)
+ print "Output files are in '%s'" % base_dir run_fit_test(mkimage, options.u_boot)
print '\nTests passed'

On 18 May 2015 at 16:27, Karl Apsite Karl.Apsite@dornerworks.com wrote:
From: Karl Apsite karl.apsite@dornerworks.com
Nothing too fancy. A simple test that attmpts to load two loadables and verify that they are properly unpacked in the u-boot sandbox. Signed-off-by: Karl Apsite Karl.Apsite@dornerworks.com
Changes in v3:
- Moved the commit that adds the test to the end of patch-stack
test/image/test-fit.py | 73 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 9 deletions(-)
Acked-by: Simon Glass sjg@chromium.org
participants (2)
-
Karl Apsite
-
Simon Glass