From: chalianis1@gmail.com
To: s.hauer@pengutronix.de, a.fatoum@barebox.org
Cc: barebox@lists.infradead.org, Chali Anis <chalianis1@gmail.com>
Subject: [PATCH v3 04/11] efi: payload: add support for fit image
Date: Tue, 16 Sep 2025 00:01:48 -0400 [thread overview]
Message-ID: <20250916040155.814159-4-chalianis1@gmail.com> (raw)
In-Reply-To: <20250916040155.814159-1-chalianis1@gmail.com>
From: Ahmad Fatoum <a.fatoum@barebox.org>
This patch has more stock, between implementing EFI STUB boot, refactor to
reuse the code and finaly support the fit image format.
This code is tested on many qemu EFI compilations comming from ovmf ubuntu
package, tianocore efi for qemu, local edk2 build, and also tested on RPi3b
64 bit EFI from tianocore and a local build of edk2, more mchines will be
tested soon. the test was for a full boot chain on RPi3b booting a fit image
containing a kernel, an fdt, and a ramdisk with ostree initrd to mount an
ostree root filesystem. for contribution in short term,
1. it would be nice to test with more hardware,
2. linux global checkup of efivars, efi capsule update, efi runtime services
3. The state.dtb to support barebox state to manage multiple system boot
and a recovery.
the case would be sys1 = new ostree commit, sys2 = old commit (rollback)
and a recovery boot system on readonly disk.
4. secure boot, PoC to check if there is a way to load TF-A from EFI
and then load the efi payload from it and launch optee??
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
efi/payload/bootm.c | 148 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 126 insertions(+), 22 deletions(-)
diff --git a/efi/payload/bootm.c b/efi/payload/bootm.c
index 6d6ecbf2e49a..ce225ab949c9 100644
--- a/efi/payload/bootm.c
+++ b/efi/payload/bootm.c
@@ -25,6 +25,7 @@
#include <libfile.h>
#include <binfmt.h>
#include <wchar.h>
+#include <image-fit.h>
#include <efi/efi-payload.h>
#include <efi/efi-device.h>
@@ -227,10 +228,93 @@ static int do_bootm_efi(struct image_data *data)
return 0;
}
+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 efi_image_data *e)
{
- return efi_load_file_image(e->data->os_file,
- &e->loaded_image, &e->handle);
+ efi_status_t efiret = EFI_SUCCESS;
+ efi_physical_addr_t mem;
+ size_t image_size = 0;
+ void *image = NULL;
+ void *vmem = NULL;
+ int ret = 0;
+
+ if (!e->data->os_fit)
+ return efi_load_file_image(e->data->os_file,
+ &e->loaded_image, &e->handle);
+
+ image = (void *)e->data->fit_kernel;
+ image_size = e->data->fit_kernel_size;
+
+ if (image_size <= 0 || !image)
+ return -EINVAL;
+
+ vmem = efi_allocate_pages(&mem, image_size, EFI_ALLOCATE_ANY_PAGES,
+ EFI_LOADER_CODE);
+ if (!vmem) {
+ pr_err("Failed to allocate pages for image\n");
+ return -ENOMEM;
+ }
+
+ memcpy(vmem, image, image_size);
+
+ efiret = BS->load_image(false, efi_parent_image, efi_device_path, image,
+ image_size, &e->handle);
+ if (EFI_ERROR(efiret)) {
+ ret = -efi_errno(efiret);
+ pr_err("failed to LoadImage: %s\n", efi_strerror(efiret));
+ goto out_mem;
+ };
+
+ efiret = BS->open_protocol(e->handle, &efi_loaded_image_protocol_guid,
+ (void **)&e->loaded_image, efi_parent_image,
+ NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(efiret)) {
+ ret = -efi_errno(efiret);
+ pr_err("failed to OpenProtocol: %s\n", efi_strerror(efiret));
+ goto out_unload;
+ }
+
+ e->image_res.base = mem;
+ e->image_res.size = image_size;
+
+ return 0;
+
+out_mem:
+ efi_free_pages(vmem, image_size);
+out_unload:
+ BS->unload_image(e->handle);
+ return ret;
}
static void efi_unload_os(struct efi_image_data *e)
@@ -252,17 +336,27 @@ static int efi_load_ramdisk(struct efi_image_data *e)
unsigned long initrd_size;
int ret;
- if (!e->data->initrd_file)
- return 0;
-
- pr_info("Loading ramdisk from '%s'\n", e->data->initrd_file);
- tmp = read_file(e->data->initrd_file, &initrd_size);
- if (!tmp || initrd_size <= 0) {
- pr_err("Failed to read initrd from file: %s\n",
- e->data->initrd_file);
- return -EINVAL;
+ if (ramdisk_is_fit(e->data)) {
+ ret = fit_open_image(e->data->os_fit, e->data->fit_config,
+ "ramdisk", &initrd, &initrd_size);
+ if (ret) {
+ pr_err("Cannot open ramdisk image in FIT image: %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+ } else {
+ if (!e->data->initrd_file)
+ return 0;
+
+ pr_info("Loading ramdisk from '%s'\n", e->data->initrd_file);
+ tmp = read_file(e->data->initrd_file, &initrd_size);
+ if (!tmp || initrd_size <= 0) {
+ pr_err("Failed to read initrd from file: %s\n",
+ e->data->initrd_file);
+ return -EINVAL;
+ }
+ initrd = tmp;
}
- initrd = tmp;
efiret = BS->allocate_pool(EFI_LOADER_DATA,
sizeof(struct efi_mem_resource),
@@ -346,17 +440,27 @@ static int efi_load_fdt(struct efi_image_data *e)
if (IS_ENABLED(CONFIG_EFI_FDT_FORCE))
return 0;
- if (!e->data->oftree_file)
- return 0;
-
- pr_info("Loading devicetree from '%s'\n", e->data->oftree_file);
- tmp = read_file(e->data->oftree_file, &of_size);
- if (!tmp || of_size <= 0) {
- pr_err("Failed to read initrd from file: %s\n",
- e->data->initrd_file);
- return -EINVAL;
+ if (fdt_is_fit(e->data)) {
+ ret = fit_open_image(e->data->os_fit, e->data->fit_config,
+ "fdt", &of_tree, &of_size);
+ if (ret) {
+ pr_err("Cannot open FDT image in FIT image: %pe\n",
+ ERR_PTR(ret));
+ return ret;
+ }
+ } else {
+ if (!e->data->oftree_file)
+ return 0;
+
+ pr_info("Loading devicetree from '%s'\n", e->data->oftree_file);
+ tmp = read_file(e->data->oftree_file, &of_size);
+ if (!tmp || of_size <= 0) {
+ pr_err("Failed to read initrd from file: %s\n",
+ e->data->initrd_file);
+ return -EINVAL;
+ }
+ of_tree = tmp;
}
- of_tree = tmp;
vmem = efi_allocate_pages(&mem, SZ_128K,
EFI_ALLOCATE_ANY_PAGES,
--
2.34.1
next prev parent reply other threads:[~2025-09-16 4:02 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-16 4:01 [PATCH v3 01/11] ARM: cpu: allow selecting CPU_V7/CPU_V8 directly chalianis1
2025-09-16 4:01 ` [PATCH v3 02/11] efi: payload: split image handling from legacy handover boot support chalianis1
2025-09-16 4:01 ` [PATCH v3 03/11] efi: payload: add support for efi stub boot chalianis1
2025-09-16 4:01 ` chalianis1 [this message]
2025-09-16 4:01 ` [PATCH v3 05/11] efi: payload: make selectable without COMPILE_TEST chalianis1
2025-09-16 4:01 ` [PATCH v3 06/11] arm: efi: add a generic defconfig for v8 efi payload, chalianis1
2025-09-16 4:01 ` [PATCH v3 07/11] efi: payload: initrd: implement efi initrd media protocol chalianis1
2025-09-16 4:01 ` [PATCH v3 08/11] common: filetype: add x86 linux filetype chalianis1
2025-09-16 4:01 ` [PATCH v3 09/11] efi: payload: early-mem: helps to correctly boot x86 linux chalianis1
2025-09-16 4:01 ` [PATCH v3 10/11] efi: payload: bootm: add x86 efi stub boot support chalianis1
2025-09-16 4:01 ` [PATCH v3 11/11] lib: fdt: remove FDT_PADDING chalianis1
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=20250916040155.814159-4-chalianis1@gmail.com \
--to=chalianis1@gmail.com \
--cc=a.fatoum@barebox.org \
--cc=barebox@lists.infradead.org \
--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