[U-Boot] [PATCH] spl: dm: Make it possible for the SPL to pick its own DTB from a FIT
Jean-Jacques Hiblot
jjhiblot at ti.com
Fri Jul 7 13:51:41 UTC 2017
Hi all,
I forgot to mention in the title that it is a RFC only. I'd like to know
if you think that this feature is desirable or not. and if the approach
seems correct. If so I will send a proper patch later with the proper
Kconfig description and proposed modifications.
Jean-Jacques
On 07/07/2017 15:46, Jean-Jacques Hiblot wrote:
> + Tom Rini <trini at konsulko.com>
>
>
> On 07/07/2017 13:44, Jean-Jacques Hiblot wrote:
>> u-boot can be embedded within a FIT image with multiple DTBs. It then
>> selects at run-time which one is best suited for the platform.
>> Use the same principle here for the SPL: put the DTBs in a FIT image,
>> compress it (LZO, GZIP, or no compression) and append it at the end
>> of the
>> SPL.
>>
>> Signed-off-by: Jean-Jacques Hiblot <jjhiblot at ti.com>
>> ---
>>
>> The impact in terms of boot time is not high when using LZO but I
>> gues it can vary
>> from platform to platform.
>> The size of the SPL binary is increased (1.5kB more code on ARM), but
>> the compression
>> really flattens the DTBS. so at the end of the day, enabling this
>> option doesn't add much.
>>
>> Here are some sumbers with a DRA7 platform (numbers in bytes):
>> size delta with ref
>> MLO.reference 123450
>> MLO.lzo_1_DTB 123715 +265
>> MLO.lzo_4_DTB 124237 +787
>> MLO.gzip_4_DTB 132006 +8556
>> MLO.no_comp_4_DTB 134184 +10734
>>
>> common/spl/spl_fit.c | 2 +-
>> dts/Kconfig | 48 ++++++++++++++++++++++++++++++++++
>> dts/Makefile | 18 +++++++++++--
>> include/spl.h | 15 +++++++++++
>> lib/Kconfig | 11 ++++++++
>> lib/Makefile | 6 ++---
>> lib/fdtdec.c | 73
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> scripts/Makefile.spl | 35 ++++++++++++++++++++++++-
>> 8 files changed, 201 insertions(+), 7 deletions(-)
>>
>> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
>> index 4c42a96..3479b05 100644
>> --- a/common/spl/spl_fit.c
>> +++ b/common/spl/spl_fit.c
>> @@ -75,7 +75,7 @@ static int spl_fit_find_config_node(const void *fdt)
>> * Return: the node offset of the respective image node or a
>> negative
>> * error number.
>> */
>> -static int spl_fit_get_image_node(const void *fit, int images,
>> +int spl_fit_get_image_node(const void *fit, int images,
>> const char *type, int index)
>> {
>> const char *name, *str;
>> diff --git a/dts/Kconfig b/dts/Kconfig
>> index b3009af..80f21e0 100644
>> --- a/dts/Kconfig
>> +++ b/dts/Kconfig
>> @@ -99,6 +99,54 @@ config OF_LIST
>> reading a board ID value). This is a list of device tree files
>> (without the directory or .dtb suffix) separated by <space>.
>> +
>> +config SPL_MULTI_DTB
>> + depends on SPL_LOAD_FIT && SPL_OF_CONTROL && !SPL_OF_PLATDATA
>> + bool "support embedding several DTB in the SPL"
>> + default n
>> +
>> +config SPL_OF_LIST
>> + string "List of device tree files to include for DT control in SPL"
>> + depends on SPL_MULTI_DTB
>> + default OF_LIST
>> + help
>> + blablablabla
>> +
>> +choice
>> + prompt "SPL OF LIST compression"
>> + depends on SPL_MULTI_DTB
>> + default SPL_MULTI_DTB_LZO
>> +
>> +config SPL_MULTI_DTB_LZO
>> + bool "Compress the DTBs with LZO"
>> + depends on SYS_MALLOC_F
>> + select SPL_LZO
>> + help
>> + Compres the FIT image containing the DTBs available for the SPL
>> + using LZO compression. (requires lzop on host).
>> +
>> +config SPL_MULTI_DTB_GZ
>> + bool "Compress the DTBs with GZip"
>> + depends on SYS_MALLOC_F
>> + select SPL_GZIP
>> + help
>> + Compres the FIT image containing the DTBs available for the SPL
>> + using GZIP compression. (requires gzip on host)
>> +
>> +config SPL_MULTI_DTB_NO_COMPRESSION
>> + bool "do not compress the DTBs"
>> + help
>> + Do not tompres the FIT image containing the DTBs available for
>> the SPL.
>> + Use this options only if LZO is not available and the DTBs are
>> very small.
>> +endchoice
>> +
>> +config SPL_MULTI_DTB_GZ_SZ
>> + hex "Size of mmemory allocated to uncompress the dtbs"
>> + depends on SYS_MALLOC_F && (SPL_MULTI_DTB_GZ || SPL_MULTI_DTB_LZO)
>> + default 0x10000
>> + help
>> + blablabla
>> +
>> config OF_SPL_REMOVE_PROPS
>> string "List of device tree properties to drop for SPL"
>> depends on SPL_OF_CONTROL
>> diff --git a/dts/Makefile b/dts/Makefile
>> index 3a93daf..5cab6bd 100644
>> --- a/dts/Makefile
>> +++ b/dts/Makefile
>> @@ -22,9 +22,23 @@ DTB := $(ARCH_PATH)/$(DEVICE_TREE).dtb
>> dtb_depends += $(DTB:.dtb=.dts)
>> endif
>> +
>> +ARCH_SPL_DTB := $(patsubst %,$(ARCH_PATH)/%.dtb,$(subst
>> ",,$(CONFIG_SPL_OF_LIST)))
>> +LOCAL_SPL_DTBS := $(patsubst %,$(obj)/%.dtb,$(subst
>> ",,$(CONFIG_SPL_OF_LIST)))
>> +
>> +.PHONY: arch-dtbs
>> +
>> $(obj)/dt.dtb: $(DTB) FORCE
>> $(call if_changed,shipped)
>> +ARCH_SPL_DTB_EXECPT_ONE := $(filter-out $(DTB),$(ARCH_SPL_DTB))
>> +$(ARCH_SPL_DTB_EXECPT_ONE): arch-dtbs
>> + @
>> +
>> +.SECONDEXPANSION:
>> +$(LOCAL_SPL_DTBS): $$(patsubst $(TARGETDIR)/%, %, arch/$(ARCH)/$$@)
>> + $(shell cp $< $@)
>> +
>> targets += dt.dtb
>> $(DTB): $(dtb_depends)
>> @@ -46,10 +60,10 @@ arch-dtbs:
>> obj-$(CONFIG_OF_EMBED) := dt.dtb.o
>> -dtbs: $(obj)/dt.dtb
>> +dtbs: $(obj)/dt.dtb $(LOCAL_SPL_DTBS)
>> @:
>> -clean-files := dt.dtb.S
>> +clean-files := dt.dtb.S *.dtb
>> # Let clean descend into dts directories
>> subdir- += ../arch/arm/dts ../arch/microblaze/dts ../arch/mips/dts
>> ../arch/sandbox/dts ../arch/x86/dts
>> diff --git a/include/spl.h b/include/spl.h
>> index ffadce9..8ff96c3 100644
>> --- a/include/spl.h
>> +++ b/include/spl.h
>> @@ -49,6 +49,21 @@ struct spl_load_info {
>> };
>> /**
>> + * spl_fit_get_image_node(): By using the matching configuration
>> subnode,
>> + * retrieve the name of an image, specified by a property name and
>> an index
>> + * into that.
>> + * @fit: Pointer to the FDT blob.
>> + * @images: Offset of the /images subnode.
>> + * @type: Name of the property within the configuration subnode.
>> + * @index: Index into the list of strings in this property.
>> + *
>> + * Return: the node offset of the respective image node or a
>> negative
>> + * error number.
>> + */
>> +int spl_fit_get_image_node(const void *fit, int images,
>> + const char *type, int index);
>> +
>> +/**
>> * spl_load_simple_fit() - Loads a fit image from a device.
>> * @spl_image: Image description to set up
>> * @info: Structure containing the information required to load
>> data.
>> diff --git a/lib/Kconfig b/lib/Kconfig
>> index 09670f0..6865325 100644
>> --- a/lib/Kconfig
>> +++ b/lib/Kconfig
>> @@ -158,6 +158,17 @@ config LZMA
>> config LZO
>> bool
>> +
>> +config SPL_LZO
>> + bool
>> +
>> +config SPL_GZIP
>> + bool
>> + depends on SPL_ZLIB
>> +
>> +config SPL_ZLIB
>> + bool
>> +
>> endmenu
>> config ERRNO_STR
>> diff --git a/lib/Makefile b/lib/Makefile
>> index eacc7d6..82b2de0 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -4,14 +4,15 @@
>> #
>> # SPDX-License-Identifier: GPL-2.0+
>> #
>> +obj-$(CONFIG_$(SPL_)ZLIB) += zlib/
>> +obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o
>> +obj-$(CONFIG_$(SPL_)LZO) += lzo/
>> ifndef CONFIG_SPL_BUILD
>> -
>> obj-$(CONFIG_EFI) += efi/
>> obj-$(CONFIG_EFI_LOADER) += efi_loader/
>> obj-$(CONFIG_LZMA) += lzma/
>> obj-$(CONFIG_LZO) += lzo/
>> -obj-$(CONFIG_ZLIB) += zlib/
>> obj-$(CONFIG_BZIP2) += bzip2/
>> obj-$(CONFIG_TIZEN) += tizen/
>> obj-$(CONFIG_FIT) += libfdt/
>> @@ -26,7 +27,6 @@ obj-y += crc16.o
>> obj-$(CONFIG_ERRNO_STR) += errno_str.o
>> obj-$(CONFIG_FIT) += fdtdec_common.o
>> obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
>> -obj-$(CONFIG_GZIP) += gunzip.o
>> obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
>> obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
>> obj-y += initcall.o
>> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
>> index 91503b8..68322d8 100644
>> --- a/lib/fdtdec.c
>> +++ b/lib/fdtdec.c
>> @@ -7,6 +7,8 @@
>> #include <common.h>
>> #include <dm.h>
>> #include <errno.h>
>> +#include <spl.h>
>> +#include <linux/lzo.h>
>> #include <serial.h>
>> #include <libfdt.h>
>> #include <fdt_support.h>
>> @@ -1208,6 +1210,65 @@ int fdtdec_setup_memory_banksize(void)
>> }
>> #endif
>> +#if defined(CONFIG_SPL_MULTI_DTB) && defined(CONFIG_SPL_BUILD)
>> +const void *get_dtb_blob_from_fit(const void *fit)
>> +{
>> + int node, images;
>> + ulong fit_size, offset;
>> +
>> +#if defined(CONFIG_SPL_MULTI_DTB_GZ) ||
>> defined(CONFIG_SPL_MULTI_DTB_LZO)
>> + if (image_get_magic(fit) != FDT_MAGIC) {
>> + /* not a valid FIT, maybe it is a compressed fit */
>> + void *dst = malloc(CONFIG_SPL_MULTI_DTB_GZ_SZ);
>> + size_t sz_out = CONFIG_SPL_MULTI_DTB_GZ_SZ;
>> + ulong sz_in = 1024*1024; /* not more than 1MB */
>> + if (!dst) {
>> + puts("Unable to allocate memory to uncompress the DTBs\n");
>> + return NULL;
>> + }
>> +#ifdef CONFIG_SPL_MULTI_DTB_GZ
>> + int rc = gunzip(dst, sz_out,
>> + (u8 *)fit, &sz_in);
>> +#elif defined CONFIG_SPL_MULTI_DTB_LZO
>> + int rc = lzop_decompress(fit, sz_in, dst, &sz_out);
>> +#endif
>> + if (rc < 0) {
>> + /* not a valid compressed blob */
>> + free(dst);
>> + return NULL;
>> + }
>> + fit = dst;
>> + }
>> +#endif
>> +
>> + if (image_get_magic(fit) != FDT_MAGIC) {
>> + debug("not a FIT image\n");
>> + return NULL;
>> + }
>> +
>> + fit_size = fdt_totalsize(fit);
>> + fit_size = (fit_size + 3) & ~3; /* align on 32bit upper boundary */
>> +
>> + /* find the node holding the images information */
>> + images = fdt_path_offset(fit, FIT_IMAGES_PATH);
>> + if (images < 0) {
>> + debug("could not find the '/images' node\n");
>> + return NULL;
>> + }
>> +
>> + /* Figure out which device tree the board wants to use */
>> + node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
>> + if (node < 0)
>> + return NULL;
>> +
>> + offset = fdtdec_get_int(fit, node, "data-offset", -1);
>> + if (offset < 0)
>> + return NULL;
>> +
>> + return fit + fit_size + offset;
>> +}
>> +#endif
>> +
>> int fdtdec_setup(void)
>> {
>> #if CONFIG_IS_ENABLED(OF_CONTROL)
>> @@ -1239,6 +1300,18 @@ int fdtdec_setup(void)
>> gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
>> (uintptr_t)gd->fdt_blob);
>> # endif
>> +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_MULTI_DTB)
>> + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
>> + const void *fdt_blob;
>> + fdt_blob = get_dtb_blob_from_fit(gd->fdt_blob);
>> + if (fdt_blob) {
>> + debug("found FIT containg several DTBs\n");
>> + gd->fdt_blob = fdt_blob;
>> + } else {
>> + debug("legacy DTB file\n");
>> + }
>> + }
>> +#endif
>> #endif
>> return fdtdec_prepare_fdt();
>> }
>> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
>> index ac3c2c7..39aa939 100644
>> --- a/scripts/Makefile.spl
>> +++ b/scripts/Makefile.spl
>> @@ -202,10 +202,21 @@ cmd_cat = cat $(filter-out $(PHONY), $^) > $@
>> quiet_cmd_copy = COPY $@
>> cmd_copy = cp $< $@
>> +ifneq ($(CONFIG_SPL_MULTI_DTB),y)
>> +FINAL_DTB_CONTAINER = $(obj)/$(SPL_BIN).dtb
>> +else ifeq ($(CONFIG_SPL_MULTI_DTB_LZO),y)
>> +FINAL_DTB_CONTAINER = $(obj)/$(SPL_BIN).multidtb.fit.lzo
>> +else ifeq ($(CONFIG_SPL_MULTI_DTB_GZ),y)
>> +FINAL_DTB_CONTAINER = $(obj)/$(SPL_BIN).multidtb.fit.gz
>> +else
>> +FINAL_DTB_CONTAINER = $(obj)/$(SPL_BIN).multidtb.fit
>> +endif
>> +
>> +
>> ifeq
>> ($(CONFIG_SPL_OF_CONTROL)$(CONFIG_OF_SEPARATE)$(CONFIG_SPL_OF_PLATDATA),yy)
>> $(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN)-nodtb.bin \
>> $(if $(CONFIG_SPL_SEPARATE_BSS),,$(obj)/$(SPL_BIN)-pad.bin) \
>> - $(obj)/$(SPL_BIN).dtb FORCE
>> + $(FINAL_DTB_CONTAINER) FORCE
>> $(call if_changed,cat)
>> $(obj)/$(SPL_BIN).bin: $(obj)/$(SPL_BIN)-dtb.bin FORCE
>> @@ -369,6 +380,28 @@ checkdtoc: tools
>> PHONY += FORCE
>> FORCE:
>> +PHONY += dtbs
>> +dtbs:
>> + $(Q)$(MAKE) $(build)=dts dtbs
>> +
>> # Declare the contents of the .PHONY variable as phony. We keep that
>> # information in a variable so we can use it in if_changed and
>> friends.
>> .PHONY: $(PHONY)
>> +
>> +SHRUNK_ARCH_DTB = $(patsubst %,$(obj)/dts/%.dtb,$(subst
>> ",,$(CONFIG_SPL_OF_LIST)))
>> +.SECONDEXPANSION:
>> +$(SHRUNK_ARCH_DTB): $$(patsubst $(obj)/dts/%, arch/$(ARCH)/dts/%, $$@)
>> + $(call if_changed,fdtgrep)
>> +
>> +MKIMAGEFLAGS_$(SPL_BIN).multidtb.fit = -f auto -A $(ARCH) -T
>> firmware -C none -O u-boot \
>> + -n "Multi DTB fit image for $(SPL_BIN) JJH" -E \
>> + $(patsubst %,-b $(obj)/dts/%.dtb,$(subst ",,$(CONFIG_SPL_OF_LIST)))
>> +
>> +$(obj)/$(SPL_BIN).multidtb.fit: /dev/null $(SHRUNK_ARCH_DTB) FORCE
>> + $(call if_changed,mkimage)
>> +
>> +$(obj)/$(SPL_BIN).multidtb.fit.gz: $(obj)/$(SPL_BIN).multidtb.fit
>> + @gzip -kf9 $< > $@
>> +
>> +$(obj)/$(SPL_BIN).multidtb.fit.lzo: $(obj)/$(SPL_BIN).multidtb.fit
>> + @lzop -f9 $< > $@
>> \ No newline at end of file
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
More information about the U-Boot
mailing list