From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH 03/10] bootm: uimage: split support into dedicated file
Date: Mon, 5 Jan 2026 09:03:35 +0100 [thread overview]
Message-ID: <20260105080653.3240497-4-a.fatoum@barebox.org> (raw)
In-Reply-To: <20260105080653.3240497-1-a.fatoum@barebox.org>
Interleaving the uImage 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-uimage.c | 176 +++++++++++++++++++++++++++++++++++++++++
common/bootm.c | 143 +++------------------------------
include/bootm-uimage.h | 57 +++++++++++++
4 files changed, 243 insertions(+), 134 deletions(-)
create mode 100644 common/bootm-uimage.c
create mode 100644 include/bootm-uimage.h
diff --git a/common/Makefile b/common/Makefile
index 45bd00758e4a..751f3ba20293 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_TLV) += tlv/
obj-$(CONFIG_RATP) += ratp/
obj-$(CONFIG_BOOTCHOOSER) += bootchooser.o
obj-$(CONFIG_UIMAGE) += uimage_types.o uimage.o
+obj-$(CONFIG_BOOTM_UIMAGE) += bootm-uimage.o
obj-$(CONFIG_FITIMAGE) += image-fit.o
obj-$(CONFIG_BOOTM_FITIMAGE) += bootm-fit.o
obj-$(CONFIG_MENUTREE) += menutree.o
diff --git a/common/bootm-uimage.c b/common/bootm-uimage.c
new file mode 100644
index 000000000000..609b678e1d4a
--- /dev/null
+++ b/common/bootm-uimage.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <bootm.h>
+#include <bootm-uimage.h>
+#include <linux/kstrtox.h>
+
+static int uimage_part_num(const char *partname)
+{
+ if (!partname)
+ return 0;
+ return simple_strtoul(partname, NULL, 0);
+}
+
+/*
+ * bootm_load_uimage_os() - load uImage OS 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_uimage_os(struct image_data *data, unsigned long load_address)
+{
+ int num;
+
+ num = uimage_part_num(data->os_part);
+
+ data->os_res = uimage_load_to_sdram(data->os,
+ num, load_address);
+ if (!data->os_res)
+ return -ENOMEM;
+
+ return 0;
+}
+
+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)
+ return -EINVAL;
+
+ if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
+ ret = uimage_verify(data->initrd);
+ if (ret) {
+ pr_err("Checking data crc failed with %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+ }
+ uimage_print_contents(data->initrd);
+ } else {
+ data->initrd = data->os;
+ }
+
+ return 0;
+}
+
+/*
+ * bootm_load_uimage_initrd() - load initrd from uimage 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_uimage_initrd(struct image_data *data, unsigned long load_address)
+{
+ struct resource *res;
+ int ret;
+
+ int num;
+ ret = bootm_open_initrd_uimage(data);
+ if (ret) {
+ pr_err("loading initrd failed with %pe\n", ERR_PTR(ret));
+ return ERR_PTR(ret);
+ }
+
+ num = uimage_part_num(data->initrd_part);
+
+ res = uimage_load_to_sdram(data->initrd,
+ num, load_address);
+ if (!res)
+ return ERR_PTR(-ENOMEM);
+
+ return res;
+}
+
+int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
+ struct fdt_header **fdt)
+{
+ enum filetype ft;
+ const char *oftree = data->oftree_file;
+ int num = uimage_part_num(data->oftree_part);
+ struct uimage_handle *of_handle;
+ int release = 0;
+
+ pr_info("Loading devicetree from '%s'@%d\n", oftree, num);
+
+ if (!strcmp(data->os_file, oftree)) {
+ of_handle = data->os;
+ } else if (!strcmp(data->initrd_file, oftree)) {
+ of_handle = data->initrd;
+ } else {
+ of_handle = uimage_open(oftree);
+ if (!of_handle)
+ return -ENODEV;
+ uimage_print_contents(of_handle);
+ release = 1;
+ }
+
+ *fdt = uimage_load_to_buf(of_handle, num, size);
+
+ if (release)
+ uimage_close(of_handle);
+
+ ft = file_detect_type(*fdt, *size);
+ if (ft != filetype_oftree) {
+ pr_err("%s is not an oftree but %s\n",
+ data->oftree_file, file_type_to_string(ft));
+ free(*fdt);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int bootm_open_uimage(struct image_data *data)
+{
+ int ret;
+
+ data->os = uimage_open(data->os_file);
+ if (!data->os)
+ return -EINVAL;
+
+ if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
+ ret = uimage_verify(data->os);
+ if (ret) {
+ pr_err("Checking data crc failed with %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+ }
+
+ uimage_print_contents(data->os);
+
+ if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) {
+ pr_err("Unsupported Architecture 0x%x\n",
+ data->os->header.ih_arch);
+ return -EINVAL;
+ }
+
+ if (data->os_address == UIMAGE_SOME_ADDRESS)
+ data->os_address = data->os->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);
+}
diff --git a/common/bootm.c b/common/bootm.c
index dced46f3e067..f1beac52ec15 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -13,6 +13,7 @@
#include <libfile.h>
#include <bootm-fit.h>
#include <image-fit.h>
+#include <bootm-uimage.h>
#include <globalvar.h>
#include <init.h>
#include <environment.h>
@@ -250,18 +251,8 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
if (data->os_fit)
return bootm_load_fit_os(data, load_address);
- if (image_is_uimage(data)) {
- int num;
-
- num = uimage_part_num(data->os_part);
-
- data->os_res = uimage_load_to_sdram(data->os,
- num, load_address);
- if (!data->os_res)
- return -ENOMEM;
-
- return 0;
- }
+ if (image_is_uimage(data))
+ return bootm_load_uimage_os(data, load_address);
if (!data->os_file)
return -EINVAL;
@@ -273,34 +264,6 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
return 0;
}
-static int bootm_open_initrd_uimage(struct image_data *data)
-{
- int ret;
-
- if (!IS_ENABLED(CONFIG_BOOTM_UIMAGE))
- return -ENOSYS;
-
- if (strcmp(data->os_file, data->initrd_file)) {
- data->initrd = uimage_open(data->initrd_file);
- if (!data->initrd)
- return -EINVAL;
-
- if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
- ret = uimage_verify(data->initrd);
- if (ret) {
- pr_err("Checking data crc failed with %pe\n",
- ERR_PTR(ret));
- return ret;
- }
- }
- uimage_print_contents(data->initrd);
- } else {
- data->initrd = data->os;
- }
-
- return 0;
-}
-
/*
* bootm_load_initrd() - load initrd to RAM
*
@@ -351,18 +314,9 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
}
if (type == filetype_uimage) {
- int num;
- ret = bootm_open_initrd_uimage(data);
- if (ret) {
- pr_err("loading initrd failed with %pe\n", ERR_PTR(ret));
- return ERR_PTR(ret);
- }
-
- num = uimage_part_num(data->initrd_part);
-
- res = uimage_load_to_sdram(data->initrd, num, load_address);
- if (!res)
- return ERR_PTR(-ENOMEM);
+ res = bootm_load_uimage_initrd(data, load_address);
+ if (IS_ERR(res))
+ return res;
goto done;
}
@@ -386,48 +340,6 @@ bootm_load_initrd(struct image_data *data, unsigned long load_address)
return data->initrd_res;
}
-static int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
- struct fdt_header **fdt)
-{
- enum filetype ft;
- const char *oftree = data->oftree_file;
- int num = uimage_part_num(data->oftree_part);
- struct uimage_handle *of_handle;
- int release = 0;
-
- pr_info("Loading devicetree from '%s'@%d\n", oftree, num);
-
- if (!IS_ENABLED(CONFIG_BOOTM_OFTREE_UIMAGE))
- return -EINVAL;
-
- if (!strcmp(data->os_file, oftree)) {
- of_handle = data->os;
- } else if (!strcmp(data->initrd_file, oftree)) {
- of_handle = data->initrd;
- } else {
- of_handle = uimage_open(oftree);
- if (!of_handle)
- return -ENODEV;
- uimage_print_contents(of_handle);
- release = 1;
- }
-
- *fdt = uimage_load_to_buf(of_handle, num, size);
-
- if (release)
- uimage_close(of_handle);
-
- ft = file_detect_type(*fdt, *size);
- if (ft != filetype_oftree) {
- pr_err("%s is not an oftree but %s\n",
- data->oftree_file, file_type_to_string(ft));
- free(*fdt);
- return -EINVAL;
- }
-
- return 0;
-}
-
/*
* bootm_get_devicetree() - get devicetree
*
@@ -585,40 +497,6 @@ int bootm_get_os_size(struct image_data *data)
return s.st_size;
}
-static int bootm_open_os_uimage(struct image_data *data)
-{
- int ret;
-
- if (!IS_ENABLED(CONFIG_BOOTM_UIMAGE))
- return -ENOSYS;
-
- data->os = uimage_open(data->os_file);
- if (!data->os)
- return -EINVAL;
-
- if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
- ret = uimage_verify(data->os);
- if (ret) {
- pr_err("Checking data crc failed with %pe\n",
- ERR_PTR(ret));
- return ret;
- }
- }
-
- uimage_print_contents(data->os);
-
- if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) {
- pr_err("Unsupported Architecture 0x%x\n",
- data->os->header.ih_arch);
- return -EINVAL;
- }
-
- if (data->os_address == UIMAGE_SOME_ADDRESS)
- data->os_address = data->os->header.ih_load;
-
- return 0;
-}
-
static void bootm_print_info(struct image_data *data)
{
if (data->os_res)
@@ -727,7 +605,7 @@ int bootm_boot(struct bootm_data *bootm_data)
os_type_str = "FIT";
break;
case filetype_uimage:
- ret = bootm_open_os_uimage(data);
+ ret = bootm_open_uimage(data);
break;
default:
ret = 0;
@@ -897,11 +775,8 @@ int bootm_boot(struct bootm_data *bootm_data)
release_sdram_region(data->oftree_res);
if (data->tee_res)
release_sdram_region(data->tee_res);
- if (image_is_uimage(data)) {
- if (data->initrd && data->initrd != data->os)
- uimage_close(data->initrd);
- uimage_close(data->os);
- }
+ if (image_is_uimage(data))
+ bootm_close_uimage(data);
if (data->os_fit)
bootm_close_fit(data);
if (data->of_root_node)
diff --git a/include/bootm-uimage.h b/include/bootm-uimage.h
new file mode 100644
index 000000000000..aac2beb35e2a
--- /dev/null
+++ b/include/bootm-uimage.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __BOOTM_UIMAGE_H
+#define __BOOTM_UIMAGE_H
+
+#include <linux/types.h>
+#include <linux/err.h>
+
+struct image_data;
+struct fdt_header;
+struct resource;
+
+#ifdef CONFIG_BOOTM_UIMAGE
+
+int bootm_load_uimage_os(struct image_data *data, unsigned long load_address);
+
+struct resource *bootm_load_uimage_initrd(struct image_data *data,
+ unsigned long load_address);
+
+int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
+ struct fdt_header **fdt);
+int bootm_open_uimage(struct image_data *data);
+
+void bootm_close_uimage(struct image_data *data);
+
+#else
+
+static inline int bootm_load_uimage_os(struct image_data *data,
+ unsigned long load_address)
+{
+ return -ENOSYS;
+}
+
+static inline struct resource *
+bootm_load_uimage_initrd(struct image_data *data, unsigned long load_address)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline int bootm_open_oftree_uimage(struct image_data *data,
+ size_t *size,
+ struct fdt_header **fdt)
+{
+ return -ENOSYS;
+}
+
+static inline int bootm_open_uimage(struct image_data *data)
+{
+ return -ENOSYS;
+}
+
+static inline void bootm_close_uimage(struct image_data *data)
+{
+}
+
+#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 ` [PATCH 02/10] bootm: fit: split support into dedicated file Ahmad Fatoum
2026-01-05 8:03 ` Ahmad Fatoum [this message]
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-4-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