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:
parent
acdf7d157b
commit
46ce6cf774
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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',
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user