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.
This commit is contained in:
Lennart Poettering
2026-04-21 08:30:26 +02:00
parent f6b5fcc3cf
commit 9d7fa23d38
3 changed files with 49 additions and 44 deletions
+45
View File
@@ -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;
}
+4
View File
@@ -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);
-44
View File
@@ -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 */