-
Notifications
You must be signed in to change notification settings - Fork 0
firmware update
kvm-pilot can detect stale KVM firmware (see firmware-registry.md)
and, on drivers that support it, offer and perform a gated remote flash of the
KVM's own firmware. This page documents the GL.iNet GLKVM update API, the
reliability model, and the operating procedure.
Read this first. Flashing a KVM's own firmware is the single most destructive thing this tool does: the device reboots into a new image — dropping the very control channel you'd use to watch it — and on the GL RM1 family a failed or interrupted flash bricks onboard storage with no remote recovery. The command defaults to a dry-run and refuses to execute on a device with no out-of-band recovery path unless you explicitly override. Prefer flashing with physical (or same-site remote-hands) access. This code has never been run against real hardware — treat the execute path as unverified.
Remote update is the FirmwareUpdate capability (drivers/base.py), implemented
today only by GLKVMDriver. A driver advertises it structurally, so
kvm-pilot capabilities lists firmware_update when available.
-
kvm-pilot healthcheck— when firmware is behind and the model's registryprofile.remote_update.supportedis true, the "Firmware update available" finding's remediation becomes actionable: it names thefirmware-updatecommand and states the risk. The healthcheck itself never flashes. -
kvm-pilot firmware-update— read-only by default: prints installed→latest, the reliability assessment, and the planned/api/upgrade/*steps, sending nothing.-
--executeperforms the flash (routed through thefirmware.flashsafety gate; without--yesit prompts first). -
--image PATHuploads a local firmware image before flashing (preferred — it's deterministic and retryable from a known-good file); omit it to flash the image the device has already staged. -
--i-have-physical-accessoverrides the refusal on a device with no out-of-band recovery path (acknowledges that a failed flash needs a physical trip).
-
kvm-pilot firmware-update --profile homelab2 # assess only (dry run)
kvm-pilot firmware-update --profile homelab2 --image rm1pe.img --execute --yesGL adds a proprietary upgrade layer on top of kvmd (upstream PiKVM has no
OS-update REST API — it updates via pikvm-update over SSH). GL publishes no
per-endpoint spec; the map below was reverse-engineered from live probing of a
GL-RM1PE (fw V1.5.1 release2, kvmd 4.82) plus the gl-inet/glkvm source, so treat
request bodies as provisional and feature-detect via /api/upgrade/status.
| Endpoint | Verb | Response / role |
|---|---|---|
/api/upgrade/status |
GET |
{"enabled": true} — is the subsystem available |
/api/upgrade/version |
GET |
{"model","version"} — installed version (also used by get_firmware_info) |
/api/upgrade/compare |
GET | GL's online check (installed vs GL's server); needs internet, and 502'd on the probed unit. Feeds get_available_update. |
/api/upgrade/download |
GET |
{"size": …} — size of the available/staged image (~293 MB observed) |
/api/upgrade/upload |
POST | upload a local firmware image |
/api/upgrade/start |
POST | begin the flash; the device auto-reboots |
/api/upgrade/reboot |
GET | action-shaped status ({"status":"Reboot started"}) — not used by kvm-pilot |
get_upgrade_status() aggregates the three read endpoints. apply_firmware_update()
optionally uploads (--image) then POSTs /api/upgrade/start; it is routed through
safety.guard("firmware.flash", …) and defaults to dry_run=True.
Per-model risk is data in the registry (profile.remote_update), not hard-coded:
"remote_update": {
"supported": true, "method": "gl-api", "risk": "high",
"recovery_required": true, "self_flash_blind": true,
"notes": "…"
}For the GL RM1/RM1PE this is risk: high, because:
-
Recovery is physical-only. A failed flash needs the GL U-Boot failsafe: hold
Reset while powering on (blue LED flashes 5×), set your NIC to static
192.168.1.2/24, browse tohttp://192.168.1.1, and upload the firmware. GL's docs state "No remote recovery option exists." - Self-flash is blind. The KVM flashes itself and reboots, so kvm-pilot loses its only sensor/control channel across the reboot.
- No A/B rollback, and an interrupted power cycle bricks onboard storage (GL's own warning).
-
The update can disable the REST API. A GL update commonly reverts
/etc/kvmd/nginx-kvmd.confand re-disables the PiKVM REST API kvm-pilot depends on, and may reset config — so even a successful flash can lock the tool out until the API is re-enabled over SSH (gl-inet/glkvm#13). -
Media-mounted flashes corrupt. A GL flash can start with virtual media still
mounted, with no warning (
gl-inet/glkvm#120) —firmware-updateejects media first.
- Run
kvm-pilot healthcheck— fix a missing out-of-band recovery path if you can. - Ensure stable power (UPS). Do not interrupt power during the flash.
- Eject virtual media (the command does this, but confirm the host isn't mid-install).
- Prefer
--imagewith a file from the vendor's stable channel over the online path. - Have the U-Boot recovery kit ready (laptop + Ethernet + the reset procedure above).
- After the flash + reboot: if
/api/*now 404s, re-enable the API in/etc/kvmd/nginx-kvmd.conf, restart kvmd, and re-runkvm-pilot healthcheck.
- PiKVM OS update / recovery: https://docs.pikvm.org/_update_os/, https://docs.pikvm.org/api/
- GL firmware upgrade: https://docs.gl-inet.com/kvm/en/faq/firmware_upgrade/
- GL U-Boot debrick (recovery): https://docs.gl-inet.com/kvm/en/faq/debrick/
- GL firmware channel: https://dl.gl-inet.com/kvm/rm1/stable
- API re-disabled on update: https://github.com/gl-inet/glkvm/issues/13
- Flash starts with media mounted: https://github.com/gl-inet/glkvm/issues/120
- Update-induced hang (PiKVM): https://github.com/pikvm/pikvm/issues/1539
Tracking issue: #92.
- Home
- Getting started
- Architecture
- CLI reference
- Configuration
- Design decisions
- Reflexes (RFC)
- Redfish reference
- Firmware registry
- Remote firmware update
- Claude skill
- MCP server
- Contributing
- Security policy
- Analysis: 2026-07-01 deep review
- Analysis: 2026-07-03 RM1PE firmware + encoder
- Hardware compatibility