From 9d7fa23d38bff0b2986e0ee754a210b336ffd409 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 25 Mar 2026 18:09:01 +0100 Subject: [PATCH] boot: share combine_initrds() between stub/boot We'd like to use combine_initrds() later in systemd-boot, hence move it out of stub.c and into shared code. --- src/boot/initrd.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/boot/initrd.h | 4 ++++ src/boot/stub.c | 44 -------------------------------------------- 3 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/boot/initrd.c b/src/boot/initrd.c index 4780715e792..044e011f60e 100644 --- a/src/boot/initrd.c +++ b/src/boot/initrd.c @@ -215,3 +215,48 @@ EFI_STATUS initrd_read_previous(struct iovec *ret_initrd) { return EFI_SUCCESS; } + +EFI_STATUS combine_initrds( + const struct iovec initrds[], size_t n_initrds, + Pages *ret_initrd_pages, size_t *ret_initrd_size) { + + size_t n = 0; + + /* Combine initrds by concatenation in memory */ + + assert(initrds || n_initrds == 0); + assert(ret_initrd_pages); + assert(ret_initrd_size); + + FOREACH_ARRAY(i, initrds, n_initrds) { + /* some initrds (the ones from UKI sections) need padding, pad all to be safe */ + size_t initrd_size = ALIGN4(i->iov_len); + if (n > SIZE_MAX - initrd_size) + return EFI_OUT_OF_RESOURCES; + + n += initrd_size; + } + + _cleanup_pages_ Pages pages = xmalloc_initrd_pages(n); + uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr); + + FOREACH_ARRAY(i, initrds, n_initrds) { + size_t pad; + + p = mempcpy(p, i->iov_base, i->iov_len); + + pad = ALIGN4(i->iov_len) - i->iov_len; + if (pad == 0) + continue; + + memzero(p, pad); + p += pad; + } + + assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + n) == p); + + *ret_initrd_pages = TAKE_STRUCT(pages); + *ret_initrd_size = n; + + return EFI_SUCCESS; +} diff --git a/src/boot/initrd.h b/src/boot/initrd.h index d34f8ef4c4f..cfcb8d1c6f5 100644 --- a/src/boot/initrd.h +++ b/src/boot/initrd.h @@ -2,6 +2,8 @@ #pragma once #include "efi.h" +#include "iovec-util-fundamental.h" +#include "util.h" EFI_STATUS initrd_register( const struct iovec *initrd, @@ -15,3 +17,5 @@ static inline void cleanup_initrd(EFI_HANDLE *initrd_handle) { } EFI_STATUS initrd_read_previous(struct iovec *ret_initrd); + +EFI_STATUS combine_initrds(const struct iovec initrds[], size_t n_initrds, Pages *ret_initrd_pages, size_t *ret_initrd_size); diff --git a/src/boot/stub.c b/src/boot/stub.c index 00ffa2889c5..8632a603a21 100644 --- a/src/boot/stub.c +++ b/src/boot/stub.c @@ -102,50 +102,6 @@ static void combine_measured_flag(int *value, int measured) { *value = *value < 0 ? measured : *value && measured; } -/* Combine initrds by concatenation in memory */ -static EFI_STATUS combine_initrds( - const struct iovec initrds[], size_t n_initrds, - Pages *ret_initrd_pages, size_t *ret_initrd_size) { - - size_t n = 0; - - assert(initrds || n_initrds == 0); - assert(ret_initrd_pages); - assert(ret_initrd_size); - - FOREACH_ARRAY(i, initrds, n_initrds) { - /* some initrds (the ones from UKI sections) need padding, pad all to be safe */ - size_t initrd_size = ALIGN4(i->iov_len); - if (n > SIZE_MAX - initrd_size) - return EFI_OUT_OF_RESOURCES; - - n += initrd_size; - } - - _cleanup_pages_ Pages pages = xmalloc_initrd_pages(n); - uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr); - - FOREACH_ARRAY(i, initrds, n_initrds) { - size_t pad; - - p = mempcpy(p, i->iov_base, i->iov_len); - - pad = ALIGN4(i->iov_len) - i->iov_len; - if (pad == 0) - continue; - - memzero(p, pad); - p += pad; - } - - assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + n) == p); - - *ret_initrd_pages = TAKE_STRUCT(pages); - *ret_initrd_size = n; - - return EFI_SUCCESS; -} - static void export_stub_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, unsigned profile) { static const uint64_t stub_features = EFI_STUB_FEATURE_REPORT_BOOT_PARTITION | /* We set LoaderDevicePartUUID */ -- 2.47.3