mirror of
https://git.proxmox.com/git/fwupd
synced 2026-03-27 00:21:50 +00:00
altos: Remove support for the ChaosKey
The hardware is discontinued, and no further update from 1.6.7 was ever supplied.
This commit is contained in:
parent
a9e696ab62
commit
9ef27052d5
2
.github/workflows/freebsd.yml
vendored
2
.github/workflows/freebsd.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
prepare: |
|
||||
pkg install -y git python3 glib meson pkgconf gobject-introspection \
|
||||
vala gtk-doc json-glib gpgme gnutls sqlite3 curl gcab libarchive \
|
||||
libelf libgpg-error gettext-tools gtk-update-icon-cache atk pango \
|
||||
libgpg-error gettext-tools gtk-update-icon-cache atk pango \
|
||||
binutils gcc protobuf-c
|
||||
sync: rsync
|
||||
run: ./contrib/ci/build_freebsd_package.sh
|
||||
|
||||
@ -27,7 +27,6 @@ meson .. \
|
||||
-Dplugin_flashrom=false \
|
||||
-Dplugin_uefi_capsule=false \
|
||||
-Dplugin_redfish=false \
|
||||
-Dplugin_altos=false \
|
||||
-Dplugin_dell=false \
|
||||
-Dplugin_logitech_bulkcontroller=false \
|
||||
-Dplugin_nvme=false \
|
||||
|
||||
@ -18,7 +18,6 @@ BUILD_DEPENDS= gtkdoc-scan:textproc/gtk-doc \
|
||||
${PYTHON_PKGNAMEPREFIX}gobject3>0:devel/py-gobject3@${PY_FLAVOR}
|
||||
LIB_DEPENDS= libcurl.so:ftp/curl \
|
||||
libefiboot.so:devel/libefiboot \
|
||||
libelf.so:devel/libelf \
|
||||
libgcab-1.0.so:archivers/gcab \
|
||||
libgnutls.so:security/gnutls \
|
||||
libgpg-error.so:security/libgpg-error \
|
||||
@ -42,7 +41,6 @@ USE_LDCONFIG= yes
|
||||
SHEBANG_GLOB= *.py
|
||||
|
||||
MESON_ARGS= -Dgudev=false \
|
||||
-Dplugin_altos=false \
|
||||
-Dplugin_amt=false \
|
||||
-Dplugin_dell=false \
|
||||
-Dplugin_emmc=false \
|
||||
|
||||
@ -70,7 +70,6 @@ BuildRequires: gcab
|
||||
BuildRequires: valgrind
|
||||
BuildRequires: valgrind-devel
|
||||
%endif
|
||||
BuildRequires: elfutils-libelf-devel
|
||||
BuildRequires: gtk-doc
|
||||
BuildRequires: gnutls-devel
|
||||
BuildRequires: gnutls-utils
|
||||
@ -411,7 +410,6 @@ done
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_acpi_dmar.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_acpi_facp.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_acpi_phat.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_altos.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_amt.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_analogix.so
|
||||
%{_libdir}/fwupd-plugins-%{fwupdplugin_version}/libfu_plugin_ata.so
|
||||
|
||||
@ -296,11 +296,6 @@ if get_option('offline')
|
||||
conf.set('HAVE_FWUPDOFFLINE', '1')
|
||||
endif
|
||||
|
||||
|
||||
if build_standalone and get_option('plugin_altos')
|
||||
libelf = dependency('libelf')
|
||||
endif
|
||||
|
||||
host_cpu = host_machine.cpu_family()
|
||||
|
||||
if cc.has_header('sys/utsname.h')
|
||||
|
||||
@ -12,7 +12,6 @@ option('bluez', type : 'boolean', value : false, description : 'enable BlueZ sup
|
||||
option('polkit', type: 'boolean', value : true, description : 'enable PolKit support in daemon')
|
||||
option('gnutls', type: 'boolean', value : true, description : 'enable GnuTLS support')
|
||||
option('lzma', type: 'boolean', value : false, description : 'enable LZMA support')
|
||||
option('plugin_altos', type : 'boolean', value : true, description : 'enable altos support')
|
||||
option('plugin_amt', type : 'boolean', value : true, description : 'enable Intel AMT support')
|
||||
option('plugin_dell', type : 'boolean', value : true, description : 'enable Dell-specific support')
|
||||
option('plugin_dummy', type : 'boolean', value : false, description : 'enable the dummy device')
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
# Altos
|
||||
|
||||
## Introduction
|
||||
|
||||
Altos is a 8051 operating system for Altus-Metrum projects.
|
||||
The ChaosKey is a hardware random number generator that attaches via USB.
|
||||
|
||||
When the ChaosKey when inserted it appears as a device handled by the kernel
|
||||
with VID 0x1d50 and PID 0x60c6. If pins 1 and 5 are shorted as the device is
|
||||
connected then the bootloader is run, which presents VID 0xfffe and PID 0x000a.
|
||||
|
||||
The bootloader communication is not handled in the kernel, and a tty device is
|
||||
created so userspace can communicate with the hardware. Commands the bootloader
|
||||
accept are as follows:
|
||||
|
||||
## Firmware Format
|
||||
|
||||
The daemon will decompress the cabinet archive and extract a firmware blob in
|
||||
ELF file format. The firmware image is inserted into the `.text` section.
|
||||
|
||||
This plugin supports the following protocol ID:
|
||||
|
||||
* org.altusmetrum.altos
|
||||
|
||||
## GUID Generation
|
||||
|
||||
These devices use the standard USB DeviceInstanceId values, e.g.
|
||||
|
||||
* `USB\VID_1D50&PID_60C6&REV_0001`
|
||||
* `USB\VID_1D50&PID_60C6`
|
||||
* `USB\VID_1D50`
|
||||
|
||||
## Update Behavior
|
||||
|
||||
The device usually presents in runtime mode, but on detach re-enumerates with a
|
||||
different USB PID in a bootloader mode. On attach the device again re-enumerates
|
||||
back to the runtime mode.
|
||||
|
||||
For this reason the `REPLUG_MATCH_GUID` internal device flag is used so that
|
||||
the bootloader and runtime modes are treated as the same device.
|
||||
|
||||
## Vendor ID Security
|
||||
|
||||
The vendor ID is set from the USB vendor, in this instance set to `USB:0x1D50`
|
||||
|
||||
## External Interface Access
|
||||
|
||||
This plugin requires read/write access to `/dev/bus/usb`.
|
||||
|
||||
### List Information
|
||||
|
||||
Command: `l\n`
|
||||
Several lines of text about the device are transferred to the host, e.g.
|
||||
|
||||
```text
|
||||
altos-loader
|
||||
manufacturer altusmetrum.org
|
||||
product AltosFlash
|
||||
flash-range 08001000 08008000
|
||||
software-version 1.6.8
|
||||
```
|
||||
|
||||
There doesn't appear to be any kind of end-of-message signal.
|
||||
|
||||
### Read Flash
|
||||
|
||||
Command: `R $addr\n` where `$addr` is a memory address `0x8001000->0x8008000`.
|
||||
256 bytes of raw data are then transferred to the host.
|
||||
|
||||
### Write Flash
|
||||
|
||||
Command: `W $addr\n` where `$addr` is a memory address `0x8001000->0x8008000`.
|
||||
256 bytes of raw data are then transferred to the device.
|
||||
|
||||
### Application Mode
|
||||
|
||||
Command: `v\n`
|
||||
The device will reboot into application mode. This is typically performed after
|
||||
flashing firmware completes successfully.
|
||||
@ -1,11 +0,0 @@
|
||||
# ChaosKey
|
||||
[USB\VID_1D50&PID_60C6]
|
||||
Plugin = altos
|
||||
Flags = ~is-bootloader
|
||||
Name = Altus-Metrum ChaosKey
|
||||
CounterpartGuid = USB\VID_FFFE&PID_000A
|
||||
|
||||
[USB\VID_FFFE&PID_000A]
|
||||
Plugin = altos
|
||||
Flags = is-bootloader
|
||||
Name = Altos [bootloader]
|
||||
@ -1,90 +0,0 @@
|
||||
Bus 001 Device 037: ID fffe:000a
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.10
|
||||
bDeviceClass 2 Communications
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 32
|
||||
idVendor 0xfffe
|
||||
idProduct 0x000a
|
||||
bcdDevice 1.00
|
||||
iManufacturer 1 altusmetrum.org
|
||||
iProduct 2 AltosFlash
|
||||
iSerial 3 000001
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 67
|
||||
bNumInterfaces 2
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0xc0
|
||||
Self Powered
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 2 Communications
|
||||
bInterfaceSubClass 2 Abstract (modem)
|
||||
bInterfaceProtocol 1 AT-commands (v.25ter)
|
||||
iInterface 0
|
||||
CDC Header:
|
||||
bcdCDC 1.10
|
||||
CDC Call Management:
|
||||
bmCapabilities 0x01
|
||||
call management
|
||||
bDataInterface 1
|
||||
CDC ACM:
|
||||
bmCapabilities 0x02
|
||||
line coding and serial state
|
||||
CDC Union:
|
||||
bMasterInterface 0
|
||||
bSlaveInterface 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x81 EP 1 IN
|
||||
bmAttributes 3
|
||||
Transfer Type Interrupt
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0008 1x 8 bytes
|
||||
bInterval 255
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 1
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 10 CDC Data
|
||||
bInterfaceSubClass 0
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x04 EP 4 OUT
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x85 EP 5 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 0
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
||||
@ -1,58 +0,0 @@
|
||||
Bus 001 Device 036: ID 1d50:60c6 OpenMoko, Inc.
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 1.10
|
||||
bDeviceClass 255 Vendor Specific Class
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 32
|
||||
idVendor 0x1d50 OpenMoko, Inc.
|
||||
idProduct 0x60c6
|
||||
bcdDevice 1.00
|
||||
iManufacturer 1 altusmetrum.org
|
||||
iProduct 2 ChaosKey-hw-1.0-sw-1.6.7
|
||||
iSerial 3 001b002f5346430b20333632
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 32
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 255 Vendor Specific Class
|
||||
bInterfaceSubClass 0
|
||||
bInterfaceProtocol 0
|
||||
iInterface 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x85 EP 5 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 0
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x86 EP 6 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 0
|
||||
Device Status: 0x0000
|
||||
(Bus Powered)
|
||||
@ -1,581 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "fu-altos-device.h"
|
||||
#include "fu-altos-firmware.h"
|
||||
|
||||
struct _FuAltosDevice {
|
||||
FuUsbDevice parent_instance;
|
||||
gchar *tty;
|
||||
guint64 addr_base;
|
||||
guint64 addr_bound;
|
||||
struct termios tty_termios;
|
||||
FuIOChannel *io_channel;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuAltosDevice, fu_altos_device, FU_TYPE_USB_DEVICE)
|
||||
|
||||
static void
|
||||
fu_altos_device_to_string(FuDevice *device, guint idt, GString *str)
|
||||
{
|
||||
FuAltosDevice *self = FU_ALTOS_DEVICE(device);
|
||||
fu_common_string_append_kv(str, idt, "TTY", self->tty);
|
||||
if (self->addr_base != 0x0)
|
||||
fu_common_string_append_kx(str, idt, "AddrBase", self->addr_base);
|
||||
if (self->addr_bound != 0x0)
|
||||
fu_common_string_append_kx(str, idt, "AddrBound", self->addr_bound);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_device_finalize(GObject *object)
|
||||
{
|
||||
FuAltosDevice *self = FU_ALTOS_DEVICE(object);
|
||||
|
||||
g_free(self->tty);
|
||||
|
||||
G_OBJECT_CLASS(fu_altos_device_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_find_tty(FuAltosDevice *self, GError **error)
|
||||
{
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(self));
|
||||
g_autoptr(GList) devices = NULL;
|
||||
g_autoptr(GUdevClient) gudev_client = g_udev_client_new(NULL);
|
||||
|
||||
/* find all tty devices */
|
||||
devices = g_udev_client_query_by_subsystem(gudev_client, "tty");
|
||||
for (GList *l = devices; l != NULL; l = l->next) {
|
||||
GUdevDevice *dev = G_UDEV_DEVICE(l->data);
|
||||
|
||||
/* get the tty device */
|
||||
const gchar *dev_file = g_udev_device_get_device_file(dev);
|
||||
if (dev_file == NULL)
|
||||
continue;
|
||||
|
||||
/* get grandparent */
|
||||
dev = g_udev_device_get_parent(dev);
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
dev = g_udev_device_get_parent(dev);
|
||||
if (dev == NULL)
|
||||
continue;
|
||||
|
||||
/* check correct device */
|
||||
if (g_udev_device_get_sysfs_attr_as_int(dev, "busnum") !=
|
||||
g_usb_device_get_bus(usb_device))
|
||||
continue;
|
||||
if (g_udev_device_get_sysfs_attr_as_int(dev, "devnum") !=
|
||||
g_usb_device_get_address(usb_device))
|
||||
continue;
|
||||
|
||||
/* success */
|
||||
self->tty = g_strdup(dev_file);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* failure */
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"failed to find tty for %u:%u",
|
||||
g_usb_device_get_bus(usb_device),
|
||||
g_usb_device_get_address(usb_device));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_tty_write(FuAltosDevice *self, const gchar *data, gssize data_len, GError **error)
|
||||
{
|
||||
/* lets assume this is text */
|
||||
if (data_len < 0)
|
||||
data_len = strlen(data);
|
||||
if (g_getenv("FWUPD_ALTOS_VERBOSE") != NULL)
|
||||
fu_common_dump_raw(G_LOG_DOMAIN, "write", (const guint8 *)data, (gsize)data_len);
|
||||
return fu_io_channel_write_raw(self->io_channel,
|
||||
(const guint8 *)data,
|
||||
(gsize)data_len,
|
||||
500, /* ms */
|
||||
FU_IO_CHANNEL_FLAG_NONE,
|
||||
error);
|
||||
}
|
||||
|
||||
static GString *
|
||||
fu_altos_device_tty_read(FuAltosDevice *self, guint timeout_ms, gssize max_size, GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) buf = NULL;
|
||||
buf = fu_io_channel_read_bytes(self->io_channel,
|
||||
max_size,
|
||||
timeout_ms,
|
||||
FU_IO_CHANNEL_FLAG_NONE,
|
||||
error);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
if (g_getenv("FWUPD_ALTOS_VERBOSE") != NULL)
|
||||
fu_common_dump_bytes(G_LOG_DOMAIN, "read", buf);
|
||||
return g_string_new_len(g_bytes_get_data(buf, NULL), g_bytes_get_size(buf));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_tty_open(FuAltosDevice *self, GError **error)
|
||||
{
|
||||
struct termios termios;
|
||||
g_autoptr(GString) str = NULL;
|
||||
|
||||
/* open device */
|
||||
self->io_channel = fu_io_channel_new_file(self->tty, error);
|
||||
if (self->io_channel == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* get the old termios settings so we can restore later */
|
||||
if (tcgetattr(fu_io_channel_unix_get_fd(self->io_channel), &termios) < 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to get attributes from fd");
|
||||
return FALSE;
|
||||
}
|
||||
self->tty_termios = termios;
|
||||
cfmakeraw(&termios);
|
||||
|
||||
/* set speed */
|
||||
if (cfsetspeed(&termios, B9600) < 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to set terminal speed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* one input byte is enough to return
|
||||
* inter-character timer off */
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 0;
|
||||
|
||||
/* set all new data */
|
||||
if (tcsetattr(fu_io_channel_unix_get_fd(self->io_channel), TCSAFLUSH, &termios) < 0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to set attributes on fd");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* dump any pending input */
|
||||
str = fu_altos_device_tty_read(self, 50, -1, NULL);
|
||||
if (str != NULL)
|
||||
g_debug("dumping pending buffer: %s", str->str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_tty_close(FuAltosDevice *self, GError **error)
|
||||
{
|
||||
if (self->io_channel != NULL) {
|
||||
tcsetattr(fu_io_channel_unix_get_fd(self->io_channel),
|
||||
TCSAFLUSH,
|
||||
&self->tty_termios);
|
||||
if (!fu_io_channel_shutdown(self->io_channel, error))
|
||||
return FALSE;
|
||||
g_clear_object(&self->io_channel);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GString *
|
||||
fu_altos_device_read_page(FuAltosDevice *self, guint address, GError **error)
|
||||
{
|
||||
g_autoptr(GString) str = NULL;
|
||||
g_autofree gchar *cmd = g_strdup_printf("R %x\n", address);
|
||||
if (!fu_altos_device_tty_write(self, cmd, -1, error))
|
||||
return NULL;
|
||||
str = fu_altos_device_tty_read(self, 1500, 256, error);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
return g_steal_pointer(&str);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_write_page(FuAltosDevice *self,
|
||||
guint address,
|
||||
const guint8 *data,
|
||||
guint data_len,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree gchar *cmd = g_strdup_printf("W %x\n", address);
|
||||
if (!fu_altos_device_tty_write(self, cmd, -1, error))
|
||||
return FALSE;
|
||||
if (!fu_altos_device_tty_write(self, (const gchar *)data, data_len, error))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_write_firmware(FuDevice *device,
|
||||
FuFirmware *firmware,
|
||||
FuProgress *progress,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
FuAltosDevice *self = FU_ALTOS_DEVICE(device);
|
||||
const gchar *data;
|
||||
const gsize data_len;
|
||||
guint flash_len;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(GBytes) fw = NULL;
|
||||
g_autoptr(GString) buf = g_string_new(NULL);
|
||||
|
||||
/* check kind */
|
||||
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"verification only supported in bootloader");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* open */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 90);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 5); /* attach */
|
||||
|
||||
/* check sizes */
|
||||
if (self->addr_base == 0x0 || self->addr_bound == 0x0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"address base and bound are unset");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* read in blocks of 256 bytes */
|
||||
flash_len = self->addr_bound - self->addr_base;
|
||||
if (flash_len == 0x0 || flash_len > 0x100000) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"address range was icorrect");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check the start address */
|
||||
if (fu_firmware_get_addr(firmware) != self->addr_base) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"start address not correct %" G_GUINT64_FORMAT ":"
|
||||
"%" G_GUINT64_FORMAT,
|
||||
fu_firmware_get_addr(firmware),
|
||||
self->addr_base);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check firmware will fit */
|
||||
fw = fu_firmware_get_bytes(firmware, error);
|
||||
if (fw == NULL)
|
||||
return FALSE;
|
||||
data = g_bytes_get_data(fw, (gsize *)&data_len);
|
||||
if (data_len > flash_len) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INVALID_FILE,
|
||||
"firmware too large for device %" G_GSIZE_FORMAT ":%u",
|
||||
data_len,
|
||||
flash_len);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* open tty for download */
|
||||
locker = fu_device_locker_new_full(device,
|
||||
(FuDeviceLockerFunc)fu_altos_device_tty_open,
|
||||
(FuDeviceLockerFunc)fu_altos_device_tty_close,
|
||||
error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
for (guint i = 0; i < flash_len; i += 0x100) {
|
||||
g_autoptr(GString) str = NULL;
|
||||
guint8 buf_tmp[0x100];
|
||||
|
||||
/* copy remaining data into buf if required */
|
||||
memset(buf_tmp, 0xff, sizeof(buf));
|
||||
if (i < data_len) {
|
||||
gsize chunk_len = 0x100;
|
||||
if (i + 0x100 > data_len)
|
||||
chunk_len = data_len - i;
|
||||
if (!fu_memcpy_safe(buf_tmp,
|
||||
sizeof(buf_tmp),
|
||||
0, /* dst */
|
||||
(const guint8 *)data,
|
||||
data_len,
|
||||
i, /* src */
|
||||
chunk_len,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* verify data from device */
|
||||
if (!fu_altos_device_write_page(self, self->addr_base + i, buf_tmp, 0x100, error))
|
||||
return FALSE;
|
||||
|
||||
/* verify data written on device */
|
||||
str = fu_altos_device_read_page(self, self->addr_base + i, error);
|
||||
if (str == NULL)
|
||||
return FALSE;
|
||||
if (str->len != 0x100) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_WRITE,
|
||||
"failed to verify @%x, "
|
||||
"not enough data returned",
|
||||
(guint)(self->addr_base + i));
|
||||
return FALSE;
|
||||
}
|
||||
if (memcmp(str->str, buf_tmp, 0x100) != 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_WRITE,
|
||||
"failed to verify @%x",
|
||||
(guint)(self->addr_base + i));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_percentage_full(fu_progress_get_child(progress),
|
||||
i + 0x100,
|
||||
flash_len);
|
||||
g_string_append_len(buf, str->str, str->len);
|
||||
}
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* go to application mode */
|
||||
if (!fu_altos_device_tty_write(self, "a\n", -1, error))
|
||||
return FALSE;
|
||||
fu_progress_step_done(progress);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
fu_altos_device_dump_firmware(FuDevice *device, FuProgress *progress, GError **error)
|
||||
{
|
||||
FuAltosDevice *self = FU_ALTOS_DEVICE(device);
|
||||
guint flash_len;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_autoptr(GString) buf = g_string_new(NULL);
|
||||
|
||||
/* check kind */
|
||||
if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"verification only supported in bootloader");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check sizes */
|
||||
if (self->addr_base == 0x0 || self->addr_bound == 0x0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"address base and bound are unset");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read in blocks of 256 bytes */
|
||||
flash_len = self->addr_bound - self->addr_base;
|
||||
if (flash_len == 0x0 || flash_len > 0x100000) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"address range was icorrect");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* open tty for download */
|
||||
locker = fu_device_locker_new_full(device,
|
||||
(FuDeviceLockerFunc)fu_altos_device_tty_open,
|
||||
(FuDeviceLockerFunc)fu_altos_device_tty_close,
|
||||
error);
|
||||
if (locker == NULL)
|
||||
return NULL;
|
||||
for (guint i = self->addr_base; i < self->addr_bound; i += 0x100) {
|
||||
g_autoptr(GString) str = NULL;
|
||||
|
||||
/* request data from device */
|
||||
str = fu_altos_device_read_page(self, i, error);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
/* progress */
|
||||
fu_progress_set_percentage_full(progress,
|
||||
i - self->addr_base,
|
||||
self->addr_bound - self->addr_base);
|
||||
g_string_append_len(buf, str->str, str->len);
|
||||
}
|
||||
|
||||
/* success */
|
||||
return g_bytes_new(buf->str, buf->len);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_probe_bootloader(FuAltosDevice *self, GError **error)
|
||||
{
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
g_auto(GStrv) lines = NULL;
|
||||
g_autoptr(GString) str = NULL;
|
||||
|
||||
/* get tty for upload */
|
||||
if (!fu_altos_device_find_tty(self, error))
|
||||
return FALSE;
|
||||
locker = fu_device_locker_new_full(self,
|
||||
(FuDeviceLockerFunc)fu_altos_device_tty_open,
|
||||
(FuDeviceLockerFunc)fu_altos_device_tty_close,
|
||||
error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* get the version information */
|
||||
if (!fu_altos_device_tty_write(self, "v\n", -1, error))
|
||||
return FALSE;
|
||||
str = fu_altos_device_tty_read(self, 100, -1, error);
|
||||
if (str == NULL) {
|
||||
g_prefix_error(error, "failed to get version information: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* parse each line */
|
||||
lines = g_strsplit_set(str->str, "\n\r", -1);
|
||||
for (guint i = 0; lines[i] != NULL; i++) {
|
||||
/* ignore */
|
||||
if (lines[i][0] == '\0')
|
||||
continue;
|
||||
if (g_str_has_prefix(lines[i], "manufacturer "))
|
||||
continue;
|
||||
if (g_str_has_prefix(lines[i], "product "))
|
||||
continue;
|
||||
|
||||
/* we can flash firmware */
|
||||
if (g_strcmp0(lines[i], "altos-loader") == 0) {
|
||||
fu_device_remove_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* version number */
|
||||
if (g_str_has_prefix(lines[i], "software-version ")) {
|
||||
fu_device_set_version(FU_DEVICE(self), lines[i] + 17);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* address base and bound */
|
||||
if (g_str_has_prefix(lines[i], "flash-range ")) {
|
||||
g_auto(GStrv) addrs = g_strsplit(lines[i] + 17, " ", -1);
|
||||
self->addr_base = g_ascii_strtoull(addrs[0], NULL, 16);
|
||||
self->addr_bound = g_ascii_strtoull(addrs[1], NULL, 16);
|
||||
g_debug("base: %x, bound: %x",
|
||||
(guint)self->addr_base,
|
||||
(guint)self->addr_bound);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* unknown line */
|
||||
g_debug("unknown data: '%s'", lines[i]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_altos_device_probe(FuDevice *device, GError **error)
|
||||
{
|
||||
FuAltosDevice *self = FU_ALTOS_DEVICE(device);
|
||||
GUsbDevice *usb_device = fu_usb_device_get_dev(FU_USB_DEVICE(self));
|
||||
const gchar *version_prefix = "ChaosKey-hw-1.0-sw-";
|
||||
guint8 version_idx;
|
||||
g_autofree gchar *version = NULL;
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
|
||||
/* bootloader uses tty */
|
||||
if (fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
|
||||
return fu_altos_device_probe_bootloader(self, error);
|
||||
|
||||
/* open */
|
||||
locker = fu_device_locker_new(usb_device, error);
|
||||
if (locker == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* get string */
|
||||
version_idx = g_usb_device_get_product_index(usb_device);
|
||||
version = g_usb_device_get_string_descriptor(usb_device, version_idx, error);
|
||||
if (version == NULL)
|
||||
return FALSE;
|
||||
if (!g_str_has_prefix(version, version_prefix)) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"not a ChaosKey v1.0 device: %s",
|
||||
version);
|
||||
return FALSE;
|
||||
}
|
||||
fu_device_set_version(FU_DEVICE(self), version + 19);
|
||||
|
||||
/* success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_device_set_progress(FuDevice *self, FuProgress *progress)
|
||||
{
|
||||
fu_progress_set_id(progress, G_STRLOC);
|
||||
fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED);
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* detach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 98); /* write */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 0); /* attach */
|
||||
fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2); /* reload */
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_device_init(FuAltosDevice *self)
|
||||
{
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UPDATABLE);
|
||||
fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
|
||||
fu_device_set_version_format(FU_DEVICE(self), FWUPD_VERSION_FORMAT_TRIPLET);
|
||||
fu_device_set_vendor(FU_DEVICE(self), "altusmetrum.org");
|
||||
fu_device_set_summary(FU_DEVICE(self), "USB hardware random number generator");
|
||||
fu_device_add_protocol(FU_DEVICE(self), "org.altusmetrum.altos");
|
||||
fu_device_set_firmware_gtype(FU_DEVICE(self), FU_TYPE_ALTOS_FIRMWARE);
|
||||
|
||||
/* requires manual step */
|
||||
if (!fu_device_has_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_IS_BOOTLOADER))
|
||||
fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_NEEDS_BOOTLOADER);
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_device_class_init(FuAltosDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
FuDeviceClass *klass_device = FU_DEVICE_CLASS(klass);
|
||||
klass_device->to_string = fu_altos_device_to_string;
|
||||
klass_device->probe = fu_altos_device_probe;
|
||||
klass_device->write_firmware = fu_altos_device_write_firmware;
|
||||
klass_device->dump_firmware = fu_altos_device_dump_firmware;
|
||||
klass_device->set_progress = fu_altos_device_set_progress;
|
||||
object_class->finalize = fu_altos_device_finalize;
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#define FU_TYPE_ALTOS_DEVICE (fu_altos_device_get_type())
|
||||
G_DECLARE_FINAL_TYPE(FuAltosDevice, fu_altos_device, FU, ALTOS_DEVICE, FuUsbDevice)
|
||||
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gelf.h>
|
||||
#include <libelf.h>
|
||||
|
||||
#include "fu-altos-firmware.h"
|
||||
|
||||
struct _FuAltosFirmware {
|
||||
FuFirmware parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FuAltosFirmware, fu_altos_firmware, FU_TYPE_FIRMWARE)
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Elf, elf_end);
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
static gboolean
|
||||
fu_altos_firmware_parse(FuFirmware *firmware,
|
||||
GBytes *blob,
|
||||
guint64 addr_start,
|
||||
guint64 addr_end,
|
||||
FwupdInstallFlags flags,
|
||||
GError **error)
|
||||
{
|
||||
const gchar *name;
|
||||
Elf_Scn *scn = NULL;
|
||||
GElf_Shdr shdr;
|
||||
size_t shstrndx;
|
||||
g_autoptr(Elf) e = NULL;
|
||||
|
||||
/* load library */
|
||||
if (elf_version(EV_CURRENT) == EV_NONE) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"ELF library init failed: %s",
|
||||
elf_errmsg(-1));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* parse data */
|
||||
e = elf_memory((gchar *)g_bytes_get_data(blob, NULL), g_bytes_get_size(blob));
|
||||
if (e == NULL) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"failed to load data as ELF: %s",
|
||||
elf_errmsg(-1));
|
||||
return FALSE;
|
||||
}
|
||||
if (elf_kind(e) != ELF_K_ELF) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"not a supported ELF format: %s",
|
||||
elf_errmsg(-1));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* add interesting section */
|
||||
if (elf_getshdrstrndx(e, &shstrndx) != 0) {
|
||||
g_set_error(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"invalid ELF file: %s",
|
||||
elf_errmsg(-1));
|
||||
return FALSE;
|
||||
}
|
||||
while ((scn = elf_nextscn(e, scn)) != NULL) {
|
||||
if (gelf_getshdr(scn, &shdr) != &shdr)
|
||||
continue;
|
||||
|
||||
/* not program data with the same section name */
|
||||
if (shdr.sh_type != SHT_PROGBITS)
|
||||
continue;
|
||||
if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL)
|
||||
continue;
|
||||
|
||||
if (g_strcmp0(name, ".text") == 0) {
|
||||
Elf_Data *data = elf_getdata(scn, NULL);
|
||||
if (data != NULL && data->d_buf != NULL) {
|
||||
g_autoptr(GBytes) bytes = NULL;
|
||||
bytes = g_bytes_new(data->d_buf, data->d_size);
|
||||
fu_firmware_set_addr(firmware, shdr.sh_addr);
|
||||
fu_firmware_set_bytes(firmware, bytes);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_INTERNAL,
|
||||
"no firmware found in ELF file");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_firmware_class_init(FuAltosFirmwareClass *klass)
|
||||
{
|
||||
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS(klass);
|
||||
klass_firmware->parse = fu_altos_firmware_parse;
|
||||
}
|
||||
|
||||
static void
|
||||
fu_altos_firmware_init(FuAltosFirmware *self)
|
||||
{
|
||||
}
|
||||
|
||||
FuFirmware *
|
||||
fu_altos_firmware_new(void)
|
||||
{
|
||||
return FU_FIRMWARE(g_object_new(FU_TYPE_ALTOS_FIRMWARE, NULL));
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#define FU_TYPE_ALTOS_FIRMWARE (fu_altos_firmware_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FuAltosFirmware, fu_altos_firmware, FU, ALTOS_FIRMWARE, FuFirmware)
|
||||
|
||||
FuFirmware *
|
||||
fu_altos_firmware_new(void);
|
||||
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Richard Hughes <richard@hughsie.com>
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fwupdplugin.h>
|
||||
|
||||
#include "fu-altos-device.h"
|
||||
#include "fu-altos-firmware.h"
|
||||
|
||||
static void
|
||||
fu_plugin_altos_init(FuPlugin *plugin)
|
||||
{
|
||||
fu_plugin_add_device_gtype(plugin, FU_TYPE_ALTOS_DEVICE);
|
||||
fu_plugin_add_firmware_gtype(plugin, NULL, FU_TYPE_ALTOS_FIRMWARE);
|
||||
}
|
||||
|
||||
void
|
||||
fu_plugin_init_vfuncs(FuPluginVfuncs *vfuncs)
|
||||
{
|
||||
vfuncs->build_hash = FU_BUILD_HASH;
|
||||
vfuncs->init = fu_plugin_altos_init;
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
if get_option('plugin_altos')
|
||||
if not get_option('gudev') or not get_option('gusb')
|
||||
error('gudev and gusb is required for plugin_altos')
|
||||
endif
|
||||
cargs = ['-DG_LOG_DOMAIN="FuPluginAltos"']
|
||||
|
||||
install_data(['altos.quirk'],
|
||||
install_dir: join_paths(datadir, 'fwupd', 'quirks.d')
|
||||
)
|
||||
|
||||
shared_module('fu_plugin_altos',
|
||||
fu_hash,
|
||||
sources : [
|
||||
'fu-altos-device.c',
|
||||
'fu-altos-firmware.c',
|
||||
'fu-plugin-altos.c',
|
||||
],
|
||||
include_directories : [
|
||||
root_incdir,
|
||||
fwupd_incdir,
|
||||
fwupdplugin_incdir,
|
||||
],
|
||||
install : true,
|
||||
install_dir: plugin_dir,
|
||||
link_with : [
|
||||
fwupd,
|
||||
fwupdplugin,
|
||||
],
|
||||
c_args : cargs,
|
||||
dependencies : [
|
||||
libelf,
|
||||
plugin_deps,
|
||||
],
|
||||
)
|
||||
endif
|
||||
@ -1,7 +1,6 @@
|
||||
subdir('acpi-dmar')
|
||||
subdir('acpi-facp')
|
||||
subdir('acpi-phat')
|
||||
subdir('altos')
|
||||
subdir('amt')
|
||||
subdir('analogix')
|
||||
subdir('ata')
|
||||
|
||||
@ -197,7 +197,6 @@ parts:
|
||||
- gnu-efi
|
||||
- libarchive-dev
|
||||
- libcairo-dev
|
||||
- libelf-dev
|
||||
- libefiboot-dev
|
||||
- libefivar-dev
|
||||
- libftdi1-dev
|
||||
@ -225,7 +224,6 @@ parts:
|
||||
- liblcms2-2
|
||||
- libefivar1
|
||||
- libefiboot1
|
||||
- libelf1
|
||||
- libusb-1.0-0
|
||||
- libgudev-1.0-0
|
||||
- libgpgme11
|
||||
|
||||
Loading…
Reference in New Issue
Block a user