mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: chalianis1@gmail.com
To: s.hauer@pengutronix.de
Cc: barebox@lists.infradead.org, Chali Anis <chalianis1@gmail.com>,
	Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH v2 04/10] efi: payload: add support for EFI initrd media protocol
Date: Mon,  6 Oct 2025 20:59:49 -0400	[thread overview]
Message-ID: <20251007005955.1427990-4-chalianis1@gmail.com> (raw)
In-Reply-To: <20251007005955.1427990-1-chalianis1@gmail.com>

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..7a9317fa070e
--- /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




  parent reply	other threads:[~2025-10-07  1:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-07  0:59 [PATCH v2 01/10] efi: payload: split out payload Kconfig symbols chalianis1
2025-10-07  0:59 ` [PATCH v2 02/10] tlsf: move kasan_poison_shadow into tlsf_add_pool chalianis1
2025-10-07  0:59 ` [PATCH v2 03/10] tlsf: support on-demand requesting memory from external store chalianis1
2025-10-07  0:59 ` chalianis1 [this message]
2025-10-07  0:59 ` [PATCH v2 05/10] efi: payload: earlymem: allocate only the barebox needs in term of memory chalianis1
2025-10-07  0:59 ` [PATCH v2 06/10] efi: payload: split image handling from legacy handover boot and add linux x86 image filetype chalianis1
2025-10-07  0:59 ` [PATCH v2 07/10] efi: payload: bootm: add support for efi stub boot chalianis1
2025-10-07  0:59 ` [PATCH v2 08/10] efi: payload: bootm: add support for fit image chalianis1
2025-10-07  0:59 ` [PATCH v2 09/10] efi: payload: make selectable without COMPILE_TEST chalianis1
2025-10-07  0:59 ` [PATCH v2 10/10] ARM: efi: add a generic defconfig for v8 efi payload 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=20251007005955.1427990-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