diff --git a/plugins/uefi/fu-plugin-uefi.c b/plugins/uefi/fu-plugin-uefi.c index f4891cb26..434890e55 100644 --- a/plugins/uefi/fu-plugin-uefi.c +++ b/plugins/uefi/fu-plugin-uefi.c @@ -241,7 +241,7 @@ fu_plugin_uefi_write_splash_data (FuPlugin *plugin, /* save to a predicatable filename */ esp_path = fu_volume_get_mount_point (data->esp); - directory = fu_uefi_get_esp_path_for_os (esp_path); + directory = fu_uefi_get_esp_path_for_os (device, esp_path); basename = g_strdup_printf ("fwupd-%s.cap", FU_EFIVAR_GUID_UX_CAPSULE); fn = g_build_filename (directory, "fw", basename, NULL); if (!fu_common_mkdir_parent (fn, error)) @@ -425,6 +425,7 @@ static void fu_plugin_uefi_load_config (FuPlugin *plugin, FuDevice *device) { gboolean disable_shim; + gboolean fallback_removable_path; guint64 sz_reqd = FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE; g_autofree gchar *require_esp_free_space = NULL; @@ -439,6 +440,12 @@ fu_plugin_uefi_load_config (FuPlugin *plugin, FuDevice *device) fu_device_set_metadata_boolean (device, "RequireShimForSecureBoot", !disable_shim); + + /* check if using UEFI removeable path */ + fallback_removable_path = fu_plugin_get_config_value_boolean (plugin, "FallbacktoRemovablePath"); + fu_device_set_metadata_boolean (device, + "FallbacktoRemovablePath", + fallback_removable_path); } static void diff --git a/plugins/uefi/fu-uefi-bootmgr.c b/plugins/uefi/fu-uefi-bootmgr.c index ee7396728..50f8ac4ad 100644 --- a/plugins/uefi/fu-uefi-bootmgr.c +++ b/plugins/uefi/fu-uefi-bootmgr.c @@ -239,10 +239,11 @@ fu_uefi_copy_asset (const gchar *source, const gchar *target, GError **error) } gboolean -fu_uefi_bootmgr_bootnext (const gchar *esp_path, - const gchar *description, - FuUefiBootmgrFlags flags, - GError **error) +fu_uefi_bootmgr_bootnext (FuDevice *device, + const gchar *esp_path, + const gchar *description, + FuUefiBootmgrFlags flags, + GError **error) { const gchar *filepath; gboolean use_fwup_path = TRUE; @@ -273,14 +274,23 @@ fu_uefi_bootmgr_bootnext (const gchar *esp_path, secure_boot = fu_efivar_secure_boot_enabled (); if (secure_boot) { /* test to make sure shim is there if we need it */ - shim_app = fu_uefi_get_esp_app_path (esp_path, "shim", error); + shim_app = fu_uefi_get_esp_app_path (device, esp_path, "shim", error); if (shim_app == NULL) return FALSE; + /* try to fallback to use UEFI removable path if the shim path doesn't exist */ + if (!g_file_test (shim_app, G_FILE_TEST_EXISTS)) { + if (fu_device_get_metadata_boolean (device, "FallbacktoRemovablePath")) { + shim_app = fu_uefi_get_esp_app_path (device, esp_path, "boot", error); + if (shim_app == NULL) + return FALSE; + } + } + if (g_file_test (shim_app, G_FILE_TEST_EXISTS)) { /* use a custom copy of shim for firmware updates */ if (flags & FU_UEFI_BOOTMGR_FLAG_USE_SHIM_UNIQUE) { - shim_cpy = fu_uefi_get_esp_app_path (esp_path, "shimfwupd", error); + shim_cpy = fu_uefi_get_esp_app_path (device, esp_path, "shimfwupd", error); if (shim_cpy == NULL) return FALSE; if (!fu_uefi_cmp_asset (shim_app, shim_cpy)) { @@ -302,7 +312,7 @@ fu_uefi_bootmgr_bootnext (const gchar *esp_path, } /* test if correct asset in place */ - target_app = fu_uefi_get_esp_app_path (esp_path, "fwupd", error); + target_app = fu_uefi_get_esp_app_path (device, esp_path, "fwupd", error); if (target_app == NULL) return FALSE; if (!fu_uefi_cmp_asset (source_app, target_app)) { diff --git a/plugins/uefi/fu-uefi-bootmgr.h b/plugins/uefi/fu-uefi-bootmgr.h index eda193c55..d839f7010 100644 --- a/plugins/uefi/fu-uefi-bootmgr.h +++ b/plugins/uefi/fu-uefi-bootmgr.h @@ -10,6 +10,8 @@ #include #include +#include "fu-device.h" + typedef enum { FU_UEFI_BOOTMGR_FLAG_NONE = 0, FU_UEFI_BOOTMGR_FLAG_USE_SHIM_FOR_SB = 1 << 0, @@ -17,7 +19,8 @@ typedef enum { FU_UEFI_BOOTMGR_FLAG_LAST } FuUefiBootmgrFlags; -gboolean fu_uefi_bootmgr_bootnext (const gchar *esp_path, +gboolean fu_uefi_bootmgr_bootnext (FuDevice *device, + const gchar *esp_path, const gchar *description, FuUefiBootmgrFlags flags, GError **error); diff --git a/plugins/uefi/fu-uefi-common.c b/plugins/uefi/fu-uefi-common.c index a5b554293..04d393e8f 100644 --- a/plugins/uefi/fu-uefi-common.c +++ b/plugins/uefi/fu-uefi-common.c @@ -61,13 +61,16 @@ fu_uefi_bootmgr_get_suffix (GError **error) } gchar * -fu_uefi_get_esp_app_path (const gchar *esp_path, const gchar *cmd, GError **error) +fu_uefi_get_esp_app_path (FuDevice *device, + const gchar *esp_path, + const gchar *cmd, + GError **error) { const gchar *suffix = fu_uefi_bootmgr_get_suffix (error); g_autofree gchar *base = NULL; if (suffix == NULL) return NULL; - base = fu_uefi_get_esp_path_for_os (esp_path); + base = fu_uefi_get_esp_path_for_os (device, esp_path); return g_strdup_printf ("%s/%s%s.efi", base, cmd, suffix); } @@ -219,11 +222,11 @@ fu_uefi_get_esrt_entry_paths (const gchar *esrt_path, GError **error) } gchar * -fu_uefi_get_esp_path_for_os (const gchar *base) +fu_uefi_get_esp_path_for_os (FuDevice *device, const gchar *base) { #ifndef EFI_OS_DIR const gchar *os_release_id = NULL; - const gchar *id_like_id; + const gchar *id_like_id = NULL; g_autofree gchar *esp_path = NULL; g_autoptr(GError) error_local = NULL; g_autoptr(GHashTable) os_release = fwupd_get_os_release (&error_local); @@ -247,6 +250,12 @@ fu_uefi_get_esp_path_for_os (const gchar *base) g_debug ("Using ID_LIKE key from os-release"); return g_steal_pointer (&id_like_path); } + } + /* try to fallback to use UEFI removable path if ID_LIKE path doesn't exist */ + if (fu_device_get_metadata_boolean (device, "FallbacktoRemovablePath")) { + esp_path = g_build_filename (base, "EFI", "boot", NULL); + if (!g_file_test (esp_path, G_FILE_TEST_IS_DIR)) + g_debug ("failed to fallback due to missing %s", esp_path); } return g_steal_pointer (&esp_path); #else diff --git a/plugins/uefi/fu-uefi-common.h b/plugins/uefi/fu-uefi-common.h index 42f89e956..c8842d2ad 100644 --- a/plugins/uefi/fu-uefi-common.h +++ b/plugins/uefi/fu-uefi-common.h @@ -11,6 +11,8 @@ #include "fwupd-common.h" +#include "fu-device.h" + #define EFI_CAPSULE_HEADER_FLAGS_PERSIST_ACROSS_RESET 0x00010000 #define EFI_CAPSULE_HEADER_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000 #define EFI_CAPSULE_HEADER_FLAGS_INITIATE_RESET 0x00040000 @@ -58,7 +60,8 @@ typedef struct __attribute__((__packed__)) { /* the biggest size SPI part currently seen */ #define FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE (32 * 1024 * 1024) -gchar *fu_uefi_get_esp_app_path (const gchar *esp_path, +gchar *fu_uefi_get_esp_app_path (FuDevice *device, + const gchar *esp_path, const gchar *cmd, GError **error); gchar *fu_uefi_get_built_app_path (GError **error); @@ -70,7 +73,8 @@ gboolean fu_uefi_get_bitmap_size (const guint8 *buf, gboolean fu_uefi_get_framebuffer_size (guint32 *width, guint32 *height, GError **error); -gchar *fu_uefi_get_esp_path_for_os (const gchar *esp_path); +gchar *fu_uefi_get_esp_path_for_os (FuDevice *device, + const gchar *esp_path); GPtrArray *fu_uefi_get_esrt_entry_paths (const gchar *esrt_path, GError **error); guint64 fu_uefi_read_file_as_uint64 (const gchar *path, diff --git a/plugins/uefi/fu-uefi-device.c b/plugins/uefi/fu-uefi-device.c index e3608f816..d5179cf31 100644 --- a/plugins/uefi/fu-uefi-device.c +++ b/plugins/uefi/fu-uefi-device.c @@ -560,7 +560,7 @@ fu_uefi_device_write_firmware (FuDevice *device, return FALSE; /* save the blob to the ESP */ - directory = fu_uefi_get_esp_path_for_os (esp_path); + directory = fu_uefi_get_esp_path_for_os (device, esp_path); basename = g_strdup_printf ("fwupd-%s.cap", self->fw_class); fn = g_build_filename (directory, "fw", basename, NULL); if (!fu_common_mkdir_parent (fn, error)) @@ -588,7 +588,7 @@ fu_uefi_device_write_firmware (FuDevice *device, /* some legacy devices use the old name to deduplicate boot entries */ if (fu_device_has_custom_flag (device, "use-legacy-bootmgr-desc")) bootmgr_desc = "Linux-Firmware-Updater"; - if (!fu_uefi_bootmgr_bootnext (esp_path, bootmgr_desc, flags, error)) + if (!fu_uefi_bootmgr_bootnext (device, esp_path, bootmgr_desc, flags, error)) return FALSE; /* success! */ diff --git a/plugins/uefi/uefi.conf b/plugins/uefi/uefi.conf index d9ef4610e..d9775263e 100644 --- a/plugins/uefi/uefi.conf +++ b/plugins/uefi/uefi.conf @@ -10,3 +10,7 @@ # amount of free space required on the ESP, for example using 0x2000000 for 32Mb #RequireESPFreeSpace= + +# with the UEFI removable path enabled, the default esp path is set to /EFI/boot +# the shim EFI binary and presumably this is $ESP/EFI/boot/bootx64.efi +#FallbacktoRemovablePath=false