mail archive of the barebox mailing list
 help / color / mirror / Atom feed
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




  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