[PATCH 5/7] ARM: introduce jump_to_linux helper
Ahmad Fatoum
a.fatoum at pengutronix.de
Wed Apr 9 07:01:33 PDT 2025
The upcoming FIP bootm handler should be usable on both ARM32 and ARM64
and thus we need an arch-independent way of booting a kernel with a
given device tree.
Introduce a jump_to_linux helper in <asm/boot.h> for this purpose.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
arch/arm/include/asm/boot.h | 28 ++++++++++++++++++++++++++++
arch/arm/lib32/armlinux.c | 14 +++++++-------
arch/arm/lib64/armlinux.c | 12 ++++++------
3 files changed, 41 insertions(+), 13 deletions(-)
create mode 100644 arch/arm/include/asm/boot.h
diff --git a/arch/arm/include/asm/boot.h b/arch/arm/include/asm/boot.h
new file mode 100644
index 000000000000..a75d139ed8ea
--- /dev/null
+++ b/arch/arm/include/asm/boot.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef _ASM_BOOT_H_
+#define _ASM_BOOT_H_
+
+#include <linux/types.h>
+
+#ifdef CONFIG_ARM64
+static inline void jump_to_linux(const void *_kernel, phys_addr_t dtb)
+{
+ void (*kernel)(unsigned long dtb, unsigned long x1, unsigned long x2,
+ unsigned long x3) = _kernel;
+ kernel(dtb, 0, 0, 0);
+}
+#else
+static inline void __jump_to_linux(const void *_kernel, unsigned arch,
+ phys_addr_t params)
+{
+ void (*kernel)(int zero, unsigned arch, ulong params) = _kernel;
+ kernel(0, arch, params);
+}
+static inline void jump_to_linux(const void *_kernel, phys_addr_t dtb)
+{
+ __jump_to_linux(_kernel, ~0, dtb);
+}
+#endif
+
+#endif /* _ASM_BOOT_H_ */
diff --git a/arch/arm/lib32/armlinux.c b/arch/arm/lib32/armlinux.c
index 0b332d23639d..56f278d3dbae 100644
--- a/arch/arm/lib32/armlinux.c
+++ b/arch/arm/lib32/armlinux.c
@@ -26,6 +26,7 @@
#include <asm/armlinux.h>
#include <asm/system.h>
#include <asm/secure.h>
+#include <asm/boot.h>
static struct tag *params;
static void *armlinux_bootparams = NULL;
@@ -251,8 +252,7 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
unsigned long initrd_size, void *oftree,
enum arm_security_state state, void *optee)
{
- void (*kernel)(int zero, unsigned arch, void *params) = adr;
- void *params = NULL;
+ phys_addr_t params = 0;
unsigned architecture;
int ret;
@@ -264,11 +264,11 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
if (oftree) {
pr_debug("booting kernel with devicetree\n");
- params = oftree;
+ params = virt_to_phys(oftree);
} else {
- params = armlinux_get_bootparams();
+ params = virt_to_phys(armlinux_get_bootparams());
- if ((unsigned long)params < PAGE_SIZE)
+ if (params < PAGE_SIZE)
zero_page_access();
setup_tags(initrd_address, initrd_size, swap);
@@ -288,8 +288,8 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
}
if (optee && IS_ENABLED(CONFIG_BOOTM_OPTEE)) {
- start_kernel_optee(optee, kernel, oftree);
+ start_kernel_optee(optee, adr, oftree);
} else {
- kernel(0, architecture, params);
+ __jump_to_linux(adr, architecture, params);
}
}
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
index 5feee9c24f2a..13721a71236b 100644
--- a/arch/arm/lib64/armlinux.c
+++ b/arch/arm/lib64/armlinux.c
@@ -5,18 +5,18 @@
#include <memory.h>
#include <init.h>
#include <bootm.h>
+#include <asm/boot.h>
#include <efi/efi-mode.h>
static int do_bootm_linux(struct image_data *data)
{
- void (*fn)(unsigned long dtb, unsigned long x1, unsigned long x2,
- unsigned long x3);
+ void *image;
phys_addr_t devicetree;
int ret;
- fn = booti_load_image(data, &devicetree);
- if (IS_ERR(fn))
- return PTR_ERR(fn);
+ image = booti_load_image(data, &devicetree);
+ if (IS_ERR(image))
+ return PTR_ERR(image);
if (data->dryrun)
return 0;
@@ -27,7 +27,7 @@ static int do_bootm_linux(struct image_data *data)
shutdown_barebox();
- fn(devicetree, 0, 0, 0);
+ jump_to_linux(image, devicetree);
return -EINVAL;
}
--
2.39.5
More information about the barebox
mailing list