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