Skip to main content

¿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.

Interfaz gráfica de usuario del navegador web para SWUpdate

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

  1. 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.
  2. 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

  1. Arranque el CM5 en el sistema de rescate.
  2. Cree un punto de montaje, por ejemplo:
sudo mkdir -p /mnt/update
  1. Monte un recurso compartido NFS que contenga el archivo de actualización:
sudo mount -t nfs :/path/to/share /mnt/update
  1. Aplique la actualización:
sudo swupdate -i /mnt/update/update.swu

Posibilidades 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.