ZBT-WD323 images unusable - proposed workaround

I am evaluating the use of the ZBT-WD323

In the OpenWRT images (all versions), the router reboots every 30 seconds which seems to be due to the watchdog tripping it. I saw other people having the same issue so wrote a script to loop through all the GPIO pins to find out which one is connected to the watchdog and it seems to be GPIO 21.

A hacky script such as the following seems sufficient to keep the router alive:

echo "21" > /sys/class/gpio/export; echo "out" > /sys/class/gpio/gpio21/direction; done
while true; do echo "1" > /sys/class/gpio/gpio21/value; sleep 5; echo "0" > /sys/class/gpio/gpio21/value; sleep 5; done

Since this workaround is required to use the router, where is best to document this?

  • In the wiki page for the router (happy to add this myself)
  • Submit as patch for this router in the git repo (not sure where we would put this though? /etc/board.d somewhere?)
  • Look into integrating with OpenWRT's watchdog?

Either way this needs flagging up somewhere given that the stock image is unusable without some kind of workaround

Also, if anyone is interested I have done a dump of this router's stock firmware (it's not accessible anywhere on the internet as far as I can see), happy to upload it here or somewhere else. Since it's based on OpenWRT, I don't think the manufacturer would be able to restrict the licence even if they did complain.


You can try implementing the change in the dts(i), see https://github.com/openwrt/openwrt/blob/master/target/linux/ramips/dts/mt7620a_zbtlink_zbt-we1026-5g.dtsi#L30

Edit: one more useful link: https://www.kernel.org/doc/Documentation/devicetree/bindings/watchdog/gpio-wdt.txt

Thanks for this @AndrewZ. I added this to my custom image to this section:

	watchdog {
		compatible = "linux,wdt-gpio";
		gpios = <&gpio 21 GPIO_ACTIVE_HIGH>;
		hw_algo = "toggle";
		hw_margin_ms = <30000>;

This seems to work and keeps the watchdog alive. But the dmesg logs get the following warnings:

[    1.506335] watchdog: GPIO Watchdog: cannot register miscdev on minor=130 (err=-16).
[    1.514243] watchdog: GPIO Watchdog: a legacy watchdog module is probably present.

Perhaps this can be ignored, if they're considering GPIO a legacy form of watchdog but for this device is necessary? And I can submit a PR for this? I'm also suspecting that the mapping for the RTC is incorrect, but this might be something to address separately later.

1 Like

Please see the explanation of the errors here.

OK sounds like it's not a major issue, I'll look into seeing if I can draft a PR.
Also for reference, I just found this in the stock FW in /bin/feed_dog.sh - looks like this is how they'd implemented the watchdog (looks pretty hacky):


echo $wd_gpio > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio$wd_gpio/direction

while [ 1 ]
    echo 1 >/sys/class/gpio/gpio$wd_gpio/value
    sleep 1
    echo 0 >/sys/class/gpio/gpio$wd_gpio/value
    sleep 1
	echo 1 >/sys/class/gpio/gpio$wd_gpio/value
    sleep 1
    echo 0 >/sys/class/gpio/gpio$wd_gpio/value
    sleep 1
	echo 1 >/sys/class/gpio/gpio$wd_gpio/value
    sleep 1
    echo 0 >/sys/class/gpio/gpio$wd_gpio/value
    sleep 1
1 Like

For reference of any OpenWRT users who may be wanting this to be fixed - I've opened a PR here, will see if it gets accepted or not

hi @joshun Can you provide the script that you used to do this?

Hi @darknblack it was something like this

function walk_gpio() {
	end=$(($1 + $2))

	for chip in `seq $start $end`
		printf 'Press ENTER to write %s' $chip
		echo "$chip" > /sys/class/gpio/export
		echo "out" > "/sys/class/gpio/gpio$chip/direction"
		echo "1" > "/sys/class/gpio/gpio$chip/value"

If you source that function in a shell. I can't remember what the starting chip offset was though as I haven't been working on one of these devices for a while.

Hi @joshun thanks for the script. How do I know if that's the correct one?

Press ENTER to write 494
ash: write error: Resource busy
-ash: can't create /sys/class/gpio/gpio494/direction: nonexistent directory
-ash: can't create /sys/class/gpio/gpio494/value: nonexistent directory
Press ENTER to write 495
Press ENTER to write 496
client_loop: send disconnect: Connection reset

Router will disconnect on 496th

Hi @darknblack I can't remember what all the GPIOs do unfortunately as I haven't been working on this router for a while. Are you trying to resolve the watchdog issue? As I think the fix for this has been merged into the main branch now:

1 Like

Hi, I'm just trying to learn reverse engineering (Openwrt). I am planning to add support for z8103ax (thread). Stuff like this is very helpful. Thank you!

Take a look here: Adding OpenWrt support for ZBT Z8102AX

1 Like

Hi @AndrewZ Yes, I was basing my work on that. Here's my progress so far