[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