Repository navigation
sysupgrade: the watchdog keeper never runs on Xiongmai (xm_wdt is /dev/wdt and cannot be fed by write) #2611
Description
Summary
sysupgrade's RAM-phase watchdog keeper (watchdog_keep, general/overlay/usr/sbin/sysupgrade) protects the flash from a watchdog reset after majestic dies mid-write. It does nothing on xm510/xm530/xm550. Two things stop it, and fixing the first alone doesn't help:
- Wrong device.
WDOG=${WDOG:-/dev/watchdog}, butxm_wdt.koregisters a misc device namedwdt, so XM has/dev/wdtand no/dev/watchdog.watchdog_owner()returns 1 at[ -c "$WDOG" ], sowdog_userspace_ownedis never set and no keeper is started. The pre-flash report printsWatchdog: none, even though majestic holds/dev/wdtand feeds it. - No write() feed. Even pointed at
/dev/wdt, the keeper'sprintf 1 >&9feeds nothing.xm_wdt.ko'sfile_operationshas onlyopen,releaseandunlocked_ioctl, and nowrite(the relocations against.datain both the xm510 and xm530 builds of the module show this). Feeding is only possible through its private ioctl,_IO('W', 2)=0x5702, which no busybox applet can issue. busyboxwatchdogwrites to the device and uses the standardWDIOC_*numbers, so it doesn't work here either.
Why it matters
When majestic arms the watchdog it asks for 300 s:
Watchdog armed: asked 300 s, assuming 300 s, fed every 10.000s, magic close NOT supported by this driver
wdt_release is a no-op (the driver has no magic close), so if majestic dies during the flash (the SIGBUS-after-erase case the keeper exists for), the SP805 counts down and resets the board about 300 s after majestic's last feed. The keeper's own comment describes the result: a camera that comes back with a part-written rootfs from an upgrade whose log looked fine. On XM nothing guards against that today.
I have not measured how long a full sysupgrade takes on an XM board, so I can't say how often the 300 s window is hit in practice. The mechanism above was read from the module and from majestic's log, not observed as a failed upgrade.
What the driver does (from disassembly of general/package/xiongmai-osdrv-xm530/files/kmod/xm_wdt.ko)
The hardware is an ARM PrimeCell SP805:
| Function | What it does |
|---|---|
init_module |
wdt_start() then wdt_set_timeout(60): the countdown runs from module load, not from open (see #743) |
ioctl 0x5700 (_IO('W',0)) |
wdt_start |
ioctl 0x40045701 (_IOW('W',1,int)) |
wdt_set_timeout(*arg) |
ioctl 0x5702 (_IO('W',2)) |
feed: unlock (0x1ACCE551 to LOCK at +0xC00), write INTCLR at +0x0C, relock |
ioctl 0x5703 (_IO('W',3)) |
wdt_stop: unlock, CONTROL at +0x08 to 0, INTCLR, relock |
release |
nothing |
cleanup_module |
wdt_stop(), then misc_deregister: rmmod xm_wdt stops the hardware |
Options
- a. Keeper stands the dog down on XM. When the owner is gone and the device is
/dev/wdt, runrmmod xm_wdt(the module's exit stops the SP805) instead of trying to pet it.- Pros: shell only, no new binary.
- Cons: it gives up the property the keeper deliberately keeps on other SoCs, where an armed dog recovers a camera whose final
rebootcan't exec (sysupgrade--no_reboot(-x) corrupts the running rootfs and locks out SSH after an on-device flash #2231). It also needsrmmodand the module's path to still work from the ramfs.
- b. Small ioctl feeder. A tiny C helper, packaged with source in the xm osdrv packages (or a sysupgrade helper), that feeds
/dev/wdtwith0x5702. The keeper uses it whenWDOG=/dev/wdt. This keeps the "armed until reboot" behaviour. It has to live in the RAM root like the rest of the flash phase. - c. Replace xm_wdt with the upstream
sp805_wdtdriver. That gives a real/dev/watchdogwithwrite()feeding,WDIOC_*and magic close, and the hardware stays idle until opened. That would also have made XM530 reboots after ~ 1 minute #743 impossible. It needs the AMBA device registered for the SoC, which is kernel work for OpenIPC/linux, plus a majestic change to open/dev/watchdogon XM.
Whichever is chosen, WDOG needs to resolve per platform (or probe /dev/watchdog, then /dev/wdt). That way the pre-flash Watchdog: line reports the truth on XM instead of none.
Related: #743 (xm_wdt starts counting at module load; fixed in majestic by stopping it when the watchdog is disabled).
Activity