Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
flashrom: Add a plugin for updating using the flashrom command line tool
- Loading branch information
Showing
15 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Flashrom | ||
======== | ||
|
||
Introduction | ||
------------ | ||
|
||
This plugin uses `flashrom` to update the system firmware. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#/bin/sh | ||
appstream-util validate-relax com.Flashrom.Laptop.metainfo.xml | ||
tar -cf firmware.tar startup.sh random-tool | ||
gcab --create --nopath Flashrom-Laptop-1.2.3.cab firmware.tar com.Flashrom.Laptop.metainfo.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- Copyright 2017 Richard Hughes <richard@hughsie.com> --> | ||
<component type="firmware"> | ||
<id>com.Flashrom.Laptop.firmware</id> | ||
<name>Flashrom Laptop Firmware</name> | ||
<summary>System firmware for a Flashrom laptop</summary> | ||
<description> | ||
<p> | ||
The laptop can be updated using flashrom. | ||
</p> | ||
</description> | ||
<provides> | ||
<!-- this is a suitable HWID, found using `fwupdmgr hwids` --> | ||
<firmware type="flashed">a0ce5085-2dea-5086-ae72-45810a186ad0</firmware> | ||
</provides> | ||
<url type="homepage">http://www.bbc.co.uk/</url> | ||
<metadata_license>CC0-1.0</metadata_license> | ||
<project_license>Proprietary</project_license> <!-- FIXME? --> | ||
<developer_name>Flashrom</developer_name> | ||
<releases> | ||
<release urgency="high" version="1.2.3" date="2017-08-15"> | ||
<checksum filename="firmware.tar" target="content"/> | ||
<description> | ||
<p> | ||
This release updates a frobnicator to frob faster. | ||
</p> | ||
</description> | ||
</release> | ||
</releases> | ||
|
||
<!-- this script is run with bubblewrap -- the old firmware is in /boot --> | ||
<custom> | ||
<value key="fwupd::BuilderScript">startup.sh</value> | ||
<value key="fwupd::BuilderOutput">firmware.bin</value> | ||
</custom> | ||
|
||
<!-- only newer versions of fwupd know how to write to this hardware --> | ||
<requires> | ||
<id compare="ge" version="1.0.1">org.freedesktop.fwupd</id> | ||
</requires> | ||
|
||
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#/bin/sh | ||
echo "hello from the sandbox" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#/bin/sh | ||
|
||
# do something with the old firmware | ||
sha1sum /boot/flashrom-librem15v3.bin | ||
|
||
# run a random tool | ||
./random-tool | ||
|
||
# this is the deliverable | ||
cp /boot/flashrom-librem15v3.bin firmware.bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[fwupd-flashrom-hwid] | ||
|
||
# Purism | ||
a0ce5085-2dea-5086-ae72-45810a186ad0=librem15v3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- | ||
* | ||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com> | ||
* | ||
* Licensed under the GNU General Public License Version 2 | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
*/ | ||
|
||
#include "config.h" | ||
|
||
#include <string.h> | ||
|
||
#include "fu-plugin.h" | ||
#include "fu-plugin-vfuncs.h" | ||
|
||
struct FuPluginData { | ||
gchar *flashrom_fn; | ||
}; | ||
|
||
void | ||
fu_plugin_init (FuPlugin *plugin) | ||
{ | ||
fu_plugin_alloc_data (plugin, sizeof (FuPluginData)); | ||
} | ||
|
||
void | ||
fu_plugin_destroy (FuPlugin *plugin) | ||
{ | ||
FuPluginData *data = fu_plugin_get_data (plugin); | ||
g_free (data->flashrom_fn); | ||
} | ||
|
||
gboolean | ||
fu_plugin_startup (FuPlugin *plugin, GError **error) | ||
{ | ||
FuPluginData *data = fu_plugin_get_data (plugin); | ||
GPtrArray *hwids; | ||
|
||
/* we need flashrom from the host system */ | ||
data->flashrom_fn = g_find_program_in_path ("flashrom"); | ||
if (data->flashrom_fn == NULL) { | ||
g_set_error_literal (error, | ||
FWUPD_ERROR, | ||
FWUPD_ERROR_NOT_SUPPORTED, | ||
"flashrom is not installed"); | ||
return FALSE; | ||
} | ||
|
||
/* search for devices */ | ||
hwids = fu_plugin_get_hwids (plugin); | ||
for (guint i = 0; i < hwids->len; i++) { | ||
const gchar *quirk; | ||
const gchar *guid = g_ptr_array_index (hwids, i); | ||
quirk = fu_plugin_lookup_quirk_by_id (plugin, | ||
FU_QUIRKS_FLASHROM_HWID, | ||
guid); | ||
if (quirk != NULL) { | ||
g_autofree gchar *device_id = g_strdup_printf ("flashrom-%s", quirk); | ||
g_autoptr(FuDevice) dev = fu_device_new (); | ||
fu_device_set_id (dev, device_id); | ||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL); | ||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); | ||
fu_device_add_guid (dev, guid); | ||
fu_device_set_version (dev, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_BIOS_VERSION)); | ||
fu_device_set_name (dev, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_PRODUCT_NAME)); | ||
fu_device_set_vendor (dev, fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER)); | ||
fu_plugin_device_add (plugin, dev); | ||
fu_plugin_cache_add (plugin, device_id, dev); | ||
break; | ||
} | ||
} | ||
return TRUE; | ||
} | ||
|
||
static guint | ||
fu_plugin_flashrom_parse_percentage (FuPlugin *plugin, const gchar *lines_verbose) | ||
{ | ||
const guint64 addr_highest = 0xffffff; | ||
guint64 addr_best = 0x0; | ||
g_auto(GStrv) chunks = NULL; | ||
|
||
/* parse 0x000000-0x000fff:S, 0x001000-0x001fff:S */ | ||
chunks = g_strsplit_set (lines_verbose, "x-:S, \n\r", -1); | ||
for (guint i = 0; chunks[i] != NULL; i++) { | ||
guint64 addr_tmp; | ||
if (strlen (chunks[i]) != 6) | ||
continue; | ||
addr_tmp = g_ascii_strtoull (chunks[i], NULL, 16); | ||
if (addr_tmp > addr_best) | ||
addr_best = addr_tmp; | ||
} | ||
return (addr_best * 100) / addr_highest; | ||
} | ||
|
||
static void | ||
fu_plugin_flashrom_read_cb (const gchar *line, gpointer user_data) | ||
{ | ||
FuPlugin *plugin = FU_PLUGIN (user_data); | ||
if (g_strcmp0 (line, "Reading flash...") == 0) | ||
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_VERIFY); | ||
fu_plugin_set_percentage (plugin, fu_plugin_flashrom_parse_percentage (plugin, line)); | ||
} | ||
|
||
static void | ||
fu_plugin_flashrom_write_cb (const gchar *line, gpointer user_data) | ||
{ | ||
FuPlugin *plugin = FU_PLUGIN (user_data); | ||
if (g_strcmp0 (line, "Writing flash...") == 0) | ||
fu_plugin_set_status (plugin, FWUPD_STATUS_DEVICE_WRITE); | ||
fu_plugin_set_percentage (plugin, fu_plugin_flashrom_parse_percentage (plugin, line)); | ||
} | ||
|
||
gboolean | ||
fu_plugin_update_prepare (FuPlugin *plugin, | ||
FuDevice *device, | ||
GError **error) | ||
{ | ||
FuPluginData *data = fu_plugin_get_data (plugin); | ||
g_autofree gchar *firmware_orig = NULL; | ||
g_autofree gchar *basename = NULL; | ||
|
||
/* not us */ | ||
if (fu_plugin_cache_lookup (plugin, fu_device_get_id (device)) == NULL) | ||
return TRUE; | ||
|
||
/* if the original firmware doesn't exist, grab it now */ | ||
basename = g_strdup_printf ("flashrom-%s.bin", fu_device_get_id (device)); | ||
firmware_orig = g_build_filename (LOCALSTATEDIR, "lib", "fwupd", | ||
"builder", basename, NULL); | ||
if (!fu_common_mkdir_parent (firmware_orig, error)) | ||
return FALSE; | ||
if (!g_file_test (firmware_orig, G_FILE_TEST_EXISTS)) { | ||
const gchar *argv[] = { | ||
data->flashrom_fn, | ||
"--programmer", "internal:laptop=force_I_want_a_brick", | ||
"--read", firmware_orig, | ||
"--verbose", NULL }; | ||
if (!fu_common_spawn_sync ((const gchar * const *) argv, | ||
fu_plugin_flashrom_read_cb, plugin, | ||
NULL, error)) { | ||
g_prefix_error (error, "failed to get original firmware: "); | ||
return FALSE; | ||
} | ||
fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE); | ||
} | ||
|
||
return TRUE; | ||
} | ||
|
||
gboolean | ||
fu_plugin_update (FuPlugin *plugin, | ||
FuDevice *device, | ||
GBytes *blob_fw, | ||
FwupdInstallFlags flags, | ||
GError **error) | ||
{ | ||
FuPluginData *data = fu_plugin_get_data (plugin); | ||
g_autofree gchar *firmware_fn = NULL; | ||
g_autofree gchar *tmpdir = NULL; | ||
const gchar *argv[] = { | ||
data->flashrom_fn, | ||
"--programmer", "internal:laptop=force_I_want_a_brick", | ||
"--write", "xxx", | ||
"--verbose", NULL }; | ||
|
||
/* write blob to temp location */ | ||
tmpdir = g_dir_make_tmp ("fwupd-XXXXXX", error); | ||
if (tmpdir == NULL) | ||
return FALSE; | ||
firmware_fn = g_build_filename (tmpdir, "flashrom-firmware.bin", NULL); | ||
if (!fu_common_set_contents_bytes (firmware_fn, blob_fw, error)) | ||
return FALSE; | ||
|
||
/* use flashrom to write image */ | ||
argv[4] = firmware_fn; | ||
if (!fu_common_spawn_sync ((const gchar * const *) argv, | ||
fu_plugin_flashrom_write_cb, plugin, | ||
NULL, error)) { | ||
g_prefix_error (error, "failed to write firmware: "); | ||
return FALSE; | ||
} | ||
|
||
/* delete temp location */ | ||
if (!fu_common_rmtree (tmpdir, error)) | ||
return FALSE; | ||
|
||
/* success */ | ||
fu_plugin_set_status (plugin, FWUPD_STATUS_IDLE); | ||
return TRUE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
cargs = ['-DG_LOG_DOMAIN="FuPluginFlashrom"'] | ||
|
||
install_data(['flashrom.quirk'], | ||
install_dir: join_paths(get_option('datadir'), 'fwupd', 'quirks.d') | ||
) | ||
|
||
shared_module('fu_plugin_flashrom', | ||
sources : [ | ||
'fu-plugin-flashrom.c', | ||
], | ||
include_directories : [ | ||
include_directories('../..'), | ||
include_directories('../../src'), | ||
include_directories('../../libfwupd'), | ||
], | ||
install : true, | ||
install_dir: plugin_dir, | ||
c_args : [ | ||
cargs, | ||
'-DLOCALSTATEDIR="' + localstatedir + '"', | ||
], | ||
dependencies : [ | ||
plugin_deps, | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
subdir('dfu') | ||
subdir('ebitdo') | ||
subdir('flashrom') | ||
subdir('raspberrypi') | ||
subdir('steelseries') | ||
subdir('test') | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.