1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-10 05:18:17 +03:00

boot: Add LINUX_INITRD_MEDIA support to boot.c

This commit is contained in:
Jan Janssen 2022-03-10 12:53:16 +01:00 committed by Luca Boccassi
parent acdf7d157b
commit 46ce6cf774
4 changed files with 53 additions and 8 deletions

View File

@ -2302,27 +2302,63 @@ static void config_load_xbootldr(
static EFI_STATUS initrd_prepare(
EFI_FILE *root,
const ConfigEntry *entry,
CHAR16 **ret_options) {
CHAR16 **ret_options,
void **ret_initrd,
UINTN *ret_initrd_size) {
assert(root);
assert(entry);
assert(ret_options);
assert(ret_initrd);
assert(ret_initrd_size);
if (entry->type != LOADER_LINUX || !entry->initrd) {
ret_options = NULL;
ret_initrd = NULL;
ret_initrd_size = 0;
return EFI_SUCCESS;
}
/* Note that order of initrds matters. The kernel will only look for microcode updates in the very
* first one it sees. */
/* Add initrd= to options for older kernels that do not support LINUX_INITRD_MEDIA. Should be dropped
* if linux_x86.c is dropped. */
_cleanup_freepool_ CHAR16 *options = NULL;
EFI_STATUS err;
UINTN size = 0;
_cleanup_freepool_ UINT8 *initrd = NULL;
STRV_FOREACH(i, entry->initrd) {
_cleanup_freepool_ CHAR16 *o = options;
if (o)
options = xpool_print(L"%s initrd=%s", o, *i);
else
options = xpool_print(L"initrd=%s", *i);
_cleanup_(file_closep) EFI_FILE *handle = NULL;
err = root->Open(root, &handle, *i, EFI_FILE_MODE_READ, 0);
if (EFI_ERROR(err))
return err;
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
err = get_file_info_harder(handle, &info, NULL);
if (EFI_ERROR(err))
return err;
UINTN new_size, read_size = info->FileSize;
if (__builtin_add_overflow(size, read_size, &new_size))
return EFI_OUT_OF_RESOURCES;
initrd = xreallocate_pool(initrd, size, new_size);
err = handle->Read(handle, &read_size, initrd + size);
if (EFI_ERROR(err))
return err;
/* Make sure the actual read size is what we expected. */
assert(size + read_size == new_size);
size = new_size;
}
if (entry->options) {
@ -2331,6 +2367,8 @@ static EFI_STATUS initrd_prepare(
}
*ret_options = TAKE_PTR(options);
*ret_initrd = TAKE_PTR(initrd);
*ret_initrd_size = size;
return EFI_SUCCESS;
}
@ -2357,8 +2395,10 @@ static EFI_STATUS image_start(
if (!path)
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Error getting device path.");
UINTN initrd_size = 0;
_cleanup_freepool_ void *initrd = NULL;
_cleanup_freepool_ CHAR16 *options_initrd = NULL;
err = initrd_prepare(image_root, entry, &options_initrd);
err = initrd_prepare(image_root, entry, &options_initrd, &initrd, &initrd_size);
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Error preparing initrd: %r", err);
@ -2372,6 +2412,11 @@ static EFI_STATUS image_start(
return log_error_status_stall(err, L"Error loading %s: %r", entry->devicetree, err);
}
_cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
err = initrd_register(initrd, initrd_size, &initrd_handle);
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Error registering initrd: %r", err);
CHAR16 *options = options_initrd ?: entry->options;
if (options) {
EFI_LOADED_IMAGE *loaded_image;

View File

@ -9,3 +9,8 @@ EFI_STATUS initrd_register(
EFI_HANDLE *ret_initrd_handle);
EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle);
static inline void cleanup_initrd(EFI_HANDLE *initrd_handle) {
(void) initrd_unregister(*initrd_handle);
*initrd_handle = NULL;
}

View File

@ -87,11 +87,6 @@ static EFI_STATUS loaded_image_unregister(EFI_HANDLE loaded_image_handle) {
return EFI_SUCCESS;
}
static inline void cleanup_initrd(EFI_HANDLE *initrd_handle) {
(void) initrd_unregister(*initrd_handle);
*initrd_handle = NULL;
}
static inline void cleanup_loaded_image(EFI_HANDLE *loaded_image_handle) {
(void) loaded_image_unregister(*loaded_image_handle);
*loaded_image_handle = NULL;

View File

@ -351,6 +351,7 @@ common_sources = files(
'devicetree.c',
'disk.c',
'graphics.c',
'initrd.c',
'measure.c',
'pe.c',
'secure-boot.c',
@ -369,7 +370,6 @@ systemd_boot_sources = files(
stub_sources = files(
'cpio.c',
'initrd.c',
'splash.c',
'stub.c',
)