• Stars
    star
    159
  • Rank 228,507 (Top 5 %)
  • Language
    Rust
  • License
    GNU General Publi...
  • Created almost 5 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Generic framework and GTK UI for firmware updates from system76-firmware and fwupd, written in Rust.

Firmware Manager

One of the remaining issues with firmware management on Linux is the lack of options for graphical frontends to firmware management services like fwupd and system76-firmware. For fwupd, the only solutions available were to distribute either GNOME Software, or KDE Discover; which is not viable for Linux distributions which have their own application centers, or frontends to package managers. For system76-firmware, an official GTK application exists, but it only supports updating System76 firmware, when it would be more ideal if it could support updating firmware from both services.

fwupd is a system service which connects to LVFS to check for firmware updates to a wide variety of hardware from multiple vendors. system76-firmware is our own system service which connects to System76 to check for firmware updates for System76 hardware.

Privacy

To increase privacy, we have disabled telemetry reporting in fwupd on Pop!_OS.

To solve this problem, we've been working on the Firmware Manager project, which we will be shipping to all Pop!_OS users, and System76 hardware customers on any other distribution. It supports checking and updating firmware from the fwupd and system76-firmware services, is Wayland-compatible, and provides both a GTK application and library.

Wayland disallows applications from being run as root, so applications must either call pkexec to prompt the user for permission to run a background process that is root, or connect to an existing background service provided the needed capabilities.

In Pop!_OS, the firmware manager will be integrated into GNOME Settings in a new Firmware panel under the Devices category with the GTK widget library. For other Linux distributions, and for those who do not use GNOME, the GTK application is available to provide the firmware manager widget as a standalone application in its own application window.

Although we've created a GTK application and widget library for our use in Pop!_OS, the core framework is toolkit-agnostic, thereby enabling firmware manager frontends to be written in any toolkit. However, it should be noted that since the framework is written in Rust, frontends would need to use Rust in order to interact with it.

GTK Application

Ubuntu, and other Linux distributions which would prefer to have a standalone desktop application, are free to use the included GTK application.

Screenshot of GTK Application

GNOME Settings Integration

Pop!_OS will be integrating a patch into GNOME Settings which embeds the GTK widget into a new Firmware panel in the Devices category section.

Screenshot of GNOME Settings Integration

Distributing Firmware Manager

When packaging the firmware manager with the GTK frontend, the only dependencies required are libdbus, libgtk, libssl, and libudev. The firmware manager uses DBus to communicate with the system76-firmware and fwupd daemons. Both of which are optional and do not need to be installed in order to use or compile the project. The firmware manager has an initial check for the existence of either daemon. If no daemon is installed, no firmware will be found. If one daemon is installed, then it will discover firmware managed by that service, if managed firmware is found on the system.

As it is written in Rust, Rustc and its Cargo counterpart are required to compile the project. The rust-toolchain file in the root directory of the source repository defines the minimum-supported version of the compiler. We will always depend on a version of Rust that is packaged in the most recent LTS of Ubuntu. You can check what Ubuntu supports here.

To package the project so that it can be built offline in a schroot, there is a make vendor rule which uses the official cargo-vendor utility to fetch all crate dependencies locally, and then generates a tarball which can be distributed in or alongside your source packages. You can then instruct the makefile to build the project with the vendored dependencies by setting VENDOR=1, like so: make VENDOR=1 prefix=/usr.

If your version of Cargo does not have the cargo-vendor feature, you can install cargo-vendor separately here.

For any unfamiliar with Rust, crates are modules of source code with specific functionality that can be massively distributed through public registries like Crates.io, or fetched directly by URL. They are statically-linked when used in a project which builds a library or binary. For applications, Cargo generates a Cargo.lock file which specifies the exact version of every crate that is depended on, and their SHA256 sums. This is to ensure that anyone pulling the project will have the same versions for crate dependencies as used by upstream.

Implementation Details

Like all of our projects today, it is written in Rust, and adheres to current best practices. The project is configured as a workspace, with the core crate providing a generic library for discovering and managing firmware from multiple firmware services. Both fwupd and system76-firmware are supported.

The core is used as the foundation for the two members of this workspace: a notification binary to provide desktop notifications about firmware updates; and a GTK project which serves as both a widget library and desktop application.

Visualization of project structure

* firmware-manager
    * firmware-manager-notify
    * firmware-manager-gtk
        * firmware-manager-gtk-ffi

Core Library

The firmware-manager library provides functions for scanning firmware, and an event loop which receives and sends event signals through channels. One channel receives messages from the frontend, whereas the other sends messages to the frontend. This is designed to be run in a background thread in order to prevent a UI that uses the firmware manager from blocking as requests are being processed.

Additionally, the event API is expected to be used with the provided slotmap-based entity-component architecture. This allows a frontend to assign entity IDs to their requests, and receive those entity IDs back in responses. In doing so, frontends can avoid the need for complex runtime reference-counting, or creating reference cycles. The frontend has exclusive ownership of the data that an entity ID refers to.

GTK Application / Library

The firmware-manager-gtk member of the project provides the firmware widget as a library, and an application which places that widget into a window. This member contains a C FFI sub-member, which builds a dynamic library with a C API and header, and can be used to integrate the widget into any GTK application written in C.

This implementation takes full advantage of the slotmap EC, assigning its own component storages to keep track of state relative to a device entity, such as the widgets assigned to an entity, and information about their firmware.

The included GTK application statically-links the Rust widget library into the binary.

Notification Binary

The firmware-manager-notify member comes with a systemd user timer so that it is executed at login, and then periodically run again at set intervals to check for updates again. When updates are found, a clickable notification will be displayed, which will either open the Firmware panel in GNOME Settings, or the standalone desktop application, depending on which is available on the system.

Supporting Other Frontends

Although the project will release with only a GTK frontend, it is possible for anyone to use it as the foundations for developing a frontend written in any other graphical toolkit. All functionality in the core library is GUI-agnostic, and the entity-component architecture can be extended to their specialized needs. If you write a frontend for another toolkit and want it included in the project, feel free to submit a pull request!

How to Implement Frontend Support

Frontends are expected to store information about devices in the included entity-component architecture in the firmware-manager. Events sent to firmware manager's event loop requires the entity IDs to be sent along with messages. This makes it easier to keep cyclic references out of widget signals, and to identify which firmware a response is referring to. Widgets belonging to a specific firmware device need only send a message through their sender with their attached entity ID.

Build Instructions

This project uses a Makefile. When building the application, the prefix flag must be provided, so that the desktop entry file is generated to point to the correct path of the target binary after installation.

make prefix=/usr
sudo make install prefix=/usr

Note that the generated desktop entry is stored in the target directory, where the pkgconfig file is also stored after it is generated. If you need to regenerate the desktop entry with a different prefix, you can manually call the desktop rule.

make desktop prefix=/usr

Debug Binaries

To build a debug binary, pass DEBUG=1 into make.

make prefix=/usr DEBUG=1
sudo make install DEBUG=1

Vendoring

To vendor the project for packaging, call make vendor. To build a project that has been vendored, pass VENDOR=1 to the makefile.

make vendor
make prefix=/usr VENDOR=1

API Overview

This section provides details about the API and how to call it from Rust or C.

Rust API

The primary API, which the C API is based upon. An example of the Rust API in practice in a GTK application can be found here.

use firmware_manager_gtk::FirmwareWidget;

// Create a new firmware widget
//
// This spawns a background thread which listens for widget events until
// the `Quit` signal is received, which occurs when the firmware widget
// is dropped.
let mut firmware = FirmwareWidget::new();

// Signal the widget's background thread to begin scanning for firmware.
firmware.scan();

// Get the GTK widget from the firmware widget to add into a window.
let widget = firmware.container();

C API

The Rust library also supports C interface with FFI rules in the Makefile for generating a dynamic C library with pkg-config support. This is integrated in GNOME Settings on Pop!_OS.

make ffi prefix=/usr
sudo make install-ffi prefix=/usr

Which can then be imported into a C code base with:

#include <s76_firmware.h>

// Create a new firmware widget
S76FirmwareWidget *firmware =
    s76_firmware_widget_new ();

// Signal the widget's background thread to begin scanning for firmware.
s76_firmware_widget_scan (firmware);

// Get the GTK widget from the firmware widget to attach it to a container.
GtkWidget *firmware_widget =
    s76_firmware_widget_container (firmware);

// Destroy the widget and signal its background thread to quit.
s76_firmware_widget_destroy (firmware);

The C implementation of the Rust application is here, demonstrated with the Meson build system.

More Repositories

1

shell

Pop!_OS Shell
TypeScript
4,276
star
2

pop

A project for managing all Pop!_OS sources
Rust
2,128
star
3

cosmic-text

Pure Rust multi-line text handling
Rust
1,433
star
4

cosmic-epoch

Next generation Cosmic desktop environment
Just
1,129
star
5

cosmic

Computer Operating System Main Interface Components
JavaScript
1,066
star
6

gtk-theme

System76 Pop GTK+ Theme
SCSS
747
star
7

popsicle

Multiple USB File Flasher
Rust
520
star
8

system76-power

System76 Power Management
Rust
512
star
9

system76-scheduler

Auto-configure CFS and process priorities for improved desktop responsiveness
Rust
473
star
10

iso

Pop!_OS ISO production
Makefile
439
star
11

cosmic-comp

Compositor for the COSMIC desktop environment
Rust
368
star
12

beta

Pop!_OS Beta
353
star
13

libcosmic

WIP library for COSMIC applications
Rust
265
star
14

keyboard-configurator

Keyboard configuration UI
Rust
231
star
15

distinst

Installer Backend
Rust
207
star
16

launcher

Modular IPC-based desktop launcher service
Rust
203
star
17

tensorman

Utility for easy management of Tensorflow containers
Rust
190
star
18

cosmic-term

WIP COSMIC terminal emulator
Rust
183
star
19

cosmic-edit

COSMIC Text Editor
Rust
181
star
20

icon-theme

System76 Pop icon theme for Linux
Python
169
star
21

cosmic-applets

WIP applets for cosmic-panel
Rust
169
star
22

wallpapers

Wallpapers for Pop!_OS
Makefile
149
star
23

cosmic-settings

COSMIC Settings
Rust
116
star
24

nvidia-graphics-drivers

Pop!_OS NVIDIA Graphics Drivers
110
star
25

system76-driver

System76 Driver for Pop!_OS
Python
101
star
26

cosmic-panel

WIP
Rust
94
star
27

upgrade

Utility for upgrading Pop!_OS and its recovery partition to new releases.
Rust
90
star
28

cosmic-launcher

WIP
Rust
80
star
29

gnome-shell-extension-system76-power

System76 Power Management Extension
TypeScript
74
star
30

cosmic-time

Animation Library for https://github.com/iced-rs/iced and https://github.com/pop-os/cosmic-epoch
Rust
72
star
31

system76-firmware

System76 Firmware Tool and Daemon
Rust
71
star
32

cosmic-dock

Pop!_OS fork of https://github.com/micheleg/dash-to-dock/tree/ubuntu-dock
JavaScript
68
star
33

fonts

Fonts for the System76 Pop look, Fira and Roboto Slab
Makefile
68
star
34

tiler

Generic tiling window manager library in Rust
Rust
65
star
35

pop-arm64

Experimental scripts for building an Pop!_OS for ARM64 EFI platforms.
Shell
59
star
36

core

WIP immutable base
Rust
55
star
37

shell-shortcuts

Application for displaying and demoing Pop Shell shortcuts
Rust
53
star
38

debrepbuild

A project for automatically generating and maintaining Debian repositories from a TOML spec.
Rust
53
star
39

cosmic-session

Session manager for the COSMIC desktop environment
Rust
44
star
40

theme

A metapackage including pop-fonts, pop-gtk-theme, and pop-icon-theme
42
star
41

desktop-widget

Pop Desktop Settings Widget
Fluent
41
star
42

cosmic-files

WIP COSMIC file manager
Rust
38
star
43

cosmic-applibrary

WIP
Rust
37
star
44

touchegg

Pop!_OS fork of https://github.com/JoseExposito/touchegg
C++
36
star
45

async-fetcher

Rust crate for asynchronous file fetching, using optional fetching based on modified times and checksums
Rust
36
star
46

system76-dkms

System76 DKMS driver
C
36
star
47

sys-mount

High level FFI binding around the sys mount & umount2 calls, for Rust
Rust
36
star
48

url-scraper

Rust crate for scraping URLs from HTML pages
Rust
36
star
49

gnome-shell-theme

The GNOME Shell theme for Pop!_OS
CSS
35
star
50

default-settings

Distribution Default Settings
Shell
35
star
51

cosmic-workspaces

Pop!_OS fork of https://github.com/RensAlthuis/vertical-overview
JavaScript
32
star
52

cosmic-store

WIP COSMIC app store
Rust
32
star
53

linux-firmware

Pop!_OS fork of https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux-firmware
C
29
star
54

cosmic-greeter

libcosmic greeter for greetd, which can be run inside cosmic-comp
Rust
29
star
55

gnome-control-center

Pop!_OS fork of https://git.launchpad.net/~ubuntu-desktop/ubuntu/+source/gnome-control-center
C
27
star
56

buildchain

Software for creating and managing a distributed and reproducible chain of builds
Rust
27
star
57

system-updater

Systemd services for checking for and applying system updates.
Rust
27
star
58

pidfd

Rust crate providing Linux (>= 5.3) PID file descriptor support
Rust
27
star
59

website

The Pop!_OS website
Vue
27
star
60

bus-writer

Single-reader, multi-writer & single-reader, multi-verifier; broadcasts reads to multiple writeable destinations in parallel
Rust
27
star
61

desktop

Desktop metapackage
25
star
62

system76-oled

Control brightness on OLED displays
Rust
24
star
63

xdg-desktop-portal-cosmic

Rust
23
star
64

libparted

Rust wrappers for libparted
Rust
22
star
65

gnome-shell-extension-do-not-disturb

Enable or disable do not disturb mode.
JavaScript
21
star
66

gnome-shell

Pop!_OS fork of https://git.launchpad.net/~ubuntu-desktop/ubuntu/+source/gnome-shell
C
21
star
67

theme-switcher

Pop!_OS GTK widget library / app for switching themes
Rust
20
star
68

progress-streams

Rust crate to extend io::Read & io::Write types with progress callbacks
Rust
19
star
69

freedesktop-desktop-entry

Rust crate for navigating Freedesktop desktop entries
Rust
19
star
70

cosmic-theme-editor

WIP
Rust
19
star
71

sysfs-class

Rust library for viewing /sys/class in an object-oriented format
Rust
18
star
72

system76-wallpapers

System76 Wallpapers
17
star
73

plymouth-theme

Plymouth splash screen themes
Shell
17
star
74

systemd-boot-conf

Rust crate for managing the systemd-boot loader configuration.
Rust
17
star
75

cosmic-protocols

Addtional wayland-protocols used by the COSMIC desktop environment
Rust
17
star
76

repo-release

Produces Pop release package repositories
Shell
16
star
77

dbus-udisks2

Rust library for interacting with the UDisks2 DBus API
Rust
16
star
78

cosmic-settings-daemon

Rust
16
star
79

system76-acpi-dkms

System76 ACPI Driver (DKMS)
C
15
star
80

cosmic-osd

Rust
15
star
81

gtk-extras

Rust crate containing an assortment of extra, unofficial GTK patterns, widgets, and traits.
Rust
13
star
82

proc-mounts

Rust crate for fetching active mounts and swaps on a Linux system
Rust
13
star
83

as-result

Rust crate which provides the `AsResult<T, E>` and `IntoResult<T, E>` traits.
Rust
13
star
84

debarchive

Rust crate which provides direct access to files within a Debian archive
Rust
13
star
85

mutter-rs

Rust wrappers for Mutter and related projects
Rust
13
star
86

os-release

Rust crate for parsing the /etc/os-release file, common with Linux distributions
Rust
13
star
87

cosmic-randr

Library and utility for displaying and configuring Wayland outputs
Rust
13
star
88

cosmic-player

WIP COSMIC media player
Rust
12
star
89

grub-theme

Grub bootloader theme
12
star
90

cog-stable-diffusion

Packaging for convenience of installation and setup of stable diffusion on Pop
Python
12
star
91

cosmic-theme

WIP
Rust
12
star
92

cosmic-screenshot

Utility for capturing screenshots via XDG Desktop Portal
Rust
12
star
93

repo-curated-free

APT repository configuration for building an apt repository with only free software.
11
star
94

iced-sctk

WIP
Rust
11
star
95

cosmic-notifications

Rust
11
star
96

cosmic-workspaces-epoch

Rust
11
star
97

partition-identity

Find the ID of a device by its path, or find a device path by its ID.
Rust
11
star
98

repolib

Python library for managing APT sources
Python
11
star
99

hp-vendor

Vendor support for HP products using Pop!_OS
Rust
10
star
100

snapshot

A utility for taking btrfs snapshots of Pop!_OS installs
Rust
10
star