Skip to content
HackingGate edited this page Aug 17, 2026 · 6 revisions

Photonicat PM Wiki

Checking and flashing wrapped Photonicat 2 MCU firmware.

MCU flashing is power-sensitive: keep stable power connected and do not reboot, power off, or unplug the device while an update is running.

TL;DR

Requires pcat-pmu-updater and a /dev/pcat-pm-ctl control device — see Install pcat-pmu-updater if command -v pcat-pmu-updater finds nothing.

1. Check the running version

cat /sys/kernel/photonicat-pm/pmu_fw_version
sudo pcat-pmu-updater --pmu-fw-version-get

2. List what the vendor publishes

Two endpoints, neither complete on its own. latest_img.json is the current production target; versions.json lists older releases and does not include the current target.

curl -fsSL -o /tmp/pcat2-mcu-latest.json \
  https://dl.photonicat.com/firmware/pcat2_mcu/latest_img.json
curl -fsSL -o /tmp/pcat2-mcu-versions.json \
  https://dl.photonicat.com/firmware/pcat2_mcu/versions.json

python3 - /tmp/pcat2-mcu-latest.json /tmp/pcat2-mcu-versions.json <<'PY'
import json
import pathlib
import sys

for arg in sys.argv[1:]:
    data = json.loads(pathlib.Path(arg).read_text())
    for entry in data.get("versions", [data]):
        message = " ".join(entry.get("message", "").split())
        print(entry.get("version", ""), entry.get("url", ""),
              entry.get("sha256sum", ""), message, sep="  ")
PY

Both endpoints use the same fields, so this prints one line per available package. Pick the url filename you want.

Ignore ota.bin: it tracks the current production target and is not a rollback image.

3. Download and validate

FW=ota_RA2E120260813002000.bin

curl -fsSL -o /tmp/pcat2-firmware.bin \
  "https://dl.photonicat.com/firmware/pcat2_mcu/$FW"
sha256sum /tmp/pcat2-firmware.bin

python3 - /tmp/pcat2-firmware.bin <<'PY'
import pathlib
import struct
import sys
import zlib

data = pathlib.Path(sys.argv[1]).read_bytes()
version = data[8:22].decode("ascii", "replace")
raw_size, expected_crc = struct.unpack_from("<II", data, 22)

assert data[:8] == b"ARBDPHC2", "bad magic"
assert version.startswith("RA2E1"), f"bad version: {version}"
assert raw_size + 512 == len(data), f"bad size: raw={raw_size} file={len(data)}"
assert zlib.crc32(data[512:]) & 0xffffffff == expected_crc, "bad crc"

print("ok", version, raw_size)
PY

Compare the printed SHA256 against the listing from step 2, and only continue if the validator prints the version you intended.

4. Flash

sudo pcat-pmu-updater /tmp/pcat2-firmware.bin

Downgrading or reinstalling the same version needs the force flag:

sudo pcat-pmu-updater --force /tmp/pcat2-firmware.bin

The updater powers the system off on success. Wait for shutdown, then restore power and boot.

5. Verify after boot — do not skip

cat /sys/kernel/photonicat-pm/pmu_fw_version

A successful updater run is not proof the firmware was applied. RA2E1260730001 and RA2E1260813002 both stream to 100%, print PMU firmware updated successfully., and then roll back: the PMU comes up on RA2E1250815002 regardless of what was running before. If the version did not change, the MCU rejected the update. Pick an older package from versions.json and flash it with --force.

Reference Pages

Optional. Use these for the long form of any step above, or for inspecting vendor tooling.

  1. pcat-manager-web IPK Inspection
  2. OpenWrt Image Inspection
  3. Vendor OpenWrt MCU Version Check
  4. Install pcat-pmu-updater
  5. Check and Download MCU Firmware
  6. Flash MCU Firmware
  7. PMU Firmware Observed Behavior — per-firmware driver test results

pcat-manager-web is now open source — prefer reading the source directly over bytecode inspection.

Endpoints

URL What it is
https://dl.photonicat.com/firmware/pcat2_mcu/latest_img.json Current production target
https://dl.photonicat.com/firmware/pcat2_mcu/versions.json Older releases; excludes the current target
https://dl.photonicat.com/firmware/pcat2_mcu/ota.bin Copy of the current target, not a rollback image

Clone this wiki locally