]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
efi: use 'struct iovec' more, pass initrds down with it
authorLennart Poettering <lennart@poettering.net>
Wed, 14 Jan 2026 17:22:29 +0000 (18:22 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 15 Jan 2026 10:32:33 +0000 (11:32 +0100)
src/boot/boot.c
src/boot/initrd.c
src/boot/initrd.h
src/boot/linux.c

index 3ff757c53d6a8642e3144f0623f6aa7270f1dbe8..b8a9264a496d92aedc33ba9cb01780dc7c1b9c9b 100644 (file)
@@ -13,6 +13,7 @@
 #include "export-vars.h"
 #include "graphics.h"
 #include "initrd.h"
+#include "iovec-util-fundamental.h"
 #include "line-edit.h"
 #include "measure.h"
 #include "memory-util-fundamental.h"
@@ -2690,7 +2691,7 @@ static EFI_STATUS call_image_start(
                                 return log_error_status(err, "Error loading %ls: %m", entry->devicetree);
                 }
 
-                err = initrd_register(PHYSICAL_ADDRESS_TO_POINTER(initrd_pages.addr), initrd_size, &initrd_handle);
+                err = initrd_register(&IOVEC_MAKE(PHYSICAL_ADDRESS_TO_POINTER(initrd_pages.addr), initrd_size), &initrd_handle);
                 if (err != EFI_SUCCESS)
                         return log_error_status(err, "Error registering initrd: %m");
         }
index 1de4fcfa054d9117d54507478faa8a1ddc415166..f817fc3fdf2d42cbac1d62349deb603846ce64a0 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include "initrd.h"
+#include "iovec-util-fundamental.h"
 #include "proto/device-path.h"
 #include "proto/load-file.h"
 #include "util.h"
@@ -11,8 +12,7 @@
 /* extend LoadFileProtocol */
 struct initrd_loader {
         EFI_LOAD_FILE_PROTOCOL load_file;
-        const void *address;
-        size_t length;
+        struct iovec data;
 };
 
 /* static structure for LINUX_INITRD_MEDIA device path
@@ -52,23 +52,21 @@ static EFIAPI EFI_STATUS initrd_load_file(
                 return EFI_UNSUPPORTED;
 
         loader = (struct initrd_loader *) this;
-
-        if (loader->length == 0 || !loader->address)
+        if (!iovec_is_set(&loader->data))
                 return EFI_NOT_FOUND;
 
-        if (!buffer || *buffer_size < loader->length) {
-                *buffer_size = loader->length;
+        if (!buffer || *buffer_size < loader->data.iov_len) {
+                *buffer_size = loader->data.iov_len;
                 return EFI_BUFFER_TOO_SMALL;
         }
 
-        memcpy(buffer, loader->address, loader->length);
-        *buffer_size = loader->length;
+        memcpy(buffer, loader->data.iov_base, loader->data.iov_len);
+        *buffer_size = loader->data.iov_len;
         return EFI_SUCCESS;
 }
 
 EFI_STATUS initrd_register(
-                const void *initrd_address,
-                size_t initrd_length,
+                const struct iovec *initrd,
                 EFI_HANDLE *ret_initrd_handle) {
 
         EFI_STATUS err;
@@ -78,7 +76,10 @@ EFI_STATUS initrd_register(
 
         assert(ret_initrd_handle);
 
-        if (!initrd_address || initrd_length == 0)
+        /* If no initrd is specified we'll not install any. This avoids regstration of the protocol for that
+         * case, leaving it open for something else. */
+
+        if (!iovec_is_set(initrd))
                 return EFI_SUCCESS;
 
         /* check if a LINUX_INITRD_MEDIA_GUID DevicePath is already registered.
@@ -92,8 +93,7 @@ EFI_STATUS initrd_register(
         loader = xnew(struct initrd_loader, 1);
         *loader = (struct initrd_loader) {
                 .load_file.LoadFile = initrd_load_file,
-                .address = initrd_address,
-                .length = initrd_length
+                .data = *initrd,
         };
 
         /* create a new handle and register the LoadFile2 protocol with the InitrdMediaPath on it */
index e7685aeb4a65875c238eb1b0af28f8b75ef095eb..50987c497d66768a60c2a923628749af18af65c0 100644 (file)
@@ -4,8 +4,7 @@
 #include "efi.h"
 
 EFI_STATUS initrd_register(
-                const void *initrd_address,
-                size_t initrd_length,
+                const struct iovec *initrd,
                 EFI_HANDLE *ret_initrd_handle);
 
 EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle);
index 376b52d72ac9c3996124994f1bb42b7555381bdf..22b758b8e641c30ae6193b83cc8c0688ee42e4a4 100644 (file)
@@ -96,7 +96,7 @@ static EFI_STATUS load_via_boot_services(
         }
 
         _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
-        err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle);
+        err = initrd_register(initrd, &initrd_handle);
         if (err != EFI_SUCCESS)
                 return log_error_status(err, "Error registering initrd: %m");
 
@@ -315,7 +315,7 @@ EFI_STATUS linux_exec(
         }
 
         _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
-        err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle);
+        err = initrd_register(initrd, &initrd_handle);
         if (err != EFI_SUCCESS)
                 return log_error_status(err, "Error registering initrd: %m");