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