* https://github.com/mjg59/efitools
*/
-#include "device-path-util.h"
#include "efi-efivars.h"
#include "secure-boot.h"
#include "shim.h"
if (!device_path)
return false;
- EFI_HANDLE device_handle;
- EFI_DEVICE_PATH *file_dp = (EFI_DEVICE_PATH *) device_path;
- err = BS->LocateDevicePath(
- MAKE_GUID_PTR(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL), &file_dp, &device_handle);
- if (err != EFI_SUCCESS)
- return false;
-
- _cleanup_file_close_ EFI_FILE *root = NULL;
- err = open_volume(device_handle, &root);
- if (err != EFI_SUCCESS)
- return false;
-
- _cleanup_free_ char16_t *dp_str = NULL;
- err = device_path_to_str(file_dp, &dp_str);
- if (err != EFI_SUCCESS)
- return false;
-
- err = file_read(root, dp_str, 0, 0, &file_buffer_owned, &file_size);
+ err = load_file_from_simple_filesystem(device_path, &file_buffer_owned, &file_size);
if (err != EFI_SUCCESS)
return false;
if (have_shim)
install_security_override(shim_validate, NULL);
+ _cleanup_free_ char *source_buffer = NULL;
+ size_t source_size = 0;
+
+ /* For some AMI firmware, BS->LoadImage() does not read correctly when the file comes the ESP on an
+ * optical drive. But the simple filesystem protocol does work. So we try to load it. If that does
+ * not work, we let BS->LoadImage() try instead.
+ */
+ (void) load_file_from_simple_filesystem(device_path, &source_buffer, &source_size);
+
EFI_STATUS ret = BS->LoadImage(
/* BootPolicy= */ boot_policy,
parent,
(EFI_DEVICE_PATH *) device_path,
- /* SourceBuffer= */ NULL,
- /* SourceSize= */ 0,
+ source_buffer,
+ source_size,
ret_image);
if (have_shim)
uninstall_security_override();
return file_handle_read(handle, offset, size, ret, ret_size);
}
+EFI_STATUS load_file_from_simple_filesystem(const EFI_DEVICE_PATH *device_path, char **file_buffer, size_t *file_size) {
+ EFI_STATUS err;
+ EFI_HANDLE device_handle;
+ EFI_DEVICE_PATH *file_dp = (EFI_DEVICE_PATH *) device_path;
+
+ assert(device_path);
+ assert(file_buffer);
+ assert(file_size);
+
+ err = BS->LocateDevicePath(MAKE_GUID_PTR(EFI_SIMPLE_FILE_SYSTEM_PROTOCOL), &file_dp, &device_handle);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ _cleanup_file_close_ EFI_FILE *root = NULL;
+ err = open_volume(device_handle, &root);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ _cleanup_free_ char16_t *dp_str = NULL;
+ err = device_path_to_str(file_dp, &dp_str);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ return file_read(root, dp_str, 0, 0, file_buffer, file_size);
+}
+
void set_attribute_safe(size_t attr) {
/* Various UEFI implementations suppress color changes from a color to the same color. Often, we want
* to force out the color change though, hence change the color here once, and then back. We simply
EFI_STATUS chunked_read(EFI_FILE *file, size_t *size, void *buf);
EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, uint64_t offset, size_t size, char **ret, size_t *ret_size);
+EFI_STATUS load_file_from_simple_filesystem(const EFI_DEVICE_PATH *device_path, char **file_buffer, size_t *file_size);
EFI_STATUS file_handle_read(EFI_FILE *handle, uint64_t offset, size_t size, char **ret, size_t *ret_size);
static inline void file_closep(EFI_FILE **handle) {