[U-Boot] [PATCH v4 05/20] SPL: FIT: allow loading multiple images
Kever Yang
kever.yang at rock-chips.com
Tue May 16 01:37:06 UTC 2017
On 04/26/2017 08:32 AM, Andre Przywara wrote:
> So far we were not using the FIT image format to its full potential:
> The SPL FIT loader was just loading the first image from the /images
> node plus one of the listed DTBs.
> Now with the refactored loader code it's easy to load an arbitrary
> number of images in addition to the two mentioned above.
> As described in the FIT image source file format description, iterate
> over all images listed at the "loadables" property in the configuration
> node and load every image at its desired location.
> This allows to load any kind of images:
> - firmware images to execute before U-Boot proper (for instance
> ARM Trusted Firmware (ATF))
> - firmware images for management processors (SCP, arisc, ...)
> - firmware images for devices like WiFi controllers
> - bit files for FPGAs
> - additional configuration data
> - kernels and/or ramdisks
> The actual usage of this feature would be platform and/or board specific.
>
> Also update the FIT documentation to mention the new SPL feature and
> provide an example .its file to demonstrate its features.
>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> Reviewed-by: Lokesh Vutla <lokeshvuta at ti.com>
> Reviewed-by: Simon Glass <sjg at chromium.org>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>
Tested-by: Kever Yang <kever.yang at rock-chips.com>
Thanks,
- Kever
> ---
> common/spl/spl_fit.c | 42 ++++++++++++++++++++-
> doc/uImage.FIT/howto.txt | 21 +++++++++++
> doc/uImage.FIT/multi_spl.its | 89 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 150 insertions(+), 2 deletions(-)
> create mode 100644 doc/uImage.FIT/multi_spl.its
>
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> index 9d9338c..4c42a96 100644
> --- a/common/spl/spl_fit.c
> +++ b/common/spl/spl_fit.c
> @@ -234,6 +234,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
> struct spl_image_info image_info;
> int node, images, ret;
> int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
> + int index = 0;
>
> /*
> * Figure out where the external images start. This is the base for the
> @@ -278,6 +279,11 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
> if (node < 0) {
> debug("could not find firmware image, trying loadables...\n");
> node = spl_fit_get_image_node(fit, images, "loadables", 0);
> + /*
> + * If we pick the U-Boot image from "loadables", start at
> + * the second image when later loading additional images.
> + */
> + index = 1;
> }
> if (node < 0) {
> debug("%s: Cannot find u-boot image node: %d\n",
> @@ -305,6 +311,38 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
> * Align the destination address to ARCH_DMA_MINALIGN.
> */
> image_info.load_addr = spl_image->load_addr + spl_image->size;
> - return spl_load_fit_image(info, sector, fit, base_offset, node,
> - &image_info);
> + ret = spl_load_fit_image(info, sector, fit, base_offset, node,
> + &image_info);
> + if (ret < 0)
> + return ret;
> +
> + /* Now check if there are more images for us to load */
> + for (; ; index++) {
> + node = spl_fit_get_image_node(fit, images, "loadables", index);
> + if (node < 0)
> + break;
> +
> + ret = spl_load_fit_image(info, sector, fit, base_offset, node,
> + &image_info);
> + if (ret < 0)
> + continue;
> +
> + /*
> + * If the "firmware" image did not provide an entry point,
> + * use the first valid entry point from the loadables.
> + */
> + if (spl_image->entry_point == FDT_ERROR &&
> + image_info.entry_point != FDT_ERROR)
> + spl_image->entry_point = image_info.entry_point;
> + }
> +
> + /*
> + * If a platform does not provide CONFIG_SYS_UBOOT_START, U-Boot's
> + * Makefile will set it to 0 and it will end up as the entry point
> + * here. What it actually means is: use the load address.
> + */
> + if (spl_image->entry_point == FDT_ERROR || spl_image->entry_point == 0)
> + spl_image->entry_point = spl_image->load_addr;
> +
> + return 0;
> }
> diff --git a/doc/uImage.FIT/howto.txt b/doc/uImage.FIT/howto.txt
> index 14e316f..2988a52 100644
> --- a/doc/uImage.FIT/howto.txt
> +++ b/doc/uImage.FIT/howto.txt
> @@ -44,6 +44,27 @@ image source file mkimage + dtc transfer to target
> + ---------------> image file --------------------> bootm
> image data file(s)
>
> +SPL usage
> +---------
> +
> +The SPL can make use of the new image format as well, this traditionally
> +is used to ship multiple device tree files within one image. Code in the SPL
> +will choose the one matching the current board and append this to the
> +U-Boot proper binary to be automatically used up by it.
> +Aside from U-Boot proper and one device tree blob the SPL can load multiple,
> +arbitrary image files as well. These binaries should be specified in their
> +own subnode under the /images node, which should then be referenced from one or
> +multiple /configurations subnodes. The required images must be enumerated in
> +the "loadables" property as a list of strings.
> +
> +If a platform specific image source file (.its) is shipped with the U-Boot
> +source, it can be specified using the CONFIG_SPL_FIT_SOURCE Kconfig symbol.
> +In this case it will be automatically used by U-Boot's Makefile to generate
> +the image.
> +If a static source file is not flexible enough, CONFIG_SPL_FIT_GENERATOR
> +can point to a script which generates this image source file during
> +the build process. It gets passed a list of device tree files (taken from the
> +CONFIG_OF_LIST symbol).
>
> Example 1 -- old-style (non-FDT) kernel booting
> -----------------------------------------------
> diff --git a/doc/uImage.FIT/multi_spl.its b/doc/uImage.FIT/multi_spl.its
> new file mode 100644
> index 0000000..e5551d4
> --- /dev/null
> +++ b/doc/uImage.FIT/multi_spl.its
> @@ -0,0 +1,89 @@
> +/dts-v1/;
> +
> +/*
> + * (Bogus) example FIT image description file demonstrating the usage
> + * of multiple images loaded by the SPL.
> + * Several binaries will be loaded at their respective load addresses.
> + * Finally the one image specifying an entry point will be entered by the SPL.
> + */
> +
> +/ {
> + description = "multiple firmware blobs and U-Boot, loaded by SPL";
> + #address-cells = <0x1>;
> +
> + images {
> +
> + uboot {
> + description = "U-Boot (64-bit)";
> + type = "standalone";
> + arch = "arm64";
> + compression = "none";
> + load = <0x4a000000>;
> + };
> +
> + atf {
> + description = "ARM Trusted Firmware";
> + type = "firmware";
> + arch = "arm64";
> + compression = "none";
> + load = <0x18000>;
> + entry = <0x18000>;
> + };
> +
> + mgmt-firmware {
> + description = "arisc management processor firmware";
> + type = "firmware";
> + arch = "or1k";
> + compression = "none";
> + load = <0x40000>;
> + };
> +
> + fdt at 1 {
> + description = "Pine64+ DT";
> + type = "flat_dt";
> + compression = "none";
> + load = <0x4fa00000>;
> + arch = "arm64";
> + };
> +
> + fdt at 2 {
> + description = "Pine64 DT";
> + type = "flat_dt";
> + compression = "none";
> + load = <0x4fa00000>;
> + arch = "arm64";
> + };
> +
> + kernel {
> + description = "4.7-rc5 kernel";
> + type = "kernel";
> + compression = "none";
> + load = <0x40080000>;
> + arch = "arm64";
> + };
> +
> + initrd {
> + description = "Debian installer initrd";
> + type = "ramdisk";
> + compression = "none";
> + load = <0x4fe00000>;
> + arch = "arm64";
> + };
> + };
> +
> + configurations {
> + default = "config at 1";
> +
> + config at 1 {
> + description = "sun50i-a64-pine64-plus";
> + loadables = "uboot", "atf", "kernel", "initrd";
> + fdt = "fdt at 1";
> + };
> +
> + config at 2 {
> + description = "sun50i-a64-pine64";
> + loadables = "uboot", "atf", "mgmt-firmware";
> + fdt = "fdt at 2";
> + };
> + };
> +};
More information about the U-Boot
mailing list