Add a new plugin for legacy BIOS

This plugin is only enabled when coreboot isn't detected.
It intentionally does not check for EFI to be disabled at startup
since it can also notify the user that UEFI capsule updates are
disabled on the system even if running in UEFI mode.
This commit is contained in:
Mario Limonciello 2020-06-21 16:25:24 -05:00 committed by Richard Hughes
parent 5a831fa7ab
commit 91e27e145a
6 changed files with 131 additions and 49 deletions

View File

@ -333,6 +333,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
%{_libdir}/fwupd-plugins-3/libfu_plugin_altos.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_amt.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_ata.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_bios.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_ccgx.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_colorhug.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_coreboot.so

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2020 Mario Limonciello <mario.limonciello@dell.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include "fu-efivar.h"
#include "fu-plugin-vfuncs.h"
#include "fu-hash.h"
void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
}
gboolean
fu_plugin_startup (FuPlugin *plugin, GError **error)
{
const gchar *vendor;
vendor = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
if (g_strcmp0 (vendor, "coreboot") == 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_FOUND,
"system uses coreboot");
return FALSE;
}
return TRUE;
}
static gboolean
fu_plugin_bios_create_dummy (FuPlugin *plugin, const gchar *reason, GError **error)
{
const gchar *key;
g_autoptr(FuDevice) dev = fu_device_new ();
fu_device_set_version_format (dev, FWUPD_VERSION_FORMAT_PLAIN);
key = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER);
if (key != NULL)
fu_device_set_vendor (dev, key);
key = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
if (key != NULL) {
g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", key);
fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id);
}
key = "System Firmware";
fu_device_set_name (dev, key);
key = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VERSION);
if (key != NULL)
fu_device_set_version (dev, key);
fu_device_set_update_error (dev, reason);
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_icon (dev, "computer");
fu_device_set_id (dev, "BIOS-dummy");
fu_device_add_instance_id (dev, "main-system-firmware");
if (!fu_device_setup (dev, error))
return FALSE;
fu_plugin_device_add (plugin, dev);
return TRUE;
}
gboolean
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
{
g_autofree gchar *sysfsfwdir = NULL;
g_autoptr(GError) error_local = NULL;
g_autofree gchar *esrt_path = NULL;
/* are the EFI dirs set up so we can update each device */
if (!fu_efivar_supported (&error_local)) {
const gchar *reason = "Firmware can not be updated in legacy BIOS mode, switch to UEFI mode";
g_warning ("%s", error_local->message);
return fu_plugin_bios_create_dummy (plugin, reason, error);
}
/* get the directory of ESRT entries */
sysfsfwdir = fu_common_get_path (FU_PATH_KIND_SYSFSDIR_FW);
esrt_path = g_build_filename (sysfsfwdir, "efi", "esrt", NULL);
if (!g_file_test (esrt_path, G_FILE_TEST_IS_DIR)) {
const gchar *reason = "UEFI Capsule updates not available or enabled";
return fu_plugin_bios_create_dummy (plugin, reason, error);
}
/* we appear to have UEFI capsule updates */
fu_plugin_set_enabled (plugin, FALSE);
return TRUE;
}

23
plugins/bios/meson.build Normal file
View File

@ -0,0 +1,23 @@
cargs = ['-DG_LOG_DOMAIN="FuPluginBios"']
shared_module('fu_plugin_bios',
fu_hash,
sources : [
'fu-plugin-bios.c',
],
include_directories : [
root_incdir,
fwupd_incdir,
fwupdplugin_incdir,
],
install : true,
install_dir: plugin_dir,
link_with : [
fwupd,
fwupdplugin,
],
c_args : cargs,
dependencies : [
plugin_deps,
],
)

View File

@ -87,7 +87,7 @@ void
fu_plugin_init (FuPlugin *plugin)
{
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_BETTER_THAN, "uefi");
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_BETTER_THAN, "bios");
}
gboolean
@ -172,6 +172,8 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error)
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_LOCKED);
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
fu_device_set_update_error (dev, "Firmware updates disabled; run 'fwupdmgr unlock' to enable");
if (!fu_device_setup (dev, error))
return FALSE;
fu_plugin_device_add (plugin, dev);
return TRUE;
}

View File

@ -1,5 +1,6 @@
subdir('acpi-dmar')
subdir('acpi-facp')
subdir('bios')
subdir('ccgx')
subdir('cros-ec')
subdir('cpu')

View File

@ -725,43 +725,6 @@ fu_plugin_unlock (FuPlugin *plugin, FuDevice *device, GError **error)
return TRUE;
}
static gboolean
fu_plugin_uefi_create_dummy (FuPlugin *plugin, const gchar *reason, GError **error)
{
const gchar *key;
g_autoptr(FuDevice) dev = fu_device_new ();
fu_device_set_version_format (dev, FWUPD_VERSION_FORMAT_PLAIN);
key = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER);
if (key != NULL)
fu_device_set_vendor (dev, key);
key = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VENDOR);
if (key != NULL) {
g_autofree gchar *vendor_id = g_strdup_printf ("DMI:%s", key);
fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id);
}
key = fu_plugin_uefi_get_name_for_type (plugin, FU_UEFI_DEVICE_KIND_SYSTEM_FIRMWARE);
fu_device_set_name (dev, key);
key = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VERSION);
if (key != NULL)
fu_device_set_version (dev, key);
fu_device_set_update_error (dev, reason);
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_MD_SET_VERFMT);
fu_device_add_icon (dev, "computer");
fu_device_set_id (dev, "UEFI-dummy");
fu_device_add_instance_id (dev, "main-system-firmware");
if (!fu_device_setup (dev, error))
return FALSE;
fu_plugin_device_add (plugin, dev);
return TRUE;
}
gboolean
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
{
@ -776,21 +739,15 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error)
g_autoptr(GPtrArray) entries = NULL;
/* are the EFI dirs set up so we can update each device */
if (!fu_efivar_supported (&error_local)) {
const gchar *reason = "Firmware can not be updated in legacy mode, switch to UEFI mode";
g_warning ("%s", error_local->message);
return fu_plugin_uefi_create_dummy (plugin, reason, error);
}
if (!fu_efivar_supported (error))
return FALSE;
/* get the directory of ESRT entries */
sysfsfwdir = fu_common_get_path (FU_PATH_KIND_SYSFSDIR_FW);
esrt_path = g_build_filename (sysfsfwdir, "efi", "esrt", NULL);
entries = fu_uefi_get_esrt_entry_paths (esrt_path, &error_local);
if (entries == NULL) {
const gchar *reason = "UEFI Capsule updates not available or enabled";
g_warning ("%s", error_local->message);
return fu_plugin_uefi_create_dummy (plugin, reason, error);
}
entries = fu_uefi_get_esrt_entry_paths (esrt_path, error);
if (entries == NULL)
return FALSE;
/* make sure that efivarfs is rw */
if (!fu_plugin_uefi_ensure_efivarfs_rw (&error_efivarfs))