A compressed booti image relies on the compression-format's header at
the start to indicate which compression algorithm is used.

We don't support this elsewhere in U-Boot, so assume that a compressed
file is always a booti file. Once it is compressed, a check is made to
make sure that it actually is.

Simplify the implementation by adding a new function which returns the
booti image-type if compression is detected.

Signed-off-by: Simon Glass <s...@chromium.org>
---

(no changes since v4)

Changes in v4:
- Correct for updated lmb_reserve() call

Changes in v3:
- Add new patch to support compressed booti images in bootm

 boot/bootm.c       | 37 ++++++++++++++++++++++++++++++-------
 boot/image-board.c | 13 ++++++++++++-
 include/image.h    | 11 +++++++++++
 3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/boot/bootm.c b/boot/bootm.c
index 272623c9258..8a1aac7515f 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -146,7 +146,7 @@ static int boot_get_kernel(const char *addr_fit, struct 
bootm_headers *images,
        /* check image type, for FIT images get FIT kernel node */
        *os_data = *os_len = 0;
        buf = map_sysmem(img_addr, 0);
-       switch (genimg_get_format(buf)) {
+       switch (genimg_get_format_comp(buf)) {
 #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
        case IMAGE_FORMAT_LEGACY:
                printf("## Booting kernel from Legacy Image at %08lx ...\n",
@@ -228,11 +228,8 @@ static int boot_get_kernel(const char *addr_fit, struct 
bootm_headers *images,
        }
 #endif
        case IMAGE_FORMAT_BOOTI:
-               if (IS_ENABLED(CONFIG_CMD_BOOTI)) {
-                       *os_data = img_addr;
-                       break;
-               }
-               fallthrough;
+               *os_data = img_addr;
+               break;
        default:
                bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
                return -EPROTOTYPE;
@@ -306,6 +303,17 @@ static int found_booti_os(enum image_comp_t comp)
        log_debug("load %lx start %lx len %lx ep %lx os %x comp %x\n",
                  images.os.load, images.os.image_start, images.os.image_len,
                  images.ep, images.os.os, images.os.comp);
+       if (comp != IH_COMP_NONE) {
+               images.os.load = env_get_hex("kernel_comp_addr_r", 0);
+               images.os.image_len = env_get_ulong("kernel_comp_size", 16, 0);
+               if (!images.os.load || !images.os.image_len) {
+                       puts("kernel_comp_addr_r or kernel_comp_size is not 
provided!\n");
+                       return -ENOTSUPP;
+               }
+               if (lmb_reserve(images.os.load, images.os.image_len, LMB_NONE)
+                   < 0)
+                       return -EXDEV;
+       }
 
        return 0;
 }
@@ -423,6 +431,19 @@ static int bootm_find_os(const char *cmd_name, const char 
*addr_fit)
                }
                fallthrough;
        default:
+               /* any compressed image is probably a booti image */
+               if (IS_ENABLED(CONFIG_CMD_BOOTI)) {
+                       int comp;
+
+                       comp = image_decomp_type(os_hdr, 2);
+                       if (comp != IH_COMP_NONE) {
+                               if (found_booti_os(comp))
+                                       return 1;
+                               ep_found = true;
+                       }
+                       break;
+               }
+
                puts("ERROR: unknown image format type!\n");
                return 1;
        }
@@ -1166,7 +1187,9 @@ int bootz_run(struct bootm_info *bmi)
 
 int booti_run(struct bootm_info *bmi)
 {
-       return boot_run(bmi, "booti", 0);
+       return boot_run(bmi, "booti", BOOTM_STATE_START | BOOTM_STATE_FINDOS |
+                       BOOTM_STATE_PRE_LOAD | BOOTM_STATE_FINDOTHER |
+                       BOOTM_STATE_LOADOS);
 }
 
 int bootm_boot_start(ulong addr, const char *cmdline)
diff --git a/boot/image-board.c b/boot/image-board.c
index 07931c64198..a2bafba7ae1 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -257,6 +257,17 @@ enum image_fmt_t genimg_get_format(const void *img_addr)
        return IMAGE_FORMAT_INVALID;
 }
 
+enum image_fmt_t genimg_get_format_comp(const void *img_addr)
+{
+       enum image_fmt_t fmt = genimg_get_format(img_addr);
+
+       if (IS_ENABLED(CONFIG_CMD_BOOTI) && fmt == IMAGE_FORMAT_INVALID &&
+           image_decomp_type(img_addr, 2) != IH_COMP_NONE)
+               fmt = IMAGE_FORMAT_BOOTI;
+
+       return fmt;
+}
+
 /**
  * fit_has_config - check if there is a valid FIT configuration
  * @images: pointer to the bootm command headers structure
@@ -353,7 +364,7 @@ static int select_ramdisk(struct bootm_headers *images, 
const char *select, u8 a
         * check image type, for FIT images get FIT node.
         */
        buf = map_sysmem(rd_addr, 0);
-       switch (genimg_get_format(buf)) {
+       switch (genimg_get_format_comp(buf)) {
        case IMAGE_FORMAT_LEGACY:
                if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
                        const struct legacy_img_hdr *rd_hdr;
diff --git a/include/image.h b/include/image.h
index 5b9bd6a9649..2455baa6667 100644
--- a/include/image.h
+++ b/include/image.h
@@ -648,6 +648,17 @@ ulong genimg_get_kernel_addr(char * const img_addr);
  */
 enum image_fmt_t genimg_get_format(const void *img_addr);
 
+/**
+ * genimg_get_format_comp() - Like genimg_get_format() but adds compressed 
booti
+ *
+ * If a compressed file is detected (with image_decomp_type()) and
+ * CONFIG_CMD_BOOTI is enabled, then this returns IMAGE_FORMAT_BOOTI
+ *
+ * @img_addr: image start address
+ * Return: image format type or IMAGE_FORMAT_INVALID if no image is present
+ */
+enum image_fmt_t genimg_get_format_comp(const void *img_addr);
+
 int genimg_has_config(struct bootm_headers *images);
 
 /**
-- 
2.43.0

Reply via email to