From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH 02/10] bootm: fit: split support into dedicated file
Date: Mon, 5 Jan 2026 09:03:34 +0100 [thread overview]
Message-ID: <20260105080653.3240497-3-a.fatoum@barebox.org> (raw)
In-Reply-To: <20260105080653.3240497-1-a.fatoum@barebox.org>
Interleaving the FIT handling with the generic bootm code makes the
generic code harder to follow. Let's factor it out into a dedicated
file.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
common/Makefile | 1 +
common/bootm-fit.c | 185 ++++++++++++++++++++++++++++++++++++++++++++
common/bootm.c | 156 ++++---------------------------------
include/bootm-fit.h | 70 +++++++++++++++++
4 files changed, 271 insertions(+), 141 deletions(-)
create mode 100644 common/bootm-fit.c
create mode 100644 include/bootm-fit.h
diff --git a/common/Makefile b/common/Makefile
index 36dee5f7a98a..45bd00758e4a 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_RATP) += ratp/
obj-$(CONFIG_BOOTCHOOSER) += bootchooser.o
obj-$(CONFIG_UIMAGE) += uimage_types.o uimage.o
obj-$(CONFIG_FITIMAGE) += image-fit.o
+obj-$(CONFIG_BOOTM_FITIMAGE) += bootm-fit.o
obj-$(CONFIG_MENUTREE) += menutree.o
lwl-$(CONFIG_IMD) += imd-barebox.o
obj-$(CONFIG_IMD) += imd.o
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
new file mode 100644
index 000000000000..f9c8bff43912
--- /dev/null
+++ b/common/bootm-fit.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <bootm.h>
+#include <image-fit.h>
+#include <bootm-fit.h>
+#include <memory.h>
+#include <zero_page.h>
+
+/*
+ * bootm_load_fit_os() - load OS from FIT to RAM
+ *
+ * @data: image data context
+ * @load_address: The address where the OS should be loaded to
+ *
+ * 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
+ * an error.
+ *
+ * Return: 0 on success, negative error code otherwise
+ */
+int bootm_load_fit_os(struct image_data *data, unsigned long load_address)
+{
+ const void *kernel = data->fit_kernel;
+ unsigned long kernel_size = data->fit_kernel_size;
+
+ data->os_res = request_sdram_region("kernel",
+ load_address, kernel_size,
+ MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
+ if (!data->os_res) {
+ pr_err("unable to request SDRAM region for kernel at"
+ " 0x%08llx-0x%08llx\n",
+ (unsigned long long)load_address,
+ (unsigned long long)load_address + kernel_size - 1);
+ return -ENOMEM;
+ }
+ zero_page_memcpy((void *)load_address, kernel, kernel_size);
+ return 0;
+}
+
+static bool fitconfig_has_ramdisk(struct image_data *data)
+{
+ return fit_has_image(data->os_fit, data->fit_config, "ramdisk");
+}
+
+/*
+ * bootm_load_fit_initrd() - load initrd from FIT to RAM
+ *
+ * @data: image data context
+ * @load_address: The address where the initrd should be loaded to
+ *
+ * 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.
+ *
+ * Return: initrd resource on success, NULL if no initrd is present or
+ * an error pointer if an error occurred.
+ */
+struct resource *bootm_load_fit_initrd(struct image_data *data, unsigned long load_address)
+{
+ struct resource *res;
+ const void *initrd;
+ unsigned long initrd_size;
+ int ret;
+
+ if (!fitconfig_has_ramdisk(data))
+ return NULL;
+
+ ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
+ &initrd, &initrd_size);
+ if (ret) {
+ pr_err("Cannot open ramdisk image in FIT image: %pe\n",
+ ERR_PTR(ret));
+ return ERR_PTR(ret);
+ }
+ res = request_sdram_region("initrd",
+ load_address, initrd_size,
+ MEMTYPE_LOADER_DATA, MEMATTRS_RW);
+ if (!res) {
+ pr_err("unable to request SDRAM region for initrd at"
+ " 0x%08llx-0x%08llx\n",
+ (unsigned long long)load_address,
+ (unsigned long long)load_address + initrd_size - 1);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ memcpy((void *)load_address, initrd, initrd_size);
+ return res;
+}
+
+/*
+ * bootm_get_fit_devicetree() - get devicetree
+ *
+ * @data: image data context
+ *
+ * This gets the fixed devicetree from the various image sources or the internal
+ * devicetree. It returns a pointer to the allocated devicetree which must be
+ * freed after use.
+ *
+ * Return: pointer to the fixed devicetree, NULL if image_data has an empty DT
+ * or a ERR_PTR() on failure.
+ */
+void *bootm_get_fit_devicetree(struct image_data *data)
+{
+ int ret;
+ const void *of_tree;
+ unsigned long of_size;
+
+ ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
+ &of_tree, &of_size);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return of_unflatten_dtb(of_tree, of_size);
+}
+
+static bool bootm_fit_config_valid(struct fit_handle *fit,
+ struct device_node *config)
+{
+ /*
+ * Consider only FIT configurations which do provide a loadable kernel
+ * image.
+ */
+ return !!fit_has_image(fit, config, "kernel");
+}
+
+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));
+ if (IS_ERR(fit)) {
+ pr_err("Loading FIT image %s failed with: %pe\n", data->os_file, fit);
+ return PTR_ERR(fit);
+ }
+
+ data->os_fit = fit;
+
+ data->fit_config = fit_open_configuration(data->os_fit,
+ data->os_part,
+ bootm_fit_config_valid);
+ if (IS_ERR(data->fit_config)) {
+ pr_err("Cannot open FIT image configuration '%s'\n",
+ data->os_part ? data->os_part : "default");
+ return PTR_ERR(data->fit_config);
+ }
+
+ ret = fit_open_image(data->os_fit, data->fit_config, kernel_img,
+ &data->fit_kernel, &data->fit_kernel_size);
+ if (ret)
+ return ret;
+ if (data->os_address == UIMAGE_SOME_ADDRESS) {
+ ret = fit_get_image_address(data->os_fit,
+ data->fit_config,
+ kernel_img,
+ "load", &data->os_address);
+ if (!ret)
+ pr_info("Load address from FIT '%s': 0x%lx\n",
+ kernel_img, data->os_address);
+ /* Note: Error case uses default value. */
+ }
+ if (data->os_entry == UIMAGE_SOME_ADDRESS) {
+ unsigned long entry;
+ ret = fit_get_image_address(data->os_fit,
+ data->fit_config,
+ kernel_img,
+ "entry", &entry);
+ if (!ret) {
+ data->os_entry = entry - data->os_address;
+ pr_info("Entry address from FIT '%s': 0x%lx\n",
+ kernel_img, entry);
+ }
+ /* Note: Error case uses default value. */
+ }
+
+ return 0;
+}
diff --git a/common/bootm.c b/common/bootm.c
index e60c81a9021e..dced46f3e067 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -11,6 +11,7 @@
#include <memory.h>
#include <block.h>
#include <libfile.h>
+#include <bootm-fit.h>
#include <image-fit.h>
#include <globalvar.h>
#include <init.h>
@@ -246,23 +247,8 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
if (load_address == UIMAGE_INVALID_ADDRESS)
return -EINVAL;
- if (data->os_fit) {
- const void *kernel = data->fit_kernel;
- unsigned long kernel_size = data->fit_kernel_size;
-
- data->os_res = request_sdram_region("kernel",
- load_address, kernel_size,
- MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
- if (!data->os_res) {
- pr_err("unable to request SDRAM region for kernel at"
- " 0x%08llx-0x%08llx\n",
- (unsigned long long)load_address,
- (unsigned long long)load_address + kernel_size - 1);
- return -ENOMEM;
- }
- zero_page_memcpy((void *)load_address, kernel, kernel_size);
- return 0;
- }
+ if (data->os_fit)
+ return bootm_load_fit_os(data, load_address);
if (image_is_uimage(data)) {
int num;
@@ -287,14 +273,6 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
return 0;
}
-static bool fitconfig_has_ramdisk(struct image_data *data)
-{
- if (!IS_ENABLED(CONFIG_FITIMAGE) || !data->os_fit)
- return false;
-
- return fit_has_image(data->os_fit, data->fit_config, "ramdisk");
-}
-
static int bootm_open_initrd_uimage(struct image_data *data)
{
int ret;
@@ -352,28 +330,13 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
if (data->initrd_res)
return data->initrd_res;
- if (fitconfig_has_ramdisk(data)) {
- const void *initrd;
- unsigned long initrd_size;
+ if (data->os_fit) {
+ res = bootm_load_fit_initrd(data, load_address);
+ if (IS_ERR(res))
+ return res;
+ if (res)
+ pr_info("Loaded initrd from FIT image\n");
- ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
- &initrd, &initrd_size);
- if (ret) {
- pr_err("Cannot open ramdisk image in FIT image: %pe\n",
- ERR_PTR(ret));
- return ERR_PTR(ret);
- }
- res = request_sdram_region("initrd", load_address, initrd_size,
- MEMTYPE_LOADER_DATA, MEMATTRS_RW);
- if (!res) {
- pr_err("unable to request SDRAM region for initrd at"
- " 0x%08llx-0x%08llx\n",
- (unsigned long long)load_address,
- (unsigned long long)load_address + initrd_size - 1);
- return ERR_PTR(-ENOMEM);
- }
- memcpy((void *)load_address, initrd, initrd_size);
- pr_info("Loaded initrd from FIT image\n");
goto done1;
}
@@ -416,7 +379,8 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
pr_info(", multifile image %s", data->initrd_part);
pr_info("\n");
done1:
- pr_info("initrd is at %pa-%pa\n", &res->start, &res->end);
+ if (res)
+ pr_info("initrd is at %pa-%pa\n", &res->start, &res->end);
data->initrd_res = res;
return data->initrd_res;
@@ -464,14 +428,6 @@ static int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
return 0;
}
-static bool fitconfig_has_fdt(struct image_data *data)
-{
- if (!IS_ENABLED(CONFIG_FITIMAGE) || !data->os_fit)
- return false;
-
- return fit_has_image(data->os_fit, data->fit_config, "fdt");
-}
-
/*
* bootm_get_devicetree() - get devicetree
*
@@ -494,20 +450,12 @@ void *bootm_get_devicetree(struct image_data *data)
if (!IS_ENABLED(CONFIG_OFTREE))
return ERR_PTR(-ENOSYS);
- from_fit = fitconfig_has_fdt(data);
+ from_fit = bootm_fit_has_fdt(data);
if (bootm_get_override(&data->oftree_file, bootm_overrides.oftree_file))
from_fit = false;
if (from_fit) {
- const void *of_tree;
- unsigned long of_size;
-
- ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
- &of_tree, &of_size);
- if (ret)
- return ERR_PTR(ret);
-
- data->of_root_node = of_unflatten_dtb(of_tree, of_size);
+ data->of_root_node = bootm_get_fit_devicetree(data);
} else if (data->oftree_file) {
size_t size;
@@ -671,80 +619,6 @@ static int bootm_open_os_uimage(struct image_data *data)
return 0;
}
-static bool bootm_fit_config_valid(struct fit_handle *fit,
- struct device_node *config)
-{
- /*
- * Consider only FIT configurations which do provide a loadable kernel
- * image.
- */
- return !!fit_has_image(fit, config, "kernel");
-}
-
-static 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;
-
- if (!IS_ENABLED(CONFIG_FITIMAGE))
- return -ENOSYS;
-
- 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));
- if (IS_ERR(fit)) {
- pr_err("Loading FIT image %s failed with: %pe\n", data->os_file, fit);
- return PTR_ERR(fit);
- }
-
- data->os_fit = fit;
-
- data->fit_config = fit_open_configuration(data->os_fit,
- data->os_part,
- bootm_fit_config_valid);
- if (IS_ERR(data->fit_config)) {
- pr_err("Cannot open FIT image configuration '%s'\n",
- data->os_part ? data->os_part : "default");
- return PTR_ERR(data->fit_config);
- }
-
- ret = fit_open_image(data->os_fit, data->fit_config, kernel_img,
- &data->fit_kernel, &data->fit_kernel_size);
- if (ret)
- return ret;
- if (data->os_address == UIMAGE_SOME_ADDRESS) {
- ret = fit_get_image_address(data->os_fit,
- data->fit_config,
- kernel_img,
- "load", &data->os_address);
- if (!ret)
- pr_info("Load address from FIT '%s': 0x%lx\n",
- kernel_img, data->os_address);
- /* Note: Error case uses default value. */
- }
- if (data->os_entry == UIMAGE_SOME_ADDRESS) {
- unsigned long entry;
- ret = fit_get_image_address(data->os_fit,
- data->fit_config,
- kernel_img,
- "entry", &entry);
- if (!ret) {
- data->os_entry = entry - data->os_address;
- pr_info("Entry address from FIT '%s': 0x%lx\n",
- kernel_img, entry);
- }
- /* Note: Error case uses default value. */
- }
-
- return 0;
-}
-
static void bootm_print_info(struct image_data *data)
{
if (data->os_res)
@@ -1028,8 +902,8 @@ int bootm_boot(struct bootm_data *bootm_data)
uimage_close(data->initrd);
uimage_close(data->os);
}
- if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit)
- fit_close(data->os_fit);
+ if (data->os_fit)
+ bootm_close_fit(data);
if (data->of_root_node)
of_delete_node(data->of_root_node);
diff --git a/include/bootm-fit.h b/include/bootm-fit.h
new file mode 100644
index 000000000000..8deddd62e328
--- /dev/null
+++ b/include/bootm-fit.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __BOOTM_FIT_H
+#define __BOOTM_FIT_H
+
+#include <linux/types.h>
+#include <image-fit.h>
+#include <bootm.h>
+
+struct resource;
+
+#ifdef CONFIG_BOOTM_FITIMAGE
+
+int bootm_load_fit_os(struct image_data *data, unsigned long load_address);
+
+struct resource *bootm_load_fit_initrd(struct image_data *data,
+ unsigned long load_address);
+
+void *bootm_get_fit_devicetree(struct image_data *data);
+
+int bootm_open_fit(struct image_data *data);
+
+static inline void bootm_close_fit(struct image_data *data)
+{
+ fit_close(data->os_fit);
+}
+
+static inline bool bootm_fit_has_fdt(struct image_data *data)
+{
+ if (!data->os_fit)
+ return false;
+
+ return fit_has_image(data->os_fit, data->fit_config, "fdt");
+}
+
+#else
+
+static inline int bootm_load_fit_os(struct image_data *data,
+ unsigned long load_address)
+{
+ return -ENOSYS;
+}
+
+static inline struct resource *bootm_load_fit_initrd(struct image_data *data,
+ unsigned long load_address)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void *bootm_get_fit_devicetree(struct image_data *data)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline int bootm_open_fit(struct image_data *data)
+{
+ return -ENOSYS;
+}
+
+static inline void bootm_close_fit(struct image_data *data)
+{
+}
+
+static inline bool bootm_fit_has_fdt(struct image_data *data)
+{
+ return false;
+}
+
+#endif
+
+#endif
--
2.47.3
next prev parent reply other threads:[~2026-01-05 8:07 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-05 8:03 [PATCH 00/10] bootm: refactor to prepare multiple initrd support Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 01/10] bootm: set image_data::initrd_res at a single place Ahmad Fatoum
2026-01-05 8:03 ` Ahmad Fatoum [this message]
2026-01-05 8:03 ` [PATCH 03/10] bootm: uimage: split support into dedicated file Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 04/10] filetype: introduce filetype_fit Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 05/10] bootm: refactor for readability and extensibility Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 06/10] memory: move release_sdram_region into header Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 07/10] resource: make NULL in release_[sdram_]region a no-op Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 08/10] common: elf: use release_region unconditionally Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 09/10] memory: always print errors on request_sdram_region failure Ahmad Fatoum
2026-01-05 8:03 ` [PATCH 10/10] memory: drop now duplicate request_sdram_region error messages Ahmad Fatoum
2026-01-09 8:20 ` [PATCH 00/10] bootm: refactor to prepare multiple initrd support Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260105080653.3240497-3-a.fatoum@barebox.org \
--to=a.fatoum@barebox.org \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox