uefi-recovery: Add a plugin to add a fake ESRT entry for device recovery

The factory-shipped MinnowBoardMAX board has firmware that does not include
the ESRT table. Create a 'fake' UEFI device with the lowest possible version
so that it can be updated to any version firmware.

All the HwId GUIDs are used for the fake UEFI device, and so should be used in
the firmware metadata for releases that should recover the system.
This commit is contained in:
Richard Hughes 2019-09-10 21:11:32 +01:00
parent 1984180592
commit 04cb360847
7 changed files with 105 additions and 1 deletions

View File

@ -340,6 +340,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
%{_libdir}/fwupd-plugins-3/libfu_plugin_udev.so
%if 0%{?have_uefi}
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so
%endif
%{_libdir}/fwupd-plugins-3/libfu_plugin_unifying.so
%{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so

View File

@ -57,6 +57,7 @@ endif
if get_option('plugin_uefi')
subdir('uefi')
subdir('uefi-recovery')
endif
if get_option('plugin_flashrom')

View File

@ -0,0 +1,17 @@
UEFI Support
============
Introduction
------------
Some devices have firmware bugs which mean they do not include a valid ESRT
table in old firmware versions.
Create a 'fake' UEFI device with the lowest possible version so that it can be
updated to a version of firmware which does have an ESRT table.
GUID Generation
---------------
All the HwId GUIDs are used for the fake UEFI device, and so should be used in
the firmware metadata for releases that should recover the system.

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#include "config.h"
#include "fu-device-metadata.h"
#include "fu-plugin-vfuncs.h"
void
fu_plugin_init (FuPlugin *plugin)
{
/* make sure that UEFI plugin is ready to receive devices */
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "uefi");
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
}
gboolean
fu_plugin_startup (FuPlugin *plugin, GError **error)
{
if (!fu_plugin_has_custom_flag (plugin, "requires-uefi-recovery")) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"not required");
return FALSE;
}
return TRUE;
}
gboolean
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
{
GPtrArray *hwids = fu_plugin_get_hwids (plugin);
g_autoptr(FuDevice) device = fu_device_new ();
fu_device_set_id (device, "uefi-recovery");
fu_device_set_name (device, "System Firmware ESRT Recovery");
fu_device_set_version (device, "0.0.0", FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
fu_device_set_metadata (device, FU_DEVICE_METADATA_UEFI_DEVICE_KIND, "system-firmware");
fu_device_add_icon (device, "computer");
for (guint i = 0; i < hwids->len; i++) {
const gchar *hwid = g_ptr_array_index (hwids, i);
fu_device_add_guid (device, hwid);
}
fu_plugin_device_register (plugin, device);
return TRUE;
}

View File

@ -0,0 +1,28 @@
cargs = ['-DG_LOG_DOMAIN="FuPluginUefiRecovery"']
install_data(['uefi-recovery.quirk'],
install_dir: join_paths(datadir, 'fwupd', 'quirks.d')
)
shared_module('fu_plugin_uefi_recovery',
fu_hash,
sources : [
'fu-plugin-uefi-recovery.c',
],
include_directories : [
include_directories('../..'),
include_directories('../../src'),
include_directories('../../libfwupd'),
],
install : true,
install_dir: plugin_dir,
link_with : [
libfwupdprivate,
],
c_args : [
cargs,
],
dependencies : [
plugin_deps,
],
)

View File

@ -0,0 +1,3 @@
# Silicom Minnowboard Turbot MNW2MAX1.X64.0100.R01.1811141729
[HwId=ea358e00-39f1-55b6-97be-a39225a585e1]
Flags = requires-uefi-recovery

View File

@ -12,6 +12,7 @@
#include <gio/gunixmounts.h>
#include <glib/gi18n.h>
#include "fu-device-metadata.h"
#include "fu-plugin-vfuncs.h"
#include "fu-uefi-bgrt.h"
@ -448,7 +449,7 @@ fu_plugin_uefi_register_proxy_device (FuPlugin *plugin, FuDevice *device)
void
fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device)
{
if (fu_device_get_metadata (device, "UefiDeviceKind") != NULL) {
if (fu_device_get_metadata (device, FU_DEVICE_METADATA_UEFI_DEVICE_KIND) != NULL) {
if (fu_device_get_guid_default (device) == NULL) {
g_autofree gchar *dbg = fu_device_to_string (device);
g_warning ("cannot create proxy device as no GUID: %s", dbg);