mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: chalianis1@gmail.com, s.hauer@pengutronix.de
Cc: barebox@lists.infradead.org
Subject: Re: [PATCH 08/11] efi: payload: bootm: add support for efi stub boot
Date: Mon, 6 Oct 2025 13:40:55 +0200	[thread overview]
Message-ID: <e7b6d543-9d79-4aef-9bb6-b0367a7b7d89@pengutronix.de> (raw)
In-Reply-To: <20251006041512.1360284-8-chalianis1@gmail.com>



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 |




  reply	other threads:[~2025-10-06 11:41 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 11:31   ` Ahmad Fatoum
2025-10-06  4:15 ` [PATCH 04/11] tlsf: move kasan_poison_shadow into tlsf_add_pool chalianis1
2025-10-06  4:15 ` [PATCH 05/11] tlsf: support on-demand requesting memory from external store chalianis1
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
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
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 [this message]
2025-10-06  4:15 ` [PATCH 09/11] efi: payload: bootm: add support for fit image chalianis1
2025-10-06 11:41   ` Ahmad Fatoum
2025-10-06  4:15 ` [PATCH 10/11] efi: payload: make selectable without COMPILE_TEST chalianis1
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
2025-10-06 11:39 ` [PATCH 01/11] common: filetype: add detection for x86 Linux kernel images Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e7b6d543-9d79-4aef-9bb6-b0367a7b7d89@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=chalianis1@gmail.com \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox