¿Por qué SWUpdate?
Las actualizaciones sobre el terreno son inevitables. SWUpdate proporciona una solución robusta y modular para actualizar el firmware, los sistemas de archivos raíz y las capas de aplicación, todo ello con capacidad de reversión incorporada.
Es de código abierto, está bien documentado y se integra a la perfección con una distribución de particiones A/B.
Visión general de la arquitectura
SWUpdate consta de varios componentes clave:
- Demonio de actualización (swupdate) - se ejecuta en el dispositivo y aplica las actualizaciones
- Manejadores de actualización - definen qué actualizar (rootfs, archivos, scripts, etc.)
- Interfaces de cliente - interfaz web, API REST o CLI local
- sw-description archivo - define la estructura y la lógica del paquete de actualización
Ejemplo de flujo de actualización
- Construya un paquete de actualización (.swu) que contenga:
- Una nueva imagen del sistema de archivos raíz
- El sw-description archivo
- Scripts opcionales (para personalización o verificación)
2.swupdate escribe la actualización en los dispositivos definidos.
- Un script posterior a la actualización confirma el éxito o activa una reversión si es necesario.
Ejemplo
En este ejemplo, dividimos una Raspberry Pi OS imagen Trixie en dos archivos:
- 2025-10-01-raspios-trixie-arm64.boot.vfat
- 2025-10-01-raspios-trixie-arm64.root.ext4
Se hace referencia a estos archivos en el archivo sw-description para crear el paquete .swu:
software =
{
version = "0.1.0";
description = "Firmware update for XXXXX Project";
hardware-compatibility: [ "1.0", "1.2", "1.3"];
images: (
{
filename = "2025-10-01-raspios-trixie-arm64.boot.vfat";
device = "/dev/mmcblk0p1";
compressed = "zlib";
installed-directly = true;
},
{
filename = "2025-10-01-raspios-trixie-arm64.root.ext4";
device = "/dev/mmcblk0p2";
compressed = "zlib";
installed-directly = true;
}
);
scripts: (
{
type: "lua",
filename: "repair-disk-uuid.lua"
}
),
}El siguiente script Lua ajusta los UUID de las particiones en cmdline.txt y fstab después del flasheo:
#!/usr/bin/lua
-- helper: run shell command and capture output
function run(cmd)
local f = io.popen(cmd)
local out = f:read("*a")
f:close()
return (out:gsub("%s+$", ""))
end
-- detect PARTUUIDs
local root_part = "/dev/mmcblk0p2"
local boot_part = "/dev/mmcblk0p1"
local root_uuid = run("blkid -s PARTUUID -o value " .. root_part)
local boot_uuid = run("blkid -s PARTUUID -o value " .. boot_part)
print("Rootfs PARTUUID: " .. root_uuid)
print("Boot PARTUUID: " .. boot_uuid)
-- mount points
os.execute("mkdir -p /mnt/root /mnt/boot")
os.execute("mount " .. root_part .. " /mnt/root")
os.execute("mount " .. boot_part .. " /mnt/boot")
-- update cmdline.txt
local cmdline_path = "/mnt/boot/cmdline.txt"
local file = io.open(cmdline_path, "r")
local text = file:read("*a")
file:close()
text = text:gsub("root=PARTUUID=[^ ]+", "root=PARTUUID=" .. root_uuid)
file = io.open(cmdline_path, "w")
file:write(text)
file:close()
-- update /etc/fstab
local fstab_path = "/mnt/root/etc/fstab"
local fstab = io.open(fstab_path, "r")
local content = fstab:read("*a")
fstab:close()
-- replace root line
content = content:gsub("PARTUUID=[^%s]+%s+/%s", "PARTUUID=" .. root_uuid .. " /")
-- replace boot line (/boot or /boot/firmware)
content = content:gsub("PARTUUID=[^%s]+%s+/boot", "PARTUUID=" .. boot_uuid .. " /boot")
fstab = io.open(fstab_path, "w")
fstab:write(content)
fstab:close()
os.execute("sync")
os.execute("umount /mnt/boot")
os.execute("umount /mnt/root")
print("All PARTUUIDs updated successfully.")Utilice swugenerator para agrupar la actualización:(https://github.com/sbabic/swugenerator).
Aplicar la actualización
Para probar el archivo .swu generado
- Arranque el CM5 en el sistema de rescate.
- Cree un punto de montaje, por ejemplo:
sudo mkdir -p /mnt/update- Monte un recurso compartido NFS que contenga el archivo de actualización:
sudo mount -t nfs :/path/to/share /mnt/update- Aplique la actualización:
sudo swupdate -i /mnt/update/update.swuPosibilidades de integración
Activar actualizaciones desde una interfaz de usuario local o una API backend
- Firme y verifique las actualizaciones para mejorar la seguridad
- Utilizar SWUpdate’s interfaz web para pruebas o depuración
- Combínelo con los servicios de systemd para automatizar la recuperación y las reversiones
Por qué encaja en esta pila
Junto con rpi-image-gen y rpi-sb-provisioner, SWUpdate completa el cuadro:
- Construir → rpi-image-gen (Creación de imágenes)
- Desplegar → rpi-sb-provisioner (Aprovisionamiento de dispositivos)
- Mantener → SWUpdate (Actualizaciones OTA y gestión del ciclo de vida)
El resultado es una plataforma integrada flexible, abierta y fácil de mantener. Linux una plataforma que evoluciona con su producto, sin la sobrecarga de Yocto.
Artículos de esta serie
- Building a Production-Ready Linux for Raspberry Pi Compute Module 5
- Del sistema operativo de stock a la plataforma de producción
- Customizing Raspberry Pi OS with rpi-image-gen
- Robustez del sistema - Diseño de un sistema de archivos raíz A/B
- Provisioning — Automating First Boot with rpi-sb-provisioner
- OTA y ciclo de vida - Actualizaciones de software con SWUpdate
Fuentes
- rpi-image-gen: https://github.com/raspberrypi/rpi-image-gen
- rpi-sb-provisioner: https://github.com/raspberrypi/rpi-sb-provisioner
- SWUpdate: https://github.com/sbabic/swupdate
- swugenerator: https://github.com/sbabic/swugenerator