Skip to content
OpenIPCPublic

About

Universal camera recovery tool - shocking dead devices back to life

Topics

Resources

Code of conduct

Stars

3 stars

Watchers

1 watching

Forks

Latest commit

 

History

170 Commits

Folders and files

Repository files navigation

defib

Universal camera recovery tool - shocking dead devices back to life.

A modern, async Python tool for recovering bricked IP cameras via UART serial and network protocols. Supports HiSilicon, Goke, and other SoC families.

Web UI (No Install Needed)

Launch Web Recovery Tool — works directly in Chrome/Edge/Opera using the WebSerial API. Just open the page, select your chip and firmware, connect your USB-serial adapter, and go.

Installation (CLI)

defib is not published on PyPI — install it from the repository:

uv tool install git+https://github.com/OpenIPC/defib
# or
pipx install git+https://github.com/OpenIPC/defib

To run it once without installing anything (swap in your own chip and port):

uvx --from git+https://github.com/OpenIPC/defib defib burn -c hi3516ev300 -p /dev/ttyUSB0 -t

Quick Start

# List supported chips (120+)
defib list-chips

# List available serial ports
defib ports

# Recover a device via UART using a raw device path
defib burn -c hi3516ev300 -f u-boot.bin -p /dev/ttyUSB0

# Recover a device via UART using a stable alias
defib burn -c hi3516ev300 -f u-boot.bin -p /dev/uart-orangepi5plus

# Interactive TUI
defib tui

# Network recovery via TFTP
defib network -f firmware.bin --nic eth0

# JSON output for AI agents / automation
defib burn -c gk7205v200 -f u-boot.bin --output json

Full Firmware Install (UART + TFTP)

Flash a complete OpenIPC release (U-Boot + kernel + rootfs) in one command:

defib install -c hi3516ev300 \
  --firmware openipc.hi3516ev300-nor-lite-split.tgz \
  -p /dev/uart-IVG85HG50PYA-S \
  --power-cycle --nor-size 8

The install command orchestrates the entire process:

  1. Extracts and verifies the firmware tarball (MD5 checksums)
  2. Resolves U-Boot from OpenIPC releases (or uses cached/local copy)
  3. Reaches an OpenIPC U-Boot shell through boot ROM or a registered stock-U-Boot bootstrap
  4. Detects the flash and selects the standard OpenIPC layout
  5. Starts a multi-file TFTP server and configures U-Boot networking
  6. Flashes U-Boot and the firmware with CRC32 verification: the kernel and rootfs into fixed slots, or, from a -split.tgz package, one firmware.bin where the boot area ends (0x50000), which the kernel divides at boot
  7. Saves the boot environment and resets

Requires root for TFTP port 69 and NIC IP assignment. Standard 8/16/32 MiB NOR layouts are selected from U-Boot flash detection; --nor-size remains an explicit override.

hi3516ev200, hi3516ev300, hi3518ev300, hi3516dv200, gk7205v500/v510/v530, the gk7205v200 family and hi3516cv300/ev100 take their U-Boot from OpenIPC/u-boot, published once per flash type as u-boot-<chip>-nor.bin and u-boot-<chip>-nand.bin. install picks the build from --nand; burn loads the NOR build unless --nand is given. On NAND these SoCs use a UBI-only layout:

Offset Size Contents
0x000000 768K boot: u-boot-<chip>-nand.bin
0x0C0000 256K env
0x100000 rest of chip ubi: rootfs.ubi.<board> (volume rootfs with the kernel as /boot/fitImage, plus rootfs_data)
defib install -c hi3516ev300 --nand \
  --firmware openipc.hi3516ev300-nand-lite.tgz \
  -p /dev/ttyUSB0 --power-cycle

The NAND U-Boot's default environment defines mtdparts, bootcmd and bootargs for this layout, so the installer leaves them alone: it writes U-Boot, erases the ubi partition (nand erase.part ubi) and writes the UBI image with nand write.trimffs, then resets the environment to the U-Boot defaults (env default -a), restores the camera's ethaddr and saves. The kernel and rootfs-data stages are no-ops on this layout: both live inside the UBI image. gk7205v510/v530 NAND packages are published under board gk7205v500. install --nand on any other chip still uses the older split layout (raw kernel partition, mtdparts and bootcmd set by the installer).

gk7202v300, gk7205v200, gk7205v300 and gk7605v100 take their U-Boot from OpenIPC/u-boot (openipc-hisilicon), also published per flash type. That NOR U-Boot works out the layout at every boot, so install loads its default environment (env default -a, keeping the camera's ethaddr) instead of writing mtdparts and bootcmd. Besides the fixed-slot package, their firmware ships a split NOR package, openipc.<board>-nor-<variant>-split.tgz, and install recognises it by its contents:

Offset Size Contents
0x000000 256K boot: u-boot-<chip>-nor.bin
0x040000 64K env
0x050000 rest of chip firmware: firmware.bin.<board> (the uImage, then the squashfs at the next 64 KiB); the kernel divides it into kernel, rootfs and rootfs_data at boot, from its own device tree

hi3516cv608/cv610/cv613 and hi3519dv500/hi3516dv500 ship only the split package, one build per family (openipc.hi3516cv6xx-nor-lite-split.tgz, openipc.hi3519dv500-nor-ultimate-split.tgz). Their boot partition holds the signed boot image, boot-<chip>[-<variant>]-nor.bin. hi3519dv500's image is 383 KiB, so its board puts the env at 0x80000 (256K) and the firmware at 0xC0000. Each board's boot area is data in defib.firmware (NOR_BOOT_AREAS), and install writes firmware.bin where it ends.

defib install -c gk7205v300 \
  --firmware openipc.gk7205v300-nor-ultimate-split.tgz \
  -p /dev/ttyUSB0 --power-cycle

The rootfs stage writes firmware.bin where the boot area ends and erases the rest of the chip, so the first boot starts with an empty overlay; the kernel and rootfs-data stages have nothing of their own to do. Any U-Boot that loads the kernel from there boots the image -- the kernel ignores whatever mtdparts and root= it passes -- so a plan without the uboot stage needs no more than that. See the OpenIPC wiki for the layout itself.

Targets that must bootstrap through a stock U-Boot use an explicit U-Boot variant. For example, HiWatch DS-I203 uses:

defib install -c hi3518ev100:hiwatch-ds-i203 \
  --firmware hi3518ev100_lite_hiwatch-ds-i203-nor.tgz \
  --wipe-env -p /dev/ttyUSB0

For such selectors, Defib resolves the published U-Boot variant through the normal OpenIPC release/cache mechanism. Hikvision Ctrl+U / HKVS # / YMODEM handling lives in defib.vendors.hikvision. The registry also carries any installer-only runtime environment required to complete the migration (for the DS-I203, phyaddru=3 so the chainloaded U-Boot can use TFTP). These values are transient and disappear when Defib replaces the old persistent environment. The env stage on a stock-U-Boot NOR migration requires explicit --wipe-env; Defib refuses that destructive environment migration otherwise, and restores the captured factory ethaddr. Other selected stages can be run without wiping the environment.

Generic NOR installs preserve the existing rootfs_data overlay by default. Add --wipe-rootfs-data when a clean persistent overlay is desired; Defib erases the region and verifies the erased contents by CRC before continuing. When an exact --stage plan is used, that plan must include --stage rootfs-data; --skip-stage rootfs-data conflicts with an explicit wipe. Registered stock-U-Boot migrations retain their existing rootfs_data cleanup behavior.

The release U-Boot owns boot-critical hardware initialization such as DDR cold-init and RAM probing limits. Defib owns the layout it actually flashes: it detects NOR capacity, selects the standard OpenIPC 8/16/32 MiB layout, and persists the matching mtdparts before the first Linux boot (except on the gk7205v200 family above, whose U-Boot sets mtdparts itself). Device runtime policy such as osmem, Linux PHY parameters and sensor selection belongs to the firmware/device profile. An explicit local U-Boot can still be supplied with --uboot.

For development and hardware bring-up, install can run a selected subset of the destructive stages without changing the default production flow. Repeat --stage to build an exact plan, or repeat --skip-stage to subtract from the normal full install. Available stages are uboot, kernel, rootfs, rootfs-data, env, and reset.

# On a device that already boots OpenIPC U-Boot, re-run only persistent
# environment migration/verification. No TFTP starts and U-Boot/kernel/rootfs
# are left untouched. Exact stage selection does not imply the final reset
# unless `--stage reset` is also present.
defib install -c hi3518ev100:hiwatch-ds-i203 \
  --firmware hi3518ev100_lite_hiwatch-ds-i203-nor.tgz \
  --uboot u-boot-hi3518ev100-ddr3-256m-universal.bin \
  --wipe-env --stage env -p /dev/ttyUSB0 -d

# Starting from genuine stock U-Boot, include the bootloader write before env.
defib install -c hi3518ev100:hiwatch-ds-i203 \
  --firmware hi3518ev100_lite_hiwatch-ds-i203-nor.tgz \
  --uboot u-boot-hi3518ev100-ddr3-256m-universal.bin \
  --wipe-env --stage uboot --stage env -p /dev/ttyUSB0 -d

# Generic NOR install with a clean persistent overlay.
defib install -c hi3516ev200 \
  --firmware openipc.hi3516ev200-nor-lite.tgz \
  --wipe-rootfs-data -p /dev/ttyUSB0

# Full production plan except kernel/rootfs writes.
defib install -c hi3518ev100:hiwatch-ds-i203 \
  --firmware hi3518ev100_lite_hiwatch-ds-i203-nor.tgz \
  --wipe-env --skip-stage kernel --skip-stage rootfs -p /dev/ttyUSB0

--stage and --skip-stage are mutually exclusive. On a registered stock U-Boot target, if Defib actually had to chainload OpenIPC U-Boot from the factory bootloader, a partial persistent plan must include the uboot stage; this prevents an accidental kernel/rootfs/environment migration while leaving the factory bootloader installed. Later partial stages are available once the device already boots OpenIPC U-Boot.

Flash Dump Restore

Restore a full flash dump (e.g., vendor firmware backup) to a device. Supports NOR, NAND, and eMMC — auto-detected from U-Boot.

# Restore from a directory of mtd partition files
defib restore -c hi3516av200 -i /path/to/dump/ \
  -p /dev/uart-hi3516av200 --power-cycle

# Restore a single flash image to NOR
defib restore -c hi3516ev300 -i flash_dump.bin \
  -p /dev/ttyUSB0 --flash-type nor --power-cycle

# Use a custom U-Boot binary (e.g., vendor or custom build)
defib restore -c hi3516av200 -i /path/to/dump/ \
  --uboot /path/to/u-boot.bin -p /dev/ttyUSB0 --power-cycle

# Restore directly from an ipctool backup file
defib restore -c hi3516av200 -i backup.bin \
  --uboot /path/to/u-boot.bin -p /dev/ttyUSB0 --power-cycle

ipctool backup files (.bin with YAML header) are auto-detected. Partition layout, names, and UBI volume metadata are extracted from the embedded YAML — no manual --mtdparts needed.

The restore process:

  1. Burns U-Boot to RAM via boot ROM protocol
  2. Detects post-boot mode (download command protocol or U-Boot shell)
  3. Auto-detects flash type (NAND/NOR/eMMC) from U-Boot
  4. Sets up networking and starts a TFTP server
  5. Transfers each partition to RAM and writes to flash
  6. Resets the device

For NAND devices, writes are automatically page-aligned (2KB). Handles both tftpboot and tftp U-Boot commands transparently.

Features

  • All 3 HiSilicon/Goke UART protocols (Standard, V500, CV6xx)
  • 120+ supported SoC chips
  • Full firmware install via UART + TFTP with CRC32 verification
  • Reusable stock U-Boot bootstrap implementations plus release U-Boot variants
  • Multiple interfaces: CLI, TUI, Web UI, JSON for automation
  • Multi-file TFTP server with filename-based routing
  • UART session capture/replay (.dcap format)
  • Friendly serial-port discovery for multi-UART setups
  • macOS serial workaround (ACK byte correction)
  • Cross-platform: Linux, macOS, Windows

Automated Power Cycling

Defib can automatically power-cycle devices, eliminating manual intervention for recovery loops and research workflows. The backend is selected via DEFIB_POWER_TYPE:

MikroTik RouterOS PoE switch (default)

export DEFIB_POWER_TYPE=routeros           # optional, the default
export DEFIB_POE_HOST=192.168.88.1
export DEFIB_POE_USER=admin
export DEFIB_POE_PASS=

defib burn -c hi3516ev300 -p /dev/uart-IVG85HG50PYA-S --power-cycle -b

# Burn and open serial terminal to see boot output (Ctrl-C to exit)
defib burn -c hi3516ev300 -p /dev/uart-IVG85HG50PYA-S --power-cycle -t

OpenIPC Vectis UART bridge

Vectis is a USB/Ethernet UART bridge that exposes the camera's UART over TCP and drives camera power via the bridge's RTS/DTR lines. Vectis ≥ 1.2.0 speaks RFC 2217 (Telnet COM Port Control Option) on the listener: the data path is binary safe and modem-control lines are commanded out-of-band as SET-CONTROL sub-options instead of in-band magic bytes. Defib uses the same TCP connection for the UART and the reset:

export DEFIB_POWER_TYPE=vectis
export DEFIB_VECTIS_HOST=172.17.32.17
export DEFIB_VECTIS_PORT=35240             # optional, the upstream default

defib burn -c hi3516cv300 -p rfc2217://172.17.32.17:35240 --power-cycle -b

The rfc2217:// URL scheme routes the UART through pyserial's RFC 2217 client (which handles RFC 854 escaping for 0xFF and the SET-CONTROL DTR/RTS pulse for reset). An older Vectis without RFC 2217 support is still reachable via the legacy tcp://host:port URL and the in-band Ctrl+P reset trigger.

Smoke-test the bridge first with telnet (which negotiates RFC 2217) or with socat (which stays in legacy raw mode):

telnet 172.17.32.17 35240
# Or, legacy raw mode:
socat -,raw,echo=0 TCP:172.17.32.17:35240

Note: Vectis only emits a fixed-width reset pulse, so it does not work with defib restore (which needs independent power_off/power_on).

Note: tight-loop bootrom catching needs a low-RTT link to Vectis. Over a high-RTT WAN link the bootrom's 0x20-marker / 0xAA-ack window can close before the round-trip completes; running Vectis on the same host as defib (or close to it on a LAN) is recommended.

Tasmota smart plug

Any plug running Tasmota (or a firmware that speaks the same /cm?cmnd= HTTP API) in front of the camera's power supply. Each switch is confirmed from the plug's reply, so a cycle that did not happen is an error rather than a silent no-op:

export DEFIB_POWER_TYPE=tasmota
export DEFIB_TASMOTA_HOST=192.168.1.50
export DEFIB_TASMOTA_RELAY=1               # optional, multi-relay devices only
export DEFIB_TASMOTA_USER=admin            # optional, if a web password is set
export DEFIB_TASMOTA_PASSWORD=secret

defib burn -c gk7205v500 -f u-boot-gk7205v500-nand.bin -p /dev/ttyUSB0 --power-cycle -t

On a mains plug, leave the default 3 s off time alone: a camera brick can hold enough charge to ride through a shorter gap.

Generic HTTP relay

Any relay that turns on and off with a plain GET request — for example a small local bridge in front of a cloud-only smart switch:

export DEFIB_POWER_TYPE=http
export DEFIB_HTTP_POWER_ON_URL=http://127.0.0.1:8090/relay/on
export DEFIB_HTTP_POWER_OFF_URL=http://127.0.0.1:8090/relay/off
export DEFIB_HTTP_POWER_TIMEOUT=10         # optional, seconds per request

defib agent upload -c hi3516ev300 -p /dev/ttyUSB0 --power-cycle

The cycle is timed on the host, so it inherits the relay's latency. agent upload --power-cycle copes with that by starting the handshake while the camera is still off and re-cycling once if the bootrom does not answer.

Both are single-outlet controllers: --poe-port does not apply, and like Vectis they do not work with defib restore.

The -t flag auto-detects the post-boot mode:

  • Normal U-Boot shell (e.g. hi3516ev300): a two-way serial terminal — your keystrokes go to the board and its output comes back. Ctrl-C exits the terminal rather than being sent on to U-Boot.
  • Download command mode (e.g. hi3516av200): interactive defib> prompt that wraps commands in HiSilicon's XHEAD/XCMD protocol, enabling flash operations on devices that enter download_process() after serial boot
# Interactive download command mode (hi3516av200 enters this automatically)
defib burn -c hi3516av200 -p /dev/ttyUSB0 --power-cycle -t
# defib> nand info
# Device 0: nand0, sector size 128 KiB
# [OK]
# defib> nand erase 0x200000 0x800000
# [OK]

The --power-cycle flag connects to the RouterOS API, auto-discovers the PoE port by matching the serial device name against switch interface comments, and power-cycles the device before recovery. A continuous ACK mechanism ensures the bootrom is caught even on fast-booting devices where the bootrom window is <100ms.

Tested on real hardware with CRS112-8P-4S:

Camera SoC Serial Port
IVGHP203Y-AF hi3516cv300 /dev/uart-IVGHP203Y-AF
IVG85HG50PYA-S hi3516ev300 /dev/uart-IVG85HG50PYA-S

Flash Agent (High-Speed Recovery)

Defib includes a bare-metal flash agent that runs directly on the SoC, replacing U-Boot in the boot chain. It communicates over a COBS binary protocol at 921600 baud for high-speed flash operations.

One-Command Firmware Install

Flash a complete firmware image via UART in a single command:

defib agent flash -c hi3516ev300 -i firmware.bin -p /dev/ttyUSB0

Power-cycle the camera when prompted. The command handles everything:

  1. Uploads the bare-metal agent via boot protocol
  2. Switches to 921600 baud for high-speed transfer
  3. Streams firmware directly to flash (skips 0xFF sectors)
  4. Verifies CRC32 of the written data
  5. Reboots the device

Typical 8MB OpenIPC firmware on 16MB flash: ~2 minutes total (upload + flash + verify + boot). No network required — just a USB-serial adapter.

Other Agent Commands

# Upload agent only (for manual operations)
defib agent upload -c hi3516ev300 -p /dev/ttyUSB0

# Dump the entire flash (address and size auto-detected)
defib agent read -p /dev/ttyUSB0 -o flash_dump.bin

# Query device info (flash size, RAM base, JEDEC ID, agent version)
defib agent info -p /dev/ttyUSB0

# Write data back to flash
defib agent write -p /dev/ttyUSB0 -i flash_dump.bin

# Scan flash health (bad sectors, stuck bits)
defib agent scan -p /dev/ttyUSB0

Address defaults to flash base (0x14000000) and size is auto-detected from the device. Override with -a and -s if needed. Use --no-verify to skip the CRC32 check, or --output json for automation. See agent/README.md for protocol details and supported chips.

Testing with QEMU

Defib can be tested end-to-end against the qemu-hisilicon emulator without physical hardware. When QEMU starts without -kernel, it emulates the HiSilicon boot ROM serial protocol.

# Terminal 1: start QEMU in fastboot mode
qemu-system-arm -M hi3516ev300 -m 64M -nographic \
    -chardev socket,id=ser0,path=/tmp/qemu-hisi.sock,server=on,wait=off \
    -serial chardev:ser0

# Terminal 2: recover via socket (auto-downloads OpenIPC U-Boot)
defib burn -c hi3516ev300 -p socket:///tmp/qemu-hisi.sock

The socket:// transport prefix connects defib directly to QEMU's chardev Unix socket. All three protocol phases (DDR init, SPL, U-Boot) transfer with full CRC-16 validation. After the upload, QEMU starts the CPU and U-Boot output appears on the same connection.

Supported: all Standard protocol chips (hi3516cv300, hi3516ev200, hi3516ev300, hi3518ev300, gk7205v200, gk7205v300, etc.). V500 and CV6xx protocol emulation is not yet available in QEMU.

License

MIT

About

Universal camera recovery tool - shocking dead devices back to life

Topics

Resources

Code of conduct

Stars

3 stars

Watchers

1 watching

Forks

Contributors

Languages