git: f1163b9436b7 - main - loader.efi: For ipxe booting, fall back to md when ramdisk fails
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 11 Sep 2026 05:04:22 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=f1163b9436b750f6d141e3db72e9000f9cf8b5e4
commit f1163b9436b750f6d141e3db72e9000f9cf8b5e4
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-09-11 04:13:29 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-09-11 04:15:28 +0000
loader.efi: For ipxe booting, fall back to md when ramdisk fails
Some UEFI firmwares do not contain the RamDisk protocol. When this
happens, load the file into a md disk instead. This is less desireable
than the RamDisk (since that allows better chain-booting options), but
sufficient to boot an image as a md device for FreeBSD. While most
severs have the RamDisk protocol enabled in their builds, I have two
IoT class boards from different manufacturers that do not. Since it
works just fine with this fallback, that's preferable.
Sponsored by: Netflix
Differential Revision: https://reviews.freebsd.org/D59421
---
stand/efi/loader/memdisk.c | 48 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/stand/efi/loader/memdisk.c b/stand/efi/loader/memdisk.c
index aa843916c799..a425d628a85f 100644
--- a/stand/efi/loader/memdisk.c
+++ b/stand/efi/loader/memdisk.c
@@ -9,6 +9,7 @@
*/
#include "loader_efi.h"
+#include <bootstrap.h>
#include <efilib.h>
#include <Protocol/RamDisk.h>
#include "decompress.h"
@@ -110,6 +111,20 @@ download_finish(IN VOID *Context, IN EFI_STATUS Status)
decomp_fini(ctx->dctx, EFI_ERROR(Status));
}
+static void
+fallback_to_md(EFI_PHYSICAL_ADDRESS pa, size_t len)
+{
+ int unit;
+
+ unit = md_register((void *)(uintptr_t)pa, len, MD_FLAG_KERNEL);
+ if (unit < 0) {
+ printf("Could not register downloaded image as an md: %s\n",
+ strerror(errno));
+ return;
+ }
+ setenv("uefi_ignore_boot_mgr", "true", 1);
+}
+
static void
do_download_ramdisk(CHAR8 *url, bool is_disk)
{
@@ -120,12 +135,10 @@ do_download_ramdisk(CHAR8 *url, bool is_disk)
dl_state *ctx = &dl;
Status = BS->LocateProtocol(&ipxeGuid, NULL, (void**)&ipxe_download);
- if (EFI_ERROR(Status))
+ if (EFI_ERROR(Status)) {
+ printf("No ipxe download\n");
return; /* most uses won't have this, don't whine */
- Status = BS->LocateProtocol(&ramdiskGuid, NULL, (void**)&ram_disk);
- if (EFI_ERROR(Status))
- return; /* XXX whine about it? */
-
+ }
printf("Downloading %s as a %s\n", url, is_disk ? "disk" : "cd");
ctx->in_progress = true;
Status = ipxe_download->Start(ipxe_download, url, download_data, download_finish,
@@ -152,6 +165,23 @@ do_download_ramdisk(CHAR8 *url, bool is_disk)
printf("\nDownloaded %llu bytes, actual size %llu -- registering ramdisk\n",
ULL(ctx->size), ULL(decomp_buffer_length(ctx->dctx)));
+ /* ram_disk will be NULL if this fails */
+ BS->LocateProtocol(&ramdiskGuid, NULL, (void**)&ram_disk);
+
+ /*
+ * If there's no ram_disk protocol installed in this firmware, do the
+ * next best thing by saving a pointer and using that later.
+ */
+ if (ram_disk == NULL) {
+ printf("No RamDisk protocol, falling back to md image\n");
+ error = fallback_to_md(decomp_buffer(ctx->dctx), decomp_buffer_length(ctx->dctx));
+ if (error) {
+ printf("Failed to register as an MD device\n");
+ download_cleanup(ctx);
+ }
+ return;
+ }
+
/*
* Register the RamDisk with UEFI. This registers it so the rest of the
* boot loader can see it as a block device.
@@ -159,8 +189,12 @@ do_download_ramdisk(CHAR8 *url, bool is_disk)
Status = ram_disk->Register(decomp_buffer(ctx->dctx), decomp_buffer_length(ctx->dctx),
&disk_type, NULL, &ram_disk_path);
if (EFI_ERROR(Status)) {
- printf("failed to register ram disk %u\n", (unsigned)Status);
- download_cleanup(ctx);
+ printf("failed to register ram disk %u, falling back to md image\n", (unsigned)Status);
+ error = fallback_to_md(decomp_buffer(ctx->dctx), decomp_buffer_length(ctx->dctx));
+ if (error) {
+ printf("Failed to register as an MD device\n");
+ download_cleanup(ctx);
+ }
return;
}