[U-Boot] [RFC] fit: include uncompression into fit_image_load

Simon Goldschmidt simon.k.r.goldschmidt at gmail.com
Tue Oct 16 19:33:48 UTC 2018


Currently, only the kernel can be compressed in a FIT image.
By moving the uncompression logic to 'fit_image_load()', all types
of images can be compressed.

This works perfectly for me when using a gzip'ed FPGA image in
a FIT image on a cyclone5 board (socrates). Also, a gzip'ed initrd
being unzipped by U-Boot (not the kernel) worked.

To clean this up, the uncompression function would have to be moved
from bootm.c ('bootm_decomp_image()') to a more generic location,
but I decided to keep it for now to make the patch easier to read.
Because of this setup, the kernel is currently uncompressed twice.
which doesn't work...

There are, however, some more things to discuss:
- The max. size passed to gunzip() (etc.) is not known before, so
  we currently configure this to 8 MByte in U-Boot (via
  CONFIG_SYS_BOOTM_LEN), which proved too small for my initrd...
- CONFIG_SYS_BOOTM_LEN is set to 64 MByte default in SPL, so it's
  a different default for SPL than for U-Boot !?!
- CONFIG_SYS_BOOTM_LEN seemed to initially be used for kernel
  uncompression but is now used as a copy-only limit, too (no unzip)
- Uncompression only works if a load address is given, what should
  happen if the FIT image does not contain a load address?
- The whole memory management around FIT images is a bit messed up
  in that memory allocation is a mix of where U-Boot relocates itself
  (and which address ranges it used), the load addresses of the FIT
  image and the load addresses of the FIT image contents (and sizes).
  What's the point here to check CONFIG_SYS_BOOTM_LEN? Maybe it would
  be better to keep a memory map of allowed and already used data to
  check if we're overwriting things or to get the maximum size passed
  to gunzip etc.?
- Some code paths (like the command 'fpga loadmk') directly use
  'fit_image_get_data()'. These will have to be converted to use
  'fit_image_load()' instead (which will do nothing if the subimage
  does not contain a load address.
- 'fit_image_load()' should probably check for subimages that have
  a compression set but no load address... Or should we try to malloc()
  here?

A long list of questions, hopefully someone will join me in discussing
them :-)

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt at gmail.com>
---

 common/bootm.c     |  8 ++++----
 common/image-fit.c | 17 +++++++++++++++--
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/common/bootm.c b/common/bootm.c
index 8bf84ebcb7..6b85edb80b 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -361,6 +361,9 @@ int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
 {
 	int ret = 0;
 
+	if (!unc_len)
+		unc_len = CONFIG_SYS_BOOTM_LEN;
+
 	*load_end = load;
 	print_decomp_msg(comp, type, load == image_start);
 
@@ -373,10 +376,7 @@ int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
 	case IH_COMP_NONE:
 		if (load == image_start)
 			break;
-		if (image_len <= unc_len)
-			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
-		else
-			ret = 1;
+		memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
 		break;
 #ifdef CONFIG_GZIP
 	case IH_COMP_GZIP: {
diff --git a/common/image-fit.c b/common/image-fit.c
index 8d39a243f8..030f0098c7 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -23,6 +23,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 
 #include <image.h>
+#include <bootm.h>
 #include <bootstage.h>
 #include <u-boot/crc.h>
 #include <u-boot/md5.h>
@@ -1969,8 +1970,9 @@ 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;
+		ulong load_end, uncomp_len;
 		void *dst;
+		u8 image_comp;
 
 		/*
 		 * move image data to the load address,
@@ -1986,11 +1988,22 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 			return -EXDEV;
 		}
 
+		if (fit_image_get_comp(fit, noffset, &image_comp)) {
+			puts("Can't get image compression!\n");
+			return -EINVAL;
+		}
 		printf("   Loading %s from 0x%08lx to 0x%08lx\n",
 		       prop_name, data, load);
 
 		dst = map_sysmem(load, len);
-		memmove(dst, buf, len);
+		ret = bootm_decomp_image(image_comp, load, image_start,
+					 image_type, dst, (void *)buf, len, 0,
+					 &load_end);
+		if (ret) {
+			bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
+			return ret;
+		}
+		len = load_end - load;
 		data = load;
 	}
 	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
-- 
2.17.1



More information about the U-Boot mailing list