boot: Support compressed booti images in bootm

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 <sjg@chromium.org>
This commit is contained in:
Simon Glass 2025-03-05 17:25:11 -07:00 committed by Tom Rini
parent d6bb0ea535
commit ecd50bb464
3 changed files with 53 additions and 8 deletions

View file

@ -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)

View file

@ -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;

View file

@ -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);
/**