diff options
author | Tom Rini <trini@konsulko.com> | 2025-04-11 09:09:08 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-04-11 09:09:08 -0600 |
commit | dea298c62e904dd697e7b91bd3dae5d839f31d8f (patch) | |
tree | 796cb253e7511a277c0b54e1c3fb87306a56f353 /lib/efi_loader/efi_load_initrd.c | |
parent | 048266be426865282e8a482fe1f25bb919a9bfb8 (diff) | |
parent | a73b854700abcf680379497c32b92aa39fed6270 (diff) |
Merge tag 'efi-2025-07-rc1' of https://source.denx.de/u-boot/custodians/u-boot-efi
Pull request efi-2025-07-rc1
CI:
* https://source.denx.de/u-boot/custodians/u-boot-efi/-/pipelines/25648
Documentation:
* Update authenticated capsules documentation
UEFI:
* Add support for loading FIT images including initrd
- efi_loader: efi_load_initrd: provide a memory mapped initrd
- efi_loader: binary_run: register an initrd
- bootm: add support for initrd in do_bootm_efi
* efi_selftest: remove un-needed NULL checks
* efi: Fix efiboot for payloads loaded from memory
* Print extra information from the bootmgr
* Move public cert for capsules to .rodata
* Set EFI capsule dfu_alt_info env explicitly
* Make FDT extra space configurable
* Install the ACPI table from the bloblist
* Handle GD_FLG_SKIP_RELOC
* Handle malloc() errors
Others:
* acpi: select CONFIG_BLOBLIST
* smbios: select CONFIG_BLOBLIST
* xilinx: dfu: Fill directly update_info.dfu_string
* cmd: fwu: Dump custom fields from mdata structure
* board: remove capsule update support in set_dfu_alt_info()
Diffstat (limited to 'lib/efi_loader/efi_load_initrd.c')
-rw-r--r-- | lib/efi_loader/efi_load_initrd.c | 71 |
1 files changed, 60 insertions, 11 deletions
diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c index fb8cc7bcbe3..b5d58943a80 100644 --- a/lib/efi_loader/efi_load_initrd.c +++ b/lib/efi_loader/efi_load_initrd.c @@ -42,6 +42,7 @@ static const struct efi_lo_dp_prefix dp_lf2_handle = { }; static efi_handle_t efi_initrd_handle; +static struct efi_device_path *efi_initrd_dp; /** * get_initrd_fp() - Get initrd device path from a FilePathList device path @@ -73,6 +74,41 @@ static efi_status_t get_initrd_fp(struct efi_device_path **initrd_fp) } /** + * efi_initrd_from_mem() - load initial RAM disk from memory + * + * This function copies the initrd from the memory mapped device + * path pointed to by efi_initrd_dp + * + * @buffer_size: size of allocated buffer + * @buffer: buffer to load the file + * + * Return: status code + */ +static efi_status_t efi_initrd_from_mem(efi_uintn_t *buffer_size, void *buffer) +{ + efi_status_t ret = EFI_NOT_FOUND; + efi_uintn_t bs; + struct efi_device_path_memory *mdp; + + mdp = (struct efi_device_path_memory *)efi_initrd_dp; + if (!mdp) + return ret; + + bs = mdp->end_address - mdp->start_address; + + if (!buffer || *buffer_size < bs) { + ret = EFI_BUFFER_TOO_SMALL; + *buffer_size = bs; + } else { + memcpy(buffer, (void *)(uintptr_t)mdp->start_address, bs); + *buffer_size = bs; + ret = EFI_SUCCESS; + } + + return ret; +} + +/** * efi_load_file2_initrd() - load initial RAM disk * * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL @@ -118,6 +154,9 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this, goto out; } + if (efi_initrd_dp) + return EFI_EXIT(efi_initrd_from_mem(buffer_size, buffer)); + ret = get_initrd_fp(&initrd_fp); if (ret != EFI_SUCCESS) goto out; @@ -209,6 +248,9 @@ efi_status_t efi_initrd_deregister(void) NULL); efi_initrd_handle = NULL; + efi_free_pool(efi_initrd_dp); + efi_initrd_dp = NULL; + return ret; } @@ -234,24 +276,31 @@ static void EFIAPI efi_initrd_return_notify(struct efi_event *event, * This function creates a new handle and installs a Linux specific vendor * device path and an EFI_LOAD_FILE2_PROTOCOL. Linux uses the device path * to identify the handle and then calls the LoadFile service of the - * EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk. + * EFI_LOAD_FILE2_PROTOCOL to read the initial RAM disk. If dp_initrd is + * not provided, the initrd will be taken from the BootCurrent variable + * + * @dp_initrd: optional device path containing an initrd * * Return: status code */ -efi_status_t efi_initrd_register(void) +efi_status_t efi_initrd_register(struct efi_device_path *dp_initrd) { efi_status_t ret; struct efi_event *event; - /* - * Allow the user to continue if Boot#### file path is not set for - * an initrd - */ - ret = check_initrd(); - if (ret == EFI_INVALID_PARAMETER) - return EFI_SUCCESS; - if (ret != EFI_SUCCESS) - return ret; + if (dp_initrd) { + efi_initrd_dp = dp_initrd; + } else { + /* + * Allow the user to continue if Boot#### file path is not set for + * an initrd + */ + ret = check_initrd(); + if (ret == EFI_INVALID_PARAMETER) + return EFI_SUCCESS; + if (ret != EFI_SUCCESS) + return ret; + } ret = efi_install_multiple_protocol_interfaces(&efi_initrd_handle, /* initramfs */ |