ipq806x: Added support for compressed dtb images
This commit lays a foundation for packing multiple dtb
images in a single itb image, by supporting compressed dtb
images. This is basically to support all boards across
different soc versions in a single itb image.
The plan is to compress the dtb images, so as to save flash space.
Change-Id: Iba81e311cfda55696209cf99c81e062980629871
Signed-off-by: Gokul Sriram Palanisamy <gpalan@codeaurora.org>
diff --git a/common/bootm.c b/common/bootm.c
index 58936ca..9c8d28a 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -334,6 +334,11 @@
*load_end = load;
print_decomp_msg(comp, type, load == image_start);
+#if defined(CONFIG_DTB_COMPRESSION)
+ if(type == IH_TYPE_FLATDT)
+ unc_len = CONFIG_DTB_LOAD_MAXLEN;
+#endif
+
/*
* Load the image to the right place, decompressing if needed. After
* this, image_len will be set to the number of uncompressed bytes
@@ -413,8 +418,8 @@
}
#ifndef USE_HOSTCC
-static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
- int boot_progress)
+int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
+ int boot_progress)
{
image_info_t os = images->os;
ulong load = os.load;
@@ -437,8 +442,10 @@
}
flush_cache(load, (*load_end - load) * sizeof(ulong));
- debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
- bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
+ debug(" %s loaded at 0x%08lx, end = 0x%08lx\n",
+ genimg_get_type_name(os.type), load, *load_end);
+ if (os.type == IH_TYPE_KERNEL)
+ bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);
no_overlap = (os.comp == IH_COMP_NONE && load == image_start);
diff --git a/common/image-fit.c b/common/image-fit.c
index c531ee7..fb66c46 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1569,6 +1569,10 @@
uint8_t os;
const char *prop_name;
int ret;
+#if defined(CONFIG_DTB_COMPRESSION)
+ bootm_headers_t fdt = {0};
+#endif
+ uint8_t comp_type = IH_COMP_NONE;
fit = map_sysmem(addr, 0);
fit_uname = fit_unamep ? *fit_unamep : NULL;
@@ -1650,11 +1654,13 @@
return -ENOEXEC;
}
#endif
+#if !defined(CONFIG_DTB_COMPRESSION)
if (image_type == IH_TYPE_FLATDT &&
!fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
puts("FDT image is compressed");
return -EPROTONOSUPPORT;
}
+#endif
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
type_ok = fit_image_check_type(fit, noffset, image_type) ||
@@ -1691,10 +1697,30 @@
}
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;
+#if defined(CONFIG_DTB_COMPRESSION)
+ if (!fit_image_get_comp(fit, noffset, &comp_type)
+ && (comp_type != IH_COMP_NONE)) {
+ printf(" %s %s image found\n",
+ genimg_get_comp_name(comp_type), prop_name);
+ if (fit_image_get_load(fit, noffset,
+ &load) != 0) {
+ printf("ERROR: load address not found for "
+ "compressed %s..\n", prop_name);
+ return -EFAULT;
+ } else {
+ fdt.os.comp = comp_type;
+ fdt.os.type = IH_TYPE_FLATDT;
+ printf(" %s load address is: 0x%08x\n", prop_name,
+ (unsigned int)load);
+ }
+ }
+#endif
+ if (comp_type == IH_COMP_NONE) {
+ /* 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);
@@ -1722,7 +1748,6 @@
} 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,
@@ -1741,8 +1766,27 @@
printf(" Loading %s from 0x%08lx to 0x%08lx\n",
prop_name, data, load);
- dst = map_sysmem(load, len);
+#if defined(CONFIG_DTB_COMPRESSION)
+ if (comp_type != IH_COMP_NONE) {
+ fdt.os.image_start = (ulong)data;
+ fdt.os.image_len = len;
+ fdt.os.load = load;
+ if (!bootm_load_os(&fdt, &load_end, 1)) {
+ /*
+ * verify that uncompressed image
+ * data is a proper FDT blob
+ * */
+ if (fdt_check_header((char *)load) != 0) {
+ printf("Error: Uncompresed FIT Subimage"
+ " data is not a %s", prop_name);
+ return -ENOEXEC;
+ }
+ }
+ }
+#else
+ void *dst = map_sysmem(load, len);
memmove(dst, buf, len);
+#endif
data = load;
}
bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
diff --git a/include/image.h b/include/image.h
index c34c230..61ad3a8 100644
--- a/include/image.h
+++ b/include/image.h
@@ -917,6 +917,9 @@
int calculate_hash(const void *data, int data_len, const char *algo,
uint8_t *value, int *value_len);
+int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
+ int boot_progress);
+
/*
* At present we only support signing on the host, and verification on the
* device