On Thu, Jul 11, 2019 at 10:53 PM Julius Werner <jwer...@chromium.org> wrote: > > 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 <jwer...@chromium.org> > --- > - 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
If there haven't been any changes from v4, why did you drop Simon Glass's Reviewed-by tag? Regards, Simon > > 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@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@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@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.20.1 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot