mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/2] bootm: move ELF handling to bootm handlers
@ 2025-04-07 13:07 Sascha Hauer
  2025-04-07 13:07 ` [PATCH 2/2] bootm: create generic FIT image handler Sascha Hauer
  0 siblings, 1 reply; 2+ messages in thread
From: Sascha Hauer @ 2025-04-07 13:07 UTC (permalink / raw)
  To: Barebox List

The generic bootm code is for picking the correct OS, device tree and
initrd files. Additionally it parses the container formats like FIT and
uImage. It has no business to handle particular image formats, so push
the ELF handling back to the image handlers themselves. The resulting
diffstat is negative, so having the ELF code inside bootm doesn't really
serve a purpose. Move it out there.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/Kconfig         |  8 ++++++++
 arch/arm/cpu/Makefile    |  2 +-
 arch/arm/cpu/bootm-elf.c | 28 ++++++++++++++++++++--------
 arch/kvx/Kconfig         |  1 -
 arch/kvx/lib/bootm.c     | 22 +++++++++++++---------
 arch/mips/lib/bootm.c    | 18 +++++++++++++-----
 common/Kconfig           |  8 --------
 common/bootm.c           | 29 -----------------------------
 include/bootm.h          |  3 ---
 9 files changed, 55 insertions(+), 64 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7d46dcfb63..ab7ff5369b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -465,6 +465,14 @@ config ARM_MODULE_PLTS
 	  Say y if your memory configuration puts the heap to far away from the
 	  barebox image, causing relocation out of range errors
 
+config ARM_BOOTM_ELF
+	bool
+	depends on BOOTM
+	select ELF
+	prompt "elf loading support"
+	help
+	  Add support to load elf file with bootm.
+
 config ARM_ATF
 	bool
 
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 1769249645..d59aae1ee5 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -31,7 +31,7 @@ obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap_$(S64_32).o
 obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o
 obj-$(CONFIG_MMUINFO) += mmuinfo.o mmuinfo_$(S64_32).o
 obj-$(CONFIG_OFDEVICE) += dtb.o
-obj-$(CONFIG_BOOTM_ELF)	+= bootm-elf.o
+obj-$(CONFIG_ARM_BOOTM_ELF)	+= bootm-elf.o
 
 ifeq ($(CONFIG_MMU),)
 obj-$(CONFIG_CPU_32v7) += no-mmu.o
diff --git a/arch/arm/cpu/bootm-elf.c b/arch/arm/cpu/bootm-elf.c
index bcca3931f2..d3132b6f5a 100644
--- a/arch/arm/cpu/bootm-elf.c
+++ b/arch/arm/cpu/bootm-elf.c
@@ -12,26 +12,33 @@ static int do_bootm_elf(struct image_data *data)
 {
 	void (*fn)(unsigned long x0, unsigned long x1, unsigned long x2,
 		   unsigned long x3);
-	struct elf_image *elf = data->elf;
+	struct elf_image *elf;
 	int ret;
 
+	elf = elf_open(data->os_file);
+	if (IS_ERR(elf))
+		return PTR_ERR(elf);
+
 	if (elf_hdr_e_machine(elf, elf->hdr_buf) != ELF_ARCH) {
 		pr_err("Unsupported machine: 0x%02x, but 0x%02x expected\n",
 		       elf_hdr_e_machine(elf, elf->hdr_buf), ELF_ARCH);
 
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err;
 	}
 
-	ret = bootm_load_os(data, data->os_address);
+	ret = elf_load(elf);
 	if (ret)
-		return ret;
+		goto err;
 
-	if (data->dryrun)
-		return ret;
+	if (data->dryrun) {
+		ret = 0;
+		goto err;
+	}
 
 	ret = of_overlay_load_firmware();
 	if (ret)
-		return ret;
+		goto err;
 
 	shutdown_barebox();
 
@@ -40,7 +47,12 @@ static int do_bootm_elf(struct image_data *data)
 	fn(0, 0, 0, 0);
 
 	pr_err("ELF application terminated\n");
-	return -EINVAL;
+	ret = -EINVAL;
+
+err:
+	elf_close(elf);
+
+	return ret;
 }
 
 static struct image_handler elf_handler = {
diff --git a/arch/kvx/Kconfig b/arch/kvx/Kconfig
index 9b733cd792..bb662e4fd8 100644
--- a/arch/kvx/Kconfig
+++ b/arch/kvx/Kconfig
@@ -4,7 +4,6 @@ config KVX
 	bool
 	select 64BIT
 	select BOOTM
-	select BOOTM_ELF
 	select BOOTM_OFTREE
 	select BOOTM_INITRD
 	select COMMON_CLK
diff --git a/arch/kvx/lib/bootm.c b/arch/kvx/lib/bootm.c
index 42c15ff273..3cb2521842 100644
--- a/arch/kvx/lib/bootm.c
+++ b/arch/kvx/lib/bootm.c
@@ -60,6 +60,10 @@ static int do_boot_elf(struct image_data *data, struct elf_image *elf)
 	boot_func_entry entry;
 	unsigned long load_addr, initrd_address;
 
+	ret = elf_load(elf);
+	if (ret)
+		return ret;
+
 	/* load initrd after the elf */
 	load_addr = PAGE_ALIGN((unsigned long) elf->high_addr);
 	if (data->initrd_address != UIMAGE_INVALID_ADDRESS)
@@ -112,13 +116,8 @@ static int do_bootm_fit(struct image_data *data)
 	if (IS_ERR(elf))
 		return PTR_ERR(data->elf);
 
-	ret = elf_load(elf);
-	if (ret)
-		goto close_elf;
-
 	ret = do_boot_elf(data, elf);
 
-close_elf:
 	elf_close(elf);
 
 	return ret;
@@ -126,13 +125,18 @@ static int do_bootm_fit(struct image_data *data)
 
 static int do_bootm_elf(struct image_data *data)
 {
+	struct elf_image *elf;
 	int ret;
 
-	ret = bootm_load_os(data, data->os_address);
-	if (ret)
-		return ret;
+	elf = elf_open(data->os_file);
+	if (IS_ERR(elf))
+		return PTR_ERR(elf);
+
+	ret = do_boot_elf(data, elf);
+
+	elf_close(elf);
 
-	return do_boot_elf(data, data->elf);
+	return ret;
 }
 
 static struct image_handler elf_handler = {
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index 86573dec7f..a623b1c83b 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -58,20 +58,26 @@ static int do_bootm_elf(struct image_data *data)
 {
 	void (*entry)(int, void *);
 	void *fdt;
+	struct elf_image *elf;
 	int ret = 0;
 
-	ret = bootm_load_os(data, data->os_address);
+	elf = elf_open(data->os_file);
+	if (IS_ERR(elf))
+		return PTR_ERR(elf);
+
+	ret = elf_load(elf);
 	if (ret)
-		return ret;
+		goto err;
 
 	fdt = bootm_get_devicetree(data);
 	if (IS_ERR(fdt)) {
 		pr_err("Failed to load dtb\n");
-		return PTR_ERR(fdt);
+		ret = PTR_ERR(fdt);
+		goto bootm_free_fdt;
 	}
 
 	pr_info("Starting application at 0x%08lx, dts 0x%p...\n",
-		data->os_address, data->of_root_node);
+		elf->entry, data->of_root_node);
 
 	if (data->dryrun)
 		goto bootm_free_fdt;
@@ -82,7 +88,7 @@ static int do_bootm_elf(struct image_data *data)
 
 	shutdown_barebox();
 
-	entry = (void *) (unsigned long) data->os_address;
+	entry = (void *) (unsigned long) elf->entry;
 
 	entry(-2, fdt);
 
@@ -91,6 +97,8 @@ static int do_bootm_elf(struct image_data *data)
 
 bootm_free_fdt:
 	free(fdt);
+err:
+	elf_close(elf);
 
 	return ret;
 }
diff --git a/common/Kconfig b/common/Kconfig
index ddc76b2033..93ab618898 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -668,14 +668,6 @@ config PE
 config ELF
 	bool "ELF Support" if COMPILE_TEST
 
-config BOOTM_ELF
-	bool
-	depends on BOOTM
-	select ELF
-	prompt "elf loading support"
-	help
-	  Add support to load elf file with bootm.
-
 config BOOTM_FITIMAGE
 	bool
 	prompt "FIT image support"
diff --git a/common/bootm.c b/common/bootm.c
index a5065c3860..69816cdf5b 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -211,9 +211,6 @@ int bootm_load_os(struct image_data *data, unsigned long load_address)
 		return 0;
 	}
 
-	if (IS_ENABLED(CONFIG_ELF) && data->elf)
-		return elf_load(data->elf);
-
 	if (!data->os_file)
 		return -EINVAL;
 
@@ -562,8 +559,6 @@ int bootm_get_os_size(struct image_data *data)
 	struct stat s;
 	int ret;
 
-	if (data->elf)
-		return elf_get_mem_size(data->elf);
 	if (image_is_uimage(data))
 		return uimage_get_size(data->os, uimage_part_num(data->os_part));
 	if (data->os_fit)
@@ -676,25 +671,6 @@ static int bootm_open_fit(struct image_data *data)
 	return 0;
 }
 
-static int bootm_open_elf(struct image_data *data)
-{
-	struct elf_image *elf;
-
-	if (!IS_ENABLED(CONFIG_ELF))
-		return -ENOSYS;
-
-	elf = elf_open(data->os_file);
-	if (IS_ERR(elf))
-		return PTR_ERR(elf);
-
-	pr_info("Entry Point:  %08llx\n", elf->entry);
-
-	data->os_address = elf->entry;
-	data->elf = elf;
-
-	return 0;
-}
-
 static void bootm_print_info(struct image_data *data)
 {
 	if (data->os_res)
@@ -800,9 +776,6 @@ int bootm_boot(struct bootm_data *bootm_data)
 	case filetype_uimage:
 		ret = bootm_open_os_uimage(data);
 		break;
-	case filetype_elf:
-		ret = bootm_open_elf(data);
-		break;
 	default:
 		ret = 0;
 		break;
@@ -965,8 +938,6 @@ int bootm_boot(struct bootm_data *bootm_data)
 			uimage_close(data->initrd);
 		uimage_close(data->os);
 	}
-	if (IS_ENABLED(CONFIG_ELF) && data->elf)
-		elf_close(data->elf);
 	if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit)
 		fit_close(data->os_fit);
 	if (data->of_root_node)
diff --git a/include/bootm.h b/include/bootm.h
index b86d06b0f5..bc6c69e813 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -53,9 +53,6 @@ struct image_data {
 	/* if os is an uImage this will be provided */
 	struct uimage_handle *os;
 
-	/* if os is an elf file this will be provided */
-	struct elf_image *elf;
-
 	/* if os is a FIT image this will be provided */
 	struct fit_handle *os_fit;
 
-- 
2.39.5




^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2/2] bootm: create generic FIT image handler
  2025-04-07 13:07 [PATCH 1/2] bootm: move ELF handling to bootm handlers Sascha Hauer
@ 2025-04-07 13:07 ` Sascha Hauer
  0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2025-04-07 13:07 UTC (permalink / raw)
  To: Barebox List

So far every architecture registers its own image handler for handling
FIT images. FIT is a container format and as such we can create a
generic handler for it. To find the correct handler for the kernel we
then have to detect the OS file type from the kernel within the fit
image instead of the original image.

For the generic FIT handler repurpose the sandbox FIT image handler. The
code therein was bogus anyway as it tried to open the FIT image which
will already be opened by the generic code. Remove that stuff and just
print an error message.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/lib32/bootm.c    |  6 ------
 arch/arm/lib64/armlinux.c |  9 ---------
 arch/kvx/lib/bootm.c      | 28 +++++-----------------------
 arch/riscv/lib/bootm.c    |  9 ---------
 common/bootm.c            | 12 +++++-------
 common/image-fit.c        | 33 +++++++--------------------------
 6 files changed, 17 insertions(+), 80 deletions(-)

diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c
index 5be98b920b..485041a7eb 100644
--- a/arch/arm/lib32/bootm.c
+++ b/arch/arm/lib32/bootm.c
@@ -729,12 +729,6 @@ BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs
 BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage");
 #endif
 
-static struct image_handler arm_fit_handler = {
-        .name = "FIT image",
-        .bootm = do_bootm_linux,
-        .filetype = filetype_oftree,
-};
-
 static struct binfmt_hook binfmt_aimage_hook = {
 	.type = filetype_aimage,
 	.exec = "bootm",
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index 3b108b21cb..5feee9c24f 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -44,12 +44,6 @@ static struct image_handler aarch64_linux_efi_handler = {
         .filetype = filetype_arm64_efi_linux_image,
 };
 
-static struct image_handler aarch64_fit_handler = {
-	.name = "FIT image",
-	.bootm = do_bootm_linux,
-	.filetype = filetype_oftree,
-};
-
 static int do_bootm_barebox(struct image_data *data)
 {
 	void (*fn)(unsigned long x0, unsigned long x1, unsigned long x2,
@@ -97,9 +91,6 @@ static int aarch64_register_image_handler(void)
 	register_image_handler(&aarch64_linux_handler);
 	register_image_handler(&aarch64_barebox_handler);
 
-	if (IS_ENABLED(CONFIG_FITIMAGE))
-		register_image_handler(&aarch64_fit_handler);
-
 	return 0;
 }
 late_initcall(aarch64_register_image_handler);
diff --git a/arch/kvx/lib/bootm.c b/arch/kvx/lib/bootm.c
index 3cb2521842..968fc624dc 100644
--- a/arch/kvx/lib/bootm.c
+++ b/arch/kvx/lib/bootm.c
@@ -107,28 +107,16 @@ static int do_boot_elf(struct image_data *data, struct elf_image *elf)
 	return ret;
 }
 
-static int do_bootm_fit(struct image_data *data)
-{
-	int ret;
-	struct elf_image *elf;
-
-	elf = elf_open_binary((void *) data->fit_kernel);
-	if (IS_ERR(elf))
-		return PTR_ERR(data->elf);
-
-	ret = do_boot_elf(data, elf);
-
-	elf_close(elf);
-
-	return ret;
-}
-
 static int do_bootm_elf(struct image_data *data)
 {
 	struct elf_image *elf;
 	int ret;
 
-	elf = elf_open(data->os_file);
+	if (data->fit_kernel)
+		elf = elf_open_binary((void *) data->fit_kernel);
+	else
+		elf = elf_open(data->os_file);
+
 	if (IS_ERR(elf))
 		return PTR_ERR(elf);
 
@@ -145,12 +133,6 @@ static struct image_handler elf_handler = {
 	.filetype = filetype_elf,
 };
 
-static struct image_handler fit_handler = {
-	.name = "FIT",
-	.bootm = do_bootm_fit,
-	.filetype = filetype_oftree,
-};
-
 static struct binfmt_hook binfmt_elf_hook = {
 	.type = filetype_elf,
 	.exec = "bootm",
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index a6655b8aaf..23ce3873b1 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -42,12 +42,6 @@ static struct image_handler riscv_linux_efi_handler = {
         .filetype = filetype_riscv_efi_linux_image,
 };
 
-static struct image_handler riscv_fit_handler = {
-	.name = "FIT image",
-	.bootm = do_bootm_linux,
-	.filetype = filetype_oftree,
-};
-
 static struct image_handler riscv_barebox_handler = {
         .name = "RISC-V barebox image",
         .bootm = do_bootm_linux,
@@ -60,9 +54,6 @@ static int riscv_register_image_handler(void)
 	register_image_handler(&riscv_linux_efi_handler);
 	register_image_handler(&riscv_barebox_handler);
 
-	if (IS_ENABLED(CONFIG_FITIMAGE))
-		register_image_handler(&riscv_fit_handler);
-
 	return 0;
 }
 late_initcall(riscv_register_image_handler);
diff --git a/common/bootm.c b/common/bootm.c
index 69816cdf5b..3858569302 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -714,6 +714,7 @@ int bootm_boot(struct bootm_data *bootm_data)
 	int ret;
 	enum filetype os_type;
 	size_t size;
+	const char *os_type_str;
 
 	if (!bootm_data->os_file) {
 		pr_err("no image given\n");
@@ -769,9 +770,13 @@ int bootm_boot(struct bootm_data *bootm_data)
 		}
 	}
 
+	os_type_str = file_type_to_short_string(os_type);
+
 	switch (os_type) {
 	case filetype_oftree:
 		ret = bootm_open_fit(data);
+		os_type = file_detect_type(data->fit_kernel, data->fit_kernel_size);
+		os_type_str = "FIT";
 		break;
 	case filetype_uimage:
 		ret = bootm_open_os_uimage(data);
@@ -782,13 +787,6 @@ int bootm_boot(struct bootm_data *bootm_data)
 	}
 
 	if (ret) {
-		const char *os_type_str;
-
-		if (os_type == filetype_oftree)
-			os_type_str = "FIT";
-		else
-			os_type_str = file_type_to_short_string(os_type);
-
 		pr_err("Loading %s image failed with: %pe\n", os_type_str, ERR_PTR(ret));
 		goto err_out;
 	}
diff --git a/common/image-fit.c b/common/image-fit.c
index 6eda041935..05dfec8856 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -979,40 +979,21 @@ void fit_close(struct fit_handle *handle)
 	free(handle);
 }
 
-static int do_bootm_sandbox_fit(struct image_data *data)
+static int do_bootm_fit(struct image_data *data)
 {
-	struct fit_handle *handle;
-	void *config;
-	int ret;
-
-	handle = fit_open(data->os_file, data->verbose, BOOTM_VERIFY_NONE,
-			  FILESIZE_MAX);
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-
-	config = fit_open_configuration(handle, data->os_part);
-	if (IS_ERR(config)) {
-		ret = PTR_ERR(config);
-		goto out;
-	}
-
-	ret = 0;
-out:
-	fit_close(handle);
+	pr_err("Cannot boot device tree binary blob\n");
 
-	return ret;
+	return -EINVAL;
 }
 
-static struct image_handler sandbox_fit_handler = {
+static struct image_handler fit_handler = {
 	.name = "FIT image",
-	.bootm = do_bootm_sandbox_fit,
+	.bootm = do_bootm_fit,
 	.filetype = filetype_oftree,
 };
 
-static __maybe_unused int sandbox_fit_register(void)
+static int sandbox_fit_register(void)
 {
-	return register_image_handler(&sandbox_fit_handler);
+	return register_image_handler(&fit_handler);
 }
-#ifdef CONFIG_SANDBOX
 late_initcall(sandbox_fit_register);
-#endif
-- 
2.39.5




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-04-07 13:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-07 13:07 [PATCH 1/2] bootm: move ELF handling to bootm handlers Sascha Hauer
2025-04-07 13:07 ` [PATCH 2/2] bootm: create generic FIT image handler Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox