Firmware Updates with fwupd on Linux
fwupd is the standard open-source daemon for managing firmware updates on Linux, supporting BIOS/UEFI, NVMe, network cards, and hundreds of other devices through the Linux Vendor Firmware Service (LVFS). This guide covers installing fwupd, discovering updatable devices, applying BIOS/UEFI updates, automating firmware updates, and handling rollbacks.
Prerequisites
- Ubuntu 20.04/22.04 or CentOS/Rocky Linux 8+
- UEFI firmware (most hardware from 2012 onwards)
- EFI System Partition (ESP) mounted at
/boot/efi - Root or sudo access
- Internet access for downloading firmware from LVFS
Install fwupd
# Ubuntu/Debian (usually pre-installed)
sudo apt update && sudo apt install -y fwupd
# CentOS/Rocky Linux
sudo dnf install -y fwupd
# Enable and start the fwupd service
sudo systemctl enable fwupd
sudo systemctl start fwupd
# Verify installation
fwupdmgr --version
sudo systemctl status fwupd
Discover Devices and Updates
# Refresh the firmware metadata from LVFS
sudo fwupdmgr refresh
# List all devices that fwupd can manage
fwupdmgr get-devices
# Example output:
# UEFI Device Firmware
# DeviceId: b0f340b1-361e-55f8-b071-f9eb5e55e7c6
# Summary: UEFI ESRT device
# Current version: 0.1.8
# Vendor: Dell
# GUIDs: ...
# Device flags: updatable
#
# SAMSUNG MZNLN256HAJQ-000H1
# DeviceId: ...
# Current version: MAV21H3Q
# Vendor: Samsung
# Check for available updates
fwupdmgr get-updates
# Show update details
fwupdmgr get-updates --verbose
# Show devices with no updates available (not just updateable ones)
fwupdmgr get-devices --show-all-devices
Apply Firmware Updates
# Update all devices with available updates
sudo fwupdmgr update
# Update a specific device by DeviceId
sudo fwupdmgr update <DeviceId>
# Dry run — show what would be updated without applying
fwupdmgr update --dry-run
# Update with verbose output to see progress
sudo fwupdmgr update --verbose
# Some updates require a reboot to apply
# fwupdmgr will tell you if a reboot is needed:
# "Successfully wrote firmware to /boot/efi/EFI/..."
# "System needs to reboot for firmware update to apply"
sudo reboot
BIOS and UEFI Updates
BIOS/UEFI updates work through the UEFI Update Capsule mechanism:
# Check if UEFI updates are supported
fwupdmgr get-devices | grep -A 10 "UEFI Device Firmware"
# Verify the EFI System Partition is mounted
mount | grep efi
ls /boot/efi/EFI/
# Check UEFI capsule update support
sudo fwupdmgr security --force
# Look for "Capsule Updates" — should show "Enabled"
# Apply a BIOS/UEFI update
sudo fwupdmgr update
# The process:
# 1. fwupd downloads the capsule from LVFS
# 2. Writes the capsule to the EFI System Partition
# 3. Sets UEFI boot variable to apply the update on next boot
# 4. Reboots into firmware update mode
# 5. Firmware applies the update and reboots again into Linux
# After reboot, verify the update was applied
fwupdmgr get-devices | grep "Current version"
Check Host Security ID (HSI) score after updates:
# Show security posture based on firmware/hardware features
sudo fwupdmgr security --force
# Output includes:
# HSI-1: UEFI Platform Key (PK) is set
# HSI-2: Secure Boot is enabled
# HSI-3: TPM v2.0 is in use
# HSI-4: Device-based encryption is enabled
Automate Firmware Updates
# Enable automatic firmware updates via the fwupd system service
# The fwupd-refresh service fetches metadata daily
# Check automatic update configuration
cat /etc/fwupd/daemon.conf
# Enable automatic downloading of firmware updates
sudo tee -a /etc/fwupd/daemon.conf > /dev/null <<'EOF'
[fwupd]
# Download updates automatically, but don't apply without consent
UpdateMotd=true
EOF
# Create a script for unattended firmware updates with notification
sudo tee /usr/local/bin/firmware-update-check.sh > /dev/null <<'EOF'
#!/bin/bash
LOGFILE="/var/log/fwupd-auto.log"
EMAIL="[email protected]"
# Refresh metadata
fwupdmgr refresh >> $LOGFILE 2>&1
# Check for updates
UPDATES=$(fwupdmgr get-updates 2>&1)
if echo "$UPDATES" | grep -q "No upgrades"; then
echo "$(date): No firmware updates available" >> $LOGFILE
else
echo "$(date): Firmware updates available:" >> $LOGFILE
echo "$UPDATES" >> $LOGFILE
echo "$UPDATES" | mail -s "Firmware Updates Available on $(hostname)" "$EMAIL"
fi
EOF
sudo chmod +x /usr/local/bin/firmware-update-check.sh
# Schedule weekly check
echo "0 9 * * 1 root /usr/local/bin/firmware-update-check.sh" | \
sudo tee /etc/cron.d/firmware-check
Systemd timer for automatic metadata refresh:
# fwupd includes a built-in timer for refreshing metadata
sudo systemctl enable fwupd-refresh.timer
sudo systemctl start fwupd-refresh.timer
# Check the timer
sudo systemctl status fwupd-refresh.timer
sudo systemctl list-timers | grep fwupd
Rollback Procedures
# List available firmware versions for a device (if older versions are cached)
fwupdmgr get-history
# Example output showing update history:
# SAMSUNG MZNLN256HAJQ-000H1
# Previous version: MAV21H2Q
# Current version: MAV21H3Q
# Update state: success
# Downgrade to a previous version (if supported by LVFS for this device)
sudo fwupdmgr downgrade
# The downgrade command shows available older versions:
# 1. MAV21H2Q (previous)
# 2. MAV21H1Q
# Select which version to downgrade to
# For BIOS rollbacks: many systems prevent downgrading BIOS
# Check with your hardware vendor for BIOS rollback procedures
# If a firmware update causes boot issues:
# 1. Boot from recovery/USB
# 2. Mount the EFI partition
# 3. Remove the pending capsule update file:
sudo mount /dev/sda1 /mnt
ls /mnt/EFI/UpdateCapsule/
sudo rm /mnt/EFI/UpdateCapsule/*.cap # Remove pending updates
sudo umount /mnt
Offline Updates
For air-gapped servers or systems without internet access:
# On an internet-connected machine, download the firmware CAB file
# from https://fwupd.org/ or directly from the device vendor
# Copy the CAB file to the target server
scp firmware-update.cab admin@target-server:/tmp/
# Install from local file
sudo fwupdmgr install /tmp/firmware-update.cab
# Install without network signature checking (not recommended for production)
sudo fwupdmgr install --allow-older --no-reboot-check /tmp/firmware-update.cab
# For complete offline operation, pre-populate the metadata cache:
# Download metadata on internet-connected machine:
fwupdmgr refresh --export=/tmp/fwupd-cache.tar.gz
# Import on offline machine:
sudo fwupdmgr refresh --import=/tmp/fwupd-cache.tar.gz
Troubleshooting
"No devices found" or device not listed:
# Check if the device is supported by LVFS
fwupdmgr get-devices --show-all-devices | grep -i "not updateable\|No supported"
# Check fwupd daemon is running
sudo systemctl status fwupd
# Check for plugin errors
sudo journalctl -u fwupd -n 100 | grep -E "error|fail"
# Force device re-detection
sudo fwupdmgr get-devices --force
UEFI updates fail with "EFI partition not found":
# Verify EFI partition is mounted
mount | grep /boot/efi
# If not mounted:
sudo mkdir -p /boot/efi
sudo mount /dev/sda1 /boot/efi # Replace sda1 with your EFI partition
# Check UEFI support
sudo efibootmgr # Should show EFI boot entries
ls /sys/firmware/efi # Should exist on UEFI systems
"Update not signed" or signature verification failed:
# Check LVFS metadata is current
sudo fwupdmgr refresh --force
# Check system time is correct (affects certificate validation)
timedatectl
# View the full signature error
sudo fwupdmgr update --verbose 2>&1 | grep -i "sign\|cert"
Update downloads but doesn't apply:
# Check if a reboot is pending
fwupdmgr get-updates | grep -i "reboot"
# Check the update status
fwupdmgr get-history
# View detailed progress during update
sudo journalctl -u fwupd -f &
sudo fwupdmgr update --verbose
Conclusion
fwupd streamlines firmware management on Linux by providing a unified interface for updating BIOS, SSDs, NICs, and other devices through the LVFS ecosystem. Regular firmware updates are essential for security patches, bug fixes, and hardware compatibility improvements. Implement automated update checking and integrate with your change management process before applying firmware updates to production baremetal servers.


