* [PATCH 02/11] efi: payload: split out payload Kconfig symbols
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 4:15 ` [PATCH 03/11] efi: payload: add support for EFI initrd media protocol chalianis1
` (9 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Ahmad Fatoum, Chali Anis
From: Ahmad Fatoum <a.fatoum@barebox.org>
We are already keeping different directories for payload and common EFI
support. In preparation for adding more payload-specific config options,
move the existing ones into their own Kconfig file.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
efi/Kconfig | 20 +-------------------
efi/payload/Kconfig | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+), 19 deletions(-)
create mode 100644 efi/payload/Kconfig
diff --git a/efi/Kconfig b/efi/Kconfig
index 84f670fd23d3..35850b20ef50 100644
--- a/efi/Kconfig
+++ b/efi/Kconfig
@@ -2,21 +2,7 @@
menu "EFI (Extensible Firmware Interface) Support"
-config HAVE_EFI_PAYLOAD
- bool
-
-config EFI_PAYLOAD
- bool "Build as EFI payload" if COMPILE_TEST
- depends on HAVE_EFI_PAYLOAD
- select PBL_FULLY_PIC if ARM64
- select EFI
- select EFI_GUID
- select EFI_DEVICEPATH
- select PRINTF_UUID
- select PRINTF_WCHAR
- select BLOCK
- select PARTITION_DISK
- select HW_HAS_PCI
+source "efi/payload/Kconfig"
config EFI
bool
@@ -26,10 +12,6 @@ config HAVE_EFI_STUB
if EFI
-config EFI_STUB
- def_bool EFI_PAYLOAD
- depends on HAVE_EFI_STUB
-
config EFI_GUID
bool
help
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
new file mode 100644
index 000000000000..9263d59de94a
--- /dev/null
+++ b/efi/payload/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config HAVE_EFI_PAYLOAD
+ bool
+
+config EFI_PAYLOAD
+ bool "Build as EFI payload" if COMPILE_TEST
+ depends on HAVE_EFI_PAYLOAD
+ select PBL_FULLY_PIC if ARM64
+ select EFI
+ select EFI_GUID
+ select EFI_DEVICEPATH
+ select PRINTF_UUID
+ select PRINTF_WCHAR
+ select BLOCK
+ select PARTITION_DISK
+ select HW_HAS_PCI
+
+config HAVE_EFI_STUB
+ bool
+
+if EFI_PAYLOAD
+
+config EFI_STUB
+ def_bool HAVE_EFI_STUB
+
+endif
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 03/11] efi: payload: add support for EFI initrd media protocol
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
2025-10-06 4:15 ` [PATCH 02/11] efi: payload: split out payload Kconfig symbols chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 11:31 ` Ahmad Fatoum
2025-10-06 4:15 ` [PATCH 04/11] tlsf: move kasan_poison_shadow into tlsf_add_pool chalianis1
` (8 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Chali Anis, Ahmad Fatoum
From: Chali Anis <chalianis1@gmail.com>
Implement the EFI initrd media protocol, which allows registering an
initramfs data to be loaded by the linux after vi EFI Initrd Media
protocol.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
efi/guid.c | 4 ++
efi/payload/Makefile | 1 +
efi/payload/efi-initrd.c | 104 ++++++++++++++++++++++++++++++++++++++
include/efi.h | 4 ++
include/efi/efi-payload.h | 3 ++
5 files changed, 116 insertions(+)
create mode 100644 efi/payload/efi-initrd.c
diff --git a/efi/guid.c b/efi/guid.c
index ef230a2b2403..46440c9f3328 100644
--- a/efi/guid.c
+++ b/efi/guid.c
@@ -44,6 +44,7 @@ const efi_guid_t efi_load_file_protocol_guid = EFI_LOAD_FILE_PROTOCOL_GUID;
const efi_guid_t efi_load_file2_protocol_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
const efi_guid_t efi_device_path_utilities_protocol_guid =
EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
+const efi_guid_t efi_linux_initrd_media_guid = EFI_LINUX_INITRD_MEDIA_GUID;
#define EFI_GUID_STRING(guid, short, long) do { \
if (!efi_guidcmp(guid, *g)) \
@@ -128,5 +129,8 @@ const char *efi_guid_string(efi_guid_t *g)
EFI_GUID_STRING(EFI_ISCSIDXE_INF_GUID, "IScsiDxe.inf", "EFI IScsiDxe.inf File GUID");
EFI_GUID_STRING(EFI_VLANCONFIGDXE_INF_GUID, "VlanConfigDxe.inf", "EFI VlanConfigDxe.inf File GUID");
+ /* Ramdisk */
+ EFI_GUID_STRING(EFI_LINUX_INITRD_MEDIA_GUID, "Initrd Media", "EFI Linux Initrd Media GUID");
+
return "unknown";
}
diff --git a/efi/payload/Makefile b/efi/payload/Makefile
index a4a0332a8288..1250535302d3 100644
--- a/efi/payload/Makefile
+++ b/efi/payload/Makefile
@@ -2,6 +2,7 @@
obj-y += init.o
obj-y += image.o
+obj-y += efi-initrd.o
obj-$(CONFIG_OFTREE) += fdt.o
bbenv-y += env-efi
obj-$(CONFIG_CMD_IOMEM) += iomem.o
diff --git a/efi/payload/efi-initrd.c b/efi/payload/efi-initrd.c
new file mode 100644
index 000000000000..ddc21704a8e0
--- /dev/null
+++ b/efi/payload/efi-initrd.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * efi-initrd.c - barebox EFI payload support
+ *
+ * Copyright (c) 2025 Anis Chali <chalianis1@gmail.com>
+ * Copyright (C) 2025 Ahmad Fatoum <a.fatoum@pengutronix.de>
+ */
+#include <common.h>
+#include <driver.h>
+#include <init.h>
+#include <linux/hw_random.h>
+#include <efi.h>
+#include <efi/efi-device.h>
+#include <efi/device-path.h>
+#include <efi/efi-payload.h>
+
+static efi_status_t EFIAPI efi_initrd_load_file2(
+ struct efi_load_file_protocol *this, struct efi_device_path *file_path,
+ bool boot_policy, unsigned long *buffer_size, void *buffer);
+
+static const struct {
+ struct efi_device_path_vendor vendor;
+ struct efi_device_path end;
+} __packed initrd_dev_path = {
+ { {
+ DEVICE_PATH_TYPE_MEDIA_DEVICE,
+ DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
+ sizeof(initrd_dev_path.vendor),
+ },
+ EFI_LINUX_INITRD_MEDIA_GUID },
+ { DEVICE_PATH_TYPE_END, DEVICE_PATH_SUB_TYPE_END,
+ DEVICE_PATH_END_LENGTH }
+};
+
+static struct linux_initrd {
+ struct efi_load_file_protocol base;
+ void *start;
+ size_t size;
+ efi_handle_t lf2_handle;
+} initrd;
+
+#define to_linux_initrd(x) container_of(x, struct linux_initrd, base)
+
+static efi_status_t EFIAPI efi_initrd_load_file2(
+ struct efi_load_file_protocol *this, struct efi_device_path *file_path,
+ bool boot_policy, unsigned long *buffer_size, void *buffer)
+{
+
+ struct linux_initrd *initrd = to_linux_initrd(this);
+
+ if (!this || this != &initrd->base || !buffer_size)
+ return EFI_INVALID_PARAMETER;
+
+ if (file_path->type != initrd_dev_path.end.type ||
+ file_path->sub_type != initrd_dev_path.end.sub_type)
+ return EFI_INVALID_PARAMETER;
+
+ if (boot_policy)
+ return EFI_UNSUPPORTED;
+
+ if (!buffer || *buffer_size < initrd->size) {
+ *buffer_size = initrd->size;
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ memcpy(buffer, initrd->start, initrd->size);
+ *buffer_size = initrd->size;
+ }
+
+ return EFI_SUCCESS;
+}
+
+int efi_initrd_register(void *initrd_base, size_t initrd_sz)
+{
+ efi_status_t efiret;
+ int ret;
+
+ initrd.base.load_file = efi_initrd_load_file2;
+ initrd.start = initrd_base;
+ initrd.size = initrd_sz;
+
+ efiret = BS->install_multiple_protocol_interfaces(
+ &initrd.lf2_handle, &efi_load_file2_protocol_guid, &initrd.base,
+ &efi_device_path_protocol_guid, &initrd_dev_path, NULL);
+ if (EFI_ERROR(efiret)) {
+ pr_err("Failed to install protocols for INITRD %s\n",
+ efi_strerror(efiret));
+ ret = -efi_errno(efiret);
+ return ret;
+ }
+
+ return 0;
+}
+
+void efi_initrd_unregister(void)
+{
+ if (!initrd.base.load_file)
+ return;
+
+ BS->uninstall_multiple_protocol_interfaces(
+ initrd.lf2_handle, &efi_device_path_protocol_guid, &initrd_dev_path,
+ &efi_load_file2_protocol_guid, &initrd.base, NULL);
+
+ initrd.base.load_file = NULL;
+}
\ No newline at end of file
diff --git a/include/efi.h b/include/efi.h
index 40b69fdb0188..bd339ea097c3 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -558,6 +558,9 @@ extern struct efi_runtime_services *RT;
#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
EFI_GUID(0x18a031ab, 0xb443, 0x4d1a, 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71)
+#define EFI_LINUX_INITRD_MEDIA_GUID \
+ EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
+
struct efi_driver_binding_protocol {
efi_status_t (EFIAPI * supported)(
struct efi_driver_binding_protocol *this,
@@ -603,6 +606,7 @@ extern const efi_guid_t efi_guid_event_group_reset_system;
extern const efi_guid_t efi_load_file_protocol_guid;
extern const efi_guid_t efi_load_file2_protocol_guid;
extern const efi_guid_t efi_device_path_utilities_protocol_guid;
+extern const efi_guid_t efi_linux_initrd_media_guid;
struct efi_config_table {
efi_guid_t guid;
diff --git a/include/efi/efi-payload.h b/include/efi/efi-payload.h
index fe45864dd8a7..d8e66a187a87 100644
--- a/include/efi/efi-payload.h
+++ b/include/efi/efi-payload.h
@@ -34,4 +34,7 @@ int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec);
void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
size_t *memsize, enum efi_memory_type mem_type);
+int efi_initrd_register(void *initrd, size_t initrd_size);
+void efi_initrd_unregister(void);
+
#endif
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 03/11] efi: payload: add support for EFI initrd media protocol
2025-10-06 4:15 ` [PATCH 03/11] efi: payload: add support for EFI initrd media protocol chalianis1
@ 2025-10-06 11:31 ` Ahmad Fatoum
0 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:31 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox, Ahmad Fatoum
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Chali Anis <chalianis1@gmail.com>
>
> Implement the EFI initrd media protocol, which allows registering an
> initramfs data to be loaded by the linux after vi EFI Initrd Media
> protocol.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> efi/guid.c | 4 ++
> efi/payload/Makefile | 1 +
> efi/payload/efi-initrd.c | 104 ++++++++++++++++++++++++++++++++++++++
> include/efi.h | 4 ++
> include/efi/efi-payload.h | 3 ++
> 5 files changed, 116 insertions(+)
> create mode 100644 efi/payload/efi-initrd.c
>
> diff --git a/efi/guid.c b/efi/guid.c
> index ef230a2b2403..46440c9f3328 100644
> --- a/efi/guid.c
> +++ b/efi/guid.c
> @@ -44,6 +44,7 @@ const efi_guid_t efi_load_file_protocol_guid = EFI_LOAD_FILE_PROTOCOL_GUID;
> const efi_guid_t efi_load_file2_protocol_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
> const efi_guid_t efi_device_path_utilities_protocol_guid =
> EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID;
> +const efi_guid_t efi_linux_initrd_media_guid = EFI_LINUX_INITRD_MEDIA_GUID;
>
> #define EFI_GUID_STRING(guid, short, long) do { \
> if (!efi_guidcmp(guid, *g)) \
> @@ -128,5 +129,8 @@ const char *efi_guid_string(efi_guid_t *g)
> EFI_GUID_STRING(EFI_ISCSIDXE_INF_GUID, "IScsiDxe.inf", "EFI IScsiDxe.inf File GUID");
> EFI_GUID_STRING(EFI_VLANCONFIGDXE_INF_GUID, "VlanConfigDxe.inf", "EFI VlanConfigDxe.inf File GUID");
>
> + /* Ramdisk */
> + EFI_GUID_STRING(EFI_LINUX_INITRD_MEDIA_GUID, "Initrd Media", "EFI Linux Initrd Media GUID");
> +
> return "unknown";
> }
> diff --git a/efi/payload/Makefile b/efi/payload/Makefile
> index a4a0332a8288..1250535302d3 100644
> --- a/efi/payload/Makefile
> +++ b/efi/payload/Makefile
> @@ -2,6 +2,7 @@
>
> obj-y += init.o
> obj-y += image.o
> +obj-y += efi-initrd.o
> obj-$(CONFIG_OFTREE) += fdt.o
> bbenv-y += env-efi
> obj-$(CONFIG_CMD_IOMEM) += iomem.o
> diff --git a/efi/payload/efi-initrd.c b/efi/payload/efi-initrd.c
> new file mode 100644
> index 000000000000..ddc21704a8e0
> --- /dev/null
> +++ b/efi/payload/efi-initrd.c
> @@ -0,0 +1,104 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * efi-initrd.c - barebox EFI payload support
> + *
> + * Copyright (c) 2025 Anis Chali <chalianis1@gmail.com>
> + * Copyright (C) 2025 Ahmad Fatoum <a.fatoum@pengutronix.de>
> + */
> +#include <common.h>
> +#include <driver.h>
> +#include <init.h>
> +#include <linux/hw_random.h>
> +#include <efi.h>
> +#include <efi/efi-device.h>
> +#include <efi/device-path.h>
> +#include <efi/efi-payload.h>
> +
> +static efi_status_t EFIAPI efi_initrd_load_file2(
> + struct efi_load_file_protocol *this, struct efi_device_path *file_path,
> + bool boot_policy, unsigned long *buffer_size, void *buffer);
> +
> +static const struct {
> + struct efi_device_path_vendor vendor;
> + struct efi_device_path end;
> +} __packed initrd_dev_path = {
> + { {
> + DEVICE_PATH_TYPE_MEDIA_DEVICE,
> + DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
> + sizeof(initrd_dev_path.vendor),
> + },
> + EFI_LINUX_INITRD_MEDIA_GUID },
> + { DEVICE_PATH_TYPE_END, DEVICE_PATH_SUB_TYPE_END,
> + DEVICE_PATH_END_LENGTH }
> +};
> +
> +static struct linux_initrd {
> + struct efi_load_file_protocol base;
> + void *start;
> + size_t size;
> + efi_handle_t lf2_handle;
> +} initrd;
> +
> +#define to_linux_initrd(x) container_of(x, struct linux_initrd, base)
> +
> +static efi_status_t EFIAPI efi_initrd_load_file2(
> + struct efi_load_file_protocol *this, struct efi_device_path *file_path,
> + bool boot_policy, unsigned long *buffer_size, void *buffer)
> +{
> +
> + struct linux_initrd *initrd = to_linux_initrd(this);
> +
> + if (!this || this != &initrd->base || !buffer_size)
> + return EFI_INVALID_PARAMETER;
> +
> + if (file_path->type != initrd_dev_path.end.type ||
> + file_path->sub_type != initrd_dev_path.end.sub_type)
> + return EFI_INVALID_PARAMETER;
> +
> + if (boot_policy)
> + return EFI_UNSUPPORTED;
> +
> + if (!buffer || *buffer_size < initrd->size) {
> + *buffer_size = initrd->size;
> + return EFI_BUFFER_TOO_SMALL;
> + } else {
> + memcpy(buffer, initrd->start, initrd->size);
> + *buffer_size = initrd->size;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +int efi_initrd_register(void *initrd_base, size_t initrd_sz)
> +{
> + efi_status_t efiret;
> + int ret;
> +
> + initrd.base.load_file = efi_initrd_load_file2;
> + initrd.start = initrd_base;
> + initrd.size = initrd_sz;
> +
> + efiret = BS->install_multiple_protocol_interfaces(
> + &initrd.lf2_handle, &efi_load_file2_protocol_guid, &initrd.base,
> + &efi_device_path_protocol_guid, &initrd_dev_path, NULL);
> + if (EFI_ERROR(efiret)) {
> + pr_err("Failed to install protocols for INITRD %s\n",
> + efi_strerror(efiret));
> + ret = -efi_errno(efiret);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +void efi_initrd_unregister(void)
> +{
> + if (!initrd.base.load_file)
> + return;
> +
> + BS->uninstall_multiple_protocol_interfaces(
> + initrd.lf2_handle, &efi_device_path_protocol_guid, &initrd_dev_path,
> + &efi_load_file2_protocol_guid, &initrd.base, NULL);
> +
> + initrd.base.load_file = NULL;
> +}
> \ No newline at end of file
> diff --git a/include/efi.h b/include/efi.h
> index 40b69fdb0188..bd339ea097c3 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -558,6 +558,9 @@ extern struct efi_runtime_services *RT;
> #define EFI_DRIVER_BINDING_PROTOCOL_GUID \
> EFI_GUID(0x18a031ab, 0xb443, 0x4d1a, 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71)
>
> +#define EFI_LINUX_INITRD_MEDIA_GUID \
> + EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
> +
> struct efi_driver_binding_protocol {
> efi_status_t (EFIAPI * supported)(
> struct efi_driver_binding_protocol *this,
> @@ -603,6 +606,7 @@ extern const efi_guid_t efi_guid_event_group_reset_system;
> extern const efi_guid_t efi_load_file_protocol_guid;
> extern const efi_guid_t efi_load_file2_protocol_guid;
> extern const efi_guid_t efi_device_path_utilities_protocol_guid;
> +extern const efi_guid_t efi_linux_initrd_media_guid;
>
> struct efi_config_table {
> efi_guid_t guid;
> diff --git a/include/efi/efi-payload.h b/include/efi/efi-payload.h
> index fe45864dd8a7..d8e66a187a87 100644
> --- a/include/efi/efi-payload.h
> +++ b/include/efi/efi-payload.h
> @@ -34,4 +34,7 @@ int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec);
> void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
> size_t *memsize, enum efi_memory_type mem_type);
>
> +int efi_initrd_register(void *initrd, size_t initrd_size);
> +void efi_initrd_unregister(void);
> +
> #endif
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 04/11] tlsf: move kasan_poison_shadow into tlsf_add_pool
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
2025-10-06 4:15 ` [PATCH 02/11] efi: payload: split out payload Kconfig symbols chalianis1
2025-10-06 4:15 ` [PATCH 03/11] efi: payload: add support for EFI initrd media protocol chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 4:15 ` [PATCH 05/11] tlsf: support on-demand requesting memory from external store chalianis1
` (7 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Ahmad Fatoum, Chali Anis
From: Ahmad Fatoum <a.fatoum@barebox.org>
Unallocated memory is poisoned by default to catch heap overflows.
Its control data can also be poisoned by default as the code takes care
to unpoison it on access.
Move the poisoning thus tlsf_add_pool(), so users need not worry about
it.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
common/tlsf.c | 7 +++++--
common/tlsf_malloc.c | 2 --
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/common/tlsf.c b/common/tlsf.c
index 8666b94ea387..4ee53a9b2f20 100644
--- a/common/tlsf.c
+++ b/common/tlsf.c
@@ -814,6 +814,7 @@ size_t tlsf_alloc_overhead(void)
pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
{
+ control_t* control = tlsf_cast(control_t*, tlsf);
block_header_t* block;
block_header_t* next;
@@ -844,7 +845,7 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
block_set_size(block, pool_bytes);
block_set_free(block);
block_set_prev_used(block);
- block_insert(tlsf_cast(control_t*, tlsf), block);
+ block_insert(control, block);
/* Split the block to create a zero-size sentinel block. */
next = block_link_next(block);
@@ -852,6 +853,9 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
block_set_used(next);
block_set_prev_free(next);
+ kasan_poison_shadow(mem, bytes, KASAN_TAG_INVALID);
+ kasan_poison_shadow(control, sizeof(control), KASAN_TAG_INVALID);
+
return mem;
}
@@ -927,7 +931,6 @@ tlsf_t tlsf_create_with_pool(void* mem, size_t bytes)
{
tlsf_t tlsf = tlsf_create(mem);
tlsf_add_pool(tlsf, (char*)mem + tlsf_size(), bytes - tlsf_size());
- kasan_poison_shadow(mem, bytes, KASAN_TAG_INVALID);
return tlsf;
}
diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c
index 6e9d48af26bb..74089fe7f390 100644
--- a/common/tlsf_malloc.c
+++ b/common/tlsf_malloc.c
@@ -115,8 +115,6 @@ void *malloc_add_pool(void *mem, size_t bytes)
if (!new_pool)
return NULL;
- kasan_poison_shadow(mem, bytes, KASAN_TAG_INVALID);
-
new_pool_entry = malloc(sizeof(*new_pool_entry));
if (!new_pool_entry)
return NULL;
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 05/11] tlsf: support on-demand requesting memory from external store
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (2 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 04/11] tlsf: move kasan_poison_shadow into tlsf_add_pool chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 4:15 ` [PATCH 06/11] efi: payload: earlymem: allocate only the barebox needs in term of memory chalianis1
` (6 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Chali Anis, Ahmad Fatoum
From: Chali Anis <chalianis1@gmail.com>
barebox running under an operating system (or nearly one like UEFI) does
not have control over all the memory and should not hog too much memory
upfront as that can interfere with other applications, e.g. EFI drivers
or the EFI firmware itself.
To accommodate this use case, allow TLSF to dynamically request more
memory from an external store via tlsf_register_store().
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
common/tlsf.c | 29 ++++++++++++++++++++++++++++-
include/tlsf.h | 1 +
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/common/tlsf.c b/common/tlsf.c
index 4ee53a9b2f20..636b57b1c642 100644
--- a/common/tlsf.c
+++ b/common/tlsf.c
@@ -159,6 +159,9 @@ typedef struct control_t
/* Empty lists point at this block to indicate they are free. */
block_header_t block_null;
+ void (*request_store)(tlsf_t, size_t);
+
+
/* Bitmaps for free lists. */
unsigned int fl_bitmap;
unsigned int sl_bitmap[FL_INDEX_COUNT];
@@ -568,7 +571,7 @@ static block_header_t* block_trim_free_leading(control_t* control, block_header_
return remaining_block;
}
-static block_header_t* block_locate_free(control_t* control, size_t size)
+static block_header_t* __block_locate_free(control_t* control, size_t size)
{
int fl = 0, sl = 0;
block_header_t* block = 0;
@@ -598,6 +601,23 @@ static block_header_t* block_locate_free(control_t* control, size_t size)
return block;
}
+static block_header_t* block_locate_free(control_t* control, size_t size)
+{
+ block_header_t *block;
+
+ block = __block_locate_free(control, size);
+ if (block)
+ return block;
+
+ if (!control->request_store || !size)
+ return NULL;
+
+ control->request_store(tlsf_cast(tlsf_t, control),
+ size + tlsf_pool_overhead());
+
+ return __block_locate_free(control, size);
+}
+
static void* block_prepare_used(control_t* control, block_header_t* block,
size_t size, size_t used)
{
@@ -934,6 +954,13 @@ tlsf_t tlsf_create_with_pool(void* mem, size_t bytes)
return tlsf;
}
+void tlsf_register_store(tlsf_t tlsf, void (*cb)(tlsf_t tlsf, size_t bytes))
+{
+ control_t* control = tlsf_cast(control_t*, tlsf);
+
+ control->request_store = cb;
+}
+
void tlsf_destroy(tlsf_t tlsf)
{
/* Nothing to do. */
diff --git a/include/tlsf.h b/include/tlsf.h
index e0dcdac1e7ab..ea86b0600c49 100644
--- a/include/tlsf.h
+++ b/include/tlsf.h
@@ -63,6 +63,7 @@ tlsf_t tlsf_create(void* mem);
tlsf_t tlsf_create_with_pool(void* mem, size_t bytes);
void tlsf_destroy(tlsf_t tlsf);
pool_t tlsf_get_pool(tlsf_t tlsf);
+void tlsf_register_store(tlsf_t tlsf, void (*cb)(tlsf_t tlsf, size_t bytes));
/* Add/remove memory pools. */
pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes);
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 06/11] efi: payload: earlymem: allocate only the barebox needs in term of memory
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (3 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 05/11] tlsf: support on-demand requesting memory from external store chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 11:32 ` Ahmad Fatoum
2025-10-06 4:15 ` [PATCH 07/11] efi: payload: split image handling from legacy handover boot chalianis1
` (5 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Chali Anis, Ahmad Fatoum
From: Chali Anis <chalianis1@gmail.com>
With TLSF now able to invoke a callback to request additional memory on
demand, limit early allocations to what barebox strictly requires and have
everything handled via the request callback. This ensures more deterministic
behavior and reduces the risk of OOM conditions.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
common/tlsf_malloc.c | 18 ++++++++++++++++++
efi/payload/Kconfig | 1 +
efi/payload/early-mem.c | 19 ++++---------------
efi/payload/entry-multi.c | 5 ++---
efi/payload/entry-single.c | 5 ++---
efi/payload/init.c | 15 +++++++++++++++
include/efi/efi-payload.h | 2 +-
include/malloc.h | 1 +
8 files changed, 44 insertions(+), 22 deletions(-)
diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c
index 74089fe7f390..d3b665a2fc40 100644
--- a/common/tlsf_malloc.c
+++ b/common/tlsf_malloc.c
@@ -11,11 +11,14 @@
#include <stdio.h>
#include <module.h>
#include <tlsf.h>
+#include <linux/sizes.h>
+#include <linux/log2.h>
#include <linux/kasan.h>
#include <linux/list.h>
tlsf_t tlsf_mem_pool;
+static void (*malloc_request_store)(size_t bytes);
struct pool_entry {
pool_t pool;
@@ -124,3 +127,18 @@ void *malloc_add_pool(void *mem, size_t bytes)
return (void *)new_pool;
}
+
+static void tlsf_request_store(tlsf_t tlsf, size_t bytes)
+{
+ size_t size;
+
+ size = __roundup_pow_of_two(bytes + sizeof(struct pool_entry));
+
+ malloc_request_store(max_t(size_t, SZ_8M, size));
+}
+
+void malloc_register_store(void (*cb)(size_t bytes))
+{
+ malloc_request_store = cb;
+ tlsf_register_store(tlsf_mem_pool, tlsf_request_store);
+}
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
index 9263d59de94a..a403acc81a93 100644
--- a/efi/payload/Kconfig
+++ b/efi/payload/Kconfig
@@ -15,6 +15,7 @@ config EFI_PAYLOAD
select BLOCK
select PARTITION_DISK
select HW_HAS_PCI
+ select MALLOC_TLSF
config HAVE_EFI_STUB
bool
diff --git a/efi/payload/early-mem.c b/efi/payload/early-mem.c
index 0f79a8c30694..c5e94b33a756 100644
--- a/efi/payload/early-mem.c
+++ b/efi/payload/early-mem.c
@@ -6,28 +6,17 @@
#include <efi/efi-payload.h>
void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
- size_t *memsize, enum efi_memory_type mem_type)
+ size_t memsize, enum efi_memory_type mem_type)
{
struct efi_boot_services *bs = sys_table->boottime;
- enum efi_allocate_type alloc_type = EFI_ALLOCATE_ANY_PAGES;
efi_physical_addr_t mem;
efi_status_t efiret;
- if (IS_ENABLED(CONFIG_X86)) {
- /* Try to stay clear of memory mapped devices */
- alloc_type = EFI_ALLOCATE_MAX_ADDRESS;
- mem = SZ_1G - 1;
- }
-
- for (*memsize = SZ_256M; *memsize >= SZ_8M; *memsize /= 2) {
- efiret = bs->allocate_pages(alloc_type, mem_type,
- *memsize / EFI_PAGE_SIZE, &mem);
- if (!EFI_ERROR(efiret) || efiret != EFI_OUT_OF_RESOURCES)
- break;
- }
+ efiret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES, mem_type,
+ memsize / EFI_PAGE_SIZE, &mem);
if (EFI_ERROR(efiret))
panic("failed to allocate %zu byte memory pool: 0x%lx\n",
- *memsize, efiret);
+ memsize, efiret);
return efi_phys_to_virt(mem);
}
diff --git a/efi/payload/entry-multi.c b/efi/payload/entry-multi.c
index d5d54cdf70a1..82f3dfffe870 100644
--- a/efi/payload/entry-multi.c
+++ b/efi/payload/entry-multi.c
@@ -23,7 +23,6 @@ static void efi_putc(void *ctx, int ch)
void __efistub_efi_pe_entry(void *image, struct efi_system_table *sys_table)
{
- size_t memsize;
void *mem;
static struct barebox_efi_data efidata;
@@ -37,7 +36,7 @@ void __efistub_efi_pe_entry(void *image, struct efi_system_table *sys_table)
handoff_data_add(HANDOFF_DATA_EFI, &efidata, sizeof(efidata));
- mem = efi_earlymem_alloc(sys_table, &memsize, EFI_LOADER_CODE);
+ mem = efi_earlymem_alloc(sys_table, SZ_16M, EFI_BOOT_SERVICES_CODE);
- barebox_pbl_entry((uintptr_t)mem, memsize, NULL);
+ barebox_pbl_entry((uintptr_t)mem, SZ_16M, NULL);
}
diff --git a/efi/payload/entry-single.c b/efi/payload/entry-single.c
index 8600bd845c49..f481d0942ba5 100644
--- a/efi/payload/entry-single.c
+++ b/efi/payload/entry-single.c
@@ -17,7 +17,6 @@
void efi_main(efi_handle_t image, struct efi_system_table *sys_table)
{
efi_status_t efiret;
- size_t memsize;
void *mem;
#ifdef DEBUG
@@ -37,9 +36,9 @@ void efi_main(efi_handle_t image, struct efi_system_table *sys_table)
BS->handle_protocol(efi_loaded_image->device_handle,
&efi_device_path_protocol_guid, (void **)&efi_device_path);
- mem = efi_earlymem_alloc(sys_table, &memsize, EFI_LOADER_DATA);
+ mem = efi_earlymem_alloc(sys_table, SZ_16M, EFI_BOOT_SERVICES_DATA);
- mem_malloc_init(mem, mem + memsize - 1);
+ mem_malloc_init(mem, mem + SZ_16M - 1);
start_barebox();
}
diff --git a/efi/payload/init.c b/efi/payload/init.c
index 239c5ce9ec18..5b827c57ed1f 100644
--- a/efi/payload/init.c
+++ b/efi/payload/init.c
@@ -270,11 +270,26 @@ static int efi_init(void)
}
device_efi_initcall(efi_init);
+static void efi_request_mem(size_t bytes)
+{
+ efi_status_t efiret;
+ efi_physical_addr_t mem;
+ size_t pages;
+
+ pages = DIV_ROUND_UP(bytes, EFI_PAGE_SIZE);
+ efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA,
+ pages, &mem);
+ if (!EFI_ERROR(efiret))
+ malloc_add_pool(efi_phys_to_virt(mem), pages * EFI_PAGE_SIZE);
+}
+
static int efi_core_init(void)
{
struct device *dev;
int ret;
+ malloc_register_store(efi_request_mem);
+
dev = device_alloc("efi-cs", DEVICE_ID_SINGLE);
ret = platform_device_register(dev);
if (ret)
diff --git a/include/efi/efi-payload.h b/include/efi/efi-payload.h
index d8e66a187a87..337471117d5a 100644
--- a/include/efi/efi-payload.h
+++ b/include/efi/efi-payload.h
@@ -32,7 +32,7 @@ int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes,
int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec);
void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
- size_t *memsize, enum efi_memory_type mem_type);
+ size_t memsize, enum efi_memory_type mem_type);
int efi_initrd_register(void *initrd, size_t initrd_size);
void efi_initrd_unregister(void);
diff --git a/include/malloc.h b/include/malloc.h
index 35551250324e..69ff23b4a058 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -23,6 +23,7 @@
#ifdef CONFIG_MALLOC_TLSF
void *malloc_add_pool(void *mem, size_t bytes);
+void malloc_register_store(void (*cb)(size_t bytes));
#endif
#if IN_PROPER
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 06/11] efi: payload: earlymem: allocate only the barebox needs in term of memory
2025-10-06 4:15 ` [PATCH 06/11] efi: payload: earlymem: allocate only the barebox needs in term of memory chalianis1
@ 2025-10-06 11:32 ` Ahmad Fatoum
0 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:32 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox, Ahmad Fatoum
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Chali Anis <chalianis1@gmail.com>
>
> With TLSF now able to invoke a callback to request additional memory on
> demand, limit early allocations to what barebox strictly requires and have
> everything handled via the request callback. This ensures more deterministic
> behavior and reduces the risk of OOM conditions.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>\
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> common/tlsf_malloc.c | 18 ++++++++++++++++++
> efi/payload/Kconfig | 1 +
> efi/payload/early-mem.c | 19 ++++---------------
> efi/payload/entry-multi.c | 5 ++---
> efi/payload/entry-single.c | 5 ++---
> efi/payload/init.c | 15 +++++++++++++++
> include/efi/efi-payload.h | 2 +-
> include/malloc.h | 1 +
> 8 files changed, 44 insertions(+), 22 deletions(-)
>
> diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c
> index 74089fe7f390..d3b665a2fc40 100644
> --- a/common/tlsf_malloc.c
> +++ b/common/tlsf_malloc.c
> @@ -11,11 +11,14 @@
> #include <stdio.h>
> #include <module.h>
> #include <tlsf.h>
> +#include <linux/sizes.h>
> +#include <linux/log2.h>
>
> #include <linux/kasan.h>
> #include <linux/list.h>
>
> tlsf_t tlsf_mem_pool;
> +static void (*malloc_request_store)(size_t bytes);
>
> struct pool_entry {
> pool_t pool;
> @@ -124,3 +127,18 @@ void *malloc_add_pool(void *mem, size_t bytes)
>
> return (void *)new_pool;
> }
> +
> +static void tlsf_request_store(tlsf_t tlsf, size_t bytes)
> +{
> + size_t size;
> +
> + size = __roundup_pow_of_two(bytes + sizeof(struct pool_entry));
> +
> + malloc_request_store(max_t(size_t, SZ_8M, size));
> +}
> +
> +void malloc_register_store(void (*cb)(size_t bytes))
> +{
> + malloc_request_store = cb;
> + tlsf_register_store(tlsf_mem_pool, tlsf_request_store);
> +}
> diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
> index 9263d59de94a..a403acc81a93 100644
> --- a/efi/payload/Kconfig
> +++ b/efi/payload/Kconfig
> @@ -15,6 +15,7 @@ config EFI_PAYLOAD
> select BLOCK
> select PARTITION_DISK
> select HW_HAS_PCI
> + select MALLOC_TLSF
>
> config HAVE_EFI_STUB
> bool
> diff --git a/efi/payload/early-mem.c b/efi/payload/early-mem.c
> index 0f79a8c30694..c5e94b33a756 100644
> --- a/efi/payload/early-mem.c
> +++ b/efi/payload/early-mem.c
> @@ -6,28 +6,17 @@
> #include <efi/efi-payload.h>
>
> void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
> - size_t *memsize, enum efi_memory_type mem_type)
> + size_t memsize, enum efi_memory_type mem_type)
> {
> struct efi_boot_services *bs = sys_table->boottime;
> - enum efi_allocate_type alloc_type = EFI_ALLOCATE_ANY_PAGES;
> efi_physical_addr_t mem;
> efi_status_t efiret;
>
> - if (IS_ENABLED(CONFIG_X86)) {
> - /* Try to stay clear of memory mapped devices */
> - alloc_type = EFI_ALLOCATE_MAX_ADDRESS;
> - mem = SZ_1G - 1;
> - }
> -
> - for (*memsize = SZ_256M; *memsize >= SZ_8M; *memsize /= 2) {
> - efiret = bs->allocate_pages(alloc_type, mem_type,
> - *memsize / EFI_PAGE_SIZE, &mem);
> - if (!EFI_ERROR(efiret) || efiret != EFI_OUT_OF_RESOURCES)
> - break;
> - }
> + efiret = bs->allocate_pages(EFI_ALLOCATE_ANY_PAGES, mem_type,
> + memsize / EFI_PAGE_SIZE, &mem);
> if (EFI_ERROR(efiret))
> panic("failed to allocate %zu byte memory pool: 0x%lx\n",
> - *memsize, efiret);
> + memsize, efiret);
>
> return efi_phys_to_virt(mem);
> }
> diff --git a/efi/payload/entry-multi.c b/efi/payload/entry-multi.c
> index d5d54cdf70a1..82f3dfffe870 100644
> --- a/efi/payload/entry-multi.c
> +++ b/efi/payload/entry-multi.c
> @@ -23,7 +23,6 @@ static void efi_putc(void *ctx, int ch)
>
> void __efistub_efi_pe_entry(void *image, struct efi_system_table *sys_table)
> {
> - size_t memsize;
> void *mem;
> static struct barebox_efi_data efidata;
>
> @@ -37,7 +36,7 @@ void __efistub_efi_pe_entry(void *image, struct efi_system_table *sys_table)
>
> handoff_data_add(HANDOFF_DATA_EFI, &efidata, sizeof(efidata));
>
> - mem = efi_earlymem_alloc(sys_table, &memsize, EFI_LOADER_CODE);
> + mem = efi_earlymem_alloc(sys_table, SZ_16M, EFI_BOOT_SERVICES_CODE);
>
> - barebox_pbl_entry((uintptr_t)mem, memsize, NULL);
> + barebox_pbl_entry((uintptr_t)mem, SZ_16M, NULL);
> }
> diff --git a/efi/payload/entry-single.c b/efi/payload/entry-single.c
> index 8600bd845c49..f481d0942ba5 100644
> --- a/efi/payload/entry-single.c
> +++ b/efi/payload/entry-single.c
> @@ -17,7 +17,6 @@
> void efi_main(efi_handle_t image, struct efi_system_table *sys_table)
> {
> efi_status_t efiret;
> - size_t memsize;
> void *mem;
>
> #ifdef DEBUG
> @@ -37,9 +36,9 @@ void efi_main(efi_handle_t image, struct efi_system_table *sys_table)
> BS->handle_protocol(efi_loaded_image->device_handle,
> &efi_device_path_protocol_guid, (void **)&efi_device_path);
>
> - mem = efi_earlymem_alloc(sys_table, &memsize, EFI_LOADER_DATA);
> + mem = efi_earlymem_alloc(sys_table, SZ_16M, EFI_BOOT_SERVICES_DATA);
>
> - mem_malloc_init(mem, mem + memsize - 1);
> + mem_malloc_init(mem, mem + SZ_16M - 1);
>
> start_barebox();
> }
> diff --git a/efi/payload/init.c b/efi/payload/init.c
> index 239c5ce9ec18..5b827c57ed1f 100644
> --- a/efi/payload/init.c
> +++ b/efi/payload/init.c
> @@ -270,11 +270,26 @@ static int efi_init(void)
> }
> device_efi_initcall(efi_init);
>
> +static void efi_request_mem(size_t bytes)
> +{
> + efi_status_t efiret;
> + efi_physical_addr_t mem;
> + size_t pages;
> +
> + pages = DIV_ROUND_UP(bytes, EFI_PAGE_SIZE);
> + efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA,
> + pages, &mem);
> + if (!EFI_ERROR(efiret))
> + malloc_add_pool(efi_phys_to_virt(mem), pages * EFI_PAGE_SIZE);
> +}
> +
> static int efi_core_init(void)
> {
> struct device *dev;
> int ret;
>
> + malloc_register_store(efi_request_mem);
> +
> dev = device_alloc("efi-cs", DEVICE_ID_SINGLE);
> ret = platform_device_register(dev);
> if (ret)
> diff --git a/include/efi/efi-payload.h b/include/efi/efi-payload.h
> index d8e66a187a87..337471117d5a 100644
> --- a/include/efi/efi-payload.h
> +++ b/include/efi/efi-payload.h
> @@ -32,7 +32,7 @@ int efi_set_variable(char *name, efi_guid_t *vendor, uint32_t attributes,
> int efi_set_variable_usec(char *name, efi_guid_t *vendor, uint64_t usec);
>
> void *efi_earlymem_alloc(const struct efi_system_table *sys_table,
> - size_t *memsize, enum efi_memory_type mem_type);
> + size_t memsize, enum efi_memory_type mem_type);
>
> int efi_initrd_register(void *initrd, size_t initrd_size);
> void efi_initrd_unregister(void);
> diff --git a/include/malloc.h b/include/malloc.h
> index 35551250324e..69ff23b4a058 100644
> --- a/include/malloc.h
> +++ b/include/malloc.h
> @@ -23,6 +23,7 @@
>
> #ifdef CONFIG_MALLOC_TLSF
> void *malloc_add_pool(void *mem, size_t bytes);
> +void malloc_register_store(void (*cb)(size_t bytes));
> #endif
>
> #if IN_PROPER
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 07/11] efi: payload: split image handling from legacy handover boot
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (4 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 06/11] efi: payload: earlymem: allocate only the barebox needs in term of memory chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 11:37 ` Ahmad Fatoum
2025-10-06 4:15 ` [PATCH 08/11] efi: payload: bootm: add support for efi stub boot chalianis1
` (4 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Chali Anis, Ahmad Fatoum
From: Chali Anis <chalianis1@gmail.com>
The handover boot support is Linux-specific and can be disabled
with CONFIG_EFI_HANDOVER_PROTOCOL. In preparation for adding a compliant
boot method, move the handover-specific parts into their own file.
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
efi/payload/Kconfig | 5 +
efi/payload/Makefile | 1 +
efi/payload/handover.c | 154 +++++++++++++++++++++++++++++
efi/payload/image.c | 192 +++++--------------------------------
efi/payload/image.h | 14 +++
| 63 ++++++++++++
6 files changed, 260 insertions(+), 169 deletions(-)
create mode 100644 efi/payload/handover.c
create mode 100644 efi/payload/image.h
create mode 100644 efi/payload/setup_header.h
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
index a403acc81a93..d0a46704a6b9 100644
--- a/efi/payload/Kconfig
+++ b/efi/payload/Kconfig
@@ -25,4 +25,9 @@ if EFI_PAYLOAD
config EFI_STUB
def_bool HAVE_EFI_STUB
+config EFI_HANDOVER_PROTOCOL
+ bool "EFI Handover protocol"
+ default y
+ depends on X86
+
endif
diff --git a/efi/payload/Makefile b/efi/payload/Makefile
index 1250535302d3..d8b577bf3e23 100644
--- a/efi/payload/Makefile
+++ b/efi/payload/Makefile
@@ -2,6 +2,7 @@
obj-y += init.o
obj-y += image.o
+obj-$(CONFIG_EFI_HANDOVER_PROTOCOL) += handover.o
obj-y += efi-initrd.o
obj-$(CONFIG_OFTREE) += fdt.o
bbenv-y += env-efi
diff --git a/efi/payload/handover.c b/efi/payload/handover.c
new file mode 100644
index 000000000000..82f4cb4f5286
--- /dev/null
+++ b/efi/payload/handover.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * handover.c - legacy x86 EFI handover protocol
+ *
+ * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ */
+
+#define pr_fmt(fmt) "efi-handover: " fmt
+
+#include <clock.h>
+#include <common.h>
+#include <linux/sizes.h>
+#include <linux/ktime.h>
+#include <memory.h>
+#include <command.h>
+#include <magicvar.h>
+#include <init.h>
+#include <driver.h>
+#include <io.h>
+#include <efi.h>
+#include <malloc.h>
+#include <string.h>
+#include <linux/err.h>
+#include <boot.h>
+#include <bootm.h>
+#include <fs.h>
+#include <libfile.h>
+#include <binfmt.h>
+#include <wchar.h>
+#include <efi/efi-payload.h>
+#include <efi/efi-device.h>
+
+#include "image.h"
+#include "setup_header.h"
+
+static int efi_do_execute_image(enum filetype filetype, const char *file)
+{
+ efi_handle_t handle;
+ struct efi_loaded_image *loaded_image;
+ int ret;
+
+ ret = efi_load_image(file, &loaded_image, &handle);
+ if (ret)
+ return ret;
+
+ return efi_execute_image(handle, loaded_image, filetype);
+}
+
+typedef void(*handover_fn)(void *image, struct efi_system_table *table,
+ struct x86_setup_header *header);
+
+static inline void linux_efi_handover(efi_handle_t handle,
+ struct x86_setup_header *header)
+{
+ handover_fn handover;
+ uintptr_t addr;
+
+ addr = header->code32_start + header->handover_offset;
+ if (IS_ENABLED(CONFIG_X86_64))
+ addr += 512;
+
+ handover = efi_phys_to_virt(addr);
+ handover(handle, efi_sys_table, header);
+}
+
+static int do_bootm_efi(struct image_data *data)
+{
+ void *tmp;
+ void *initrd = NULL;
+ size_t size;
+ efi_handle_t handle;
+ int ret;
+ const char *options;
+ struct efi_loaded_image *loaded_image;
+ struct x86_setup_header *image_header, *boot_header;
+
+ ret = efi_load_image(data->os_file, &loaded_image, &handle);
+ if (ret)
+ return ret;
+
+ image_header = (struct x86_setup_header *)loaded_image->image_base;
+
+ if (!is_x86_setup_header(image_header) ||
+ image_header->version < 0x20b ||
+ !image_header->relocatable_kernel) {
+ pr_err("Not a valid kernel image!\n");
+ BS->unload_image(handle);
+ return -EINVAL;
+ }
+
+ boot_header = xmalloc(0x4000);
+ memset(boot_header, 0, 0x4000);
+ memcpy(boot_header, image_header, sizeof(*image_header));
+
+ /* Refer to Linux kernel commit a27e292b8a54
+ * ("Documentation/x86/boot: Reserve type_of_loader=13 for barebox")
+ */
+ boot_header->type_of_loader = 0x13;
+
+ if (data->initrd_file) {
+ tmp = read_file(data->initrd_file, &size);
+ initrd = xmemalign(PAGE_SIZE, PAGE_ALIGN(size));
+ memcpy(initrd, tmp, size);
+ memset(initrd + size, 0, PAGE_ALIGN(size) - size);
+ free(tmp);
+ boot_header->ramdisk_image = efi_virt_to_phys(initrd);
+ boot_header->ramdisk_size = PAGE_ALIGN(size);
+ }
+
+ options = linux_bootargs_get();
+ if (options) {
+ boot_header->cmd_line_ptr = efi_virt_to_phys(options);
+ boot_header->cmdline_size = strlen(options);
+ }
+
+ boot_header->code32_start = efi_virt_to_phys(loaded_image->image_base +
+ (image_header->setup_sects+1) * 512);
+
+ if (bootm_verbose(data)) {
+ printf("\nStarting kernel at 0x%p", loaded_image->image_base);
+ if (data->initrd_file)
+ printf(", initrd at 0x%08x",
+ boot_header->ramdisk_image);
+ printf("...\n");
+ }
+
+ if (data->dryrun) {
+ BS->unload_image(handle);
+ free(boot_header);
+ free(initrd);
+ return 0;
+ }
+
+ efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
+ ktime_to_us(ktime_get()));
+
+ shutdown_barebox();
+ linux_efi_handover(handle, boot_header);
+
+ return 0;
+}
+
+static struct image_handler efi_handle_tr = {
+ .name = "EFI Application",
+ .bootm = do_bootm_efi,
+ .filetype = filetype_exe,
+};
+
+static int efi_register_handover_handler(void)
+{
+ register_image_handler(&efi_handle_tr);
+ return 0;
+}
+late_efi_initcall(efi_register_handover_handler);
diff --git a/efi/payload/image.c b/efi/payload/image.c
index 33c5e18dac27..ae7678188d84 100644
--- a/efi/payload/image.c
+++ b/efi/payload/image.c
@@ -5,13 +5,12 @@
* Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*/
+#define pr_fmt(fmt) "efi-image: " fmt
+
#include <clock.h>
#include <common.h>
#include <linux/sizes.h>
-#include <linux/ktime.h>
#include <memory.h>
-#include <command.h>
-#include <magicvar.h>
#include <init.h>
#include <driver.h>
#include <io.h>
@@ -19,7 +18,7 @@
#include <malloc.h>
#include <string.h>
#include <linux/err.h>
-#include <boot.h>
+#include <bootargs.h>
#include <bootm.h>
#include <fs.h>
#include <libfile.h>
@@ -28,54 +27,8 @@
#include <efi/efi-payload.h>
#include <efi/efi-device.h>
-struct linux_kernel_header {
- /* first sector of the image */
- uint8_t code1[0x0020];
- uint16_t cl_magic; /**< Magic number 0xA33F */
- uint16_t cl_offset; /**< The offset of command line */
- uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
- uint8_t setup_sects; /**< The size of the setup in sectors */
- uint16_t root_flags; /**< If the root is mounted readonly */
- uint16_t syssize; /**< obsolete */
- uint16_t swap_dev; /**< obsolete */
- uint16_t ram_size; /**< obsolete */
- uint16_t vid_mode; /**< Video mode control */
- uint16_t root_dev; /**< Default root device number */
- uint16_t boot_flag; /**< 0xAA55 magic number */
-
- /* second sector of the image */
- uint16_t jump; /**< Jump instruction (this is code!) */
- uint32_t header; /**< Magic signature "HdrS" */
- uint16_t version; /**< Boot protocol version supported */
- uint32_t realmode_swtch; /**< Boot loader hook */
- uint16_t start_sys; /**< The load-low segment (obsolete) */
- uint16_t kernel_version; /**< Points to kernel version string */
- uint8_t type_of_loader; /**< Boot loader identifier */
- uint8_t loadflags; /**< Boot protocol option flags */
- uint16_t setup_move_size; /**< Move to high memory size */
- uint32_t code32_start; /**< Boot loader hook */
- uint32_t ramdisk_image; /**< initrd load address */
- uint32_t ramdisk_size; /**< initrd size */
- uint32_t bootsect_kludge; /**< obsolete */
- uint16_t heap_end_ptr; /**< Free memory after setup end */
- uint8_t ext_loader_ver; /**< boot loader's extension of the version number */
- uint8_t ext_loader_type; /**< boot loader's extension of its type */
- uint32_t cmd_line_ptr; /**< Points to the kernel command line */
- uint32_t initrd_addr_max; /**< Highest address for initrd */
- uint32_t kernel_alignment; /**< Alignment unit required by the kernel */
- uint8_t relocatable_kernel; /** */
- uint8_t min_alignment; /** */
- uint16_t xloadflags; /** */
- uint32_t cmdline_size; /** */
- uint32_t hardware_subarch; /** */
- uint64_t hardware_subarch_data; /** */
- uint32_t payload_offset; /** */
- uint32_t payload_length; /** */
- uint64_t setup_data; /** */
- uint64_t pref_address; /** */
- uint32_t init_size; /** */
- uint32_t handover_offset; /** */
-} __attribute__ ((packed));
+#include "image.h"
+#include "setup_header.h"
static void *efi_read_file(const char *file, size_t *size)
{
@@ -85,10 +38,6 @@ static void *efi_read_file(const char *file, size_t *size)
char *buf;
ssize_t ret;
- buf = read_file(file, size);
- if (buf || errno != ENOMEM)
- return buf;
-
ret = stat(file, &s);
if (ret)
return NULL;
@@ -122,8 +71,8 @@ static void efi_free_file(void *_mem, size_t size)
BS->free_pages(mem, DIV_ROUND_UP(size, EFI_PAGE_SIZE));
}
-static int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
- efi_handle_t *h)
+int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
+ efi_handle_t *h)
{
void *exe;
size_t size;
@@ -158,10 +107,7 @@ static int efi_load_image(const char *file, struct efi_loaded_image **loaded_ima
static bool is_linux_image(enum filetype filetype, const void *base)
{
- const struct linux_kernel_header *hdr = base;
-
- if (IS_ENABLED(CONFIG_X86) &&
- hdr->boot_flag == 0xAA55 && hdr->header == 0x53726448)
+ if (IS_ENABLED(CONFIG_X86) && is_x86_setup_header(base))
return true;
if (IS_ENABLED(CONFIG_ARM64) &&
@@ -171,18 +117,13 @@ static bool is_linux_image(enum filetype filetype, const void *base)
return false;
}
-static int efi_execute_image(enum filetype filetype, const char *file)
+int efi_execute_image(efi_handle_t handle,
+ struct efi_loaded_image *loaded_image,
+ enum filetype filetype)
{
- efi_handle_t handle;
- struct efi_loaded_image *loaded_image;
efi_status_t efiret;
const char *options;
bool is_driver;
- int ret;
-
- ret = efi_load_image(file, &loaded_image, &handle);
- if (ret)
- return ret;
is_driver = (loaded_image->image_code_type == EFI_BOOT_SERVICES_CODE) ||
(loaded_image->image_code_type == EFI_RUNTIME_SERVICES_CODE);
@@ -216,110 +157,17 @@ static int efi_execute_image(enum filetype filetype, const char *file)
return -efi_errno(efiret);
}
-typedef void(*handover_fn)(void *image, struct efi_system_table *table,
- struct linux_kernel_header *header);
-
-static inline void linux_efi_handover(efi_handle_t handle,
- struct linux_kernel_header *header)
-{
- handover_fn handover;
- uintptr_t addr;
-
- addr = header->code32_start + header->handover_offset;
- if (IS_ENABLED(CONFIG_X86_64))
- addr += 512;
-
- handover = efi_phys_to_virt(addr);
- handover(handle, efi_sys_table, header);
-}
-
-static int do_bootm_efi(struct image_data *data)
+static int efi_execute(struct binfmt_hook *b, char *file, int argc, char **argv)
{
- void *tmp;
- void *initrd = NULL;
- size_t size;
+ struct efi_loaded_image *loaded_image;
efi_handle_t handle;
int ret;
- const char *options;
- struct efi_loaded_image *loaded_image;
- struct linux_kernel_header *image_header, *boot_header;
- ret = efi_load_image(data->os_file, &loaded_image, &handle);
+ ret = efi_load_image(file, &loaded_image, &handle);
if (ret)
return ret;
- image_header = (struct linux_kernel_header *)loaded_image->image_base;
-
- if (image_header->boot_flag != 0xAA55 ||
- image_header->header != 0x53726448 ||
- image_header->version < 0x20b ||
- !image_header->relocatable_kernel) {
- pr_err("Not a valid kernel image!\n");
- BS->unload_image(handle);
- return -EINVAL;
- }
-
- boot_header = xmalloc(0x4000);
- memset(boot_header, 0, 0x4000);
- memcpy(boot_header, image_header, sizeof(*image_header));
-
- /* Refer to Linux kernel commit a27e292b8a54
- * ("Documentation/x86/boot: Reserve type_of_loader=13 for barebox")
- */
- boot_header->type_of_loader = 0x13;
-
- if (data->initrd_file) {
- tmp = read_file(data->initrd_file, &size);
- initrd = xmemalign(PAGE_SIZE, PAGE_ALIGN(size));
- memcpy(initrd, tmp, size);
- memset(initrd + size, 0, PAGE_ALIGN(size) - size);
- free(tmp);
- boot_header->ramdisk_image = efi_virt_to_phys(initrd);
- boot_header->ramdisk_size = PAGE_ALIGN(size);
- }
-
- options = linux_bootargs_get();
- if (options) {
- boot_header->cmd_line_ptr = efi_virt_to_phys(options);
- boot_header->cmdline_size = strlen(options);
- }
-
- boot_header->code32_start = efi_virt_to_phys(loaded_image->image_base +
- (image_header->setup_sects+1) * 512);
-
- if (bootm_verbose(data)) {
- printf("\nStarting kernel at 0x%p", loaded_image->image_base);
- if (data->initrd_file)
- printf(", initrd at 0x%08x",
- boot_header->ramdisk_image);
- printf("...\n");
- }
-
- if (data->dryrun) {
- BS->unload_image(handle);
- free(boot_header);
- free(initrd);
- return 0;
- }
-
- efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
- ktime_to_us(ktime_get()));
-
- shutdown_barebox();
- linux_efi_handover(handle, boot_header);
-
- return 0;
-}
-
-static struct image_handler efi_handle_tr = {
- .name = "EFI Application",
- .bootm = do_bootm_efi,
- .filetype = filetype_exe,
-};
-
-static int efi_execute(struct binfmt_hook *b, char *file, int argc, char **argv)
-{
- return efi_execute_image(b->type, file);
+ return efi_execute_image(handle, loaded_image, b->type);
}
static struct binfmt_hook binfmt_efi_hook = {
@@ -352,13 +200,19 @@ static struct binfmt_hook binfmt_arm64_efi_hook = {
.hook = efi_execute,
};
+static struct binfmt_hook binfmt_x86_efi_hook = {
+ .type = filetype_x86_linux_image,
+ .hook = efi_execute,
+};
+
static int efi_register_image_handler(void)
{
- register_image_handler(&efi_handle_tr);
binfmt_register(&binfmt_efi_hook);
- if (IS_ENABLED(CONFIG_X86))
+ if (IS_ENABLED(CONFIG_X86)) {
register_image_handler(&non_efi_handle_linux_x86);
+ binfmt_register(&binfmt_x86_efi_hook);
+ }
if (IS_ENABLED(CONFIG_ARM64))
binfmt_register(&binfmt_arm64_efi_hook);
diff --git a/efi/payload/image.h b/efi/payload/image.h
new file mode 100644
index 000000000000..673b21db839a
--- /dev/null
+++ b/efi/payload/image.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __EFI_PAYLOAD_IMAGE_H__
+#define __EFI_PAYLOAD_IMAGE_H__
+
+#include <efi/types.h>
+
+int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
+ efi_handle_t *h);
+
+int efi_execute_image(efi_handle_t handle,
+ struct efi_loaded_image *loaded_image,
+ enum filetype filetype);
+
+#endif
--git a/efi/payload/setup_header.h b/efi/payload/setup_header.h
new file mode 100644
index 000000000000..4f094b844415
--- /dev/null
+++ b/efi/payload/setup_header.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __EFI_PAYLOAD_SETUP_HEADER_H__
+#define __EFI_PAYLOAD_SETUP_HEADER_H__
+
+#include <linux/types.h>
+
+struct x86_setup_header {
+ /* first sector of the image */
+ uint8_t code1[0x0020];
+ uint16_t cl_magic; /**< Magic number 0xA33F */
+ uint16_t cl_offset; /**< The offset of command line */
+ uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
+ uint8_t setup_sects; /**< The size of the setup in sectors */
+ uint16_t root_flags; /**< If the root is mounted readonly */
+ uint16_t syssize; /**< obsolete */
+ uint16_t swap_dev; /**< obsolete */
+ uint16_t ram_size; /**< obsolete */
+ uint16_t vid_mode; /**< Video mode control */
+ uint16_t root_dev; /**< Default root device number */
+ uint16_t boot_flag; /**< 0xAA55 magic number */
+
+ /* second sector of the image */
+ uint16_t jump; /**< Jump instruction (this is code!) */
+ uint32_t header; /**< Magic signature "HdrS" */
+ uint16_t version; /**< Boot protocol version supported */
+ uint32_t realmode_swtch; /**< Boot loader hook */
+ uint16_t start_sys; /**< The load-low segment (obsolete) */
+ uint16_t kernel_version; /**< Points to kernel version string */
+ uint8_t type_of_loader; /**< Boot loader identifier */
+ uint8_t loadflags; /**< Boot protocol option flags */
+ uint16_t setup_move_size; /**< Move to high memory size */
+ uint32_t code32_start; /**< Boot loader hook */
+ uint32_t ramdisk_image; /**< initrd load address */
+ uint32_t ramdisk_size; /**< initrd size */
+ uint32_t bootsect_kludge; /**< obsolete */
+ uint16_t heap_end_ptr; /**< Free memory after setup end */
+ uint8_t ext_loader_ver; /**< boot loader's extension of the version number */
+ uint8_t ext_loader_type; /**< boot loader's extension of its type */
+ uint32_t cmd_line_ptr; /**< Points to the kernel command line */
+ uint32_t initrd_addr_max; /**< Highest address for initrd */
+ uint32_t kernel_alignment; /**< Alignment unit required by the kernel */
+ uint8_t relocatable_kernel; /** */
+ uint8_t min_alignment; /** */
+ uint16_t xloadflags; /** */
+ uint32_t cmdline_size; /** */
+ uint32_t hardware_subarch; /** */
+ uint64_t hardware_subarch_data; /** */
+ uint32_t payload_offset; /** */
+ uint32_t payload_length; /** */
+ uint64_t setup_data; /** */
+ uint64_t pref_address; /** */
+ uint32_t init_size; /** */
+ uint32_t handover_offset; /** */
+} __attribute__ ((packed));
+
+static inline bool is_x86_setup_header(const void *base)
+{
+ const struct x86_setup_header *hdr = base;
+
+ return hdr->boot_flag == 0xAA55 && hdr->header == 0x53726448;
+}
+
+#endif
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 07/11] efi: payload: split image handling from legacy handover boot
2025-10-06 4:15 ` [PATCH 07/11] efi: payload: split image handling from legacy handover boot chalianis1
@ 2025-10-06 11:37 ` Ahmad Fatoum
0 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:37 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox, Ahmad Fatoum
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Chali Anis <chalianis1@gmail.com>
>
> The handover boot support is Linux-specific and can be disabled
> with CONFIG_EFI_HANDOVER_PROTOCOL. In preparation for adding a compliant
> boot method, move the handover-specific parts into their own file.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> efi/payload/Kconfig | 5 +
> efi/payload/Makefile | 1 +
> efi/payload/handover.c | 154 +++++++++++++++++++++++++++++
> efi/payload/image.c | 192 +++++--------------------------------
> efi/payload/image.h | 14 +++
> efi/payload/setup_header.h | 63 ++++++++++++
> 6 files changed, 260 insertions(+), 169 deletions(-)
> create mode 100644 efi/payload/handover.c
> create mode 100644 efi/payload/image.h
> create mode 100644 efi/payload/setup_header.h
>
> diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
> index a403acc81a93..d0a46704a6b9 100644
> --- a/efi/payload/Kconfig
> +++ b/efi/payload/Kconfig
> @@ -25,4 +25,9 @@ if EFI_PAYLOAD
> config EFI_STUB
> def_bool HAVE_EFI_STUB
>
> +config EFI_HANDOVER_PROTOCOL
> + bool "EFI Handover protocol"
> + default y
> + depends on X86
> +
> endif
> diff --git a/efi/payload/Makefile b/efi/payload/Makefile
> index 1250535302d3..d8b577bf3e23 100644
> --- a/efi/payload/Makefile
> +++ b/efi/payload/Makefile
> @@ -2,6 +2,7 @@
>
> obj-y += init.o
> obj-y += image.o
> +obj-$(CONFIG_EFI_HANDOVER_PROTOCOL) += handover.o
> obj-y += efi-initrd.o
> obj-$(CONFIG_OFTREE) += fdt.o
> bbenv-y += env-efi
> diff --git a/efi/payload/handover.c b/efi/payload/handover.c
> new file mode 100644
> index 000000000000..82f4cb4f5286
> --- /dev/null
> +++ b/efi/payload/handover.c
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * handover.c - legacy x86 EFI handover protocol
> + *
> + * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> + */
> +
> +#define pr_fmt(fmt) "efi-handover: " fmt
> +
> +#include <clock.h>
> +#include <common.h>
> +#include <linux/sizes.h>
> +#include <linux/ktime.h>
> +#include <memory.h>
> +#include <command.h>
> +#include <magicvar.h>
> +#include <init.h>
> +#include <driver.h>
> +#include <io.h>
> +#include <efi.h>
> +#include <malloc.h>
> +#include <string.h>
> +#include <linux/err.h>
> +#include <boot.h>
> +#include <bootm.h>
> +#include <fs.h>
> +#include <libfile.h>
> +#include <binfmt.h>
> +#include <wchar.h>
> +#include <efi/efi-payload.h>
> +#include <efi/efi-device.h>
> +
> +#include "image.h"
> +#include "setup_header.h"
> +
> +static int efi_do_execute_image(enum filetype filetype, const char *file)
> +{
> + efi_handle_t handle;
> + struct efi_loaded_image *loaded_image;
> + int ret;
> +
> + ret = efi_load_image(file, &loaded_image, &handle);
> + if (ret)
> + return ret;
> +
> + return efi_execute_image(handle, loaded_image, filetype);
> +}
> +
> +typedef void(*handover_fn)(void *image, struct efi_system_table *table,
> + struct x86_setup_header *header);
> +
> +static inline void linux_efi_handover(efi_handle_t handle,
> + struct x86_setup_header *header)
> +{
> + handover_fn handover;
> + uintptr_t addr;
> +
> + addr = header->code32_start + header->handover_offset;
> + if (IS_ENABLED(CONFIG_X86_64))
> + addr += 512;
> +
> + handover = efi_phys_to_virt(addr);
> + handover(handle, efi_sys_table, header);
> +}
> +
> +static int do_bootm_efi(struct image_data *data)
> +{
> + void *tmp;
> + void *initrd = NULL;
> + size_t size;
> + efi_handle_t handle;
> + int ret;
> + const char *options;
> + struct efi_loaded_image *loaded_image;
> + struct x86_setup_header *image_header, *boot_header;
> +
> + ret = efi_load_image(data->os_file, &loaded_image, &handle);
> + if (ret)
> + return ret;
> +
> + image_header = (struct x86_setup_header *)loaded_image->image_base;
> +
> + if (!is_x86_setup_header(image_header) ||
> + image_header->version < 0x20b ||
> + !image_header->relocatable_kernel) {
> + pr_err("Not a valid kernel image!\n");
> + BS->unload_image(handle);
> + return -EINVAL;
> + }
> +
> + boot_header = xmalloc(0x4000);
> + memset(boot_header, 0, 0x4000);
> + memcpy(boot_header, image_header, sizeof(*image_header));
> +
> + /* Refer to Linux kernel commit a27e292b8a54
> + * ("Documentation/x86/boot: Reserve type_of_loader=13 for barebox")
> + */
> + boot_header->type_of_loader = 0x13;
> +
> + if (data->initrd_file) {
> + tmp = read_file(data->initrd_file, &size);
> + initrd = xmemalign(PAGE_SIZE, PAGE_ALIGN(size));
> + memcpy(initrd, tmp, size);
> + memset(initrd + size, 0, PAGE_ALIGN(size) - size);
> + free(tmp);
> + boot_header->ramdisk_image = efi_virt_to_phys(initrd);
> + boot_header->ramdisk_size = PAGE_ALIGN(size);
> + }
> +
> + options = linux_bootargs_get();
> + if (options) {
> + boot_header->cmd_line_ptr = efi_virt_to_phys(options);
> + boot_header->cmdline_size = strlen(options);
> + }
> +
> + boot_header->code32_start = efi_virt_to_phys(loaded_image->image_base +
> + (image_header->setup_sects+1) * 512);
> +
> + if (bootm_verbose(data)) {
> + printf("\nStarting kernel at 0x%p", loaded_image->image_base);
> + if (data->initrd_file)
> + printf(", initrd at 0x%08x",
> + boot_header->ramdisk_image);
> + printf("...\n");
> + }
> +
> + if (data->dryrun) {
> + BS->unload_image(handle);
> + free(boot_header);
> + free(initrd);
> + return 0;
> + }
> +
> + efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
> + ktime_to_us(ktime_get()));
> +
> + shutdown_barebox();
> + linux_efi_handover(handle, boot_header);
> +
> + return 0;
> +}
> +
> +static struct image_handler efi_handle_tr = {
> + .name = "EFI Application",
> + .bootm = do_bootm_efi,
> + .filetype = filetype_exe,
> +};
> +
> +static int efi_register_handover_handler(void)
> +{
> + register_image_handler(&efi_handle_tr);
> + return 0;
> +}
> +late_efi_initcall(efi_register_handover_handler);
> diff --git a/efi/payload/image.c b/efi/payload/image.c
> index 33c5e18dac27..ae7678188d84 100644
> --- a/efi/payload/image.c
> +++ b/efi/payload/image.c
> @@ -5,13 +5,12 @@
> * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> */
>
> +#define pr_fmt(fmt) "efi-image: " fmt
> +
> #include <clock.h>
> #include <common.h>
> #include <linux/sizes.h>
> -#include <linux/ktime.h>
> #include <memory.h>
> -#include <command.h>
> -#include <magicvar.h>
> #include <init.h>
> #include <driver.h>
> #include <io.h>
> @@ -19,7 +18,7 @@
> #include <malloc.h>
> #include <string.h>
> #include <linux/err.h>
> -#include <boot.h>
> +#include <bootargs.h>
> #include <bootm.h>
> #include <fs.h>
> #include <libfile.h>
> @@ -28,54 +27,8 @@
> #include <efi/efi-payload.h>
> #include <efi/efi-device.h>
>
> -struct linux_kernel_header {
> - /* first sector of the image */
> - uint8_t code1[0x0020];
> - uint16_t cl_magic; /**< Magic number 0xA33F */
> - uint16_t cl_offset; /**< The offset of command line */
> - uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
> - uint8_t setup_sects; /**< The size of the setup in sectors */
> - uint16_t root_flags; /**< If the root is mounted readonly */
> - uint16_t syssize; /**< obsolete */
> - uint16_t swap_dev; /**< obsolete */
> - uint16_t ram_size; /**< obsolete */
> - uint16_t vid_mode; /**< Video mode control */
> - uint16_t root_dev; /**< Default root device number */
> - uint16_t boot_flag; /**< 0xAA55 magic number */
> -
> - /* second sector of the image */
> - uint16_t jump; /**< Jump instruction (this is code!) */
> - uint32_t header; /**< Magic signature "HdrS" */
> - uint16_t version; /**< Boot protocol version supported */
> - uint32_t realmode_swtch; /**< Boot loader hook */
> - uint16_t start_sys; /**< The load-low segment (obsolete) */
> - uint16_t kernel_version; /**< Points to kernel version string */
> - uint8_t type_of_loader; /**< Boot loader identifier */
> - uint8_t loadflags; /**< Boot protocol option flags */
> - uint16_t setup_move_size; /**< Move to high memory size */
> - uint32_t code32_start; /**< Boot loader hook */
> - uint32_t ramdisk_image; /**< initrd load address */
> - uint32_t ramdisk_size; /**< initrd size */
> - uint32_t bootsect_kludge; /**< obsolete */
> - uint16_t heap_end_ptr; /**< Free memory after setup end */
> - uint8_t ext_loader_ver; /**< boot loader's extension of the version number */
> - uint8_t ext_loader_type; /**< boot loader's extension of its type */
> - uint32_t cmd_line_ptr; /**< Points to the kernel command line */
> - uint32_t initrd_addr_max; /**< Highest address for initrd */
> - uint32_t kernel_alignment; /**< Alignment unit required by the kernel */
> - uint8_t relocatable_kernel; /** */
> - uint8_t min_alignment; /** */
> - uint16_t xloadflags; /** */
> - uint32_t cmdline_size; /** */
> - uint32_t hardware_subarch; /** */
> - uint64_t hardware_subarch_data; /** */
> - uint32_t payload_offset; /** */
> - uint32_t payload_length; /** */
> - uint64_t setup_data; /** */
> - uint64_t pref_address; /** */
> - uint32_t init_size; /** */
> - uint32_t handover_offset; /** */
> -} __attribute__ ((packed));
> +#include "image.h"
> +#include "setup_header.h"
>
> static void *efi_read_file(const char *file, size_t *size)
> {
> @@ -85,10 +38,6 @@ static void *efi_read_file(const char *file, size_t *size)
> char *buf;
> ssize_t ret;
>
> - buf = read_file(file, size);
> - if (buf || errno != ENOMEM)
> - return buf;
> -
> ret = stat(file, &s);
> if (ret)
> return NULL;
> @@ -122,8 +71,8 @@ static void efi_free_file(void *_mem, size_t size)
> BS->free_pages(mem, DIV_ROUND_UP(size, EFI_PAGE_SIZE));
> }
>
> -static int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
> - efi_handle_t *h)
> +int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
> + efi_handle_t *h)
> {
> void *exe;
> size_t size;
> @@ -158,10 +107,7 @@ static int efi_load_image(const char *file, struct efi_loaded_image **loaded_ima
>
> static bool is_linux_image(enum filetype filetype, const void *base)
> {
> - const struct linux_kernel_header *hdr = base;
> -
> - if (IS_ENABLED(CONFIG_X86) &&
> - hdr->boot_flag == 0xAA55 && hdr->header == 0x53726448)
> + if (IS_ENABLED(CONFIG_X86) && is_x86_setup_header(base))
> return true;
>
> if (IS_ENABLED(CONFIG_ARM64) &&
> @@ -171,18 +117,13 @@ static bool is_linux_image(enum filetype filetype, const void *base)
> return false;
> }
>
> -static int efi_execute_image(enum filetype filetype, const char *file)
> +int efi_execute_image(efi_handle_t handle,
> + struct efi_loaded_image *loaded_image,
> + enum filetype filetype)
> {
> - efi_handle_t handle;
> - struct efi_loaded_image *loaded_image;
> efi_status_t efiret;
> const char *options;
> bool is_driver;
> - int ret;
> -
> - ret = efi_load_image(file, &loaded_image, &handle);
> - if (ret)
> - return ret;
>
> is_driver = (loaded_image->image_code_type == EFI_BOOT_SERVICES_CODE) ||
> (loaded_image->image_code_type == EFI_RUNTIME_SERVICES_CODE);
> @@ -216,110 +157,17 @@ static int efi_execute_image(enum filetype filetype, const char *file)
> return -efi_errno(efiret);
> }
>
> -typedef void(*handover_fn)(void *image, struct efi_system_table *table,
> - struct linux_kernel_header *header);
> -
> -static inline void linux_efi_handover(efi_handle_t handle,
> - struct linux_kernel_header *header)
> -{
> - handover_fn handover;
> - uintptr_t addr;
> -
> - addr = header->code32_start + header->handover_offset;
> - if (IS_ENABLED(CONFIG_X86_64))
> - addr += 512;
> -
> - handover = efi_phys_to_virt(addr);
> - handover(handle, efi_sys_table, header);
> -}
> -
> -static int do_bootm_efi(struct image_data *data)
> +static int efi_execute(struct binfmt_hook *b, char *file, int argc, char **argv)
> {
> - void *tmp;
> - void *initrd = NULL;
> - size_t size;
> + struct efi_loaded_image *loaded_image;
> efi_handle_t handle;
> int ret;
> - const char *options;
> - struct efi_loaded_image *loaded_image;
> - struct linux_kernel_header *image_header, *boot_header;
>
> - ret = efi_load_image(data->os_file, &loaded_image, &handle);
> + ret = efi_load_image(file, &loaded_image, &handle);
> if (ret)
> return ret;
>
> - image_header = (struct linux_kernel_header *)loaded_image->image_base;
> -
> - if (image_header->boot_flag != 0xAA55 ||
> - image_header->header != 0x53726448 ||
> - image_header->version < 0x20b ||
> - !image_header->relocatable_kernel) {
> - pr_err("Not a valid kernel image!\n");
> - BS->unload_image(handle);
> - return -EINVAL;
> - }
> -
> - boot_header = xmalloc(0x4000);
> - memset(boot_header, 0, 0x4000);
> - memcpy(boot_header, image_header, sizeof(*image_header));
> -
> - /* Refer to Linux kernel commit a27e292b8a54
> - * ("Documentation/x86/boot: Reserve type_of_loader=13 for barebox")
> - */
> - boot_header->type_of_loader = 0x13;
> -
> - if (data->initrd_file) {
> - tmp = read_file(data->initrd_file, &size);
> - initrd = xmemalign(PAGE_SIZE, PAGE_ALIGN(size));
> - memcpy(initrd, tmp, size);
> - memset(initrd + size, 0, PAGE_ALIGN(size) - size);
> - free(tmp);
> - boot_header->ramdisk_image = efi_virt_to_phys(initrd);
> - boot_header->ramdisk_size = PAGE_ALIGN(size);
> - }
> -
> - options = linux_bootargs_get();
> - if (options) {
> - boot_header->cmd_line_ptr = efi_virt_to_phys(options);
> - boot_header->cmdline_size = strlen(options);
> - }
> -
> - boot_header->code32_start = efi_virt_to_phys(loaded_image->image_base +
> - (image_header->setup_sects+1) * 512);
> -
> - if (bootm_verbose(data)) {
> - printf("\nStarting kernel at 0x%p", loaded_image->image_base);
> - if (data->initrd_file)
> - printf(", initrd at 0x%08x",
> - boot_header->ramdisk_image);
> - printf("...\n");
> - }
> -
> - if (data->dryrun) {
> - BS->unload_image(handle);
> - free(boot_header);
> - free(initrd);
> - return 0;
> - }
> -
> - efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid,
> - ktime_to_us(ktime_get()));
> -
> - shutdown_barebox();
> - linux_efi_handover(handle, boot_header);
> -
> - return 0;
> -}
> -
> -static struct image_handler efi_handle_tr = {
> - .name = "EFI Application",
> - .bootm = do_bootm_efi,
> - .filetype = filetype_exe,
> -};
> -
> -static int efi_execute(struct binfmt_hook *b, char *file, int argc, char **argv)
> -{
> - return efi_execute_image(b->type, file);
> + return efi_execute_image(handle, loaded_image, b->type);
> }
>
> static struct binfmt_hook binfmt_efi_hook = {
> @@ -352,13 +200,19 @@ static struct binfmt_hook binfmt_arm64_efi_hook = {
> .hook = efi_execute,
> };
>
> +static struct binfmt_hook binfmt_x86_efi_hook = {
> + .type = filetype_x86_linux_image,
> + .hook = efi_execute,
> +};
> +
> static int efi_register_image_handler(void)
> {
> - register_image_handler(&efi_handle_tr);
> binfmt_register(&binfmt_efi_hook);
>
> - if (IS_ENABLED(CONFIG_X86))
> + if (IS_ENABLED(CONFIG_X86)) {
> register_image_handler(&non_efi_handle_linux_x86);
> + binfmt_register(&binfmt_x86_efi_hook);
> + }
>
> if (IS_ENABLED(CONFIG_ARM64))
> binfmt_register(&binfmt_arm64_efi_hook);
> diff --git a/efi/payload/image.h b/efi/payload/image.h
> new file mode 100644
> index 000000000000..673b21db839a
> --- /dev/null
> +++ b/efi/payload/image.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __EFI_PAYLOAD_IMAGE_H__
> +#define __EFI_PAYLOAD_IMAGE_H__
> +
> +#include <efi/types.h>
> +
> +int efi_load_image(const char *file, struct efi_loaded_image **loaded_image,
> + efi_handle_t *h);
> +
> +int efi_execute_image(efi_handle_t handle,
> + struct efi_loaded_image *loaded_image,
> + enum filetype filetype);
> +
> +#endif
> diff --git a/efi/payload/setup_header.h b/efi/payload/setup_header.h
> new file mode 100644
> index 000000000000..4f094b844415
> --- /dev/null
> +++ b/efi/payload/setup_header.h
> @@ -0,0 +1,63 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __EFI_PAYLOAD_SETUP_HEADER_H__
> +#define __EFI_PAYLOAD_SETUP_HEADER_H__
> +
> +#include <linux/types.h>
> +
> +struct x86_setup_header {
> + /* first sector of the image */
> + uint8_t code1[0x0020];
> + uint16_t cl_magic; /**< Magic number 0xA33F */
> + uint16_t cl_offset; /**< The offset of command line */
> + uint8_t code2[0x01F1 - 0x0020 - 2 - 2];
> + uint8_t setup_sects; /**< The size of the setup in sectors */
> + uint16_t root_flags; /**< If the root is mounted readonly */
> + uint16_t syssize; /**< obsolete */
> + uint16_t swap_dev; /**< obsolete */
> + uint16_t ram_size; /**< obsolete */
> + uint16_t vid_mode; /**< Video mode control */
> + uint16_t root_dev; /**< Default root device number */
> + uint16_t boot_flag; /**< 0xAA55 magic number */
> +
> + /* second sector of the image */
> + uint16_t jump; /**< Jump instruction (this is code!) */
> + uint32_t header; /**< Magic signature "HdrS" */
> + uint16_t version; /**< Boot protocol version supported */
> + uint32_t realmode_swtch; /**< Boot loader hook */
> + uint16_t start_sys; /**< The load-low segment (obsolete) */
> + uint16_t kernel_version; /**< Points to kernel version string */
> + uint8_t type_of_loader; /**< Boot loader identifier */
> + uint8_t loadflags; /**< Boot protocol option flags */
> + uint16_t setup_move_size; /**< Move to high memory size */
> + uint32_t code32_start; /**< Boot loader hook */
> + uint32_t ramdisk_image; /**< initrd load address */
> + uint32_t ramdisk_size; /**< initrd size */
> + uint32_t bootsect_kludge; /**< obsolete */
> + uint16_t heap_end_ptr; /**< Free memory after setup end */
> + uint8_t ext_loader_ver; /**< boot loader's extension of the version number */
> + uint8_t ext_loader_type; /**< boot loader's extension of its type */
> + uint32_t cmd_line_ptr; /**< Points to the kernel command line */
> + uint32_t initrd_addr_max; /**< Highest address for initrd */
> + uint32_t kernel_alignment; /**< Alignment unit required by the kernel */
> + uint8_t relocatable_kernel; /** */
> + uint8_t min_alignment; /** */
> + uint16_t xloadflags; /** */
> + uint32_t cmdline_size; /** */
> + uint32_t hardware_subarch; /** */
> + uint64_t hardware_subarch_data; /** */
> + uint32_t payload_offset; /** */
> + uint32_t payload_length; /** */
> + uint64_t setup_data; /** */
> + uint64_t pref_address; /** */
> + uint32_t init_size; /** */
> + uint32_t handover_offset; /** */
> +} __attribute__ ((packed));
> +
> +static inline bool is_x86_setup_header(const void *base)
> +{
> + const struct x86_setup_header *hdr = base;
> +
> + return hdr->boot_flag == 0xAA55 && hdr->header == 0x53726448;
> +}
> +
> +#endif
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 08/11] efi: payload: bootm: add support for efi stub boot
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (5 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 07/11] efi: payload: split image handling from legacy handover boot chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 11:40 ` Ahmad Fatoum
2025-10-06 4:15 ` [PATCH 09/11] efi: payload: bootm: add support for fit image chalianis1
` (3 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Chali Anis
From: Chali Anis <chalianis1@gmail.com>
Introduce support for booting Linux kernels with an EFI stub from the
barebox EFI payload. This includes:
- Loading the kernel image via EFI LoadImage/StartImage
- Installing the FDT into the EFI configuration table unless
EFI_FDT_FORCE is enabled
- Providing the initrd either through the Initrd Media GUID or
the initrd media protocol
- Registering image handlers for EFI applications, x86/ARM64 EFI
Linux kernels, and a fallback handler for non-EFI x86 Linux images
- Adding Kconfig options to control FDT forcing and initrd installation
This enables barebox EFI payloads to directly boot Linux kernels with
EFI stubs in a way compatible with the Linux EFI boot flow.
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
efi/payload/Kconfig | 6 +-
efi/payload/Makefile | 1 +
efi/payload/bootm.c | 219 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 225 insertions(+), 1 deletion(-)
create mode 100644 efi/payload/bootm.c
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
index d0a46704a6b9..e3a6a72d6a1c 100644
--- a/efi/payload/Kconfig
+++ b/efi/payload/Kconfig
@@ -27,7 +27,11 @@ config EFI_STUB
config EFI_HANDOVER_PROTOCOL
bool "EFI Handover protocol"
- default y
+ depends on !EFI_PAYLOAD_BOOTM
depends on X86
+config EFI_PAYLOAD_BOOTM
+ bool "EFI bootm protocol"
+ default !X86
+
endif
diff --git a/efi/payload/Makefile b/efi/payload/Makefile
index d8b577bf3e23..083728c53cb4 100644
--- a/efi/payload/Makefile
+++ b/efi/payload/Makefile
@@ -3,6 +3,7 @@
obj-y += init.o
obj-y += image.o
obj-$(CONFIG_EFI_HANDOVER_PROTOCOL) += handover.o
+obj-$(CONFIG_EFI_PAYLOAD_BOOTM) += bootm.o
obj-y += efi-initrd.o
obj-$(CONFIG_OFTREE) += fdt.o
bbenv-y += env-efi
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
new file mode 100644
index 000000000000..d0e995be5d7c
--- /dev/null
+++ b/efi/payload/bootm.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * image.c - barebox EFI payload support
+ *
+ * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ */
+
+#define pr_fmt(fmt) "efi-bootm: " fmt
+
+#include <clock.h>
+#include <common.h>
+#include <linux/sizes.h>
+#include <linux/ktime.h>
+#include <memory.h>
+#include <command.h>
+#include <magicvar.h>
+#include <init.h>
+#include <driver.h>
+#include <io.h>
+#include <efi.h>
+#include <malloc.h>
+#include <string.h>
+#include <linux/err.h>
+#include <boot.h>
+#include <bootm.h>
+#include <fs.h>
+#include <libfile.h>
+#include <binfmt.h>
+#include <wchar.h>
+#include <image-fit.h>
+#include <efi/efi-payload.h>
+#include <efi/efi-device.h>
+
+#include "image.h"
+#include "setup_header.h"
+
+static int efi_load_os(struct image_data *data,
+ struct efi_loaded_image **loaded_image,
+ efi_handle_t *handle)
+{
+ return efi_load_image(data->os_file, loaded_image, handle);
+}
+
+static int efi_load_ramdisk(struct image_data *data, void **initrd)
+{
+ unsigned long initrd_size;
+ void *initrd_mem;
+ int ret;
+
+ if (!data->initrd_file)
+ return 0;
+
+ pr_info("Loading ramdisk from '%s'\n", data->initrd_file);
+
+ initrd_mem = read_file(data->initrd_file, &initrd_size);
+ if (!initrd_mem) {
+ ret = -errno;
+ pr_err("Failed to read initrd from file '%s': %m\n",
+ data->initrd_file);
+ return ret;
+ }
+
+ ret = efi_initrd_register(initrd_mem, initrd_size);
+ if (ret) {
+ pr_err("Failed to register initrd: %pe\n", ERR_PTR(ret));
+ goto free_mem;
+ }
+
+ *initrd = initrd_mem;
+
+ return 0;
+
+free_mem:
+ free(initrd);
+
+ return ret;
+}
+
+static int efi_load_fdt(struct image_data *data, void **fdt)
+{
+ efi_physical_addr_t mem;
+ efi_status_t efiret;
+ void *of_tree, *vmem;
+ unsigned long of_size;
+ int ret;
+
+ if (!data->oftree_file)
+ return 0;
+
+ pr_info("Loading devicetree from '%s'\n", data->oftree_file);
+
+ of_tree = read_file(data->oftree_file, &of_size);
+ if (!of_tree) {
+ ret = -errno;
+ pr_err("Failed to read oftree: %m\n");
+ return ret;
+ }
+
+ efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+ EFI_ACPI_RECLAIM_MEMORY,
+ DIV_ROUND_UP(SZ_2M, EFI_PAGE_SIZE), &mem);
+ if (EFI_ERROR(efiret)) {
+ pr_err("Failed to allocate pages for FDT: %s\n", efi_strerror(efiret));
+ goto free_mem;
+ }
+
+ vmem = efi_phys_to_virt(mem);
+ memcpy(vmem, of_tree, of_size);
+
+ efiret = BS->install_configuration_table(&efi_fdt_guid, vmem);
+ if (EFI_ERROR(efiret)) {
+ pr_err("Failed to install FDT: %s\n", efi_strerror(efiret));
+ goto free_efi_mem;
+ }
+
+ *fdt = vmem;
+ return 0;
+
+free_efi_mem:
+ BS->free_pages(mem, DIV_ROUND_UP(SZ_2M, EFI_PAGE_SIZE));
+free_mem:
+ free(of_tree);
+ return -efi_errno(efiret);
+}
+
+static void efi_unload_fdt(void *fdt)
+{
+ if (!fdt)
+ return;
+
+ BS->install_configuration_table(&efi_fdt_guid, NULL);
+ BS->free_pages(efi_virt_to_phys(fdt), SZ_2M);
+}
+
+static int do_bootm_efi_stub(struct image_data *data)
+{
+ struct efi_loaded_image *loaded_image;
+ void *fdt = NULL, *initrd = NULL;
+ efi_handle_t handle;
+ enum filetype type;
+ int ret;
+
+ ret = efi_load_os(data, &loaded_image, &handle);
+ if (ret)
+ return ret;
+
+ ret = efi_load_fdt(data, &fdt);
+ if (ret)
+ goto unload_os;
+
+ ret = efi_load_ramdisk(data, &initrd);
+ if (ret)
+ goto unload_oftree;
+
+ type = file_detect_type(loaded_image->image_base, PAGE_SIZE);
+ ret = efi_execute_image(handle, loaded_image, type);
+ if (ret)
+ goto unload_ramdisk;
+
+ return 0;
+
+unload_ramdisk:
+ if (initrd)
+ efi_initrd_unregister();
+unload_oftree:
+ efi_unload_fdt(fdt);
+unload_os:
+ BS->unload_image(handle);
+
+ return ret;
+}
+
+static int efi_app_execute(struct image_data *data)
+{
+ struct efi_loaded_image *loaded_image;
+ efi_handle_t handle;
+ enum filetype type;
+ int ret;
+
+ ret = efi_load_image(data->os_file, &loaded_image, &handle);
+ if (ret)
+ return ret;
+
+ type = file_detect_type(loaded_image->image_base, PAGE_SIZE);
+
+ return efi_execute_image(handle, loaded_image, type);
+}
+
+static struct image_handler efi_app_handle_tr = {
+ .name = "EFI Application",
+ .bootm = efi_app_execute,
+ .filetype = filetype_exe,
+};
+
+static struct image_handler efi_x86_linux_handle_tr = {
+ .name = "EFI X86 Linux kernel",
+ .bootm = do_bootm_efi_stub,
+ .filetype = filetype_x86_linux_image,
+};
+
+static struct image_handler efi_arm64_handle_tr = {
+ .name = "EFI ARM64 Linux kernel",
+ .bootm = do_bootm_efi_stub,
+ .filetype = filetype_arm64_efi_linux_image,
+};
+
+static int efi_register_bootm_handler(void)
+{
+ register_image_handler(&efi_app_handle_tr);
+
+ if (IS_ENABLED(CONFIG_X86))
+ register_image_handler(&efi_x86_linux_handle_tr);
+
+ if (IS_ENABLED(CONFIG_ARM64))
+ register_image_handler(&efi_arm64_handle_tr);
+
+ return 0;
+}
+late_efi_initcall(efi_register_bootm_handler);
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 08/11] efi: payload: bootm: add support for efi stub boot
2025-10-06 4:15 ` [PATCH 08/11] efi: payload: bootm: add support for efi stub boot chalianis1
@ 2025-10-06 11:40 ` Ahmad Fatoum
0 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:40 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Chali Anis <chalianis1@gmail.com>
>
> Introduce support for booting Linux kernels with an EFI stub from the
> barebox EFI payload. This includes:
>
> - Loading the kernel image via EFI LoadImage/StartImage
> - Installing the FDT into the EFI configuration table unless
> EFI_FDT_FORCE is enabled
> - Providing the initrd either through the Initrd Media GUID or
> the initrd media protocol
> - Registering image handlers for EFI applications, x86/ARM64 EFI
> Linux kernels, and a fallback handler for non-EFI x86 Linux images
> - Adding Kconfig options to control FDT forcing and initrd installation
>
> This enables barebox EFI payloads to directly boot Linux kernels with
> EFI stubs in a way compatible with the Linux EFI boot flow.
>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> efi/payload/Kconfig | 6 +-
> efi/payload/Makefile | 1 +
> efi/payload/bootm.c | 219 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 225 insertions(+), 1 deletion(-)
> create mode 100644 efi/payload/bootm.c
>
> diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
> index d0a46704a6b9..e3a6a72d6a1c 100644
> --- a/efi/payload/Kconfig
> +++ b/efi/payload/Kconfig
> @@ -27,7 +27,11 @@ config EFI_STUB
>
> config EFI_HANDOVER_PROTOCOL
> bool "EFI Handover protocol"
> - default y
> + depends on !EFI_PAYLOAD_BOOTM
> depends on X86
>
> +config EFI_PAYLOAD_BOOTM
> + bool "EFI bootm protocol"
> + default !X86
> +
> endif
> diff --git a/efi/payload/Makefile b/efi/payload/Makefile
> index d8b577bf3e23..083728c53cb4 100644
> --- a/efi/payload/Makefile
> +++ b/efi/payload/Makefile
> @@ -3,6 +3,7 @@
> obj-y += init.o
> obj-y += image.o
> obj-$(CONFIG_EFI_HANDOVER_PROTOCOL) += handover.o
> +obj-$(CONFIG_EFI_PAYLOAD_BOOTM) += bootm.o
> obj-y += efi-initrd.o
> obj-$(CONFIG_OFTREE) += fdt.o
> bbenv-y += env-efi
> diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
> new file mode 100644
> index 000000000000..d0e995be5d7c
> --- /dev/null
> +++ b/efi/payload/bootm.c
> @@ -0,0 +1,219 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * image.c - barebox EFI payload support
> + *
> + * Copyright (c) 2014 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
> + */
> +
> +#define pr_fmt(fmt) "efi-bootm: " fmt
> +
> +#include <clock.h>
> +#include <common.h>
> +#include <linux/sizes.h>
> +#include <linux/ktime.h>
> +#include <memory.h>
> +#include <command.h>
> +#include <magicvar.h>
> +#include <init.h>
> +#include <driver.h>
> +#include <io.h>
> +#include <efi.h>
> +#include <malloc.h>
> +#include <string.h>
> +#include <linux/err.h>
> +#include <boot.h>
> +#include <bootm.h>
> +#include <fs.h>
> +#include <libfile.h>
> +#include <binfmt.h>
> +#include <wchar.h>
> +#include <image-fit.h>
> +#include <efi/efi-payload.h>
> +#include <efi/efi-device.h>
> +
> +#include "image.h"
> +#include "setup_header.h"
> +
> +static int efi_load_os(struct image_data *data,
> + struct efi_loaded_image **loaded_image,
> + efi_handle_t *handle)
> +{
> + return efi_load_image(data->os_file, loaded_image, handle);
> +}
> +
> +static int efi_load_ramdisk(struct image_data *data, void **initrd)
> +{
> + unsigned long initrd_size;
> + void *initrd_mem;
> + int ret;
> +
> + if (!data->initrd_file)
> + return 0;
> +
> + pr_info("Loading ramdisk from '%s'\n", data->initrd_file);
> +
> + initrd_mem = read_file(data->initrd_file, &initrd_size);
> + if (!initrd_mem) {
> + ret = -errno;
> + pr_err("Failed to read initrd from file '%s': %m\n",
> + data->initrd_file);
> + return ret;
> + }
> +
> + ret = efi_initrd_register(initrd_mem, initrd_size);
> + if (ret) {
> + pr_err("Failed to register initrd: %pe\n", ERR_PTR(ret));
> + goto free_mem;
> + }
> +
> + *initrd = initrd_mem;
> +
> + return 0;
> +
> +free_mem:
> + free(initrd);
> +
> + return ret;
> +}
> +
> +static int efi_load_fdt(struct image_data *data, void **fdt)
> +{
> + efi_physical_addr_t mem;
> + efi_status_t efiret;
> + void *of_tree, *vmem;
> + unsigned long of_size;
> + int ret;
> +
> + if (!data->oftree_file)
> + return 0;
> +
> + pr_info("Loading devicetree from '%s'\n", data->oftree_file);
> +
> + of_tree = read_file(data->oftree_file, &of_size);
> + if (!of_tree) {
> + ret = -errno;
> + pr_err("Failed to read oftree: %m\n");
> + return ret;
> + }
> +
> + efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
> + EFI_ACPI_RECLAIM_MEMORY,
> + DIV_ROUND_UP(SZ_2M, EFI_PAGE_SIZE), &mem);
> + if (EFI_ERROR(efiret)) {
> + pr_err("Failed to allocate pages for FDT: %s\n", efi_strerror(efiret));
> + goto free_mem;
> + }
> +
> + vmem = efi_phys_to_virt(mem);
> + memcpy(vmem, of_tree, of_size);
> +
> + efiret = BS->install_configuration_table(&efi_fdt_guid, vmem);
> + if (EFI_ERROR(efiret)) {
> + pr_err("Failed to install FDT: %s\n", efi_strerror(efiret));
> + goto free_efi_mem;
> + }
> +
> + *fdt = vmem;
> + return 0;
> +
> +free_efi_mem:
> + BS->free_pages(mem, DIV_ROUND_UP(SZ_2M, EFI_PAGE_SIZE));
> +free_mem:
> + free(of_tree);
> + return -efi_errno(efiret);
> +}
> +
> +static void efi_unload_fdt(void *fdt)
> +{
> + if (!fdt)
> + return;
> +
> + BS->install_configuration_table(&efi_fdt_guid, NULL);
> + BS->free_pages(efi_virt_to_phys(fdt), SZ_2M);
> +}
> +
> +static int do_bootm_efi_stub(struct image_data *data)
> +{
> + struct efi_loaded_image *loaded_image;
> + void *fdt = NULL, *initrd = NULL;
> + efi_handle_t handle;
> + enum filetype type;
> + int ret;
> +
> + ret = efi_load_os(data, &loaded_image, &handle);
> + if (ret)
> + return ret;
> +
> + ret = efi_load_fdt(data, &fdt);
> + if (ret)
> + goto unload_os;
> +
> + ret = efi_load_ramdisk(data, &initrd);
> + if (ret)
> + goto unload_oftree;
> +
> + type = file_detect_type(loaded_image->image_base, PAGE_SIZE);
> + ret = efi_execute_image(handle, loaded_image, type);
> + if (ret)
> + goto unload_ramdisk;
> +
> + return 0;
> +
> +unload_ramdisk:
> + if (initrd)
> + efi_initrd_unregister();
> +unload_oftree:
> + efi_unload_fdt(fdt);
> +unload_os:
> + BS->unload_image(handle);
> +
> + return ret;
> +}
> +
> +static int efi_app_execute(struct image_data *data)
> +{
> + struct efi_loaded_image *loaded_image;
> + efi_handle_t handle;
> + enum filetype type;
> + int ret;
> +
> + ret = efi_load_image(data->os_file, &loaded_image, &handle);
> + if (ret)
> + return ret;
> +
> + type = file_detect_type(loaded_image->image_base, PAGE_SIZE);
> +
> + return efi_execute_image(handle, loaded_image, type);
> +}
> +
> +static struct image_handler efi_app_handle_tr = {
> + .name = "EFI Application",
> + .bootm = efi_app_execute,
> + .filetype = filetype_exe,
> +};
> +
> +static struct image_handler efi_x86_linux_handle_tr = {
> + .name = "EFI X86 Linux kernel",
> + .bootm = do_bootm_efi_stub,
> + .filetype = filetype_x86_linux_image,
> +};
> +
> +static struct image_handler efi_arm64_handle_tr = {
> + .name = "EFI ARM64 Linux kernel",
> + .bootm = do_bootm_efi_stub,
> + .filetype = filetype_arm64_efi_linux_image,
> +};
> +
> +static int efi_register_bootm_handler(void)
> +{
> + register_image_handler(&efi_app_handle_tr);
> +
> + if (IS_ENABLED(CONFIG_X86))
> + register_image_handler(&efi_x86_linux_handle_tr);
> +
> + if (IS_ENABLED(CONFIG_ARM64))
> + register_image_handler(&efi_arm64_handle_tr);
> +
> + return 0;
> +}
> +late_efi_initcall(efi_register_bootm_handler);
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 09/11] efi: payload: bootm: add support for fit image
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (6 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 08/11] efi: payload: bootm: add support for efi stub boot chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 11:41 ` Ahmad Fatoum
2025-10-06 4:15 ` [PATCH 10/11] efi: payload: make selectable without COMPILE_TEST chalianis1
` (2 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Ahmad Fatoum, Chali Anis
From: Ahmad Fatoum <a.fatoum@barebox.org>
Extend the EFI payload boot flow to support loading kernel, initrd,
and devicetree directly from a FIT image. When a FIT is present,
the loader extracts the relevant subimages ("kernel", "ramdisk",
and "fdt") also support falling back to external files when possible.
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
efi/payload/Kconfig | 1 +
efi/payload/bootm.c | 125 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 104 insertions(+), 22 deletions(-)
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
index e3a6a72d6a1c..4fb866210a69 100644
--- a/efi/payload/Kconfig
+++ b/efi/payload/Kconfig
@@ -32,6 +32,7 @@ config EFI_HANDOVER_PROTOCOL
config EFI_PAYLOAD_BOOTM
bool "EFI bootm protocol"
+ select BOOTM_FITIMAGE
default !X86
endif
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
index d0e995be5d7c..3e9ccd42bf7f 100644
--- a/efi/payload/bootm.c
+++ b/efi/payload/bootm.c
@@ -34,11 +34,74 @@
#include "image.h"
#include "setup_header.h"
+static bool ramdisk_is_fit(struct image_data *data)
+{
+ struct stat st;
+
+ if (bootm_signed_images_are_forced())
+ return true;
+
+ if (data->initrd_file) {
+ if (!stat(data->initrd_file, &st) && st.st_size > 0)
+ return false;
+ }
+
+ return data->os_fit ? fit_has_image(data->os_fit,
+ data->fit_config, "ramdisk") > 0 : false;
+}
+
+static bool fdt_is_fit(struct image_data *data)
+{
+ struct stat st;
+
+ if (bootm_signed_images_are_forced())
+ return true;
+
+ if (data->oftree_file) {
+ if (!stat(data->oftree_file, &st) && st.st_size > 0)
+ return false;
+ }
+
+ return data->os_fit ? fit_has_image(data->os_fit,
+ data->fit_config, "fdt") > 0 : false;
+}
+
static int efi_load_os(struct image_data *data,
struct efi_loaded_image **loaded_image,
efi_handle_t *handle)
{
- return efi_load_image(data->os_file, loaded_image, handle);
+ efi_status_t efiret;
+ efi_handle_t h;
+
+ if (!data->os_fit)
+ return efi_load_image(data->os_file, loaded_image, handle);
+
+ if (!data->fit_kernel)
+ return -ENOENT;
+
+ efiret = BS->load_image(false, efi_parent_image, efi_device_path,
+ (void *)data->fit_kernel, data->fit_kernel_size, &h);
+ if (EFI_ERROR(efiret)) {
+ pr_err("failed to LoadImage: %s\n", efi_strerror(efiret));
+ goto out_mem;
+ };
+
+ efiret = BS->open_protocol(h, &efi_loaded_image_protocol_guid,
+ (void **)loaded_image, efi_parent_image,
+ NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(efiret)) {
+ pr_err("failed to OpenProtocol: %s\n", efi_strerror(efiret));
+ goto out_unload;
+ }
+
+ *handle = h;
+
+ return 0;
+
+out_unload:
+ BS->unload_image(h);
+out_mem:
+ return -efi_errno(efiret);
}
static int efi_load_ramdisk(struct image_data *data, void **initrd)
@@ -47,17 +110,26 @@ static int efi_load_ramdisk(struct image_data *data, void **initrd)
void *initrd_mem;
int ret;
- if (!data->initrd_file)
- return 0;
-
- pr_info("Loading ramdisk from '%s'\n", data->initrd_file);
-
- initrd_mem = read_file(data->initrd_file, &initrd_size);
- if (!initrd_mem) {
- ret = -errno;
- pr_err("Failed to read initrd from file '%s': %m\n",
- data->initrd_file);
- return ret;
+ if (ramdisk_is_fit(data)) {
+ ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
+ (const void **)&initrd_mem, &initrd_size);
+ if (ret) {
+ pr_err("Cannot open ramdisk image in FIT image: %m\n");
+ return ret;
+ }
+ } else {
+ if (!data->initrd_file)
+ return 0;
+
+ pr_info("Loading ramdisk from '%s'\n", data->initrd_file);
+
+ initrd_mem = read_file(data->initrd_file, &initrd_size);
+ if (!initrd_mem) {
+ ret = -errno;
+ pr_err("Failed to read initrd from file '%s': %m\n",
+ data->initrd_file);
+ return ret;
+ }
}
ret = efi_initrd_register(initrd_mem, initrd_size);
@@ -84,16 +156,25 @@ static int efi_load_fdt(struct image_data *data, void **fdt)
unsigned long of_size;
int ret;
- if (!data->oftree_file)
- return 0;
-
- pr_info("Loading devicetree from '%s'\n", data->oftree_file);
-
- of_tree = read_file(data->oftree_file, &of_size);
- if (!of_tree) {
- ret = -errno;
- pr_err("Failed to read oftree: %m\n");
- return ret;
+ if (fdt_is_fit(data)) {
+ ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
+ (const void **)&of_tree, &of_size);
+ if (ret) {
+ pr_err("Cannot open FDT image in FIT image: %m\n");
+ return ret;
+ }
+ } else {
+ if (!data->oftree_file)
+ return 0;
+
+ pr_info("Loading devicetree from '%s'\n", data->oftree_file);
+
+ of_tree = read_file(data->oftree_file, &of_size);
+ if (!of_tree) {
+ ret = -errno;
+ pr_err("Failed to read oftree: %m\n");
+ return ret;
+ }
}
efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 09/11] efi: payload: bootm: add support for fit image
2025-10-06 4:15 ` [PATCH 09/11] efi: payload: bootm: add support for fit image chalianis1
@ 2025-10-06 11:41 ` Ahmad Fatoum
0 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:41 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox, Ahmad Fatoum
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Ahmad Fatoum <a.fatoum@barebox.org>
>
> Extend the EFI payload boot flow to support loading kernel, initrd,
> and devicetree directly from a FIT image. When a FIT is present,
> the loader extracts the relevant subimages ("kernel", "ramdisk",
> and "fdt") also support falling back to external files when possible.
>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> efi/payload/Kconfig | 1 +
> efi/payload/bootm.c | 125 ++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 104 insertions(+), 22 deletions(-)
>
> diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
> index e3a6a72d6a1c..4fb866210a69 100644
> --- a/efi/payload/Kconfig
> +++ b/efi/payload/Kconfig
> @@ -32,6 +32,7 @@ config EFI_HANDOVER_PROTOCOL
>
> config EFI_PAYLOAD_BOOTM
> bool "EFI bootm protocol"
> + select BOOTM_FITIMAGE
> default !X86
>
> endif
> diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
> index d0e995be5d7c..3e9ccd42bf7f 100644
> --- a/efi/payload/bootm.c
> +++ b/efi/payload/bootm.c
> @@ -34,11 +34,74 @@
> #include "image.h"
> #include "setup_header.h"
>
> +static bool ramdisk_is_fit(struct image_data *data)
> +{
> + struct stat st;
> +
> + if (bootm_signed_images_are_forced())
> + return true;
> +
> + if (data->initrd_file) {
> + if (!stat(data->initrd_file, &st) && st.st_size > 0)
> + return false;
> + }
> +
> + return data->os_fit ? fit_has_image(data->os_fit,
> + data->fit_config, "ramdisk") > 0 : false;
> +}
> +
> +static bool fdt_is_fit(struct image_data *data)
> +{
> + struct stat st;
> +
> + if (bootm_signed_images_are_forced())
> + return true;
> +
> + if (data->oftree_file) {
> + if (!stat(data->oftree_file, &st) && st.st_size > 0)
> + return false;
> + }
> +
> + return data->os_fit ? fit_has_image(data->os_fit,
> + data->fit_config, "fdt") > 0 : false;
> +}
> +
> static int efi_load_os(struct image_data *data,
> struct efi_loaded_image **loaded_image,
> efi_handle_t *handle)
> {
> - return efi_load_image(data->os_file, loaded_image, handle);
> + efi_status_t efiret;
> + efi_handle_t h;
> +
> + if (!data->os_fit)
> + return efi_load_image(data->os_file, loaded_image, handle);
> +
> + if (!data->fit_kernel)
> + return -ENOENT;
> +
> + efiret = BS->load_image(false, efi_parent_image, efi_device_path,
> + (void *)data->fit_kernel, data->fit_kernel_size, &h);
> + if (EFI_ERROR(efiret)) {
> + pr_err("failed to LoadImage: %s\n", efi_strerror(efiret));
> + goto out_mem;
> + };
> +
> + efiret = BS->open_protocol(h, &efi_loaded_image_protocol_guid,
> + (void **)loaded_image, efi_parent_image,
> + NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
> + if (EFI_ERROR(efiret)) {
> + pr_err("failed to OpenProtocol: %s\n", efi_strerror(efiret));
> + goto out_unload;
> + }
> +
> + *handle = h;
> +
> + return 0;
> +
> +out_unload:
> + BS->unload_image(h);
> +out_mem:
> + return -efi_errno(efiret);
> }
>
> static int efi_load_ramdisk(struct image_data *data, void **initrd)
> @@ -47,17 +110,26 @@ static int efi_load_ramdisk(struct image_data *data, void **initrd)
> void *initrd_mem;
> int ret;
>
> - if (!data->initrd_file)
> - return 0;
> -
> - pr_info("Loading ramdisk from '%s'\n", data->initrd_file);
> -
> - initrd_mem = read_file(data->initrd_file, &initrd_size);
> - if (!initrd_mem) {
> - ret = -errno;
> - pr_err("Failed to read initrd from file '%s': %m\n",
> - data->initrd_file);
> - return ret;
> + if (ramdisk_is_fit(data)) {
> + ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
> + (const void **)&initrd_mem, &initrd_size);
> + if (ret) {
> + pr_err("Cannot open ramdisk image in FIT image: %m\n");
> + return ret;
> + }
> + } else {
> + if (!data->initrd_file)
> + return 0;
> +
> + pr_info("Loading ramdisk from '%s'\n", data->initrd_file);
> +
> + initrd_mem = read_file(data->initrd_file, &initrd_size);
> + if (!initrd_mem) {
> + ret = -errno;
> + pr_err("Failed to read initrd from file '%s': %m\n",
> + data->initrd_file);
> + return ret;
> + }
> }
>
> ret = efi_initrd_register(initrd_mem, initrd_size);
> @@ -84,16 +156,25 @@ static int efi_load_fdt(struct image_data *data, void **fdt)
> unsigned long of_size;
> int ret;
>
> - if (!data->oftree_file)
> - return 0;
> -
> - pr_info("Loading devicetree from '%s'\n", data->oftree_file);
> -
> - of_tree = read_file(data->oftree_file, &of_size);
> - if (!of_tree) {
> - ret = -errno;
> - pr_err("Failed to read oftree: %m\n");
> - return ret;
> + if (fdt_is_fit(data)) {
> + ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
> + (const void **)&of_tree, &of_size);
> + if (ret) {
> + pr_err("Cannot open FDT image in FIT image: %m\n");
> + return ret;
> + }
> + } else {
> + if (!data->oftree_file)
> + return 0;
> +
> + pr_info("Loading devicetree from '%s'\n", data->oftree_file);
> +
> + of_tree = read_file(data->oftree_file, &of_size);
> + if (!of_tree) {
> + ret = -errno;
> + pr_err("Failed to read oftree: %m\n");
> + return ret;
> + }
> }
>
> efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES,
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 10/11] efi: payload: make selectable without COMPILE_TEST
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (7 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 09/11] efi: payload: bootm: add support for fit image chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 4:15 ` [PATCH 11/11] ARM: efi: add a generic defconfig for v8 efi payload chalianis1
2025-10-06 11:39 ` [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images Ahmad Fatoum
10 siblings, 0 replies; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Ahmad Fatoum, Chali Anis
From: Ahmad Fatoum <a.fatoum@barebox.org>
Now that the barebox EFI payload has support for a non-x86 boot method,
let's drop the COMPILE_TEST dependency.
Signed-off-by: Chali Anis <chalianis1@gmail.com>
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
efi/payload/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/efi/payload/Kconfig b/efi/payload/Kconfig
index 4fb866210a69..3b4a16e1e80c 100644
--- a/efi/payload/Kconfig
+++ b/efi/payload/Kconfig
@@ -4,7 +4,7 @@ config HAVE_EFI_PAYLOAD
bool
config EFI_PAYLOAD
- bool "Build as EFI payload" if COMPILE_TEST
+ bool "Build as EFI payload"
depends on HAVE_EFI_PAYLOAD
select PBL_FULLY_PIC if ARM64
select EFI
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 11/11] ARM: efi: add a generic defconfig for v8 efi payload
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (8 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 10/11] efi: payload: make selectable without COMPILE_TEST chalianis1
@ 2025-10-06 4:15 ` chalianis1
2025-10-06 11:41 ` Ahmad Fatoum
2025-10-06 11:39 ` [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images Ahmad Fatoum
10 siblings, 1 reply; 18+ messages in thread
From: chalianis1 @ 2025-10-06 4:15 UTC (permalink / raw)
To: s.hauer; +Cc: barebox, Chali Anis
From: Chali Anis <chalianis1@gmail.com>
The multi_v8_efi_defconfig enables a lot of drivers that are not needed
for an EFI payload. Therefore add a minimal EFI-only config.
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
arch/arm/configs/efi_v8_defconfig | 212 ++++++++++++++++++++++++++++++
1 file changed, 212 insertions(+)
create mode 100644 arch/arm/configs/efi_v8_defconfig
diff --git a/arch/arm/configs/efi_v8_defconfig b/arch/arm/configs/efi_v8_defconfig
new file mode 100644
index 000000000000..5f946dd51d4a
--- /dev/null
+++ b/arch/arm/configs/efi_v8_defconfig
@@ -0,0 +1,212 @@
+CONFIG_64BIT=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_PSCI_CLIENT=y
+CONFIG_NAME="efi_v8_defconfig"
+CONFIG_MMU=y
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="barebox> "
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_BOOTM_SHOW_TYPE=y
+CONFIG_BOOTM_VERBOSE=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_BOOTM_AIMAGE=y
+CONFIG_BLSPEC=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
+CONFIG_PBL_CONSOLE=y
+CONFIG_CONSOLE_RATP=y
+CONFIG_PARTITION_DISK_EFI=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_STATE=y
+CONFIG_BOOTCHOOSER=y
+CONFIG_RESET_SOURCE=y
+CONFIG_MACHINE_ID=y
+CONFIG_FASTBOOT_SPARSE=y
+CONFIG_EFI_PAYLOAD=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_ARM_MMUINFO=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_BFETCH=y
+CONFIG_CMD_MMC_EXTCSD=y
+CONFIG_CMD_POLLER=y
+CONFIG_CMD_SLICE=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_BOOTCHOOSER=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_FINDMNT=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_DEFAULTENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA224SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_READF=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_MENUTREE=y
+CONFIG_CMD_SPLASH=y
+CONFIG_CMD_FBTEST=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_LED_TRIGGER=y
+CONFIG_CMD_USBGADGET=y
+CONFIG_CMD_WD=y
+CONFIG_CMD_LOGIN=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_FIRMWARELOAD=y
+CONFIG_CMD_OF_DIFF=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_DISPLAY_TIMINGS=y
+CONFIG_CMD_OF_FIXUP_STATUS=y
+CONFIG_CMD_OF_OVERLAY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_NET=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_SNTP=y
+CONFIG_NET_FASTBOOT=y
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_DEEP_PROBE_DEFAULT=y
+CONFIG_OF_BAREBOX_DRIVERS=y
+CONFIG_OF_BAREBOX_ENV_IN_FS=y
+CONFIG_OF_OVERLAY_LIVE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_DRIVER_SERIAL_EFI_STDIO=y
+CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_SERIAL_CADENCE=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_DRIVER_NET_FSL_ENETC=y
+CONFIG_DRIVER_NET_FSL_FMAN=y
+CONFIG_DRIVER_NET_VIRTIO=y
+CONFIG_DP83867_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_DSA_MV88E6XXX=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_NET_USB=y
+CONFIG_NET_USB_ASIX=y
+CONFIG_USB_NET_AX88179_178A=y
+CONFIG_NET_USB_SMSC95XX=y
+CONFIG_NET_USB_RTL8152=y
+CONFIG_DRIVER_SPI_FSL_QUADSPI=y
+CONFIG_I2C=y
+CONFIG_I2C_EFI=y
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_M25P80=y
+CONFIG_DRIVER_CFI=y
+CONFIG_CFI_BUFFER_WRITE=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_USB_HOST=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_DUAL_ROLE=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_ONBOARD_DEV=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_SERIAL=y
+CONFIG_USB_GADGET_FASTBOOT=y
+CONFIG_USB_GADGET_MASS_STORAGE=y
+CONFIG_VIDEO=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_DRIVER_VIDEO_EFI_GOP=y
+CONFIG_DRIVER_VIDEO_BOCHS_PCI=y
+CONFIG_SOUND=y
+CONFIG_MCI=y
+CONFIG_MCI_MMC_BOOT_PARTITIONS=y
+CONFIG_MCI_DW=y
+CONFIG_MCI_SUNXI_SMHC=y
+CONFIG_MCI_ROCKCHIP_DWCMSHC=y
+CONFIG_MCI_ARASAN=y
+CONFIG_MCI_AM654=y
+CONFIG_COMMON_CLK=y
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_CLOCKSOURCE_EFI=y
+CONFIG_RAVE_SP_CORE=y
+CONFIG_MFD_RK808=y
+CONFIG_LED=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_EEPROM_AT25=y
+CONFIG_VIRTIO_INPUT=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_POLLER=y
+CONFIG_WATCHDOG_EFI=y
+CONFIG_WATCHDOG_DW=y
+CONFIG_RAVE_SP_WATCHDOG=y
+CONFIG_HWRNG=y
+CONFIG_HW_RANDOM_VIRTIO=y
+CONFIG_HW_RANDOM_EFI=y
+CONFIG_DMADEVICES=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_ARM_SCMI=y
+CONFIG_REGULATOR_RK808=y
+CONFIG_RESET_IMX7=y
+CONFIG_PCI_ECAM_GENERIC=y
+CONFIG_RTC_CLASS=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_GENERIC_PHY=y
+CONFIG_USB_NOP_XCEIV=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_MAILBOX=y
+CONFIG_FS_CRAMFS=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_9P_FS=y
+CONFIG_9P_FS_WRITE=y
+CONFIG_FS_EFI=y
+CONFIG_FS_EFIVARFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_BPKFS=y
+CONFIG_FS_UIMAGEFS=y
+CONFIG_FS_PSTORE=y
+CONFIG_FS_PSTORE_CONSOLE=y
+CONFIG_FS_RATP=y
+CONFIG_DIGEST_SHA1_ARM64_CE=y
+CONFIG_DIGEST_SHA256_ARM64_CE=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_MISSING_FIRMWARE_ERROR is not set
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 11/11] ARM: efi: add a generic defconfig for v8 efi payload
2025-10-06 4:15 ` [PATCH 11/11] ARM: efi: add a generic defconfig for v8 efi payload chalianis1
@ 2025-10-06 11:41 ` Ahmad Fatoum
0 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:41 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Chali Anis <chalianis1@gmail.com>
>
> The multi_v8_efi_defconfig enables a lot of drivers that are not needed
> for an EFI payload. Therefore add a minimal EFI-only config.
>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/arm/configs/efi_v8_defconfig | 212 ++++++++++++++++++++++++++++++
> 1 file changed, 212 insertions(+)
> create mode 100644 arch/arm/configs/efi_v8_defconfig
>
> diff --git a/arch/arm/configs/efi_v8_defconfig b/arch/arm/configs/efi_v8_defconfig
> new file mode 100644
> index 000000000000..5f946dd51d4a
> --- /dev/null
> +++ b/arch/arm/configs/efi_v8_defconfig
> @@ -0,0 +1,212 @@
> +CONFIG_64BIT=y
> +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
> +CONFIG_ARM_PSCI_CLIENT=y
> +CONFIG_NAME="efi_v8_defconfig"
> +CONFIG_MMU=y
> +CONFIG_MALLOC_SIZE=0x0
> +CONFIG_KALLSYMS=y
> +CONFIG_PROMPT="barebox> "
> +CONFIG_PROMPT_HUSH_PS2="y"
> +CONFIG_HUSH_FANCY_PROMPT=y
> +CONFIG_AUTO_COMPLETE=y
> +CONFIG_MENU=y
> +CONFIG_BOOTM_SHOW_TYPE=y
> +CONFIG_BOOTM_VERBOSE=y
> +CONFIG_BOOTM_INITRD=y
> +CONFIG_BOOTM_AIMAGE=y
> +CONFIG_BLSPEC=y
> +CONFIG_CONSOLE_ALLOW_COLOR=y
> +CONFIG_PBL_CONSOLE=y
> +CONFIG_CONSOLE_RATP=y
> +CONFIG_PARTITION_DISK_EFI=y
> +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
> +CONFIG_STATE=y
> +CONFIG_BOOTCHOOSER=y
> +CONFIG_RESET_SOURCE=y
> +CONFIG_MACHINE_ID=y
> +CONFIG_FASTBOOT_SPARSE=y
> +CONFIG_EFI_PAYLOAD=y
> +CONFIG_CMD_DMESG=y
> +CONFIG_LONGHELP=y
> +CONFIG_CMD_IOMEM=y
> +CONFIG_CMD_IMD=y
> +CONFIG_CMD_MEMINFO=y
> +CONFIG_CMD_ARM_MMUINFO=y
> +CONFIG_CMD_REGULATOR=y
> +CONFIG_CMD_BFETCH=y
> +CONFIG_CMD_MMC_EXTCSD=y
> +CONFIG_CMD_POLLER=y
> +CONFIG_CMD_SLICE=y
> +CONFIG_CMD_GO=y
> +CONFIG_CMD_LOADB=y
> +CONFIG_CMD_RESET=y
> +CONFIG_CMD_BOOTCHOOSER=y
> +CONFIG_CMD_PARTITION=y
> +CONFIG_CMD_FINDMNT=y
> +CONFIG_CMD_EXPORT=y
> +CONFIG_CMD_DEFAULTENV=y
> +CONFIG_CMD_LOADENV=y
> +CONFIG_CMD_PRINTENV=y
> +CONFIG_CMD_MAGICVAR=y
> +CONFIG_CMD_MAGICVAR_HELP=y
> +CONFIG_CMD_SAVEENV=y
> +CONFIG_CMD_FILETYPE=y
> +CONFIG_CMD_LN=y
> +CONFIG_CMD_MD5SUM=y
> +CONFIG_CMD_SHA1SUM=y
> +CONFIG_CMD_SHA224SUM=y
> +CONFIG_CMD_SHA256SUM=y
> +CONFIG_CMD_UNCOMPRESS=y
> +CONFIG_CMD_LET=y
> +CONFIG_CMD_MSLEEP=y
> +CONFIG_CMD_READF=y
> +CONFIG_CMD_SLEEP=y
> +CONFIG_CMD_DHCP=y
> +CONFIG_CMD_MIITOOL=y
> +CONFIG_CMD_PING=y
> +CONFIG_CMD_TFTP=y
> +CONFIG_CMD_ECHO_E=y
> +CONFIG_CMD_EDIT=y
> +CONFIG_CMD_MENU=y
> +CONFIG_CMD_MENU_MANAGEMENT=y
> +CONFIG_CMD_MENUTREE=y
> +CONFIG_CMD_SPLASH=y
> +CONFIG_CMD_FBTEST=y
> +CONFIG_CMD_READLINE=y
> +CONFIG_CMD_TIMEOUT=y
> +CONFIG_CMD_CRC=y
> +CONFIG_CMD_CRC_CMP=y
> +CONFIG_CMD_MEMTEST=y
> +CONFIG_CMD_MM=y
> +CONFIG_CMD_CLK=y
> +CONFIG_CMD_DETECT=y
> +CONFIG_CMD_FLASH=y
> +CONFIG_CMD_LED=y
> +CONFIG_CMD_POWEROFF=y
> +CONFIG_CMD_SMC=y
> +CONFIG_CMD_LED_TRIGGER=y
> +CONFIG_CMD_USBGADGET=y
> +CONFIG_CMD_WD=y
> +CONFIG_CMD_LOGIN=y
> +CONFIG_CMD_PASSWD=y
> +CONFIG_CMD_BAREBOX_UPDATE=y
> +CONFIG_CMD_FIRMWARELOAD=y
> +CONFIG_CMD_OF_DIFF=y
> +CONFIG_CMD_OF_NODE=y
> +CONFIG_CMD_OF_PROPERTY=y
> +CONFIG_CMD_OF_DISPLAY_TIMINGS=y
> +CONFIG_CMD_OF_FIXUP_STATUS=y
> +CONFIG_CMD_OF_OVERLAY=y
> +CONFIG_CMD_OFTREE=y
> +CONFIG_CMD_TIME=y
> +CONFIG_NET=y
> +CONFIG_NET_NETCONSOLE=y
> +CONFIG_NET_SNTP=y
> +CONFIG_NET_FASTBOOT=y
> +CONFIG_NET_9P=y
> +CONFIG_NET_9P_VIRTIO=y
> +CONFIG_DEEP_PROBE_DEFAULT=y
> +CONFIG_OF_BAREBOX_DRIVERS=y
> +CONFIG_OF_BAREBOX_ENV_IN_FS=y
> +CONFIG_OF_OVERLAY_LIVE=y
> +CONFIG_SERIAL_DEV_BUS=y
> +CONFIG_SERIAL_AMBA_PL011=y
> +CONFIG_DRIVER_SERIAL_EFI_STDIO=y
> +CONFIG_DRIVER_SERIAL_NS16550=y
> +CONFIG_DRIVER_SERIAL_CADENCE=y
> +CONFIG_VIRTIO_CONSOLE=y
> +CONFIG_DRIVER_NET_FSL_ENETC=y
> +CONFIG_DRIVER_NET_FSL_FMAN=y
> +CONFIG_DRIVER_NET_VIRTIO=y
> +CONFIG_DP83867_PHY=y
> +CONFIG_MICREL_PHY=y
> +CONFIG_REALTEK_PHY=y
> +CONFIG_SMSC_PHY=y
> +CONFIG_NET_DSA_MV88E6XXX=y
> +CONFIG_MDIO_BITBANG=y
> +CONFIG_NET_USB=y
> +CONFIG_NET_USB_ASIX=y
> +CONFIG_USB_NET_AX88179_178A=y
> +CONFIG_NET_USB_SMSC95XX=y
> +CONFIG_NET_USB_RTL8152=y
> +CONFIG_DRIVER_SPI_FSL_QUADSPI=y
> +CONFIG_I2C=y
> +CONFIG_I2C_EFI=y
> +CONFIG_MTD=y
> +CONFIG_MTD_CONCAT=y
> +CONFIG_MTD_M25P80=y
> +CONFIG_DRIVER_CFI=y
> +CONFIG_CFI_BUFFER_WRITE=y
> +CONFIG_VIRTIO_BLK=y
> +CONFIG_USB_HOST=y
> +CONFIG_USB_DWC3=y
> +CONFIG_USB_DWC3_DUAL_ROLE=y
> +CONFIG_USB_EHCI=y
> +CONFIG_USB_STORAGE=y
> +CONFIG_USB_ONBOARD_DEV=y
> +CONFIG_USB_GADGET=y
> +CONFIG_USB_GADGET_SERIAL=y
> +CONFIG_USB_GADGET_FASTBOOT=y
> +CONFIG_USB_GADGET_MASS_STORAGE=y
> +CONFIG_VIDEO=y
> +CONFIG_FRAMEBUFFER_CONSOLE=y
> +CONFIG_DRIVER_VIDEO_EFI_GOP=y
> +CONFIG_DRIVER_VIDEO_BOCHS_PCI=y
> +CONFIG_SOUND=y
> +CONFIG_MCI=y
> +CONFIG_MCI_MMC_BOOT_PARTITIONS=y
> +CONFIG_MCI_DW=y
> +CONFIG_MCI_SUNXI_SMHC=y
> +CONFIG_MCI_ROCKCHIP_DWCMSHC=y
> +CONFIG_MCI_ARASAN=y
> +CONFIG_MCI_AM654=y
> +CONFIG_COMMON_CLK=y
> +CONFIG_COMMON_CLK_SCMI=y
> +CONFIG_CLOCKSOURCE_EFI=y
> +CONFIG_RAVE_SP_CORE=y
> +CONFIG_MFD_RK808=y
> +CONFIG_LED=y
> +CONFIG_LED_TRIGGERS=y
> +CONFIG_EEPROM_AT25=y
> +CONFIG_VIRTIO_INPUT=y
> +CONFIG_WATCHDOG=y
> +CONFIG_WATCHDOG_POLLER=y
> +CONFIG_WATCHDOG_EFI=y
> +CONFIG_WATCHDOG_DW=y
> +CONFIG_RAVE_SP_WATCHDOG=y
> +CONFIG_HWRNG=y
> +CONFIG_HW_RANDOM_VIRTIO=y
> +CONFIG_HW_RANDOM_EFI=y
> +CONFIG_DMADEVICES=y
> +CONFIG_PINCTRL_SINGLE=y
> +CONFIG_REGULATOR=y
> +CONFIG_REGULATOR_ARM_SCMI=y
> +CONFIG_REGULATOR_RK808=y
> +CONFIG_RESET_IMX7=y
> +CONFIG_PCI_ECAM_GENERIC=y
> +CONFIG_RTC_CLASS=y
> +CONFIG_ARM_SCMI_PROTOCOL=y
> +CONFIG_GENERIC_PHY=y
> +CONFIG_USB_NOP_XCEIV=y
> +CONFIG_VIRTIO_MMIO=y
> +CONFIG_VIRTIO_PCI=y
> +CONFIG_MAILBOX=y
> +CONFIG_FS_CRAMFS=y
> +CONFIG_FS_EXT4=y
> +CONFIG_FS_TFTP=y
> +CONFIG_FS_NFS=y
> +CONFIG_9P_FS=y
> +CONFIG_9P_FS_WRITE=y
> +CONFIG_FS_EFI=y
> +CONFIG_FS_EFIVARFS=y
> +CONFIG_FS_FAT=y
> +CONFIG_FS_FAT_WRITE=y
> +CONFIG_FS_BPKFS=y
> +CONFIG_FS_UIMAGEFS=y
> +CONFIG_FS_PSTORE=y
> +CONFIG_FS_PSTORE_CONSOLE=y
> +CONFIG_FS_RATP=y
> +CONFIG_DIGEST_SHA1_ARM64_CE=y
> +CONFIG_DIGEST_SHA256_ARM64_CE=y
> +CONFIG_LZO_DECOMPRESS=y
> +# CONFIG_MISSING_FIRMWARE_ERROR is not set
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images
2025-10-06 4:15 [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images chalianis1
` (9 preceding siblings ...)
2025-10-06 4:15 ` [PATCH 11/11] ARM: efi: add a generic defconfig for v8 efi payload chalianis1
@ 2025-10-06 11:39 ` Ahmad Fatoum
10 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2025-10-06 11:39 UTC (permalink / raw)
To: chalianis1, s.hauer; +Cc: barebox
Hi,
On 10/6/25 6:15 AM, chalianis1@gmail.com wrote:
> From: Chali Anis <chalianis1@gmail.com>
>
> Introduce a new filetype for x86 Linux kernel images by checking for
> the "HdrS" magic (0x53726448) at offset 0x202 in the setup header.
>
> Signed-off-by: Chali Anis <chalianis1@gmail.com>
This introduces intermittent breakage, which can complicate e.g. git
bisect. I suggest this patch be squashed into patch 07/11.
Alternatively, the hunk registering the binfmt and bootm handlers
need to be moved into this patch here.
Cheers,
Ahmad
> ---
> common/filetype.c | 3 +++
> include/filetype.h | 6 ++++++
> 2 files changed, 9 insertions(+)
>
> diff --git a/common/filetype.c b/common/filetype.c
> index eb397a175cb6..72f84442cae9 100644
> --- a/common/filetype.c
> +++ b/common/filetype.c
> @@ -87,6 +87,7 @@ static const struct filetype_str filetype_str[] = {
> [filetype_zstd_compressed] = { "ZSTD compressed", "zstd" },
> [filetype_rockchip_rkss_image] = { "Rockchip signed boot image",
> "rk-image" },
> + [filetype_x86_linux_image] = { "x86 Linux image", "x86-linux" },
> };
>
> static const char *file_type_to_nr_string(enum filetype f)
> @@ -435,6 +436,8 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize)
> return is_dos_exe(buf8) ? filetype_riscv_efi_linux_image : filetype_riscv_linux_image;
> if (is_riscv_linux_bootimage(buf) && !memcmp(&buf[12], "barebox", 8))
> return filetype_riscv_barebox_image;
> + if (bufsize > 0x206 && is_x86_linux_bootimage(buf))
> + return filetype_x86_linux_image;
>
> if (le32_to_cpu(buf[5]) == 0x504d5453)
> return filetype_mxs_bootstream;
> diff --git a/include/filetype.h b/include/filetype.h
> index 6f4a103df304..ff4d54ee3c45 100644
> --- a/include/filetype.h
> +++ b/include/filetype.h
> @@ -67,6 +67,7 @@ enum filetype {
> filetype_nxp_fspi_image,
> filetype_zstd_compressed,
> filetype_rockchip_rkss_image,
> + filetype_x86_linux_image,
> filetype_max,
> };
>
> @@ -150,4 +151,9 @@ static inline bool is_riscv_linux_bootimage(const void *header)
> return le32_to_cpup(header + 56) == 0x05435352;
> }
>
> +static inline bool is_x86_linux_bootimage(const void *header)
> +{
> + return le32_to_cpup(header + 0x202) == 0x53726448;
> +}
> +
> #endif /* __FILE_TYPE_H */
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 18+ messages in thread