Commit db1b79b886f085b5af09db9378f5c53417c3ecde
Committed by
Anatolij Gustschin
1 parent
7583f1f577
Exists in
smarc_8mq_lf_v2020.04
and in
22 other branches
splash: add support for loading splash from a FIT image
Enable support for loading a splash image from within a FIT image. The image is assumed to be generated with mkimage -E flag to hold the data external to the FIT. Signed-off-by: Tomas Melin <tomas.melin@vaisala.com> Acked-by: Igor Grinberg <grinberg@compulab.co.il>
Showing 5 changed files with 136 additions and 8 deletions Side-by-side Diff
common/image-fit.c
... | ... | @@ -778,6 +778,54 @@ |
778 | 778 | } |
779 | 779 | |
780 | 780 | /** |
781 | + * Get 'data-offset' property from a given image node. | |
782 | + * | |
783 | + * @fit: pointer to the FIT image header | |
784 | + * @noffset: component image node offset | |
785 | + * @data_offset: holds the data-offset property | |
786 | + * | |
787 | + * returns: | |
788 | + * 0, on success | |
789 | + * -ENOENT if the property could not be found | |
790 | + */ | |
791 | +int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset) | |
792 | +{ | |
793 | + const fdt32_t *val; | |
794 | + | |
795 | + val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL); | |
796 | + if (!val) | |
797 | + return -ENOENT; | |
798 | + | |
799 | + *data_offset = fdt32_to_cpu(*val); | |
800 | + | |
801 | + return 0; | |
802 | +} | |
803 | + | |
804 | +/** | |
805 | + * Get 'data-size' property from a given image node. | |
806 | + * | |
807 | + * @fit: pointer to the FIT image header | |
808 | + * @noffset: component image node offset | |
809 | + * @data_size: holds the data-size property | |
810 | + * | |
811 | + * returns: | |
812 | + * 0, on success | |
813 | + * -ENOENT if the property could not be found | |
814 | + */ | |
815 | +int fit_image_get_data_size(const void *fit, int noffset, int *data_size) | |
816 | +{ | |
817 | + const fdt32_t *val; | |
818 | + | |
819 | + val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL); | |
820 | + if (!val) | |
821 | + return -ENOENT; | |
822 | + | |
823 | + *data_size = fdt32_to_cpu(*val); | |
824 | + | |
825 | + return 0; | |
826 | +} | |
827 | + | |
828 | +/** | |
781 | 829 | * fit_image_hash_get_algo - get hash algorithm name |
782 | 830 | * @fit: pointer to the FIT format image header |
783 | 831 | * @noffset: hash node offset |
common/splash_source.c
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | #include <bmp_layout.h> |
11 | 11 | #include <errno.h> |
12 | 12 | #include <fs.h> |
13 | +#include <fdt_support.h> | |
13 | 14 | #include <image.h> |
14 | 15 | #include <nand.h> |
15 | 16 | #include <sata.h> |
... | ... | @@ -296,6 +297,72 @@ |
296 | 297 | return NULL; |
297 | 298 | } |
298 | 299 | |
300 | +#ifdef CONFIG_FIT | |
301 | +static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr) | |
302 | +{ | |
303 | + int res; | |
304 | + int node_offset; | |
305 | + int splash_offset; | |
306 | + int splash_size; | |
307 | + struct image_header *img_header; | |
308 | + const u32 *fit_header; | |
309 | + u32 fit_size; | |
310 | + const size_t header_size = sizeof(struct image_header); | |
311 | + | |
312 | + /* Read in image header */ | |
313 | + res = splash_storage_read_raw(location, bmp_load_addr, header_size); | |
314 | + if (res < 0) | |
315 | + return res; | |
316 | + | |
317 | + img_header = (struct image_header *)bmp_load_addr; | |
318 | + fit_size = fdt_totalsize(img_header); | |
319 | + | |
320 | + /* Read in entire FIT */ | |
321 | + fit_header = (const u32 *)(bmp_load_addr + header_size); | |
322 | + res = splash_storage_read_raw(location, (u32)fit_header, fit_size); | |
323 | + if (res < 0) | |
324 | + return res; | |
325 | + | |
326 | + res = fit_check_format(fit_header); | |
327 | + if (!res) { | |
328 | + debug("Could not find valid FIT image\n"); | |
329 | + return -EINVAL; | |
330 | + } | |
331 | + | |
332 | + node_offset = fit_image_get_node(fit_header, location->name); | |
333 | + if (node_offset < 0) { | |
334 | + debug("Could not find splash image '%s' in FIT\n", | |
335 | + location->name); | |
336 | + return -ENOENT; | |
337 | + } | |
338 | + | |
339 | + res = fit_image_get_data_offset(fit_header, node_offset, | |
340 | + &splash_offset); | |
341 | + if (res < 0) { | |
342 | + printf("Failed to load splash image (err=%d)\n", res); | |
343 | + return res; | |
344 | + } | |
345 | + | |
346 | + res = fit_image_get_data_size(fit_header, node_offset, &splash_size); | |
347 | + if (res < 0) { | |
348 | + printf("Failed to load splash image (err=%d)\n", res); | |
349 | + return res; | |
350 | + } | |
351 | + | |
352 | + /* Align data offset to 4-byte boundrary */ | |
353 | + fit_size = fdt_totalsize(fit_header); | |
354 | + fit_size = (fit_size + 3) & ~3; | |
355 | + | |
356 | + /* Read in the splash data */ | |
357 | + location->offset = (location->offset + fit_size + splash_offset); | |
358 | + res = splash_storage_read_raw(location, bmp_load_addr , splash_size); | |
359 | + if (res < 0) | |
360 | + return res; | |
361 | + | |
362 | + return 0; | |
363 | +} | |
364 | +#endif /* CONFIG_FIT */ | |
365 | + | |
299 | 366 | /** |
300 | 367 | * splash_source_load - load splash image from a supported location. |
301 | 368 | * |
... | ... | @@ -332,7 +399,10 @@ |
332 | 399 | return splash_load_raw(splash_location, bmp_load_addr); |
333 | 400 | else if (splash_location->flags & SPLASH_STORAGE_FS) |
334 | 401 | return splash_load_fs(splash_location, bmp_load_addr); |
335 | - | |
402 | +#ifdef CONFIG_FIT | |
403 | + else if (splash_location->flags == SPLASH_STORAGE_FIT) | |
404 | + return splash_load_fit(splash_location, bmp_load_addr); | |
405 | +#endif | |
336 | 406 | return -EINVAL; |
337 | 407 | } |
doc/README.splashprepare
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | common/splash.c. It is called as part of the splash screen display |
6 | 6 | sequence. It gives the board an opportunity to prepare the splash |
7 | 7 | image data before it is processed and sent to the frame buffer by |
8 | -U-Boot. Define your own version to use this feature. | |
8 | +U-Boot. Define your own version to use this feature. | |
9 | 9 | |
10 | 10 | CONFIG_SPLASH_SOURCE |
11 | 11 | |
... | ... | @@ -20,8 +20,13 @@ |
20 | 20 | - If splashsource is undefined, use the first splash location as default. |
21 | 21 | - If splashsource is set to an unsupported value, do not load a splash screen. |
22 | 22 | |
23 | -A splash source location can describe either storage with raw data, or storage | |
24 | -formatted with a file system. In case of a filesystem, the splash screen data is | |
25 | -loaded as a file. The name of the splash screen file can be controlled with the | |
26 | -environment variable "splashfile". | |
23 | +A splash source location can describe either storage with raw data, a storage | |
24 | +formatted with a file system or a FIT image. In case of a filesystem, the splash | |
25 | +screen data is loaded as a file. The name of the splash screen file can be | |
26 | +controlled with the environment variable "splashfile". | |
27 | + | |
28 | +To enable loading the splash image from a FIT image, CONFIG_FIT must be | |
29 | +enabled. Struct splash_location field 'name' should match the splash image | |
30 | +name within the FIT and the FIT should start at the 'offset' field address in | |
31 | +the specified storage. |
include/image.h
... | ... | @@ -872,6 +872,8 @@ |
872 | 872 | |
873 | 873 | /* image node */ |
874 | 874 | #define FIT_DATA_PROP "data" |
875 | +#define FIT_DATA_OFFSET_PROP "data-offset" | |
876 | +#define FIT_DATA_SIZE_PROP "data-size" | |
875 | 877 | #define FIT_TIMESTAMP_PROP "timestamp" |
876 | 878 | #define FIT_DESC_PROP "description" |
877 | 879 | #define FIT_ARCH_PROP "arch" |
... | ... | @@ -950,6 +952,8 @@ |
950 | 952 | int fit_image_get_entry(const void *fit, int noffset, ulong *entry); |
951 | 953 | int fit_image_get_data(const void *fit, int noffset, |
952 | 954 | const void **data, size_t *size); |
955 | +int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset); | |
956 | +int fit_image_get_data_size(const void *fit, int noffset, int *data_size); | |
953 | 957 | |
954 | 958 | int fit_image_hash_get_algo(const void *fit, int noffset, char **algo); |
955 | 959 | int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, |
include/splash.h
... | ... | @@ -33,8 +33,9 @@ |
33 | 33 | }; |
34 | 34 | |
35 | 35 | enum splash_flags { |
36 | - SPLASH_STORAGE_RAW, | |
37 | - SPLASH_STORAGE_FS, | |
36 | + SPLASH_STORAGE_RAW, /* Stored in raw memory */ | |
37 | + SPLASH_STORAGE_FS, /* Stored within a file system */ | |
38 | + SPLASH_STORAGE_FIT, /* Stored inside a FIT image */ | |
38 | 39 | }; |
39 | 40 | |
40 | 41 | struct splash_location { |