bootm: teach handle_decomp_error() about the noload decompression buffer
For a compressed kernel_noload image, bootm_load_os() allocates a
per-image decompression buffer of ALIGN(image_len * 8, SZ_1M) rather
than the global CONFIG_SYS_BOOTM_LEN. When decompression fails on that
path, handle_decomp_error() still prints
Image too large: increase CONFIG_SYS_BOOTM_LEN
which is misleading: increasing CONFIG_SYS_BOOTM_LEN does not help
because the smaller per-image buffer is the actual bound. Commit
2ff26c1e378d ("bootm: fix overflow of the noload kernel decompression
buffer") worked around this by printing a follow-up note right after
handle_decomp_error() returned, but the boot log then reads as two
contradictory sentences.
Introduce enum bootm_decomp_limit and pass it into
handle_decomp_error() so the helper picks the right message in one
place. For the per-image path it now prints
Image too large for the per-image decompression buffer (0x100000 bytes)
quoting the actual buffer size; the global path is unchanged. Drop the
trailing note in bootm_load_os() so only one line is printed.
Suggested-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Aristo Chen <aristo.chen@canonical.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
+29
-9
@@ -575,6 +575,18 @@ static int bootm_find_other(ulong img_addr, const char *conf_ramdisk,
|
||||
#endif /* USE_HOSTC */
|
||||
|
||||
#if !defined(USE_HOSTCC) || defined(CONFIG_FIT_SIGNATURE)
|
||||
/**
|
||||
* enum bootm_decomp_limit - What bounded the decompression buffer.
|
||||
* @BOOTM_DECOMP_LIMIT_GLOBAL: Global CONFIG_SYS_BOOTM_LEN limit.
|
||||
* @BOOTM_DECOMP_LIMIT_PER_IMAGE: Per-image buffer sized from the
|
||||
* compressed image (e.g. the
|
||||
* kernel_noload decompression buffer).
|
||||
*/
|
||||
enum bootm_decomp_limit {
|
||||
BOOTM_DECOMP_LIMIT_GLOBAL,
|
||||
BOOTM_DECOMP_LIMIT_PER_IMAGE,
|
||||
};
|
||||
|
||||
/**
|
||||
* handle_decomp_error() - display a decompression error
|
||||
*
|
||||
@@ -585,11 +597,14 @@ static int bootm_find_other(ulong img_addr, const char *conf_ramdisk,
|
||||
* @comp_type: Compression type being used (IH_COMP_...)
|
||||
* @uncomp_size: Number of bytes uncompressed
|
||||
* @buf_size: Number of bytes the decompresion buffer was
|
||||
* @limit: Which allocation actually bounded the buffer, so the
|
||||
* hint points at the knob the reader can act on
|
||||
* @ret: errno error code received from compression library
|
||||
* Return: Appropriate BOOTM_ERR_ error code
|
||||
*/
|
||||
static int handle_decomp_error(int comp_type, size_t uncomp_size,
|
||||
size_t buf_size, int ret)
|
||||
size_t buf_size,
|
||||
enum bootm_decomp_limit limit, int ret)
|
||||
{
|
||||
const char *name = genimg_get_comp_name(comp_type);
|
||||
|
||||
@@ -598,10 +613,15 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size,
|
||||
return BOOTM_ERR_UNIMPLEMENTED;
|
||||
|
||||
if ((comp_type == IH_COMP_GZIP && ret == Z_BUF_ERROR) ||
|
||||
uncomp_size >= buf_size)
|
||||
printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
|
||||
else
|
||||
uncomp_size >= buf_size) {
|
||||
if (limit == BOOTM_DECOMP_LIMIT_PER_IMAGE)
|
||||
printf("Image too large for the per-image decompression buffer (%#zx bytes)\n",
|
||||
buf_size);
|
||||
else
|
||||
printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
|
||||
} else {
|
||||
printf("%s: uncompress error %d\n", name, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* The decompression routines are now safe, so will not write beyond
|
||||
@@ -628,6 +648,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
|
||||
ulong image_start = os.image_start;
|
||||
ulong image_len = os.image_len;
|
||||
ulong decomp_len = CONFIG_SYS_BOOTM_LEN;
|
||||
enum bootm_decomp_limit decomp_limit = BOOTM_DECOMP_LIMIT_GLOBAL;
|
||||
ulong flush_start;
|
||||
bool no_overlap;
|
||||
void *load_buf, *image_buf;
|
||||
@@ -644,6 +665,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
|
||||
phys_addr_t addr;
|
||||
|
||||
decomp_len = ALIGN(image_len * 8, SZ_1M);
|
||||
decomp_limit = BOOTM_DECOMP_LIMIT_PER_IMAGE;
|
||||
err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, &addr,
|
||||
decomp_len, LMB_NONE);
|
||||
if (err)
|
||||
@@ -663,10 +685,7 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress)
|
||||
decomp_len, &load_end);
|
||||
if (err) {
|
||||
err = handle_decomp_error(os.comp, load_end - load,
|
||||
decomp_len, err);
|
||||
if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE)
|
||||
printf("Note: noload decompression buffer is %#lx bytes (not CONFIG_SYS_BOOTM_LEN)\n",
|
||||
decomp_len);
|
||||
decomp_len, decomp_limit, err);
|
||||
bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
|
||||
return err;
|
||||
}
|
||||
@@ -1288,7 +1307,8 @@ static int bootm_host_load_image(const void *fit, int req_image_type,
|
||||
free(load_buf);
|
||||
|
||||
if (ret) {
|
||||
ret = handle_decomp_error(image_comp, load_end - 0, buf_size, ret);
|
||||
ret = handle_decomp_error(image_comp, load_end - 0, buf_size,
|
||||
BOOTM_DECOMP_LIMIT_GLOBAL, ret);
|
||||
if (ret != BOOTM_ERR_UNIMPLEMENTED)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user