mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 12:54:58 +00:00
uefi: a new option for uefi configuration to use UEFI removable path
Per discussion of #2513, Ubuntu Core was going to use UEFI removable path as default esp path, and it needs to change some parts around getting the esp path and searching the shim app path. Also, a new option "FallbacktoRemovablePath" is added into uefi.conf to be applied in this case, and it will be false by default.
This commit is contained in:
parent
cceeb75c7b
commit
b47eee9a8a
@ -241,7 +241,7 @@ fu_plugin_uefi_write_splash_data (FuPlugin *plugin,
|
|||||||
|
|
||||||
/* save to a predicatable filename */
|
/* save to a predicatable filename */
|
||||||
esp_path = fu_volume_get_mount_point (data->esp);
|
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);
|
basename = g_strdup_printf ("fwupd-%s.cap", FU_EFIVAR_GUID_UX_CAPSULE);
|
||||||
fn = g_build_filename (directory, "fw", basename, NULL);
|
fn = g_build_filename (directory, "fw", basename, NULL);
|
||||||
if (!fu_common_mkdir_parent (fn, error))
|
if (!fu_common_mkdir_parent (fn, error))
|
||||||
@ -425,6 +425,7 @@ static void
|
|||||||
fu_plugin_uefi_load_config (FuPlugin *plugin, FuDevice *device)
|
fu_plugin_uefi_load_config (FuPlugin *plugin, FuDevice *device)
|
||||||
{
|
{
|
||||||
gboolean disable_shim;
|
gboolean disable_shim;
|
||||||
|
gboolean fallback_removable_path;
|
||||||
guint64 sz_reqd = FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE;
|
guint64 sz_reqd = FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE;
|
||||||
g_autofree gchar *require_esp_free_space = NULL;
|
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,
|
fu_device_set_metadata_boolean (device,
|
||||||
"RequireShimForSecureBoot",
|
"RequireShimForSecureBoot",
|
||||||
!disable_shim);
|
!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
|
static void
|
||||||
|
@ -239,7 +239,8 @@ fu_uefi_copy_asset (const gchar *source, const gchar *target, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_uefi_bootmgr_bootnext (const gchar *esp_path,
|
fu_uefi_bootmgr_bootnext (FuDevice *device,
|
||||||
|
const gchar *esp_path,
|
||||||
const gchar *description,
|
const gchar *description,
|
||||||
FuUefiBootmgrFlags flags,
|
FuUefiBootmgrFlags flags,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -273,14 +274,23 @@ fu_uefi_bootmgr_bootnext (const gchar *esp_path,
|
|||||||
secure_boot = fu_efivar_secure_boot_enabled ();
|
secure_boot = fu_efivar_secure_boot_enabled ();
|
||||||
if (secure_boot) {
|
if (secure_boot) {
|
||||||
/* test to make sure shim is there if we need it */
|
/* 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)
|
if (shim_app == NULL)
|
||||||
return FALSE;
|
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)) {
|
if (g_file_test (shim_app, G_FILE_TEST_EXISTS)) {
|
||||||
/* use a custom copy of shim for firmware updates */
|
/* use a custom copy of shim for firmware updates */
|
||||||
if (flags & FU_UEFI_BOOTMGR_FLAG_USE_SHIM_UNIQUE) {
|
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)
|
if (shim_cpy == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!fu_uefi_cmp_asset (shim_app, shim_cpy)) {
|
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 */
|
/* 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)
|
if (target_app == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!fu_uefi_cmp_asset (source_app, target_app)) {
|
if (!fu_uefi_cmp_asset (source_app, target_app)) {
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <efivar.h>
|
#include <efivar.h>
|
||||||
|
|
||||||
|
#include "fu-device.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FU_UEFI_BOOTMGR_FLAG_NONE = 0,
|
FU_UEFI_BOOTMGR_FLAG_NONE = 0,
|
||||||
FU_UEFI_BOOTMGR_FLAG_USE_SHIM_FOR_SB = 1 << 0,
|
FU_UEFI_BOOTMGR_FLAG_USE_SHIM_FOR_SB = 1 << 0,
|
||||||
@ -17,7 +19,8 @@ typedef enum {
|
|||||||
FU_UEFI_BOOTMGR_FLAG_LAST
|
FU_UEFI_BOOTMGR_FLAG_LAST
|
||||||
} FuUefiBootmgrFlags;
|
} FuUefiBootmgrFlags;
|
||||||
|
|
||||||
gboolean fu_uefi_bootmgr_bootnext (const gchar *esp_path,
|
gboolean fu_uefi_bootmgr_bootnext (FuDevice *device,
|
||||||
|
const gchar *esp_path,
|
||||||
const gchar *description,
|
const gchar *description,
|
||||||
FuUefiBootmgrFlags flags,
|
FuUefiBootmgrFlags flags,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
@ -61,13 +61,16 @@ fu_uefi_bootmgr_get_suffix (GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gchar *
|
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);
|
const gchar *suffix = fu_uefi_bootmgr_get_suffix (error);
|
||||||
g_autofree gchar *base = NULL;
|
g_autofree gchar *base = NULL;
|
||||||
if (suffix == NULL)
|
if (suffix == NULL)
|
||||||
return 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);
|
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 *
|
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
|
#ifndef EFI_OS_DIR
|
||||||
const gchar *os_release_id = NULL;
|
const gchar *os_release_id = NULL;
|
||||||
const gchar *id_like_id;
|
const gchar *id_like_id = NULL;
|
||||||
g_autofree gchar *esp_path = NULL;
|
g_autofree gchar *esp_path = NULL;
|
||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
g_autoptr(GHashTable) os_release = fwupd_get_os_release (&error_local);
|
g_autoptr(GHashTable) os_release = fwupd_get_os_release (&error_local);
|
||||||
@ -248,6 +251,12 @@ fu_uefi_get_esp_path_for_os (const gchar *base)
|
|||||||
return g_steal_pointer (&id_like_path);
|
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);
|
return g_steal_pointer (&esp_path);
|
||||||
#else
|
#else
|
||||||
return g_build_filename (base, "EFI", EFI_OS_DIR, NULL);
|
return g_build_filename (base, "EFI", EFI_OS_DIR, NULL);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "fwupd-common.h"
|
#include "fwupd-common.h"
|
||||||
|
|
||||||
|
#include "fu-device.h"
|
||||||
|
|
||||||
#define EFI_CAPSULE_HEADER_FLAGS_PERSIST_ACROSS_RESET 0x00010000
|
#define EFI_CAPSULE_HEADER_FLAGS_PERSIST_ACROSS_RESET 0x00010000
|
||||||
#define EFI_CAPSULE_HEADER_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
|
#define EFI_CAPSULE_HEADER_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
|
||||||
#define EFI_CAPSULE_HEADER_FLAGS_INITIATE_RESET 0x00040000
|
#define EFI_CAPSULE_HEADER_FLAGS_INITIATE_RESET 0x00040000
|
||||||
@ -58,7 +60,8 @@ typedef struct __attribute__((__packed__)) {
|
|||||||
/* the biggest size SPI part currently seen */
|
/* the biggest size SPI part currently seen */
|
||||||
#define FU_UEFI_COMMON_REQUIRED_ESP_FREE_SPACE (32 * 1024 * 1024)
|
#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,
|
const gchar *cmd,
|
||||||
GError **error);
|
GError **error);
|
||||||
gchar *fu_uefi_get_built_app_path (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,
|
gboolean fu_uefi_get_framebuffer_size (guint32 *width,
|
||||||
guint32 *height,
|
guint32 *height,
|
||||||
GError **error);
|
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,
|
GPtrArray *fu_uefi_get_esrt_entry_paths (const gchar *esrt_path,
|
||||||
GError **error);
|
GError **error);
|
||||||
guint64 fu_uefi_read_file_as_uint64 (const gchar *path,
|
guint64 fu_uefi_read_file_as_uint64 (const gchar *path,
|
||||||
|
@ -560,7 +560,7 @@ fu_uefi_device_write_firmware (FuDevice *device,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* save the blob to the ESP */
|
/* 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);
|
basename = g_strdup_printf ("fwupd-%s.cap", self->fw_class);
|
||||||
fn = g_build_filename (directory, "fw", basename, NULL);
|
fn = g_build_filename (directory, "fw", basename, NULL);
|
||||||
if (!fu_common_mkdir_parent (fn, error))
|
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 */
|
/* some legacy devices use the old name to deduplicate boot entries */
|
||||||
if (fu_device_has_custom_flag (device, "use-legacy-bootmgr-desc"))
|
if (fu_device_has_custom_flag (device, "use-legacy-bootmgr-desc"))
|
||||||
bootmgr_desc = "Linux-Firmware-Updater";
|
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;
|
return FALSE;
|
||||||
|
|
||||||
/* success! */
|
/* success! */
|
||||||
|
@ -10,3 +10,7 @@
|
|||||||
|
|
||||||
# amount of free space required on the ESP, for example using 0x2000000 for 32Mb
|
# amount of free space required on the ESP, for example using 0x2000000 for 32Mb
|
||||||
#RequireESPFreeSpace=
|
#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
|
||||||
|
Loading…
Reference in New Issue
Block a user