[U-Boot] [PATCH v6 2/3] fit: Support compression for non-kernel components (e.g. FDT)
Simon Goldschmidt
simon.k.r.goldschmidt at gmail.com
Thu Jul 25 04:39:03 UTC 2019
Julius Werner <jwerner at chromium.org> schrieb am Do., 25. Juli 2019, 04:38:
> This patch adds support for compressing non-kernel image nodes in a FIT
> image (kernel nodes could already be compressed previously). This can
> reduce the size of FIT images and therefore improve boot times
> (especially when an image bundles many different kernel FDTs). The
> images will automatically be decompressed on load.
>
> This patch does not support extracting compatible strings from
> compressed FDTs, so it's not very helpful in conjunction with
> CONFIG_FIT_BEST_MATCH yet, but it can already be used in environments
> that select the configuration to load explicitly.
>
> Signed-off-by: Julius Werner <jwerner at chromium.org>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
---
> - Changes for v2:
> - Changed from only supporting compressed FDTs to supporting all
> non-kernel image node types.
> - Changes for v3:
> - Fixed up some debug output that was still written for v1.
> - Fixed a mistake with handling FIT_LOAD_OPTIONAL_NON_ZERO when
> 'load' was 0 (i.e. unset).
> - Added compression test case to the test_fit pytest.
> - No changes for v4
> - No changes for v5
> - No changes for v6
>
> common/image-fit.c | 86 +++++++++++++++++++++++----------------
> test/py/tests/test_fit.py | 29 +++++++++++--
> 2 files changed, 77 insertions(+), 38 deletions(-)
>
> diff --git a/common/image-fit.c b/common/image-fit.c
> index a74b44f298..c9ffc441aa 100644
> --- a/common/image-fit.c
> +++ b/common/image-fit.c
> @@ -22,6 +22,7 @@
> DECLARE_GLOBAL_DATA_PTR;
> #endif /* !USE_HOSTCC*/
>
> +#include <bootm.h>
> #include <image.h>
> #include <bootstage.h>
> #include <u-boot/crc.h>
> @@ -1576,6 +1577,13 @@ int fit_conf_find_compat(const void *fit, const
> void *fdt)
> kfdt_name);
> continue;
> }
> +
> + if (!fit_image_check_comp(fit, kfdt_noffset,
> IH_COMP_NONE)) {
> + debug("Can't extract compat from \"%s\"
> (compressed)\n",
> + kfdt_name);
> + continue;
> + }
> +
> /*
> * Get a pointer to this configuration's fdt.
> */
> @@ -1795,11 +1803,12 @@ int fit_image_load(bootm_headers_t *images, ulong
> addr,
> const char *fit_uname_config;
> const char *fit_base_uname_config;
> const void *fit;
> - const void *buf;
> + void *buf;
> + void *loadbuf;
> size_t size;
> int type_ok, os_ok;
> - ulong load, data, len;
> - uint8_t os;
> + ulong load, load_end, data, len;
> + uint8_t os, comp;
> #ifndef USE_HOSTCC
> uint8_t os_arch;
> #endif
> @@ -1895,12 +1904,6 @@ int fit_image_load(bootm_headers_t *images, ulong
> addr,
> images->os.arch = os_arch;
> #endif
>
> - if (image_type == IH_TYPE_FLATDT &&
> - !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
> - puts("FDT image is compressed");
> - return -EPROTONOSUPPORT;
> - }
> -
> bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
> type_ok = fit_image_check_type(fit, noffset, image_type) ||
> fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
> @@ -1931,7 +1934,8 @@ int fit_image_load(bootm_headers_t *images, ulong
> addr,
> bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
>
> /* get image data address and length */
> - if (fit_image_get_data_and_size(fit, noffset, &buf, &size)) {
> + if (fit_image_get_data_and_size(fit, noffset,
> + (const void **)&buf, &size)) {
> printf("Could not find %s subimage data!\n", prop_name);
> bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
> return -ENOENT;
> @@ -1939,30 +1943,15 @@ int fit_image_load(bootm_headers_t *images, ulong
> addr,
>
> #if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS)
> /* perform any post-processing on the image data */
> - board_fit_image_post_process((void **)&buf, &size);
> + board_fit_image_post_process(&buf, &size);
> #endif
>
> len = (ulong)size;
>
> - /* verify that image data is a proper FDT blob */
> - if (image_type == IH_TYPE_FLATDT && fdt_check_header(buf)) {
> - puts("Subimage data is not a FDT");
> - return -ENOEXEC;
> - }
> -
> bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
>
> - /*
> - * Work-around for eldk-4.2 which gives this warning if we try to
> - * cast in the unmap_sysmem() call:
> - * warning: initialization discards qualifiers from pointer target
> type
> - */
> - {
> - void *vbuf = (void *)buf;
> -
> - data = map_to_sysmem(vbuf);
> - }
> -
> + data = map_to_sysmem(buf);
> + load = data;
> if (load_op == FIT_LOAD_IGNORED) {
> /* Don't load */
> } else if (fit_image_get_load(fit, noffset, &load)) {
> @@ -1974,8 +1963,6 @@ int fit_image_load(bootm_headers_t *images, ulong
> addr,
> }
> } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
> ulong image_start, image_end;
> - ulong load_end;
> - void *dst;
>
> /*
> * move image data to the load address,
> @@ -1993,14 +1980,45 @@ int fit_image_load(bootm_headers_t *images, ulong
> addr,
>
> printf(" Loading %s from 0x%08lx to 0x%08lx\n",
> prop_name, data, load);
> + } else {
> + load = data; /* No load address specified */
> + }
> +
> + comp = IH_COMP_NONE;
> + loadbuf = buf;
> + /* Kernel images get decompressed later in bootm_load_os(). */
> + if (!(image_type == IH_TYPE_KERNEL ||
> + image_type == IH_TYPE_KERNEL_NOLOAD) &&
> + !fit_image_get_comp(fit, noffset, &comp) &&
> + comp != IH_COMP_NONE) {
> + ulong max_decomp_len = len * 20;
> + if (load == data) {
> + loadbuf = malloc(max_decomp_len);
> + load = map_to_sysmem(loadbuf);
> + } else {
> + loadbuf = map_sysmem(load, max_decomp_len);
> + }
> + if (image_decomp(comp, load, data, image_type,
> + loadbuf, buf, len, max_decomp_len,
> &load_end)) {
> + printf("Error decompressing %s\n", prop_name);
>
> - dst = map_sysmem(load, len);
> - memmove(dst, buf, len);
> - data = load;
> + return -ENOEXEC;
> + }
> + len = load_end - load;
> + } else if (load != data) {
> + loadbuf = map_sysmem(load, len);
> + memcpy(loadbuf, buf, len);
> }
> +
> + /* verify that image data is a proper FDT blob */
> + if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
> + puts("Subimage data is not a FDT");
> + return -ENOEXEC;
> + }
> +
> bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
>
> - *datap = data;
> + *datap = load;
> *lenp = len;
> if (fit_unamep)
> *fit_unamep = (char *)fit_uname;
> diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py
> index 49d6fea571..8009d2907b 100755
> --- a/test/py/tests/test_fit.py
> +++ b/test/py/tests/test_fit.py
> @@ -24,7 +24,7 @@ base_its = '''
> type = "kernel";
> arch = "sandbox";
> os = "linux";
> - compression = "none";
> + compression = "%(compression)s";
> load = <0x40000>;
> entry = <0x8>;
> };
> @@ -39,11 +39,11 @@ base_its = '''
> };
> fdt at 1 {
> description = "snow";
> - data = /incbin/("u-boot.dtb");
> + data = /incbin/("%(fdt)s");
> type = "flat_dt";
> arch = "sandbox";
> %(fdt_load)s
> - compression = "none";
> + compression = "%(compression)s";
> signature at 1 {
> algo = "sha1,rsa2048";
> key-name-hint = "dev";
> @@ -56,7 +56,7 @@ base_its = '''
> arch = "sandbox";
> os = "linux";
> %(ramdisk_load)s
> - compression = "none";
> + compression = "%(compression)s";
> };
> ramdisk at 2 {
> description = "snow";
> @@ -221,6 +221,10 @@ def test_fit(u_boot_console):
> print(data, file=fd)
> return fname
>
> + def make_compressed(filename):
> + util.run_and_log(cons, ['gzip', '-f', '-k', filename])
> + return filename + '.gz'
> +
> def find_matching(text, match):
> """Find a match in a line of text, and return the unmatched line
> portion
>
> @@ -312,6 +316,7 @@ def test_fit(u_boot_console):
> loadables1 = make_kernel('test-loadables1.bin', 'lenrek')
> loadables2 = make_ramdisk('test-loadables2.bin', 'ksidmar')
> kernel_out = make_fname('kernel-out.bin')
> + fdt = make_fname('u-boot.dtb')
> fdt_out = make_fname('fdt-out.dtb')
> ramdisk_out = make_fname('ramdisk-out.bin')
> loadables1_out = make_fname('loadables1-out.bin')
> @@ -326,6 +331,7 @@ def test_fit(u_boot_console):
> 'kernel_addr' : 0x40000,
> 'kernel_size' : filesize(kernel),
>
> + 'fdt' : fdt,
> 'fdt_out' : fdt_out,
> 'fdt_addr' : 0x80000,
> 'fdt_size' : filesize(control_dtb),
> @@ -351,6 +357,7 @@ def test_fit(u_boot_console):
> 'loadables2_load' : '',
>
> 'loadables_config' : '',
> + 'compression' : 'none',
> }
>
> # Make a basic FIT and a script to load it
> @@ -417,6 +424,20 @@ def test_fit(u_boot_console):
> check_equal(loadables2, loadables2_out,
> 'Loadables2 (ramdisk) not loaded')
>
> + # Kernel, FDT and Ramdisk all compressed
> + with cons.log.section('(Kernel + FDT + Ramdisk) compressed'):
> + params['compression'] = 'gzip'
> + params['kernel'] = make_compressed(kernel)
> + params['fdt'] = make_compressed(fdt)
> + params['ramdisk'] = make_compressed(ramdisk)
> + fit = make_fit(mkimage, params)
> + cons.restart_uboot()
> + output = cons.run_command_list(cmd.splitlines())
> + check_equal(kernel, kernel_out, 'Kernel not loaded')
> + check_equal(control_dtb, fdt_out, 'FDT not loaded')
> + check_equal(ramdisk, ramdisk_out, 'Ramdisk not loaded')
> +
> +
> cons = u_boot_console
> try:
> # We need to use our own device tree file. Remember to restore it
> --
> 2.22.0.657.g960e92d24f-goog
>
>
More information about the U-Boot
mailing list