How to Update Embedded Linux Firmware Over-the-Air

What You’ll Build

A repeatable OTA flow that pushes new firmware revisions to a Pantavisor-enabled embedded Linux device — including the kernel, BSP, system services, and applications — as a single atomic, signed state revision. Failed updates roll back automatically.

Prerequisites

How OTA Works in Pantavisor

Every OTA update is a new state revision:

  1. You clone the device’s current state to a workspace.
  2. You modify it (update a container, change config, swap the BSP, etc.).
  3. You commit. PVR hashes every changed object (SHA256) and writes a new state JSON.
  4. You sign and post. Only changed object hashes are transferred to Pantahub.
  5. The device pulls the revision and switches the entire system atomically.
  6. If any container fails to reach its declared status_goal, Pantavisor reverts to the last good revision automatically.

There is no separate “kernel update” path. Updating the kernel is the same operation as updating an app — both are containers in the state.

Step 1 — Clone the Device State

pvr clone https://pvr.pantahub.com/<USER>/<DEVICE_NICK> my-device
cd my-device

The workspace contains the full state: BSP, OS, every container’s run.json, config overlays in _config/, and signatures in _sigs/.

Step 2 — Modify the Composition

Update one container, add a new one, change config — whatever you need:

# Update one container to a new upstream version
pvr app update wificonnect --from=https://gitlab.com/pantacor/pvwificonnect:latest

# Add a new container from a Docker / OCI image
pvr app add monitoring --from=docker://prom/node-exporter:latest

# Remove one
pvr app rm legacy-app

# Or edit config overlays directly:
$EDITOR _config/wificonnect/etc/wificonnect.conf

Check what changed:

pvr status
pvr diff

PVS signatures cover the state JSON, making the revision tamper-evident:

pvr sig add --parts=wificonnect,monitoring

For production fleets, sign with an x5c certificate chain so devices can verify against a trust root.

Step 4 — Commit and Post

pvr commit -m "Update wificonnect, add monitoring"
pvr post https://pvr.pantahub.com/<USER>/<DEVICE_NICK>

Differential transfer: only changed object hashes traverse the network. A 200 KB config tweak doesn’t re-send a 200 MB rootfs.

Step 5 — Watch the Rollout

pvr device logs <DEVICE_NICK>
pvr device logs <DEVICE_NICK>/pantavisor.log@INFO

Pantavisor logs the revision switch, container starts, and any rollback decision in real time.

Automatic Rollback

You don’t wire up rollback. Pantavisor watches each container against its declared status_goal (e.g. STARTED, MOUNTED). If the goal is not met within the configured window, the device reverts to the previous good revision and continues running. The failed revision remains in Pantahub for inspection.

For boot-time failures (kernel panic, init failure), the bootloader / Pantavisor combo falls back to the last booted-good revision.

Updating Many Devices at Once

Two paths:

  1. Per-device post — script pvr post against a list of device URLs. Simple, no extra infrastructure.
  2. Pantahub channels and rollouts — define a release in a channel and let Pantahub manage the staged rollout to subscribed devices, with error-rate gating. See docs.pantahub.com for channel + rollout configuration.

Offline / Air-Gapped Updates

The same workflow works without the public Pantahub:

  • Run a self-hosted Pantahub on your own network.
  • Or use pvr put / pvr export to ship a state revision via USB / private mirror, then deliver it to the device with a local push.

Common Pitfalls

  • Forgetting pvr add . — modify a file and forget to stage it; pvr commit won’t include it. pvr status catches this.
  • Pushing without pvr sig add — works, but unsigned states are rejected by devices configured for signature verification.
  • Trying to use pvr checkout as “edit mode”pvr checkout (alias pvr reset) discards uncommitted changes. To refresh from remote use pvr get.
  • Treating PVR as a build tool — PVR doesn’t build a flashable image. To produce the initial flashable image, use Yocto + meta-pantavisor (see Build an Embedded Linux Image from Containers).

Next Steps