* [PATCH 01/15] FIT: implement fit_count_images
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 02/15] FIT: add image index argument to fit_open_image Ahmad Fatoum
` (13 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
A FIT image can contain multiple images of the same type, e.g. a device
tree followed by overlays or multiple initrds.
To allow checking for that case, let's implement fit_count_images().
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/image-fit.c | 12 ++++--------
include/image-fit.h | 27 +++++++++++++++++++++++++--
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/common/image-fit.c b/common/image-fit.c
index 26bd8e265b25..85096aff31e6 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -495,19 +495,15 @@ static int fit_image_verify_signature(struct fit_handle *handle,
return ret;
}
-bool fit_has_image(struct fit_handle *handle, void *configuration,
- const char *name)
+int fit_count_images(struct fit_handle *handle, void *configuration,
+ const char *name)
{
- const char *unit;
struct device_node *conf_node = configuration;
if (!conf_node)
- return false;
+ return -EINVAL;
- if (of_property_read_string(conf_node, name, &unit))
- return false;
-
- return true;
+ return of_property_count_strings(conf_node, name);
}
static int fit_get_address(struct device_node *image, const char *property,
diff --git a/include/image-fit.h b/include/image-fit.h
index c332f77bd374..31b8b54e272d 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -34,8 +34,31 @@ struct fit_handle *fit_open_buf(const void *buf, size_t len, bool verbose,
void *fit_open_configuration(struct fit_handle *handle, const char *name,
bool (*match_valid)(struct fit_handle *handle,
struct device_node *config));
-bool fit_has_image(struct fit_handle *handle, void *configuration,
- const char *name);
+/**
+ * fit_count_images() - count images of a given type in a FIT configuration
+ * @handle: FIT handle as returned by fit_open() or fit_open_buf()
+ * @configuration: configuration node as returned by fit_open_configuration()
+ * @name: image type property name (e.g., "kernel", "fdt", "ramdisk")
+ *
+ * Return: number of images on success, negative error code on failure
+ */
+int fit_count_images(struct fit_handle *handle, void *configuration,
+ const char *name);
+
+/**
+ * fit_has_image() - check if a FIT configuration contains an image type
+ * @handle: FIT handle as returned by fit_open() or fit_open_buf()
+ * @configuration: configuration node as returned by fit_open_configuration()
+ * @name: image type property name (e.g., "kernel", "fdt", "ramdisk")
+ *
+ * Return: true if at least one image of the given type exists, false otherwise
+ */
+static inline bool fit_has_image(struct fit_handle *handle, void *configuration,
+ const char *name)
+{
+ return fit_count_images(handle, configuration, name) > 0;
+}
+
int fit_open_image(struct fit_handle *handle, void *configuration,
const char *name, const void **outdata,
unsigned long *outsize);
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 02/15] FIT: add image index argument to fit_open_image
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 01/15] FIT: implement fit_count_images Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 03/15] resource: implement gap-aware lookup_region Ahmad Fatoum
` (12 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
A FIT configuration can specify multiple images of the same type, e.g.
for device tree overlays. Add an index parameter to fit_open_image()
to allow callers to select which image to open. Existing callers pass
idx=0 to maintain current behavior of opening the first image.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/lib32/bootm.c | 2 +-
common/bootm-fit.c | 6 ++---
common/image-fit.c | 50 ++++++++++++++++++++----------------------
drivers/of/overlay.c | 2 +-
efi/payload/bootm.c | 4 ++--
include/image-fit.h | 4 ++--
6 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index 533c3ea946ff..e659d3c1a554 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -178,7 +178,7 @@ static int bootm_load_tee_from_fit(struct image_data *data)
const void *tee;
unsigned long tee_size;
- ret = fit_open_image(data->os_fit, data->fit_config, "tee",
+ ret = fit_open_image(data->os_fit, data->fit_config, "tee", 0,
&tee, &tee_size);
if (ret) {
pr_err("Error opening tee fit image: %pe\n", ERR_PTR(ret));
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
index 3b2252ca8810..a0e808e31b40 100644
--- a/common/bootm-fit.c
+++ b/common/bootm-fit.c
@@ -61,7 +61,7 @@ struct resource *bootm_load_fit_initrd(struct image_data *data, unsigned long lo
if (!fitconfig_has_ramdisk(data))
return NULL;
- ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
+ ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk", 0,
&initrd, &initrd_size);
if (ret) {
pr_err("Cannot open ramdisk image in FIT image: %pe\n",
@@ -96,7 +96,7 @@ void *bootm_get_fit_devicetree(struct image_data *data)
const void *of_tree;
unsigned long of_size;
- ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
+ ret = fit_open_image(data->os_fit, data->fit_config, "fdt", 0,
&of_tree, &of_size);
if (ret)
return ERR_PTR(ret);
@@ -144,7 +144,7 @@ int bootm_open_fit(struct image_data *data)
return PTR_ERR(data->fit_config);
}
- ret = fit_open_image(data->os_fit, data->fit_config, kernel_img,
+ ret = fit_open_image(data->os_fit, data->fit_config, kernel_img, 0,
&data->fit_kernel, &data->fit_kernel_size);
if (ret)
return ret;
diff --git a/common/image-fit.c b/common/image-fit.c
index 85096aff31e6..75592766941c 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -522,24 +522,20 @@ static int fit_get_address(struct device_node *image, const char *property,
return 0;
}
-static int
+static struct device_node *
fit_get_image(struct fit_handle *handle, void *configuration,
- const char **unit, struct device_node **image)
+ const char **unit, int idx)
{
struct device_node *conf_node = configuration;
if (conf_node) {
- if (of_property_read_string(conf_node, *unit, unit)) {
+ if (of_property_read_string_index(conf_node, *unit, idx, unit)) {
pr_err("No image named '%s'\n", *unit);
- return -ENOENT;
+ return NULL;
}
}
- *image = of_get_child_by_name(handle->images, *unit);
- if (!*image)
- return -ENOENT;
-
- return 0;
+ return of_get_child_by_name(handle->images, *unit);
}
/**
@@ -569,9 +565,9 @@ int fit_get_image_address(struct fit_handle *handle, void *configuration,
if (!address || !property || !name)
return -EINVAL;
- ret = fit_get_image(handle, configuration, &unit, &image);
- if (ret)
- return ret;
+ image = fit_get_image(handle, configuration, &unit, 0);
+ if (!image)
+ return -ENOENT;
/* Treat type = "kernel_noload" as if entry/load address is missing */
ret = of_property_read_string(image, "type", &type);
@@ -647,22 +643,22 @@ static int fit_handle_decompression(struct device_node *image,
/**
* fit_open_image - Open an image in a FIT image
* @handle: The FIT image handle
+ * @configuration: configuration cookie from fit_open_configuration(), or NULL
* @name: The name of the image to open
+ * @idx: The index of image to open (for multi-image properties like overlays)
* @outdata: The returned image
* @outsize: Size of the returned image
*
* Open an image in a FIT image. The returned image is freed during fit_close().
- * @configuration holds the cookie returned from fit_open_configuration() if
- * the image is opened as part of a configuration, or NULL if the image is
- * opened without a configuration. If @configuration is NULL then the RSA
- * signature of the image is checked if desired, if @configuration is non NULL,
- * then only the hash is checked (because opening the configuration already
- * checks the RSA signature of all involved nodes).
+ *
+ * If @configuration is NULL then the RSA signature of the image is checked
+ * if desired; otherwise only the hash is checked (because opening the
+ * configuration already checks the RSA signature of all involved nodes).
*
* Return: 0 for success, negative error code otherwise
*/
int fit_open_image(struct fit_handle *handle, void *configuration,
- const char *name, const void **outdata,
+ const char *name, int idx, const void **outdata,
unsigned long *outsize)
{
struct device_node *image;
@@ -671,9 +667,9 @@ int fit_open_image(struct fit_handle *handle, void *configuration,
int data_len;
int ret = 0;
- ret = fit_get_image(handle, configuration, &unit, &image);
- if (ret)
- return ret;
+ image = fit_get_image(handle, configuration, &unit, idx);
+ if (!image)
+ return -ENOENT;
of_property_read_string(image, "description", &desc);
if (handle->verbose)
@@ -765,9 +761,11 @@ static int fit_fdt_is_compatible(struct fit_handle *handle,
if (!of_property_present(child, "fdt"))
return 0;
- ret = fit_get_image(handle, child, &unit, &image);
- if (ret)
+ image = fit_get_image(handle, child, &unit, 0);
+ if (!image) {
+ ret = -ENOENT;
goto err;
+ }
data = of_get_property(image, "data", &data_len);
if (!data)
@@ -1134,14 +1132,14 @@ static int fuzz_fit(const u8 *data, size_t size)
goto out;
}
- ret = fit_open_image(&handle, config, imgname, &outdata, &outsize);
+ ret = fit_open_image(&handle, config, imgname, 0, &outdata, &outsize);
if (ret)
goto out;
fit_get_image_address(&handle, config, imgname, "load", &addr);
fit_get_image_address(&handle, config, imgname, "entry", &addr);
- ret = fit_open_image(&handle, NULL, imgname, &outdata, &outsize);
+ ret = fit_open_image(&handle, NULL, imgname, 0, &outdata, &outsize);
out:
__fit_close(&handle);
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index d2cf2fa3f371..b11edebd2080 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -487,7 +487,7 @@ static int of_overlay_apply_fit(struct device_node *root, struct fit_handle *fit
if (!of_overlay_matches_filter(name, NULL))
return 0;
- ret = fit_open_image(fit, config, "fdt", &ovl, &ovl_sz);
+ ret = fit_open_image(fit, config, "fdt", 0, &ovl, &ovl_sz);
if (ret)
return ret;
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
index ea5b1265aeaa..8e7ba4561f3f 100644
--- a/efi/payload/bootm.c
+++ b/efi/payload/bootm.c
@@ -129,7 +129,7 @@ static int efi_load_ramdisk(struct image_data *data, void **initrd)
int ret;
if (ramdisk_is_fit(data)) {
- ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
+ ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk", 0,
(const void **)&initrd_mem, &initrd_size);
if (ret) {
pr_err("Cannot open ramdisk image in FIT image: %m\n");
@@ -175,7 +175,7 @@ static int efi_load_fdt(struct image_data *data, void **fdt)
int ret;
if (fdt_is_fit(data)) {
- ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
+ ret = fit_open_image(data->os_fit, data->fit_config, "fdt", 0,
(const void **)&of_tree, &of_size);
if (ret) {
pr_err("Cannot open FDT image in FIT image: %m\n");
diff --git a/include/image-fit.h b/include/image-fit.h
index 31b8b54e272d..50f0482b65ad 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -60,8 +60,8 @@ static inline bool fit_has_image(struct fit_handle *handle, void *configuration,
}
int fit_open_image(struct fit_handle *handle, void *configuration,
- const char *name, const void **outdata,
- unsigned long *outsize);
+ const char *name, int idx,
+ const void **outdata, unsigned long *outsize);
int fit_get_image_address(struct fit_handle *handle, void *configuration,
const char *name, const char *property,
unsigned long *address);
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 03/15] resource: implement gap-aware lookup_region
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 01/15] FIT: implement fit_count_images Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 02/15] FIT: add image index argument to fit_open_image Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 04/15] bootm: give bootm_load_ functions an end address Ahmad Fatoum
` (11 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The incoming bootm rework hinges on being able to determine how much
total space there is for boot artifacts. For that purpose, add
memory_bank_lookup_region(), which will return the gap or the resource a
specified address resides in.
While at it, give the local variable two leading __, so it's less likely
to mask local variables.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/memory.c | 25 +++++++++++++++++++++++++
common/resource.c | 33 +++++++++++++++++++++++++++++++++
include/linux/ioport.h | 11 +++++++----
include/memory.h | 2 ++
4 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/common/memory.c b/common/memory.c
index 1c18c5b38710..b61df68e02dc 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -410,6 +410,31 @@ int memory_bank_first_find_space(resource_size_t *retstart,
return -ENOENT;
}
+/**
+ * memory_bank_lookup_region - find the memory region containing a given address
+ * @addr: physical address to look up
+ * @gap: if non-NULL and addr is in a gap, the gap info is copied here
+ *
+ * Searches all memory banks for the region containing @addr. If @addr falls
+ * within a gap between allocated regions and @gap is provided, the gap
+ * boundaries are returned via @gap.
+ *
+ * Return: pointer to the resource containing @addr, @gap if in a gap,
+ * or NULL if not found in any memory bank
+ */
+struct resource *memory_bank_lookup_region(resource_size_t addr, struct resource *gap)
+{
+ struct memory_bank *bank;
+
+ for_each_memory_bank(bank) {
+ if (addr < bank->res->start || bank->res->end < addr)
+ continue;
+ return lookup_region(bank->res, addr, gap);
+ }
+
+ return NULL;
+}
+
#ifdef CONFIG_OFTREE
static int of_memory_fixup(struct device_node *root, void *unused)
diff --git a/common/resource.c b/common/resource.c
index 33eb122f4668..e391d268e0bb 100644
--- a/common/resource.c
+++ b/common/resource.c
@@ -417,6 +417,39 @@ resource_iter_prev(struct resource *current,
return resource_iter_gap(parent, prev, gap, current);
}
+/**
+ * lookup_region - find the region containing a given address
+ * @parent: parent resource to search within
+ * @addr: address to look up
+ * @gap: if non-NULL and addr is in a gap, the gap info is copied here
+ *
+ * Searches the children of @parent (and gaps between them) for the region
+ * containing @addr.
+ *
+ * Return: pointer to the resource containing @addr, or @gap if @addr is in
+ * a gap and @gap is non-NULL, or NULL if @addr is not found or is
+ * in a gap and @gap is NULL
+ */
+struct resource *lookup_region(struct resource *parent,
+ resource_size_t addr, struct resource *gap)
+{
+ for_each_resource_region(parent, region) {
+ if (addr < region->start || region->end < addr)
+ continue;
+
+ if (!region_is_gap(region))
+ return region;
+ if (!gap)
+ return NULL;
+
+ *gap = *region;
+ INIT_LIST_HEAD(&gap->sibling);
+ return gap;
+ }
+
+ return NULL;
+}
+
struct resource_entry *resource_list_create_entry(struct resource *res,
size_t extra_size)
{
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 20c72e1b6cbb..5baae0dae10a 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -279,14 +279,17 @@ struct resource *resource_iter_last(struct resource *current, struct resource *g
struct resource *resource_iter_prev(struct resource *current, struct resource *gap);
struct resource *resource_iter_next(struct resource *current, struct resource *gap);
+struct resource *lookup_region(struct resource *parent,
+ resource_size_t addr, struct resource *gap);
+
/**
* for_each_resource_region - Iterate over child resources and gaps between them
* @parent: parent resource
* @region: pointer to child resource or gap
*/
#define for_each_resource_region(parent, region) \
- for (struct resource gap, *region = resource_iter_first((parent), &gap); \
- region; region = resource_iter_next(region, &gap))
+ for (struct resource __gap, *region = resource_iter_first((parent), &__gap); \
+ region; region = resource_iter_next(region, &__gap))
/**
* for_each_resource_region_reverse - Reverse iterate over child resources and gaps between them
@@ -294,8 +297,8 @@ struct resource *resource_iter_next(struct resource *current, struct resource *g
* @region: pointer to child resource or gap
*/
#define for_each_resource_region_reverse(parent, region) \
- for (struct resource gap, *region = resource_iter_last((parent), &gap); \
- region; region = resource_iter_prev(region, &gap))
+ for (struct resource __gap, *region = resource_iter_last((parent), &__gap); \
+ region; region = resource_iter_prev(region, &__gap))
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
diff --git a/include/memory.h b/include/memory.h
index 6b7ada641c9d..92483c39b0f4 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -97,6 +97,8 @@ void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart,
int memory_bank_first_find_space(resource_size_t *retstart,
resource_size_t *retend);
+struct resource *memory_bank_lookup_region(resource_size_t addr, struct resource *gap);
+
static inline u64 memory_sdram_size(unsigned int cols,
unsigned int rows,
unsigned int banks,
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 04/15] bootm: give bootm_load_ functions an end address
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (2 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 03/15] resource: implement gap-aware lookup_region Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 15:31 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 05/15] bootm: store separate image_type and kernel_type Ahmad Fatoum
` (10 subsequent siblings)
14 siblings, 1 reply; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
So far we expected that a load operation will not overflow, but there
was actually no way for the callee to check this.
As the architecture-specific bootm handlers are tasked with allocating
memory for boot artifacts have them pass along not only the start of the
load region, but also its end, so the callee can check that it didn't
overflow.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/arm/lib32/bootm.c | 24 +++++---
arch/arm/lib64/armlinux.c | 7 ++-
arch/arm/mach-at91/bootm-barebox.c | 7 ++-
arch/arm/mach-imx/imx-v3-image.c | 7 ++-
arch/arm/mach-layerscape/pblimage.c | 7 ++-
arch/arm/mach-rockchip/bootm.c | 13 ++--
arch/arm/mach-zynq/bootm-zynqimg.c | 7 ++-
arch/kvx/lib/bootm.c | 17 ++++--
arch/powerpc/lib/ppclinux.c | 13 +++-
common/booti.c | 30 +++++----
common/bootm-mock.c | 0
common/bootm.c | 95 ++++++++++++++++++-----------
efi/loader/bootm.c | 9 ++-
include/bootm.h | 13 ++--
14 files changed, 158 insertions(+), 91 deletions(-)
create mode 100644 common/bootm-mock.c
diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index e659d3c1a554..3641dbbdbe61 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -236,12 +236,17 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
{
unsigned long kernel;
unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
- const struct resource *initrd_res;
+ const struct resource *initrd_res, *sdram;
+ struct resource gap;
void *tee;
enum arm_security_state state = bootm_arm_security_state();
void *fdt_load_address = NULL;
int ret;
+ sdram = memory_bank_lookup_region(free_mem, &gap);
+ if (sdram != &gap)
+ return sdram ? -EBUSY : -EINVAL;
+
kernel = data->os_res->start + data->os_entry;
initrd_start = data->initrd_address;
@@ -255,7 +260,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
}
}
- initrd_res = bootm_load_initrd(data, initrd_start);
+ initrd_res = bootm_load_initrd(data, initrd_start, gap.end);
if (IS_ERR(initrd_res)) {
return PTR_ERR(initrd_res);
} else if (initrd_res) {
@@ -277,13 +282,15 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
}
if (fdt) {
+ const struct resource *fdt_res;
+
fdt_load_address = (void *)free_mem;
- ret = bootm_load_devicetree(data, fdt, free_mem);
+ fdt_res = bootm_load_devicetree(data, fdt, free_mem, gap.end);
free(fdt);
- if (ret)
- return ret;
+ if (IS_ERR(fdt_res))
+ return PTR_ERR(fdt_res);
}
if (IS_ENABLED(CONFIG_BOOTM_OPTEE)) {
@@ -339,6 +346,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
static int do_bootm_linux(struct image_data *data)
{
+ const struct resource *os_res;
unsigned long load_address, mem_free;
int ret;
@@ -349,9 +357,9 @@ static int do_bootm_linux(struct image_data *data)
if (ret)
return ret;
- ret = bootm_load_os(data, load_address);
- if (ret)
- return ret;
+ os_res = bootm_load_os(data, load_address, mem_free - 1);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
return __do_bootm_linux(data, mem_free, 0, NULL);
}
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index e40b61a26b07..febffb6c858b 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -43,6 +43,7 @@ static int do_bootm_barebox(struct image_data *data)
{
void (*fn)(unsigned long x0, unsigned long x1, unsigned long x2,
unsigned long x3);
+ const struct resource *os_res;
resource_size_t start, end;
unsigned long barebox;
int ret;
@@ -53,9 +54,9 @@ static int do_bootm_barebox(struct image_data *data)
barebox = PAGE_ALIGN(start);
- ret = bootm_load_os(data, barebox);
- if (ret)
- goto out;
+ os_res = bootm_load_os(data, barebox, end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
printf("Loaded barebox image to 0x%08lx\n", barebox);
diff --git a/arch/arm/mach-at91/bootm-barebox.c b/arch/arm/mach-at91/bootm-barebox.c
index 5540b8fad35e..f4894f247d11 100644
--- a/arch/arm/mach-at91/bootm-barebox.c
+++ b/arch/arm/mach-at91/bootm-barebox.c
@@ -13,6 +13,7 @@ EXPORT_SYMBOL(at91_bootsource);
static int do_bootm_at91_barebox_image(struct image_data *data)
{
+ const struct resource *os_res;
resource_size_t start, end;
int ret;
@@ -20,9 +21,9 @@ static int do_bootm_at91_barebox_image(struct image_data *data)
if (ret)
return ret;
- ret = bootm_load_os(data, start);
- if (ret)
- return ret;
+ os_res = bootm_load_os(data, start, end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
if (data->verbose)
printf("Loaded barebox image to 0x%08zx\n", start);
diff --git a/arch/arm/mach-imx/imx-v3-image.c b/arch/arm/mach-imx/imx-v3-image.c
index e5df5fdb81d9..5cce846f867f 100644
--- a/arch/arm/mach-imx/imx-v3-image.c
+++ b/arch/arm/mach-imx/imx-v3-image.c
@@ -8,6 +8,7 @@
static int do_bootm_imx_image_v3(struct image_data *data)
{
+ const struct resource *os_res;
void (*bb)(void);
resource_size_t start, end;
struct flash_header_v3 *hdr;
@@ -18,9 +19,9 @@ static int do_bootm_imx_image_v3(struct image_data *data)
if (ret)
return ret;
- ret = bootm_load_os(data, start);
- if (ret)
- return ret;
+ os_res = bootm_load_os(data, start, end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
hdr = (void *)start;
offset = hdr->img[0].offset;
diff --git a/arch/arm/mach-layerscape/pblimage.c b/arch/arm/mach-layerscape/pblimage.c
index 5a525f0933d5..31783f18c74d 100644
--- a/arch/arm/mach-layerscape/pblimage.c
+++ b/arch/arm/mach-layerscape/pblimage.c
@@ -15,6 +15,7 @@ static int do_bootm_layerscape_pblimage(struct image_data *data)
{
void (*barebox)(unsigned long x0, unsigned long x1, unsigned long x2,
unsigned long x3);
+ const struct resource *os_res;
resource_size_t start, end;
int ret;
@@ -22,9 +23,9 @@ static int do_bootm_layerscape_pblimage(struct image_data *data)
if (ret)
return ret;
- ret = bootm_load_os(data, start);
- if (ret)
- return ret;
+ os_res = bootm_load_os(data, start, end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
barebox = (void*)start + BAREBOX_STAGE2_OFFSET;
diff --git a/arch/arm/mach-rockchip/bootm.c b/arch/arm/mach-rockchip/bootm.c
index ff3d9a2db3a0..2e068b05cefd 100644
--- a/arch/arm/mach-rockchip/bootm.c
+++ b/arch/arm/mach-rockchip/bootm.c
@@ -40,6 +40,7 @@ static int do_bootm_rkns_barebox_image(struct image_data *data)
{
void (*barebox)(unsigned long x0, unsigned long x1, unsigned long x2,
unsigned long x3);
+ const struct resource *os_res;
resource_size_t start, end;
struct newidb *idb;
int ret, i, n_files;
@@ -50,14 +51,14 @@ static int do_bootm_rkns_barebox_image(struct image_data *data)
if (ret)
return ret;
- ret = bootm_load_os(data, start);
- if (ret)
- return ret;
+ os_res = bootm_load_os(data, start, end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
- idb = (void *)data->os_res->start;
- buf = (void *)data->os_res->start;
+ idb = (void *)os_res->start;
+ buf = (void *)os_res->start;
- image_size = resource_size(data->os_res);
+ image_size = resource_size(os_res);
if (image_size < SECTOR_SIZE)
return -EINVAL;
diff --git a/arch/arm/mach-zynq/bootm-zynqimg.c b/arch/arm/mach-zynq/bootm-zynqimg.c
index 77ed6880e4b6..ebd2d621520b 100644
--- a/arch/arm/mach-zynq/bootm-zynqimg.c
+++ b/arch/arm/mach-zynq/bootm-zynqimg.c
@@ -8,6 +8,7 @@
static int do_bootm_zynqimage(struct image_data *data)
{
resource_size_t start, end;
+ const struct resource *os_res;
void (*barebox)(void);
u32 *header;
int ret;
@@ -16,9 +17,9 @@ static int do_bootm_zynqimage(struct image_data *data)
if (ret)
return ret;
- ret = bootm_load_os(data, start);
- if (ret)
- return ret;
+ os_res = bootm_load_os(data, start, end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
header = (u32*)start;
barebox = (void*)start + header[12];
diff --git a/arch/kvx/lib/bootm.c b/arch/kvx/lib/bootm.c
index 6eba4054e500..c464b5006fa2 100644
--- a/arch/kvx/lib/bootm.c
+++ b/arch/kvx/lib/bootm.c
@@ -13,6 +13,7 @@
#include <bootm.h>
#include <binfmt.h>
#include <common.h>
+#include <memory.h>
#include <libfile.h>
#include <linux/kernel.h>
@@ -54,7 +55,8 @@ static int do_boot_entry(struct image_data *data, boot_func_entry entry,
static int do_boot_elf(struct image_data *data, struct elf_image *elf)
{
- const struct resource *initrd_res;
+ const struct resource *sdram, *initrd_res, *fdt_res;
+ struct resource gap;
int ret;
void *fdt;
boot_func_entry entry;
@@ -71,7 +73,11 @@ static int do_boot_elf(struct image_data *data, struct elf_image *elf)
else
initrd_address = load_addr;
- initrd_res = bootm_load_initrd(data, initrd_address);
+ sdram = memory_bank_lookup_region(initrd_address, &gap);
+ if (sdram != &gap)
+ return sdram ? -EBUSY : -EINVAL;
+
+ initrd_res = bootm_load_initrd(data, initrd_address, gap.end);
if (IS_ERR(initrd_res)) {
printf("Failed to load initrd\n");
return PTR_ERR(initrd_res);
@@ -93,9 +99,10 @@ static int do_boot_elf(struct image_data *data, struct elf_image *elf)
printf("Loading device tree at %lx\n", load_addr);
/* load device tree after the initrd if any */
- ret = bootm_load_devicetree(data, fdt, load_addr);
- if (ret) {
- printf("Failed to load device tree: %d\n", ret);
+ fdt_res = bootm_load_devicetree(data, fdt, load_addr, gap.end);
+ if (IS_ERR(fdt_res)) {
+ printf("Failed to load device tree: %pe\n", fdt_res);
+ ret = PTR_ERR(fdt_res);
goto err_free_fdt;
}
diff --git a/arch/powerpc/lib/ppclinux.c b/arch/powerpc/lib/ppclinux.c
index 564086482e5f..eda2539e6125 100644
--- a/arch/powerpc/lib/ppclinux.c
+++ b/arch/powerpc/lib/ppclinux.c
@@ -7,6 +7,7 @@
#include <image.h>
#include <init.h>
#include <malloc.h>
+#include <memory.h>
#include <environment.h>
#include <asm/bitops.h>
#include <asm/processor.h>
@@ -53,12 +54,18 @@ static int do_bootm_linux(struct image_data *data)
{
void (*kernel)(void *, void *, unsigned long,
unsigned long, unsigned long);
+ const struct resource *os_res, *sdram;
+ struct resource gap;
int ret;
struct fdt_header *fdt;
- ret = bootm_load_os(data, data->os_address);
- if (ret)
- return ret;
+ sdram = memory_bank_lookup_region(data->os_address, &gap);
+ if (sdram != &gap)
+ return sdram ? -EBUSY : -EINVAL;
+
+ os_res = bootm_load_os(data, data->os_address, gap.end);
+ if (IS_ERR(os_res))
+ return PTR_ERR(os_res);
fdt = of_get_fixed_tree_for_boot(data->of_root_node);
if (!fdt) {
diff --git a/common/booti.c b/common/booti.c
index 6a87b84c0308..67f31b793517 100644
--- a/common/booti.c
+++ b/common/booti.c
@@ -10,13 +10,14 @@
#include <linux/sizes.h>
static unsigned long get_kernel_address(unsigned long os_address,
- unsigned long text_offset)
+ unsigned long text_offset,
+ resource_size_t *end)
{
- resource_size_t start, end;
+ resource_size_t start;
int ret;
if (!UIMAGE_IS_ADDRESS_VALID(os_address)) {
- ret = memory_bank_first_find_space(&start, &end);
+ ret = memory_bank_first_find_space(&start, end);
if (ret)
return UIMAGE_INVALID_ADDRESS;
@@ -33,9 +34,10 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
{
const void *kernel_header =
data->os_fit ? data->fit_kernel : data->os_header;
+ const struct resource *os_res;
unsigned long text_offset, image_size, kernel;
unsigned long image_end;
- int ret;
+ resource_size_t end;
void *fdt;
print_hex_dump_bytes("header ", DUMP_PREFIX_OFFSET, kernel_header, 80);
@@ -49,24 +51,26 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
text_offset = le64_to_cpup(kernel_header + 8);
image_size = le64_to_cpup(kernel_header + 16);
- kernel = get_kernel_address(data->os_address, text_offset);
+ kernel = get_kernel_address(data->os_address, text_offset, &end);
pr_debug("Kernel to be loaded to %lx+%lx\n", kernel, image_size);
if (kernel == UIMAGE_INVALID_ADDRESS)
return ERR_PTR(-ENOENT);
+ if (kernel + image_size - 1 > end)
+ return ERR_PTR(-ENOSPC);
- ret = bootm_load_os(data, kernel);
- if (ret)
- return ERR_PTR(ret);
+ os_res = bootm_load_os(data, kernel, end);
+ if (IS_ERR(os_res))
+ return ERR_CAST(os_res);
image_end = PAGE_ALIGN(kernel + image_size);
if (oftree) {
unsigned long devicetree;
- const struct resource *initrd_res;
+ const struct resource *initrd_res, *dt_res;
- initrd_res = bootm_load_initrd(data, image_end);
+ initrd_res = bootm_load_initrd(data, image_end, end);
if (IS_ERR(initrd_res)) {
return ERR_CAST(initrd_res);
} else if (initrd_res) {
@@ -85,11 +89,11 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
goto out;
}
- ret = bootm_load_devicetree(data, fdt, devicetree);
+ dt_res = bootm_load_devicetree(data, fdt, devicetree, end);
free(fdt);
- if (ret)
- return ERR_PTR(ret);
+ if (IS_ERR(dt_res))
+ return ERR_CAST(dt_res);
*oftree = devicetree;
}
diff --git a/common/bootm-mock.c b/common/bootm-mock.c
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/common/bootm.c b/common/bootm.c
index 35305f25375a..fcf7868a5d75 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -228,57 +228,69 @@ static bool bootm_get_override(char **oldpath, const char *newpath)
return true;
}
-/*
+/**
* bootm_load_os() - load OS to RAM
- *
* @data: image data context
* @load_address: The address where the OS should be loaded to
+ * @end_address: The end address of the load buffer (inclusive)
*
* This loads the OS to a RAM location. load_address must be a valid
- * address. If the image_data doesn't have a OS specified it's considered
+ * address. If the image_data doesn't have an OS specified it's considered
* an error.
*
- * Return: 0 on success, negative error code otherwise
+ * Return: the OS resource on success, or an error pointer on failure
*/
-int bootm_load_os(struct image_data *data, unsigned long load_address)
+const struct resource *bootm_load_os(struct image_data *data,
+ ulong load_address, ulong end_address)
{
+ int err;
+
if (data->os_res)
- return 0;
+ return data->os_res;
if (load_address == UIMAGE_INVALID_ADDRESS)
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
+ if (end_address <= load_address)
+ return ERR_PTR(-EINVAL);
- if (data->os_fit)
- return bootm_load_fit_os(data, load_address);
+ if (data->os_fit) {
+ err = bootm_load_fit_os(data, load_address);
+ } else if (image_is_uimage(data)) {
+ err = bootm_load_uimage_os(data, load_address);
+ } else if (data->os_file) {
+ data->os_res = file_to_sdram(data->os_file, load_address, MEMTYPE_LOADER_CODE);
+ err = data->os_res ? 0 : -EBUSY;
+ } else {
+ err = -EINVAL;
+ }
- if (image_is_uimage(data))
- return bootm_load_uimage_os(data, load_address);
+ if (err)
+ return ERR_PTR(err);
- if (!data->os_file)
- return -EINVAL;
+ /* FIXME: We need some more rework to be able to detect this overflow
+ * before it happens, but for now, let's at least detect it.
+ */
+ if (WARN_ON(data->os_res->end > end_address))
+ return ERR_PTR(-ENOSPC);
- data->os_res = file_to_sdram(data->os_file, load_address, MEMTYPE_LOADER_CODE);
- if (!data->os_res)
- return -ENOMEM;
-
- return 0;
+ return data->os_res;
}
-/*
+/**
* bootm_load_initrd() - load initrd to RAM
- *
* @data: image data context
* @load_address: The address where the initrd should be loaded to
+ * @end_address: The end address of the load buffer (inclusive)
*
* This loads the initrd to a RAM location. load_address must be a valid
- * address. If the image_data doesn't have a initrd specified this function
- * still returns successful as an initrd is optional. Check data->initrd_res
- * to see if an initrd has been loaded.
+ * address. If the image_data doesn't have an initrd specified this function
+ * still returns successful as an initrd is optional.
*
- * Return: 0 on success, negative error code otherwise
+ * Return: the initrd resource if one was loaded, NULL if no initrd was
+ * specified, or an error pointer on failure
*/
const struct resource *
-bootm_load_initrd(struct image_data *data, unsigned long load_address)
+bootm_load_initrd(struct image_data *data, ulong load_address, ulong end_address)
{
struct resource *res = NULL;
const char *initrd, *initrd_part = NULL;
@@ -293,6 +305,8 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
*/
if (WARN_ON(data->initrd_res))
return data->initrd_res;
+ if (end_address <= load_address)
+ return ERR_PTR(-EINVAL);
bootm_get_override(&data->initrd_file, bootm_overrides.initrd_file);
@@ -313,7 +327,7 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
} else if (initrd) {
res = file_to_sdram(initrd, load_address, MEMTYPE_LOADER_DATA)
- ?: ERR_PTR(-ENOMEM);
+ ?: ERR_PTR(-EBUSY);
} else if (data->os_fit) {
res = bootm_load_fit_initrd(data, load_address);
@@ -324,6 +338,12 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
if (IS_ERR_OR_NULL(res))
return res;
+ /* FIXME: We need some more rework to be able to detect this overflow
+ * before it happens, but for now, let's at least detect it.
+ */
+ if (WARN_ON(data->initrd_res->end > end_address))
+ return ERR_PTR(-ENOSPC);
+
pr_info("Loaded initrd from %s %s%s%s to %pa-%pa\n",
file_type_to_string(type), initrd,
initrd_part ? "@" : "", initrd_part ?: "",
@@ -425,33 +445,38 @@ void *bootm_get_devicetree(struct image_data *data)
return oftree;
}
-/*
- * bootm_load_devicetree() - load devicetree
- *
+/**
+ * bootm_load_devicetree() - load devicetree into specified memory range
* @data: image data context
* @fdt: The flat device tree to load
* @load_address: The address where the devicetree should be loaded to
+ * @end_address: The end address of the load buffer (inclusive)
*
* This loads the devicetree to a RAM location. load_address must be a valid
* address which is requested with request_sdram_region. The associated region
* is released automatically in the bootm error path.
*
- * Return: 0 on success, negative error code otherwise
+ * Return: the devicetree resource on success, or an error pointer on failure
*/
-int bootm_load_devicetree(struct image_data *data, void *fdt,
- unsigned long load_address)
+const struct resource *
+bootm_load_devicetree(struct image_data *data, void *fdt,
+ ulong load_address, ulong end_address)
{
int fdt_size;
if (!IS_ENABLED(CONFIG_OFTREE))
- return -ENOSYS;
+ return ERR_PTR(-ENOSYS);
+ if (end_address <= load_address)
+ return ERR_PTR(-EINVAL);
fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize);
+ if (load_address + fdt_size - 1 > end_address)
+ return ERR_PTR(-ENOSPC);
data->oftree_res = request_sdram_region("oftree", load_address,
fdt_size, MEMTYPE_LOADER_DATA, MEMATTRS_RW);
if (!data->oftree_res)
- return -ENOMEM;
+ return ERR_PTR(-EBUSY);
memcpy((void *)data->oftree_res->start, fdt, fdt_size);
@@ -461,7 +486,7 @@ int bootm_load_devicetree(struct image_data *data, void *fdt,
fdt_print_reserve_map(fdt);
}
- return 0;
+ return data->oftree_res;
}
int bootm_get_os_size(struct image_data *data)
diff --git a/efi/loader/bootm.c b/efi/loader/bootm.c
index da664847def8..b40263ce6eb3 100644
--- a/efi/loader/bootm.c
+++ b/efi/loader/bootm.c
@@ -171,7 +171,8 @@ static efi_status_t efi_install_fdt(void *fdt)
static efi_status_t efi_install_initrd(struct image_data *data,
struct resource *source)
{
- const struct resource *initrd_res;
+ const struct resource *initrd_res, *sdram;
+ struct resource gap;
unsigned long initrd_start;
if (!IS_ENABLED(CONFIG_BOOTM_INITRD))
@@ -182,7 +183,11 @@ static efi_status_t efi_install_initrd(struct image_data *data,
else
initrd_start = EFI_PAGE_ALIGN(source->end + 1);
- initrd_res = bootm_load_initrd(data, initrd_start);
+ sdram = memory_bank_lookup_region(data->os_address, &gap);
+ if (sdram != &gap)
+ return sdram ? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;
+
+ initrd_res = bootm_load_initrd(data, initrd_start, gap.end);
if (IS_ERR(initrd_res))
return PTR_ERR(initrd_res);
if (initrd_res)
diff --git a/include/bootm.h b/include/bootm.h
index e56a999f0b11..1c3bb8899b38 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -150,14 +150,19 @@ static inline int bootm_verbose(struct image_data *data)
void bootm_data_init_defaults(struct bootm_data *data);
void bootm_data_restore_defaults(const struct bootm_data *data);
-int bootm_load_os(struct image_data *data, unsigned long load_address);
+const struct resource *
+bootm_load_os(struct image_data *data,
+ ulong load_address, ulong end_address);
const struct resource *
-bootm_load_initrd(struct image_data *data, unsigned long load_address);
+bootm_load_initrd(struct image_data *data,
+ ulong load_address, ulong end_address);
void *bootm_get_devicetree(struct image_data *data);
-int bootm_load_devicetree(struct image_data *data, void *fdt,
- unsigned long load_address);
+
+const struct resource *
+bootm_load_devicetree(struct image_data *data, void *fdt,
+ ulong load_address, ulong end_address);
int bootm_get_os_size(struct image_data *data);
enum bootm_verify bootm_get_verify_mode(void);
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 04/15] bootm: give bootm_load_ functions an end address
2026-01-27 8:39 ` [PATCH 04/15] bootm: give bootm_load_ functions an end address Ahmad Fatoum
@ 2026-01-27 15:31 ` Ahmad Fatoum
2026-01-30 13:35 ` Sascha Hauer
0 siblings, 1 reply; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 15:31 UTC (permalink / raw)
To: Ahmad Fatoum, BAREBOX
Hi,
On 1/27/26 9:39 AM, Ahmad Fatoum wrote:
> So far we expected that a load operation will not overflow, but there
> was actually no way for the callee to check this.
>
> As the architecture-specific bootm handlers are tasked with allocating
> memory for boot artifacts have them pass along not only the start of the
> load region, but also its end, so the callee can check that it didn't
> overflow.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Please dismiss this one patch. I got at least one end offset wrong and I
will just redo it separate from this series.
Thanks,
Ahmad
> ---
> arch/arm/lib32/bootm.c | 24 +++++---
> arch/arm/lib64/armlinux.c | 7 ++-
> arch/arm/mach-at91/bootm-barebox.c | 7 ++-
> arch/arm/mach-imx/imx-v3-image.c | 7 ++-
> arch/arm/mach-layerscape/pblimage.c | 7 ++-
> arch/arm/mach-rockchip/bootm.c | 13 ++--
> arch/arm/mach-zynq/bootm-zynqimg.c | 7 ++-
> arch/kvx/lib/bootm.c | 17 ++++--
> arch/powerpc/lib/ppclinux.c | 13 +++-
> common/booti.c | 30 +++++----
> common/bootm-mock.c | 0
> common/bootm.c | 95 ++++++++++++++++++-----------
> efi/loader/bootm.c | 9 ++-
> include/bootm.h | 13 ++--
> 14 files changed, 158 insertions(+), 91 deletions(-)
> create mode 100644 common/bootm-mock.c
>
> diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
> index e659d3c1a554..3641dbbdbe61 100644
> --- a/arch/arm/lib32/bootm.c
> +++ b/arch/arm/lib32/bootm.c
> @@ -236,12 +236,17 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
> {
> unsigned long kernel;
> unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
> - const struct resource *initrd_res;
> + const struct resource *initrd_res, *sdram;
> + struct resource gap;
> void *tee;
> enum arm_security_state state = bootm_arm_security_state();
> void *fdt_load_address = NULL;
> int ret;
>
> + sdram = memory_bank_lookup_region(free_mem, &gap);
> + if (sdram != &gap)
> + return sdram ? -EBUSY : -EINVAL;
> +
> kernel = data->os_res->start + data->os_entry;
>
> initrd_start = data->initrd_address;
> @@ -255,7 +260,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
> }
> }
>
> - initrd_res = bootm_load_initrd(data, initrd_start);
> + initrd_res = bootm_load_initrd(data, initrd_start, gap.end);
> if (IS_ERR(initrd_res)) {
> return PTR_ERR(initrd_res);
> } else if (initrd_res) {
> @@ -277,13 +282,15 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
> }
>
> if (fdt) {
> + const struct resource *fdt_res;
> +
> fdt_load_address = (void *)free_mem;
> - ret = bootm_load_devicetree(data, fdt, free_mem);
> + fdt_res = bootm_load_devicetree(data, fdt, free_mem, gap.end);
>
> free(fdt);
>
> - if (ret)
> - return ret;
> + if (IS_ERR(fdt_res))
> + return PTR_ERR(fdt_res);
> }
>
> if (IS_ENABLED(CONFIG_BOOTM_OPTEE)) {
> @@ -339,6 +346,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem,
>
> static int do_bootm_linux(struct image_data *data)
> {
> + const struct resource *os_res;
> unsigned long load_address, mem_free;
> int ret;
>
> @@ -349,9 +357,9 @@ static int do_bootm_linux(struct image_data *data)
> if (ret)
> return ret;
>
> - ret = bootm_load_os(data, load_address);
> - if (ret)
> - return ret;
> + os_res = bootm_load_os(data, load_address, mem_free - 1);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> return __do_bootm_linux(data, mem_free, 0, NULL);
> }
> diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
> index e40b61a26b07..febffb6c858b 100644
> --- a/arch/arm/lib64/armlinux.c
> +++ b/arch/arm/lib64/armlinux.c
> @@ -43,6 +43,7 @@ static int do_bootm_barebox(struct image_data *data)
> {
> void (*fn)(unsigned long x0, unsigned long x1, unsigned long x2,
> unsigned long x3);
> + const struct resource *os_res;
> resource_size_t start, end;
> unsigned long barebox;
> int ret;
> @@ -53,9 +54,9 @@ static int do_bootm_barebox(struct image_data *data)
>
> barebox = PAGE_ALIGN(start);
>
> - ret = bootm_load_os(data, barebox);
> - if (ret)
> - goto out;
> + os_res = bootm_load_os(data, barebox, end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> printf("Loaded barebox image to 0x%08lx\n", barebox);
>
> diff --git a/arch/arm/mach-at91/bootm-barebox.c b/arch/arm/mach-at91/bootm-barebox.c
> index 5540b8fad35e..f4894f247d11 100644
> --- a/arch/arm/mach-at91/bootm-barebox.c
> +++ b/arch/arm/mach-at91/bootm-barebox.c
> @@ -13,6 +13,7 @@ EXPORT_SYMBOL(at91_bootsource);
>
> static int do_bootm_at91_barebox_image(struct image_data *data)
> {
> + const struct resource *os_res;
> resource_size_t start, end;
> int ret;
>
> @@ -20,9 +21,9 @@ static int do_bootm_at91_barebox_image(struct image_data *data)
> if (ret)
> return ret;
>
> - ret = bootm_load_os(data, start);
> - if (ret)
> - return ret;
> + os_res = bootm_load_os(data, start, end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> if (data->verbose)
> printf("Loaded barebox image to 0x%08zx\n", start);
> diff --git a/arch/arm/mach-imx/imx-v3-image.c b/arch/arm/mach-imx/imx-v3-image.c
> index e5df5fdb81d9..5cce846f867f 100644
> --- a/arch/arm/mach-imx/imx-v3-image.c
> +++ b/arch/arm/mach-imx/imx-v3-image.c
> @@ -8,6 +8,7 @@
>
> static int do_bootm_imx_image_v3(struct image_data *data)
> {
> + const struct resource *os_res;
> void (*bb)(void);
> resource_size_t start, end;
> struct flash_header_v3 *hdr;
> @@ -18,9 +19,9 @@ static int do_bootm_imx_image_v3(struct image_data *data)
> if (ret)
> return ret;
>
> - ret = bootm_load_os(data, start);
> - if (ret)
> - return ret;
> + os_res = bootm_load_os(data, start, end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> hdr = (void *)start;
> offset = hdr->img[0].offset;
> diff --git a/arch/arm/mach-layerscape/pblimage.c b/arch/arm/mach-layerscape/pblimage.c
> index 5a525f0933d5..31783f18c74d 100644
> --- a/arch/arm/mach-layerscape/pblimage.c
> +++ b/arch/arm/mach-layerscape/pblimage.c
> @@ -15,6 +15,7 @@ static int do_bootm_layerscape_pblimage(struct image_data *data)
> {
> void (*barebox)(unsigned long x0, unsigned long x1, unsigned long x2,
> unsigned long x3);
> + const struct resource *os_res;
> resource_size_t start, end;
> int ret;
>
> @@ -22,9 +23,9 @@ static int do_bootm_layerscape_pblimage(struct image_data *data)
> if (ret)
> return ret;
>
> - ret = bootm_load_os(data, start);
> - if (ret)
> - return ret;
> + os_res = bootm_load_os(data, start, end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> barebox = (void*)start + BAREBOX_STAGE2_OFFSET;
>
> diff --git a/arch/arm/mach-rockchip/bootm.c b/arch/arm/mach-rockchip/bootm.c
> index ff3d9a2db3a0..2e068b05cefd 100644
> --- a/arch/arm/mach-rockchip/bootm.c
> +++ b/arch/arm/mach-rockchip/bootm.c
> @@ -40,6 +40,7 @@ static int do_bootm_rkns_barebox_image(struct image_data *data)
> {
> void (*barebox)(unsigned long x0, unsigned long x1, unsigned long x2,
> unsigned long x3);
> + const struct resource *os_res;
> resource_size_t start, end;
> struct newidb *idb;
> int ret, i, n_files;
> @@ -50,14 +51,14 @@ static int do_bootm_rkns_barebox_image(struct image_data *data)
> if (ret)
> return ret;
>
> - ret = bootm_load_os(data, start);
> - if (ret)
> - return ret;
> + os_res = bootm_load_os(data, start, end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> - idb = (void *)data->os_res->start;
> - buf = (void *)data->os_res->start;
> + idb = (void *)os_res->start;
> + buf = (void *)os_res->start;
>
> - image_size = resource_size(data->os_res);
> + image_size = resource_size(os_res);
>
> if (image_size < SECTOR_SIZE)
> return -EINVAL;
> diff --git a/arch/arm/mach-zynq/bootm-zynqimg.c b/arch/arm/mach-zynq/bootm-zynqimg.c
> index 77ed6880e4b6..ebd2d621520b 100644
> --- a/arch/arm/mach-zynq/bootm-zynqimg.c
> +++ b/arch/arm/mach-zynq/bootm-zynqimg.c
> @@ -8,6 +8,7 @@
> static int do_bootm_zynqimage(struct image_data *data)
> {
> resource_size_t start, end;
> + const struct resource *os_res;
> void (*barebox)(void);
> u32 *header;
> int ret;
> @@ -16,9 +17,9 @@ static int do_bootm_zynqimage(struct image_data *data)
> if (ret)
> return ret;
>
> - ret = bootm_load_os(data, start);
> - if (ret)
> - return ret;
> + os_res = bootm_load_os(data, start, end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> header = (u32*)start;
> barebox = (void*)start + header[12];
> diff --git a/arch/kvx/lib/bootm.c b/arch/kvx/lib/bootm.c
> index 6eba4054e500..c464b5006fa2 100644
> --- a/arch/kvx/lib/bootm.c
> +++ b/arch/kvx/lib/bootm.c
> @@ -13,6 +13,7 @@
> #include <bootm.h>
> #include <binfmt.h>
> #include <common.h>
> +#include <memory.h>
> #include <libfile.h>
> #include <linux/kernel.h>
>
> @@ -54,7 +55,8 @@ static int do_boot_entry(struct image_data *data, boot_func_entry entry,
>
> static int do_boot_elf(struct image_data *data, struct elf_image *elf)
> {
> - const struct resource *initrd_res;
> + const struct resource *sdram, *initrd_res, *fdt_res;
> + struct resource gap;
> int ret;
> void *fdt;
> boot_func_entry entry;
> @@ -71,7 +73,11 @@ static int do_boot_elf(struct image_data *data, struct elf_image *elf)
> else
> initrd_address = load_addr;
>
> - initrd_res = bootm_load_initrd(data, initrd_address);
> + sdram = memory_bank_lookup_region(initrd_address, &gap);
> + if (sdram != &gap)
> + return sdram ? -EBUSY : -EINVAL;
> +
> + initrd_res = bootm_load_initrd(data, initrd_address, gap.end);
> if (IS_ERR(initrd_res)) {
> printf("Failed to load initrd\n");
> return PTR_ERR(initrd_res);
> @@ -93,9 +99,10 @@ static int do_boot_elf(struct image_data *data, struct elf_image *elf)
>
> printf("Loading device tree at %lx\n", load_addr);
> /* load device tree after the initrd if any */
> - ret = bootm_load_devicetree(data, fdt, load_addr);
> - if (ret) {
> - printf("Failed to load device tree: %d\n", ret);
> + fdt_res = bootm_load_devicetree(data, fdt, load_addr, gap.end);
> + if (IS_ERR(fdt_res)) {
> + printf("Failed to load device tree: %pe\n", fdt_res);
> + ret = PTR_ERR(fdt_res);
> goto err_free_fdt;
> }
>
> diff --git a/arch/powerpc/lib/ppclinux.c b/arch/powerpc/lib/ppclinux.c
> index 564086482e5f..eda2539e6125 100644
> --- a/arch/powerpc/lib/ppclinux.c
> +++ b/arch/powerpc/lib/ppclinux.c
> @@ -7,6 +7,7 @@
> #include <image.h>
> #include <init.h>
> #include <malloc.h>
> +#include <memory.h>
> #include <environment.h>
> #include <asm/bitops.h>
> #include <asm/processor.h>
> @@ -53,12 +54,18 @@ static int do_bootm_linux(struct image_data *data)
> {
> void (*kernel)(void *, void *, unsigned long,
> unsigned long, unsigned long);
> + const struct resource *os_res, *sdram;
> + struct resource gap;
> int ret;
> struct fdt_header *fdt;
>
> - ret = bootm_load_os(data, data->os_address);
> - if (ret)
> - return ret;
> + sdram = memory_bank_lookup_region(data->os_address, &gap);
> + if (sdram != &gap)
> + return sdram ? -EBUSY : -EINVAL;
> +
> + os_res = bootm_load_os(data, data->os_address, gap.end);
> + if (IS_ERR(os_res))
> + return PTR_ERR(os_res);
>
> fdt = of_get_fixed_tree_for_boot(data->of_root_node);
> if (!fdt) {
> diff --git a/common/booti.c b/common/booti.c
> index 6a87b84c0308..67f31b793517 100644
> --- a/common/booti.c
> +++ b/common/booti.c
> @@ -10,13 +10,14 @@
> #include <linux/sizes.h>
>
> static unsigned long get_kernel_address(unsigned long os_address,
> - unsigned long text_offset)
> + unsigned long text_offset,
> + resource_size_t *end)
> {
> - resource_size_t start, end;
> + resource_size_t start;
> int ret;
>
> if (!UIMAGE_IS_ADDRESS_VALID(os_address)) {
> - ret = memory_bank_first_find_space(&start, &end);
> + ret = memory_bank_first_find_space(&start, end);
> if (ret)
> return UIMAGE_INVALID_ADDRESS;
>
> @@ -33,9 +34,10 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
> {
> const void *kernel_header =
> data->os_fit ? data->fit_kernel : data->os_header;
> + const struct resource *os_res;
> unsigned long text_offset, image_size, kernel;
> unsigned long image_end;
> - int ret;
> + resource_size_t end;
> void *fdt;
>
> print_hex_dump_bytes("header ", DUMP_PREFIX_OFFSET, kernel_header, 80);
> @@ -49,24 +51,26 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
> text_offset = le64_to_cpup(kernel_header + 8);
> image_size = le64_to_cpup(kernel_header + 16);
>
> - kernel = get_kernel_address(data->os_address, text_offset);
> + kernel = get_kernel_address(data->os_address, text_offset, &end);
>
> pr_debug("Kernel to be loaded to %lx+%lx\n", kernel, image_size);
>
> if (kernel == UIMAGE_INVALID_ADDRESS)
> return ERR_PTR(-ENOENT);
> + if (kernel + image_size - 1 > end)
> + return ERR_PTR(-ENOSPC);
>
> - ret = bootm_load_os(data, kernel);
> - if (ret)
> - return ERR_PTR(ret);
> + os_res = bootm_load_os(data, kernel, end);
> + if (IS_ERR(os_res))
> + return ERR_CAST(os_res);
>
> image_end = PAGE_ALIGN(kernel + image_size);
>
> if (oftree) {
> unsigned long devicetree;
> - const struct resource *initrd_res;
> + const struct resource *initrd_res, *dt_res;
>
> - initrd_res = bootm_load_initrd(data, image_end);
> + initrd_res = bootm_load_initrd(data, image_end, end);
> if (IS_ERR(initrd_res)) {
> return ERR_CAST(initrd_res);
> } else if (initrd_res) {
> @@ -85,11 +89,11 @@ void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
> goto out;
> }
>
> - ret = bootm_load_devicetree(data, fdt, devicetree);
> + dt_res = bootm_load_devicetree(data, fdt, devicetree, end);
> free(fdt);
>
> - if (ret)
> - return ERR_PTR(ret);
> + if (IS_ERR(dt_res))
> + return ERR_CAST(dt_res);
>
> *oftree = devicetree;
> }
> diff --git a/common/bootm-mock.c b/common/bootm-mock.c
> new file mode 100644
> index 000000000000..e69de29bb2d1
> diff --git a/common/bootm.c b/common/bootm.c
> index 35305f25375a..fcf7868a5d75 100644
> --- a/common/bootm.c
> +++ b/common/bootm.c
> @@ -228,57 +228,69 @@ static bool bootm_get_override(char **oldpath, const char *newpath)
> return true;
> }
>
> -/*
> +/**
> * bootm_load_os() - load OS to RAM
> - *
> * @data: image data context
> * @load_address: The address where the OS should be loaded to
> + * @end_address: The end address of the load buffer (inclusive)
> *
> * This loads the OS to a RAM location. load_address must be a valid
> - * address. If the image_data doesn't have a OS specified it's considered
> + * address. If the image_data doesn't have an OS specified it's considered
> * an error.
> *
> - * Return: 0 on success, negative error code otherwise
> + * Return: the OS resource on success, or an error pointer on failure
> */
> -int bootm_load_os(struct image_data *data, unsigned long load_address)
> +const struct resource *bootm_load_os(struct image_data *data,
> + ulong load_address, ulong end_address)
> {
> + int err;
> +
> if (data->os_res)
> - return 0;
> + return data->os_res;
>
> if (load_address == UIMAGE_INVALID_ADDRESS)
> - return -EINVAL;
> + return ERR_PTR(-EINVAL);
> + if (end_address <= load_address)
> + return ERR_PTR(-EINVAL);
>
> - if (data->os_fit)
> - return bootm_load_fit_os(data, load_address);
> + if (data->os_fit) {
> + err = bootm_load_fit_os(data, load_address);
> + } else if (image_is_uimage(data)) {
> + err = bootm_load_uimage_os(data, load_address);
> + } else if (data->os_file) {
> + data->os_res = file_to_sdram(data->os_file, load_address, MEMTYPE_LOADER_CODE);
> + err = data->os_res ? 0 : -EBUSY;
> + } else {
> + err = -EINVAL;
> + }
>
> - if (image_is_uimage(data))
> - return bootm_load_uimage_os(data, load_address);
> + if (err)
> + return ERR_PTR(err);
>
> - if (!data->os_file)
> - return -EINVAL;
> + /* FIXME: We need some more rework to be able to detect this overflow
> + * before it happens, but for now, let's at least detect it.
> + */
> + if (WARN_ON(data->os_res->end > end_address))
> + return ERR_PTR(-ENOSPC);
>
> - data->os_res = file_to_sdram(data->os_file, load_address, MEMTYPE_LOADER_CODE);
> - if (!data->os_res)
> - return -ENOMEM;
> -
> - return 0;
> + return data->os_res;
> }
>
> -/*
> +/**
> * bootm_load_initrd() - load initrd to RAM
> - *
> * @data: image data context
> * @load_address: The address where the initrd should be loaded to
> + * @end_address: The end address of the load buffer (inclusive)
> *
> * This loads the initrd to a RAM location. load_address must be a valid
> - * address. If the image_data doesn't have a initrd specified this function
> - * still returns successful as an initrd is optional. Check data->initrd_res
> - * to see if an initrd has been loaded.
> + * address. If the image_data doesn't have an initrd specified this function
> + * still returns successful as an initrd is optional.
> *
> - * Return: 0 on success, negative error code otherwise
> + * Return: the initrd resource if one was loaded, NULL if no initrd was
> + * specified, or an error pointer on failure
> */
> const struct resource *
> -bootm_load_initrd(struct image_data *data, unsigned long load_address)
> +bootm_load_initrd(struct image_data *data, ulong load_address, ulong end_address)
> {
> struct resource *res = NULL;
> const char *initrd, *initrd_part = NULL;
> @@ -293,6 +305,8 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
> */
> if (WARN_ON(data->initrd_res))
> return data->initrd_res;
> + if (end_address <= load_address)
> + return ERR_PTR(-EINVAL);
>
> bootm_get_override(&data->initrd_file, bootm_overrides.initrd_file);
>
> @@ -313,7 +327,7 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
>
> } else if (initrd) {
> res = file_to_sdram(initrd, load_address, MEMTYPE_LOADER_DATA)
> - ?: ERR_PTR(-ENOMEM);
> + ?: ERR_PTR(-EBUSY);
>
> } else if (data->os_fit) {
> res = bootm_load_fit_initrd(data, load_address);
> @@ -324,6 +338,12 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
> if (IS_ERR_OR_NULL(res))
> return res;
>
> + /* FIXME: We need some more rework to be able to detect this overflow
> + * before it happens, but for now, let's at least detect it.
> + */
> + if (WARN_ON(data->initrd_res->end > end_address))
> + return ERR_PTR(-ENOSPC);
> +
> pr_info("Loaded initrd from %s %s%s%s to %pa-%pa\n",
> file_type_to_string(type), initrd,
> initrd_part ? "@" : "", initrd_part ?: "",
> @@ -425,33 +445,38 @@ void *bootm_get_devicetree(struct image_data *data)
> return oftree;
> }
>
> -/*
> - * bootm_load_devicetree() - load devicetree
> - *
> +/**
> + * bootm_load_devicetree() - load devicetree into specified memory range
> * @data: image data context
> * @fdt: The flat device tree to load
> * @load_address: The address where the devicetree should be loaded to
> + * @end_address: The end address of the load buffer (inclusive)
> *
> * This loads the devicetree to a RAM location. load_address must be a valid
> * address which is requested with request_sdram_region. The associated region
> * is released automatically in the bootm error path.
> *
> - * Return: 0 on success, negative error code otherwise
> + * Return: the devicetree resource on success, or an error pointer on failure
> */
> -int bootm_load_devicetree(struct image_data *data, void *fdt,
> - unsigned long load_address)
> +const struct resource *
> +bootm_load_devicetree(struct image_data *data, void *fdt,
> + ulong load_address, ulong end_address)
> {
> int fdt_size;
>
> if (!IS_ENABLED(CONFIG_OFTREE))
> - return -ENOSYS;
> + return ERR_PTR(-ENOSYS);
> + if (end_address <= load_address)
> + return ERR_PTR(-EINVAL);
>
> fdt_size = be32_to_cpu(((struct fdt_header *)fdt)->totalsize);
> + if (load_address + fdt_size - 1 > end_address)
> + return ERR_PTR(-ENOSPC);
>
> data->oftree_res = request_sdram_region("oftree", load_address,
> fdt_size, MEMTYPE_LOADER_DATA, MEMATTRS_RW);
> if (!data->oftree_res)
> - return -ENOMEM;
> + return ERR_PTR(-EBUSY);
>
> memcpy((void *)data->oftree_res->start, fdt, fdt_size);
>
> @@ -461,7 +486,7 @@ int bootm_load_devicetree(struct image_data *data, void *fdt,
> fdt_print_reserve_map(fdt);
> }
>
> - return 0;
> + return data->oftree_res;
> }
>
> int bootm_get_os_size(struct image_data *data)
> diff --git a/efi/loader/bootm.c b/efi/loader/bootm.c
> index da664847def8..b40263ce6eb3 100644
> --- a/efi/loader/bootm.c
> +++ b/efi/loader/bootm.c
> @@ -171,7 +171,8 @@ static efi_status_t efi_install_fdt(void *fdt)
> static efi_status_t efi_install_initrd(struct image_data *data,
> struct resource *source)
> {
> - const struct resource *initrd_res;
> + const struct resource *initrd_res, *sdram;
> + struct resource gap;
> unsigned long initrd_start;
>
> if (!IS_ENABLED(CONFIG_BOOTM_INITRD))
> @@ -182,7 +183,11 @@ static efi_status_t efi_install_initrd(struct image_data *data,
> else
> initrd_start = EFI_PAGE_ALIGN(source->end + 1);
>
> - initrd_res = bootm_load_initrd(data, initrd_start);
> + sdram = memory_bank_lookup_region(data->os_address, &gap);
> + if (sdram != &gap)
> + return sdram ? EFI_OUT_OF_RESOURCES : EFI_INVALID_PARAMETER;
> +
> + initrd_res = bootm_load_initrd(data, initrd_start, gap.end);
> if (IS_ERR(initrd_res))
> return PTR_ERR(initrd_res);
> if (initrd_res)
> diff --git a/include/bootm.h b/include/bootm.h
> index e56a999f0b11..1c3bb8899b38 100644
> --- a/include/bootm.h
> +++ b/include/bootm.h
> @@ -150,14 +150,19 @@ static inline int bootm_verbose(struct image_data *data)
> void bootm_data_init_defaults(struct bootm_data *data);
> void bootm_data_restore_defaults(const struct bootm_data *data);
>
> -int bootm_load_os(struct image_data *data, unsigned long load_address);
> +const struct resource *
> +bootm_load_os(struct image_data *data,
> + ulong load_address, ulong end_address);
>
> const struct resource *
> -bootm_load_initrd(struct image_data *data, unsigned long load_address);
> +bootm_load_initrd(struct image_data *data,
> + ulong load_address, ulong end_address);
>
> void *bootm_get_devicetree(struct image_data *data);
> -int bootm_load_devicetree(struct image_data *data, void *fdt,
> - unsigned long load_address);
> +
> +const struct resource *
> +bootm_load_devicetree(struct image_data *data, void *fdt,
> + ulong load_address, ulong end_address);
> int bootm_get_os_size(struct image_data *data);
>
> enum bootm_verify bootm_get_verify_mode(void);
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 04/15] bootm: give bootm_load_ functions an end address
2026-01-27 15:31 ` Ahmad Fatoum
@ 2026-01-30 13:35 ` Sascha Hauer
0 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2026-01-30 13:35 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX
On Tue, Jan 27, 2026 at 04:31:58PM +0100, Ahmad Fatoum wrote:
> Hi,
>
> On 1/27/26 9:39 AM, Ahmad Fatoum wrote:
> > So far we expected that a load operation will not overflow, but there
> > was actually no way for the callee to check this.
> >
> > As the architecture-specific bootm handlers are tasked with allocating
> > memory for boot artifacts have them pass along not only the start of the
> > load region, but also its end, so the callee can check that it didn't
> > overflow.
> >
> > Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
>
> Please dismiss this one patch. I got at least one end offset wrong and I
> will just redo it separate from this series.
With this at least the next patch doesn't apply anymore. Please resend
then.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 05/15] bootm: store separate image_type and kernel_type
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (3 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 04/15] bootm: give bootm_load_ functions an end address Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 06/15] bootm: cache os_file for appendroot purposes Ahmad Fatoum
` (9 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
For FIT images, image_data::os_type is either the container file type or
the kernel file type, depending on when we are looking.
This makes the code harder to refactor, so let's split it into two
separate image_type and kernel_type members.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/booti.c | 3 +--
common/bootm-fit.c | 15 +++++++++++++++
common/bootm-mock.c | 0
common/bootm.c | 29 +++++++++++++++--------------
efi/loader/bootm.c | 2 +-
include/bootm.h | 6 +++++-
6 files changed, 37 insertions(+), 18 deletions(-)
delete mode 100644 common/bootm-mock.c
diff --git a/common/booti.c b/common/booti.c
index 67f31b793517..4f6ccf95f85c 100644
--- a/common/booti.c
+++ b/common/booti.c
@@ -32,8 +32,7 @@ static unsigned long get_kernel_address(unsigned long os_address,
void *booti_load_image(struct image_data *data, phys_addr_t *oftree)
{
- const void *kernel_header =
- data->os_fit ? data->fit_kernel : data->os_header;
+ const void *kernel_header = data->os_header;
const struct resource *os_res;
unsigned long text_offset, image_size, kernel;
unsigned long image_end;
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
index a0e808e31b40..5bfd8ac61d3f 100644
--- a/common/bootm-fit.c
+++ b/common/bootm-fit.c
@@ -5,6 +5,7 @@
#include <bootm-fit.h>
#include <memory.h>
#include <zero_page.h>
+#include <filetype.h>
/*
* bootm_load_fit_os() - load OS from FIT to RAM
@@ -114,6 +115,17 @@ static bool bootm_fit_config_valid(struct fit_handle *fit,
return !!fit_has_image(fit, config, "kernel");
}
+static enum filetype bootm_fit_update_os_header(struct image_data *data)
+{
+ if (data->fit_kernel_size < PAGE_SIZE)
+ return filetype_unknown;
+
+ free(data->os_header);
+ data->os_header = xmemdup(data->fit_kernel, PAGE_SIZE);
+
+ return file_detect_type(data->os_header, PAGE_SIZE);
+}
+
int bootm_open_fit(struct image_data *data)
{
struct fit_handle *fit;
@@ -148,6 +160,9 @@ int bootm_open_fit(struct image_data *data)
&data->fit_kernel, &data->fit_kernel_size);
if (ret)
return ret;
+
+ data->kernel_type = bootm_fit_update_os_header(data);
+
if (data->os_address == UIMAGE_SOME_ADDRESS) {
ret = fit_get_image_address(data->os_fit,
data->fit_config,
diff --git a/common/bootm-mock.c b/common/bootm-mock.c
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/common/bootm.c b/common/bootm.c
index fcf7868a5d75..17c94b281eb2 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -551,9 +551,8 @@ int bootm_boot(struct bootm_data *bootm_data)
struct image_data *data;
struct image_handler *handler;
int ret;
- enum filetype os_type;
size_t size;
- const char *os_type_str;
+ const char *image_type_str;
if (!bootm_data->os_file) {
pr_err("no image given\n");
@@ -584,9 +583,9 @@ int bootm_boot(struct bootm_data *bootm_data)
if (size < PAGE_SIZE)
goto err_out;
- os_type = data->os_type = file_detect_boot_image_type(data->os_header, PAGE_SIZE);
+ data->image_type = file_detect_boot_image_type(data->os_header, PAGE_SIZE);
- if (!data->force && os_type == filetype_unknown) {
+ if (!data->force && data->image_type == filetype_unknown) {
pr_err("Unknown OS filetype (try -f)\n");
ret = -EINVAL;
goto err_out;
@@ -602,19 +601,21 @@ int bootm_boot(struct bootm_data *bootm_data)
data->oftree_file = NULL;
data->initrd_file = NULL;
data->tee_file = NULL;
- if (os_type != filetype_fit) {
+ if (data->image_type != filetype_fit) {
pr_err("Signed boot and image is no FIT image, aborting\n");
ret = -EINVAL;
goto err_out;
}
}
- os_type_str = file_type_to_short_string(os_type);
+ image_type_str = file_type_to_short_string(data->image_type);
- switch (os_type) {
+ /* May be updated by below container-specific handlers */
+ data->kernel_type = data->image_type;
+
+ switch (data->image_type) {
case filetype_fit:
ret = bootm_open_fit(data);
- os_type = file_detect_type(data->fit_kernel, data->fit_kernel_size);
break;
case filetype_uimage:
ret = bootm_open_uimage(data);
@@ -625,7 +626,7 @@ int bootm_boot(struct bootm_data *bootm_data)
}
if (ret) {
- pr_err("Loading %s image failed with: %pe\n", os_type_str, ERR_PTR(ret));
+ pr_err("Loading %s image failed with: %pe\n", image_type_str, ERR_PTR(ret));
goto err_out;
}
@@ -738,9 +739,9 @@ int bootm_boot(struct bootm_data *bootm_data)
free(hostname_bootarg);
}
- pr_info("\nLoading %s '%s'", file_type_to_string(os_type),
+ pr_info("\nLoading %s '%s'", file_type_to_string(data->kernel_type),
data->os_file);
- if (os_type == filetype_uimage &&
+ if (data->kernel_type == filetype_uimage &&
data->os->header.ih_type == IH_TYPE_MULTI)
pr_info(", multifile image %d", uimage_part_num(data->os_part));
pr_info("\n");
@@ -750,11 +751,11 @@ int bootm_boot(struct bootm_data *bootm_data)
if (data->os_entry == UIMAGE_SOME_ADDRESS)
data->os_entry = 0;
- handler = bootm_find_handler(os_type, data);
+ handler = bootm_find_handler(data->kernel_type, data);
if (!handler) {
pr_err("no image handler found for image type %s\n",
- file_type_to_string(os_type));
- if (os_type == filetype_uimage)
+ file_type_to_string(data->kernel_type));
+ if (data->kernel_type == filetype_uimage)
pr_err("and OS type: %d\n", data->os->header.ih_os);
ret = -ENODEV;
goto err_out;
diff --git a/efi/loader/bootm.c b/efi/loader/bootm.c
index b40263ce6eb3..fcc17a03905f 100644
--- a/efi/loader/bootm.c
+++ b/efi/loader/bootm.c
@@ -220,7 +220,7 @@ static int efi_loader_bootm(struct image_data *data)
if (!source)
return -EINVAL;
- if (filetype_is_linux_efi_image(data->os_type)) {
+ if (filetype_is_linux_efi_image(data->kernel_type)) {
const char *options;
options = linux_bootargs_get();
diff --git a/include/bootm.h b/include/bootm.h
index 1c3bb8899b38..bdabba23f2b9 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -111,7 +111,11 @@ struct image_data {
char *tee_file;
struct resource *tee_res;
- enum filetype os_type;
+ /* Type of OS image, e.g. filetype_fit or the same as kernel_type */
+ enum filetype image_type;
+ /* Type of kernel image that's going to be booted */
+ enum filetype kernel_type;
+
enum bootm_verify verify;
int verbose;
int force;
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 06/15] bootm: cache os_file for appendroot purposes
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (4 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 05/15] bootm: store separate image_type and kernel_type Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 07/15] bootm: fit: move length calculation into fit_open Ahmad Fatoum
` (8 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Even if we were to use an override, we want appendroot to follow the
original file as the root device can already be overridden by
$global.bootm.root_dev.
Therefore cache os_file to make it easier to reorder execution during
the incoming refactor.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/bootm.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/common/bootm.c b/common/bootm.c
index 17c94b281eb2..a2301ea72458 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -548,6 +548,7 @@ static int bootm_image_name_and_part(const char *name, char **filename, char **p
*/
int bootm_boot(struct bootm_data *bootm_data)
{
+ char *os_file;
struct image_data *data;
struct image_handler *handler;
int ret;
@@ -575,9 +576,11 @@ int bootm_boot(struct bootm_data *bootm_data)
data->os_entry = bootm_data->os_entry;
data->efi_boot = bootm_data->efi_boot;
- ret = read_file_2(data->os_file, &size, &data->os_header, PAGE_SIZE);
+ os_file = xstrdup(data->os_file);
+
+ ret = read_file_2(os_file, &size, &data->os_header, PAGE_SIZE);
if (ret < 0 && ret != -EFBIG) {
- pr_err("could not open %s: %pe\n", data->os_file, ERR_PTR(ret));
+ pr_err("could not open %s: %pe\n", os_file, ERR_PTR(ret));
goto err_out;
}
if (size < PAGE_SIZE)
@@ -655,11 +658,11 @@ int bootm_boot(struct bootm_data *bootm_data)
if (root_cdev)
cdev_close(root_cdev);
} else {
- struct fs_device *fsdev = get_fsdevice_by_path(AT_FDCWD, data->os_file);
+ struct fs_device *fsdev = get_fsdevice_by_path(AT_FDCWD, os_file);
if (fsdev)
fsdev_get_linux_root_options(fsdev, &root, &rootopts);
else
- pr_err("no fsdevice under path: %s\n", data->os_file);
+ pr_err("no fsdevice under path: %s\n", os_file);
}
if (!root) {
@@ -739,8 +742,7 @@ int bootm_boot(struct bootm_data *bootm_data)
free(hostname_bootarg);
}
- pr_info("\nLoading %s '%s'", file_type_to_string(data->kernel_type),
- data->os_file);
+ pr_info("\nLoading %s '%s'", file_type_to_string(data->kernel_type), data->os_file);
if (data->kernel_type == filetype_uimage &&
data->os->header.ih_type == IH_TYPE_MULTI)
pr_info(", multifile image %d", uimage_part_num(data->os_part));
@@ -798,6 +800,7 @@ int bootm_boot(struct bootm_data *bootm_data)
free(data->oftree_file);
free(data->initrd_file);
free(data->tee_file);
+ free(os_file);
free(data);
return ret;
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 07/15] bootm: fit: move length calculation into fit_open
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (5 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 06/15] bootm: cache os_file for appendroot purposes Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 08/15] libfile: factor out zero-page resistant read_file as __read_full_anywhere Ahmad Fatoum
` (7 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
A FIT image is a device tree and its second big-endian 32-bit word
encodes the size and fit_open() takes an extra argument, so it need not
read a whole partition, but only as many bytes as the header describes.
We are going to add a new caller for fit_open(). Instead of repeating
the max_size determination at every call site, let's just move the size
calculation into the function.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/bootm-fit.c | 9 +--------
common/image-fit.c | 44 ++++++++++++++++++++++++++++++++++----------
drivers/of/overlay.c | 6 +++---
include/image-fit.h | 2 +-
include/libfile.h | 2 ++
lib/libfile.c | 40 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 81 insertions(+), 22 deletions(-)
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
index 5bfd8ac61d3f..70d6ba8edff2 100644
--- a/common/bootm-fit.c
+++ b/common/bootm-fit.c
@@ -129,17 +129,10 @@ static enum filetype bootm_fit_update_os_header(struct image_data *data)
int bootm_open_fit(struct image_data *data)
{
struct fit_handle *fit;
- struct fdt_header *header;
static const char *kernel_img = "kernel";
- size_t flen, hlen;
int ret;
- header = (struct fdt_header *)data->os_header;
- flen = bootm_get_os_size(data);
- hlen = fdt32_to_cpu(header->totalsize);
-
- fit = fit_open(data->os_file, data->verbose, data->verify,
- min(flen, hlen));
+ fit = fit_open(data->os_file, data->verbose, data->verify);
if (IS_ERR(fit)) {
pr_err("Loading FIT image %s failed with: %pe\n", data->os_file, fit);
return PTR_ERR(fit);
diff --git a/common/image-fit.c b/common/image-fit.c
index 75592766941c..d42282dfa80e 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -992,7 +992,6 @@ struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
* @filename: The filename of the FIT image
* @verbose: If true, be more verbose
* @verify: The verify mode
- * @max_size: maximum length to read from file
*
* This opens a FIT image found in @filename. The returned handle is used as
* context for the other FIT functions.
@@ -1000,11 +999,12 @@ struct fit_handle *fit_open_buf(const void *buf, size_t size, bool verbose,
* Return: A handle to a FIT image or a ERR_PTR
*/
struct fit_handle *fit_open(const char *_filename, bool verbose,
- enum bootm_verify verify, loff_t max_size)
+ enum bootm_verify verify)
{
struct fit_handle *handle;
+ ssize_t nbytes;
char *filename;
- int ret;
+ int fd, ret;
filename = canonicalize_path(AT_FDCWD, _filename);
if (!filename) {
@@ -1024,15 +1024,28 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
handle->verbose = verbose;
handle->verify = verify;
- ret = read_file_2(filename, &handle->size, &handle->fit_alloc,
- max_size);
- if (ret && ret != -EFBIG) {
- pr_err("unable to read %s: %pe\n", filename, ERR_PTR(ret));
- free(handle);
- free(filename);
- return ERR_PTR(ret);
+ fd = open_fdt(filename, &handle->size);
+ if (fd < 0) {
+ ret = fd;
+ goto free_handle;
}
+ handle->fit_alloc = malloc(handle->size);
+ if (!handle->fit_alloc) {
+ ret = -ENOMEM;
+ goto close_fd;
+ }
+
+ nbytes = read_full(fd, handle->fit_alloc, handle->size);
+ if (nbytes >= 0 && handle->size != nbytes)
+ ret = -ENODATA;
+ if (nbytes < 0) {
+ ret = nbytes;
+ goto free_fit_alloc;
+ }
+
+ close(fd);
+
handle->fit = handle->fit_alloc;
handle->filename = filename;
@@ -1046,6 +1059,17 @@ struct fit_handle *fit_open(const char *_filename, bool verbose,
}
return handle;
+
+free_fit_alloc:
+ free(handle->fit_alloc);
+close_fd:
+ close(fd);
+free_handle:
+ pr_err("unable to read %s: %pe\n", filename, ERR_PTR(ret));
+ free(filename);
+ free(handle);
+ return ERR_PTR(ret);
+
}
static bool __fit_close(struct fit_handle *handle)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index b11edebd2080..34543403e9ba 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -532,7 +532,7 @@ static bool of_overlay_valid_config(struct fit_handle *fit,
}
static int of_overlay_global_fixup_fit(struct device_node *root,
- const char *fit_path, loff_t fit_size)
+ const char *fit_path)
{
enum bootm_verify verify = bootm_get_verify_mode();
struct device_node *conf_node;
@@ -544,7 +544,7 @@ static int of_overlay_global_fixup_fit(struct device_node *root,
return -EINVAL;
}
- fit = fit_open(fit_path, 0, verify, fit_size);
+ fit = fit_open(fit_path, 0, verify);
if (IS_ERR(fit)) {
pr_err("Loading FIT image %s failed with: %pe\n", fit_path, fit);
return PTR_ERR(fit);
@@ -595,7 +595,7 @@ static int of_overlay_global_fixup(struct device_node *root, void *data)
}
/* Assume a FIT image if of_overlay_path points to a file */
- ret = of_overlay_global_fixup_fit(root, dir, s.st_size);
+ ret = of_overlay_global_fixup_fit(root, dir);
out:
free(dir);
diff --git a/include/image-fit.h b/include/image-fit.h
index 50f0482b65ad..ede43beab12e 100644
--- a/include/image-fit.h
+++ b/include/image-fit.h
@@ -28,7 +28,7 @@ struct fit_handle {
};
struct fit_handle *fit_open(const char *filename, bool verbose,
- enum bootm_verify verify, loff_t max_size);
+ enum bootm_verify verify);
struct fit_handle *fit_open_buf(const void *buf, size_t len, bool verbose,
enum bootm_verify verify);
void *fit_open_configuration(struct fit_handle *handle, const char *name,
diff --git a/include/libfile.h b/include/libfile.h
index 370f8b9725ab..f44046fb0f7b 100644
--- a/include/libfile.h
+++ b/include/libfile.h
@@ -59,4 +59,6 @@ struct resource *file_to_sdram(const char *filename, unsigned long adr,
int fixup_path_case(int dirfd, const char **path);
+int open_fdt(const char *filename, size_t *size);
+
#endif /* __LIBFILE_H */
diff --git a/lib/libfile.c b/lib/libfile.c
index 6924db587e8c..3be410855d2e 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -918,3 +918,43 @@ int fixup_path_case(int fd, const char **path)
free(resolved_path);
return -errno;
}
+
+int open_fdt(const char *filename, size_t *size)
+{
+ __be32 fdt_hdr[2];
+ u32 fdt_size;
+ struct stat st;
+ int fd, ret;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ ret = fstat(fd, &st);
+ if (ret)
+ goto err;
+
+ ret = pread_full(fd, &fdt_hdr, sizeof(fdt_hdr), 0);
+ if (ret >= 0 && ret < sizeof(fdt_hdr))
+ ret = -EILSEQ;
+ if (ret < 0)
+ goto err;
+
+ fdt_size = be32_to_cpu(fdt_hdr[1]);
+ if (st.st_size < fdt_size) {
+ ret = -ENODATA;
+ goto err;
+ }
+
+ close(fd);
+
+ /* HACK: TFTP doesn't support backwards seeking, so reopen afresh */
+ fd = open(filename, O_RDONLY);
+ if (fd >= 0)
+ *size = fdt_size;
+
+ return fd;
+err:
+ close(fd);
+ return ret;
+}
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 08/15] libfile: factor out zero-page resistant read_file as __read_full_anywhere
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (6 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 07/15] bootm: fit: move length calculation into fit_open Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 09/15] resource: implement resize_region Ahmad Fatoum
` (6 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
This function will be useful for the incoming loadable support, so factor
it out of file_to_sdram().
While at it, make it a bit safer as well: Only the first page needs to
be copied with zero_page_memcpy if at all, so copy at most one page if
the zero page is overlapped and then copy the rest as usual.
file_to_sdram() is intentionally left as-is as it's going to be removed
in a later commit.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
include/libfile.h | 1 +
lib/libfile.c | 29 +++++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/include/libfile.h b/include/libfile.h
index f44046fb0f7b..f61c45563c01 100644
--- a/include/libfile.h
+++ b/include/libfile.h
@@ -11,6 +11,7 @@ int pread_full(int fd, void *buf, size_t size, loff_t offset);
int pwrite_full(int fd, const void *buf, size_t size, loff_t offset);
int write_full(int fd, const void *buf, size_t size);
int read_full(int fd, void *buf, size_t size);
+int __read_full_anywhere(int fd, void *buf, size_t size);
int copy_fd(int in, int out, size_t size);
ssize_t read_file_into_buf(const char *filename, void *buf, size_t size);
diff --git a/lib/libfile.c b/lib/libfile.c
index 3be410855d2e..966350674a83 100644
--- a/lib/libfile.c
+++ b/lib/libfile.c
@@ -798,6 +798,35 @@ int cache_file(const char *path, char **newpath)
return 0;
}
+/*
+ * __read_full_anywhere - read from filedescriptor, even into zero_page
+ *
+ * Like read_full, but this function will temporarily remap the zero
+ * page if data is to be placed there. You should not need to use this
+ * outside of boot code!
+ */
+int __read_full_anywhere(int fd, void *buf, size_t size)
+{
+ ssize_t now = 0;
+
+ if (unlikely(zero_page_contains((ulong)buf))) {
+ void *tmp = malloc(PAGE_SIZE);
+ if (!tmp)
+ return -ENOMEM;
+
+ now = read_full(fd, tmp, min_t(size_t, size, PAGE_SIZE));
+ if (now > 0)
+ zero_page_memcpy(buf, tmp, now);
+
+ free(tmp);
+
+ if (now <= 0)
+ return now;
+ }
+
+ return now + read_full(fd, buf + now, size - now);
+}
+
#define BUFSIZ (PAGE_SIZE * 32)
struct resource *file_to_sdram(const char *filename, unsigned long adr,
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 09/15] resource: implement resize_region
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (7 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 08/15] libfile: factor out zero-page resistant read_file as __read_full_anywhere Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-30 12:38 ` Sascha Hauer
2026-01-27 8:39 ` [PATCH 10/15] bootm: rename image_data::os/initrd with _uimage suffix Ahmad Fatoum
` (5 subsequent siblings)
14 siblings, 1 reply; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
resize_region allows enlarging or reducing a region end while checking
for conflicts. This is less effort than removing a region and
reallocating it.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/resource.c | 45 ++++++++++++++++++++++++++++++++++++++++++
include/linux/ioport.h | 2 ++
2 files changed, 47 insertions(+)
diff --git a/common/resource.c b/common/resource.c
index e391d268e0bb..39867da63b69 100644
--- a/common/resource.c
+++ b/common/resource.c
@@ -92,6 +92,51 @@ struct resource *__request_region(struct resource *parent,
return new;
}
+int resize_region(struct resource *res, resource_size_t size)
+{
+ struct resource *parent;
+ struct resource *next;
+ resource_size_t newend;
+
+ if (!res)
+ return 0;
+ if (!size)
+ return release_region(res);
+
+ if (size == resource_size(res))
+ return 0;
+
+ if (size < resource_size(res)) {
+ res->end = res->start + size - 1;
+ return 0;
+ }
+
+ parent = res->parent;
+ if (!parent)
+ return -EINVAL;
+
+ if (check_add_overflow(res->start, size - 1, &newend))
+ return -EINVAL;
+
+ if (newend > parent->end)
+ return -EINVAL;
+
+ /*
+ * parent->children is the list_head that anchors the ordered list of
+ * children. If res is not the last entry, the immediate next entry is
+ * the only sibling we must check.
+ */
+ if (res->sibling.next != &parent->children) {
+ next = list_next_entry(res, sibling);
+
+ if (newend >= next->start)
+ return -EBUSY;
+ }
+
+ res->end = newend;
+ return 0;
+}
+
/*
* release a region previously requested with request_*_region
*/
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 5baae0dae10a..8f9191d1c6be 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -272,6 +272,8 @@ static inline void resource_set_range(struct resource *res,
resource_set_size(res, size);
}
+int resize_region(struct resource *res, resource_size_t size);
+
#define region_is_gap(region) ((region)->flags & IORESOURCE_UNSET)
struct resource *resource_iter_first(struct resource *current, struct resource *gap);
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 09/15] resource: implement resize_region
2026-01-27 8:39 ` [PATCH 09/15] resource: implement resize_region Ahmad Fatoum
@ 2026-01-30 12:38 ` Sascha Hauer
0 siblings, 0 replies; 19+ messages in thread
From: Sascha Hauer @ 2026-01-30 12:38 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: barebox
On Tue, Jan 27, 2026 at 09:39:19AM +0100, Ahmad Fatoum wrote:
> resize_region allows enlarging or reducing a region end while checking
> for conflicts. This is less effort than removing a region and
> reallocating it.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> common/resource.c | 45 ++++++++++++++++++++++++++++++++++++++++++
> include/linux/ioport.h | 2 ++
> 2 files changed, 47 insertions(+)
>
> diff --git a/common/resource.c b/common/resource.c
> index e391d268e0bb..39867da63b69 100644
> --- a/common/resource.c
> +++ b/common/resource.c
> @@ -92,6 +92,51 @@ struct resource *__request_region(struct resource *parent,
> return new;
> }
>
> +int resize_region(struct resource *res, resource_size_t size)
> +{
> + struct resource *parent;
> + struct resource *next;
> + resource_size_t newend;
> +
> + if (!res)
> + return 0;
> + if (!size)
> + return release_region(res);
This frees the resource itself. I am not sure if this is useful. It's an
invitation for the caller to reference freed memory. I think the caller
must distinguish between resizing and releasing the resource anyway, so
he could equally call resize_region() or release_region() directly.
> +
> + if (size == resource_size(res))
> + return 0;
> +
> + if (size < resource_size(res)) {
> + res->end = res->start + size - 1;
> + return 0;
> + }
A resource can have child resources. For completeness we should check if
the child resources are still inside the now smaller parent resource.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 10/15] bootm: rename image_data::os/initrd with _uimage suffix
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (8 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 09/15] resource: implement resize_region Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 11/15] uimage: record original file name in uimage_handle Ahmad Fatoum
` (4 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
We will use the generic unadorned for the incoming loadable support, so
add a _uimage suffix to the uimage-only members to make the association
clearer.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
arch/powerpc/lib/ppclinux.c | 2 +-
common/bootm-uimage.c | 38 ++++++++++++++++++-------------------
common/bootm.c | 12 ++++++------
include/bootm.h | 4 ++--
4 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/arch/powerpc/lib/ppclinux.c b/arch/powerpc/lib/ppclinux.c
index eda2539e6125..4e9693cbad60 100644
--- a/arch/powerpc/lib/ppclinux.c
+++ b/arch/powerpc/lib/ppclinux.c
@@ -30,7 +30,7 @@ static struct fdt_header *bootm_relocate_fdt(struct image_data *data,
*/
if (os < (void *)fdt->totalsize) {
os = (void *)PAGE_ALIGN((phys_addr_t)os +
- data->os->header.ih_size);
+ data->os_uimage->header.ih_size);
os += fdt->totalsize;
if (os < LINUX_TLB1_MAX_ADDR)
os = LINUX_TLB1_MAX_ADDR;
diff --git a/common/bootm-uimage.c b/common/bootm-uimage.c
index 609b678e1d4a..b32ed5b0e95f 100644
--- a/common/bootm-uimage.c
+++ b/common/bootm-uimage.c
@@ -29,7 +29,7 @@ int bootm_load_uimage_os(struct image_data *data, unsigned long load_address)
num = uimage_part_num(data->os_part);
- data->os_res = uimage_load_to_sdram(data->os,
+ data->os_res = uimage_load_to_sdram(data->os_uimage,
num, load_address);
if (!data->os_res)
return -ENOMEM;
@@ -42,21 +42,21 @@ static int bootm_open_initrd_uimage(struct image_data *data)
int ret;
if (strcmp(data->os_file, data->initrd_file)) {
- data->initrd = uimage_open(data->initrd_file);
- if (!data->initrd)
+ data->initrd_uimage = uimage_open(data->initrd_file);
+ if (!data->initrd_uimage)
return -EINVAL;
if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
- ret = uimage_verify(data->initrd);
+ ret = uimage_verify(data->initrd_uimage);
if (ret) {
pr_err("Checking data crc failed with %pe\n",
ERR_PTR(ret));
return ret;
}
}
- uimage_print_contents(data->initrd);
+ uimage_print_contents(data->initrd_uimage);
} else {
- data->initrd = data->os;
+ data->initrd_uimage = data->os_uimage;
}
return 0;
@@ -90,7 +90,7 @@ bootm_load_uimage_initrd(struct image_data *data, unsigned long load_address)
num = uimage_part_num(data->initrd_part);
- res = uimage_load_to_sdram(data->initrd,
+ res = uimage_load_to_sdram(data->initrd_uimage,
num, load_address);
if (!res)
return ERR_PTR(-ENOMEM);
@@ -110,9 +110,9 @@ int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
pr_info("Loading devicetree from '%s'@%d\n", oftree, num);
if (!strcmp(data->os_file, oftree)) {
- of_handle = data->os;
+ of_handle = data->os_uimage;
} else if (!strcmp(data->initrd_file, oftree)) {
- of_handle = data->initrd;
+ of_handle = data->initrd_uimage;
} else {
of_handle = uimage_open(oftree);
if (!of_handle)
@@ -141,12 +141,12 @@ int bootm_open_uimage(struct image_data *data)
{
int ret;
- data->os = uimage_open(data->os_file);
- if (!data->os)
+ data->os_uimage = uimage_open(data->os_file);
+ if (!data->os_uimage)
return -EINVAL;
if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
- ret = uimage_verify(data->os);
+ ret = uimage_verify(data->os_uimage);
if (ret) {
pr_err("Checking data crc failed with %pe\n",
ERR_PTR(ret));
@@ -154,23 +154,23 @@ int bootm_open_uimage(struct image_data *data)
}
}
- uimage_print_contents(data->os);
+ uimage_print_contents(data->os_uimage);
- if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) {
+ if (IH_ARCH == IH_ARCH_INVALID || data->os_uimage->header.ih_arch != IH_ARCH) {
pr_err("Unsupported Architecture 0x%x\n",
- data->os->header.ih_arch);
+ data->os_uimage->header.ih_arch);
return -EINVAL;
}
if (data->os_address == UIMAGE_SOME_ADDRESS)
- data->os_address = data->os->header.ih_load;
+ data->os_address = data->os_uimage->header.ih_load;
return 0;
}
void bootm_close_uimage(struct image_data *data)
{
- if (data->initrd && data->initrd != data->os)
- uimage_close(data->initrd);
- uimage_close(data->os);
+ if (data->initrd_uimage && data->initrd_uimage != data->os_uimage)
+ uimage_close(data->initrd_uimage);
+ uimage_close(data->os_uimage);
}
diff --git a/common/bootm.c b/common/bootm.c
index a2301ea72458..7fe0afe24ce8 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -33,7 +33,7 @@ static bool uimage_check(struct image_handler *handler,
enum filetype detected_filetype)
{
return detected_filetype == filetype_uimage &&
- handler->ih_os == data->os->header.ih_os;
+ handler->ih_os == data->os_uimage->header.ih_os;
}
static bool filetype_check(struct image_handler *handler,
@@ -208,7 +208,7 @@ static int uimage_part_num(const char *partname)
static inline bool image_is_uimage(struct image_data *data)
{
- return IS_ENABLED(CONFIG_BOOTM_UIMAGE) && data->os;
+ return IS_ENABLED(CONFIG_BOOTM_UIMAGE) && data->os_uimage;
}
static bool bootm_get_override(char **oldpath, const char *newpath)
@@ -322,7 +322,7 @@ bootm_load_initrd(struct image_data *data, ulong load_address, ulong end_address
if (type == filetype_uimage) {
res = bootm_load_uimage_initrd(data, load_address);
- if (data->initrd->header.ih_type == IH_TYPE_MULTI)
+ if (data->initrd_uimage->header.ih_type == IH_TYPE_MULTI)
initrd_part = data->initrd_part;
} else if (initrd) {
@@ -496,7 +496,7 @@ int bootm_get_os_size(struct image_data *data)
int ret;
if (image_is_uimage(data))
- return uimage_get_size(data->os, uimage_part_num(data->os_part));
+ return uimage_get_size(data->os_uimage, uimage_part_num(data->os_part));
if (data->os_fit)
return data->fit_kernel_size;
if (!data->os_file)
@@ -744,7 +744,7 @@ int bootm_boot(struct bootm_data *bootm_data)
pr_info("\nLoading %s '%s'", file_type_to_string(data->kernel_type), data->os_file);
if (data->kernel_type == filetype_uimage &&
- data->os->header.ih_type == IH_TYPE_MULTI)
+ data->os_uimage->header.ih_type == IH_TYPE_MULTI)
pr_info(", multifile image %d", uimage_part_num(data->os_part));
pr_info("\n");
@@ -758,7 +758,7 @@ int bootm_boot(struct bootm_data *bootm_data)
pr_err("no image handler found for image type %s\n",
file_type_to_string(data->kernel_type));
if (data->kernel_type == filetype_uimage)
- pr_err("and OS type: %d\n", data->os->header.ih_os);
+ pr_err("and OS type: %d\n", data->os_uimage->header.ih_os);
ret = -ENODEV;
goto err_out;
}
diff --git a/include/bootm.h b/include/bootm.h
index bdabba23f2b9..ef979807505d 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -59,7 +59,7 @@ struct image_data {
struct resource *os_res;
/* if os is an uImage this will be provided */
- struct uimage_handle *os;
+ struct uimage_handle *os_uimage;
/* if os is a FIT image this will be provided */
struct fit_handle *os_fit;
@@ -84,7 +84,7 @@ struct image_data {
struct resource *initrd_res;
/* if initrd is an uImage this will be provided */
- struct uimage_handle *initrd;
+ struct uimage_handle *initrd_uimage;
char *initrd_part;
/* otherwise only the filename will be provided */
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 11/15] uimage: record original file name in uimage_handle
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (9 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 10/15] bootm: rename image_data::os/initrd with _uimage suffix Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 12/15] bootm: factor out file detection into helper Ahmad Fatoum
` (3 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The struct uimage_handle only stores the file name if header->ih_name
if empty. To make it possible to always get a descriptive name for when
bootm-uimage is switched over to loadables, let's store the filename
in the uimage_handle.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/uimage.c | 2 ++
include/image.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/common/uimage.c b/common/uimage.c
index 5f7087475709..d34205572510 100644
--- a/common/uimage.c
+++ b/common/uimage.c
@@ -183,6 +183,7 @@ struct uimage_handle *uimage_open(const char *filename)
* fd is now at the first data word
*/
handle->fd = fd;
+ handle->filename = xstrdup(filename);
return handle;
err_out:
@@ -212,6 +213,7 @@ void uimage_close(struct uimage_handle *handle)
}
free(handle->name);
+ free(handle->filename);
free(handle);
}
EXPORT_SYMBOL(uimage_close);
diff --git a/include/image.h b/include/image.h
index d9a1b8f3ee02..769523d6fcaf 100644
--- a/include/image.h
+++ b/include/image.h
@@ -312,6 +312,7 @@ void *uimage_load_to_buf(struct uimage_handle *handle, int image_no,
struct uimage_handle {
struct image_header header;
char *name;
+ char *filename;
char *copy;
struct uimage_handle_data ihd[MAX_MULTI_IMAGE_COUNT];
int nb_data_entries;
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 12/15] bootm: factor out file detection into helper
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (10 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 11/15] uimage: record original file name in uimage_handle Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 13/15] efi: payload: bootm: add dry run support Ahmad Fatoum
` (2 subsequent siblings)
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
Having this function callable on its own will come in handy once we add
boot.image override support as that would need to recompute the file
type.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
common/bootm.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/common/bootm.c b/common/bootm.c
index 7fe0afe24ce8..9e302da36ca6 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -543,6 +543,25 @@ static int bootm_image_name_and_part(const char *name, char **filename, char **p
return 0;
}
+static int file_read_and_detect_boot_image_type(const char *os_file, void **os_header)
+{
+ size_t size;
+ int ret;
+
+ ret = read_file_2(os_file, &size, os_header, PAGE_SIZE);
+ if (ret < 0 && ret != -EFBIG) {
+ pr_err("could not open %s: %pe\n", os_file, ERR_PTR(ret));
+ return ret;
+ }
+ if (size < PAGE_SIZE) {
+ free(*os_header);
+ *os_header = NULL;
+ return -ENODATA;
+ }
+
+ return file_detect_boot_image_type(*os_header, PAGE_SIZE);
+}
+
/*
* bootm_boot - Boot an application image described by bootm_data
*/
@@ -552,7 +571,6 @@ int bootm_boot(struct bootm_data *bootm_data)
struct image_data *data;
struct image_handler *handler;
int ret;
- size_t size;
const char *image_type_str;
if (!bootm_data->os_file) {
@@ -577,16 +595,10 @@ int bootm_boot(struct bootm_data *bootm_data)
data->efi_boot = bootm_data->efi_boot;
os_file = xstrdup(data->os_file);
-
- ret = read_file_2(os_file, &size, &data->os_header, PAGE_SIZE);
- if (ret < 0 && ret != -EFBIG) {
- pr_err("could not open %s: %pe\n", os_file, ERR_PTR(ret));
+ ret = file_read_and_detect_boot_image_type(os_file, &data->os_header);
+ if (ret < 0)
goto err_out;
- }
- if (size < PAGE_SIZE)
- goto err_out;
-
- data->image_type = file_detect_boot_image_type(data->os_header, PAGE_SIZE);
+ data->image_type = ret;
if (!data->force && data->image_type == filetype_unknown) {
pr_err("Unknown OS filetype (try -f)\n");
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 13/15] efi: payload: bootm: add dry run support
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (11 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 12/15] bootm: factor out file detection into helper Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 14/15] efi: payload: bootm: fix memory corruption on initrd load error Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 15/15] efi: initrd: make efi_initrd_register initrd pointer param const Ahmad Fatoum
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
barebox bootm handlers are supposed to check the dry run flag.
While at it, also fix the code to free initrd in error paths.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
efi/payload/bootm.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
index 8e7ba4561f3f..38bc8b23f215 100644
--- a/efi/payload/bootm.c
+++ b/efi/payload/bootm.c
@@ -252,15 +252,16 @@ static int do_bootm_efi_stub(struct image_data *data)
goto unload_oftree;
type = file_detect_type(loaded_image->image_base, PAGE_SIZE);
- ret = efi_execute_image(handle, loaded_image, type);
- if (ret)
+
+ if (data->dryrun)
goto unload_ramdisk;
- return 0;
-
+ ret = efi_execute_image(handle, loaded_image, type);
unload_ramdisk:
- if (initrd)
+ if (initrd) {
efi_initrd_unregister();
+ free(initrd);
+ }
unload_oftree:
efi_unload_fdt(fdt);
unload_os:
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 14/15] efi: payload: bootm: fix memory corruption on initrd load error
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (12 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 13/15] efi: payload: bootm: add dry run support Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
2026-01-27 8:39 ` [PATCH 15/15] efi: initrd: make efi_initrd_register initrd pointer param const Ahmad Fatoum
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum, Claude Sonnet v4.5
initrd is a pointer to a pointer and its only used place the pointed at
pointer on stack. Freeing it will this trigger memory corruption.
Fix this by actually freeing the heap buffer.
Reported-by: Claude Sonnet v4.5 <noreply@anthropic.com>
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
efi/payload/bootm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
index 38bc8b23f215..f1f60e2eaa54 100644
--- a/efi/payload/bootm.c
+++ b/efi/payload/bootm.c
@@ -161,7 +161,7 @@ static int efi_load_ramdisk(struct image_data *data, void **initrd)
return 0;
free_mem:
- free(initrd);
+ free(initrd_mem);
return ret;
}
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 15/15] efi: initrd: make efi_initrd_register initrd pointer param const
2026-01-27 8:39 [PATCH 00/15] bootm: prepare loadable abstraction rework Ahmad Fatoum
` (13 preceding siblings ...)
2026-01-27 8:39 ` [PATCH 14/15] efi: payload: bootm: fix memory corruption on initrd load error Ahmad Fatoum
@ 2026-01-27 8:39 ` Ahmad Fatoum
14 siblings, 0 replies; 19+ messages in thread
From: Ahmad Fatoum @ 2026-01-27 8:39 UTC (permalink / raw)
To: barebox; +Cc: Ahmad Fatoum
The initrd buffer isn't actually used in a writable manner, so reflect
that in the types used to hold its base address.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
efi/initrd.c | 4 ++--
efi/loader/bootm.c | 2 +-
include/efi/initrd.h | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/efi/initrd.c b/efi/initrd.c
index 642422b38d2a..01361d0a3071 100644
--- a/efi/initrd.c
+++ b/efi/initrd.c
@@ -35,7 +35,7 @@ static const struct {
static struct linux_initrd {
struct efi_load_file_protocol base;
- void *start;
+ const void *start;
size_t size;
efi_handle_t lf2_handle;
} initrd;
@@ -70,7 +70,7 @@ static efi_status_t EFIAPI efi_initrd_load_file2(
return EFI_SUCCESS;
}
-int efi_initrd_register(void *initrd_base, size_t initrd_sz)
+int efi_initrd_register(const void *initrd_base, size_t initrd_sz)
{
struct efi_boot_services *bs;
efi_status_t efiret;
diff --git a/efi/loader/bootm.c b/efi/loader/bootm.c
index fcc17a03905f..8a0519fca3de 100644
--- a/efi/loader/bootm.c
+++ b/efi/loader/bootm.c
@@ -191,7 +191,7 @@ static efi_status_t efi_install_initrd(struct image_data *data,
if (IS_ERR(initrd_res))
return PTR_ERR(initrd_res);
if (initrd_res)
- efi_initrd_register((void *)initrd_res->start,
+ efi_initrd_register((const void *)initrd_res->start,
resource_size(initrd_res));
return EFI_SUCCESS;
diff --git a/include/efi/initrd.h b/include/efi/initrd.h
index 08af2d299ad6..b36875c7fe7c 100644
--- a/include/efi/initrd.h
+++ b/include/efi/initrd.h
@@ -5,7 +5,7 @@
#include <linux/types.h>
-int efi_initrd_register(void *initrd, size_t initrd_size);
+int efi_initrd_register(const void *initrd, size_t initrd_size);
void efi_initrd_unregister(void);
#endif
--
2.47.3
^ permalink raw reply [flat|nested] 19+ messages in thread