[PATCH 1/2] bootm: fit: open FIT images only once per loadable
Sascha Hauer
s.hauer at pengutronix.de
Thu Oct 1 00:11:20 PDT 2026
Since commit c3d383e958f3 ("bootm: fit: switch to new loadable API")
the FIT loadable calls fit_open_image() on every access. bootm accesses
the kernel loadable twice: in bootm_open_fit() to detect the kernel type
from its header and in the image handler to copy it to its load address.
Each call hashes the image again, which takes about 40 ms for a 12 MB
kernel on an RK3588.
Cache data and size in the loadable, so the image is verified and
decompressed only on first use. The data is owned by the FIT handle,
which the loadable holds a reference to until it is released.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
common/bootm-fit.c | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
index f7742b8717..68bede1300 100644
--- a/common/bootm-fit.c
+++ b/common/bootm-fit.c
@@ -194,23 +194,38 @@ struct fit_loadable_priv {
struct device_node *config;
const char *image_name;
int index;
+ const void *data;
+ unsigned long size;
};
+/*
+ * fit_loadable_open() - verify and decompress the image on first use
+ * @priv: FIT loadable private data
+ *
+ * The result is cached, so hashing and decompression happen only once.
+ * The data is owned by the FIT handle, which we hold a reference to.
+ */
+static int fit_loadable_open(struct fit_loadable_priv *priv)
+{
+ if (priv->data)
+ return 0;
+
+ return fit_open_image(priv->fit, priv->config, priv->image_name,
+ priv->index, &priv->data, &priv->size);
+}
+
static int fit_loadable_get_info(struct loadable *l, struct loadable_info *info)
{
struct fit_loadable_priv *priv = l->priv;
- const void *data;
- unsigned long size;
int ret;
/* Open image to get size */
- ret = fit_open_image(priv->fit, priv->config, priv->image_name,
- priv->index, &data, &size);
+ ret = fit_loadable_open(priv);
if (ret)
return ret;
/* TODO: This will trigger an uncompression currently.. */
- info->final_size = size;
+ info->final_size = priv->size;
return 0;
}
@@ -218,17 +233,14 @@ static int fit_loadable_get_info(struct loadable *l, struct loadable_info *info)
static const void *fit_loadable_mmap(struct loadable *l, size_t *size)
{
struct fit_loadable_priv *priv = l->priv;
- const void *data;
- unsigned long image_size;
int ret;
- ret = fit_open_image(priv->fit, priv->config, priv->image_name,
- priv->index, &data, &image_size);
+ ret = fit_loadable_open(priv);
if (ret)
return MAP_FAILED;
- *size = image_size;
- return data;
+ *size = priv->size;
+ return priv->data;
}
/**
@@ -264,11 +276,13 @@ static ssize_t fit_loadable_extract_into_buf(struct loadable *l, void *load_addr
/* TODO: optimize, so it decompresses directly to load address */
/* Open image to get data */
- ret = fit_open_image(priv->fit, priv->config, priv->image_name,
- priv->index, &data, &size);
+ ret = fit_loadable_open(priv);
if (ret)
return ret;
+ data = priv->data;
+ size = priv->size;
+
/* Check if buffer is large enough */
if (offset > size)
return 0;
--
2.47.3
More information about the barebox
mailing list