Web UI to reboot to another partition (for Linksys/ZyXEL dual-partition routers) and to power off/power down

Hi have installed OpenWRT 24.10.2 on a NETGEAR Switch GS310TP v1. Working perfectly. This device is also dual-boot capable, and it would be great to be able to use this little helper as well.

root@OpenWrt:~# ubus call system board
{
        "kernel": "6.6.93",
        "hostname": "OpenWrt",
        "system": "RTL8380",
        "model": "Netgear GS310TP v1",
        "board_name": "netgear,gs310tp-v1",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "24.10.2",
                "revision": "r28739-d9340319c6",
                "target": "realtek/rtl838x",
                "description": "OpenWrt 24.10.2 r28739-d9340319c6",
                "builddate": "1750711236"
        }
} 
root@OpenWrt:~# cat /tmp/sysinfo/board_name
netgear,gs310tp-v1

root@OpenWrt:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 000e0000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 00010000 00010000 "u-boot-env2"
mtd3: 00100000 00010000 "jffs"
mtd4: 00100000 00010000 "jffs2"
mtd5: 00e80000 00010000 "firmware"
mtd6: 00290000 00010000 "kernel"
mtd7: 00bf0000 00010000 "rootfs"
mtd8: 00990000 00010000 "rootfs_data"
mtd9: 00e80000 00010000 "runtime2"
root@OpenWrt:~# fw_printenv
baudrate=115200
boardmodel=RTL8393M_DEMO
bootcmd=boota
bootdelay=1
ethact=rtl8380#0
ethaddr=38:94:ED:A5:96:20
fileaddr=81000000
filesize=7ABE74
ipaddr=192.168.1.1
ledModeInitSkip=0
serverip=192.168.1.111
stderr=serial
stdin=serial
stdout=serial

Switching between bootimages works as below:
Run fw_setsys bootpartition {0|1} to select the boot partition
(see https://github.com/openwrt/openwrt/pull/4122 and here https://openwrt.org/toh/netgear/gs308t_1?s[]=restart&s[]=bootloader for reference) -- corrected the command

Let me know if I can provide anything else.

@aaul the wiki states the command to switch to partition 2 is different: fw_setsys bootpartition 1.

@RaylynnKnight were you considering submitting a PR for luci-app-advanced-reboot to support this device? If so, I’d wait for you to do that since you have the device on hand. If not, let me know if between you and @aaul you can test the APK i can produce.

PS. @RaylynnKnight educate me please, with only a single kernel partition, where from can I read the labels for different firmware boots on this device? I think normally there is a kernel partitions per firmware and that’s how I get the labels for different firmwares. Is an alternative kernel partition mtd9?Also what would be the labelOffset – how many bytes to skip on the flag/kernel partitions so I can read their labels?

PPS. @aaul if you can grab first 1024 bytes (I know, it’s an oddly specific number) from mtd5, mtd6 and mtd9 and post them somewhere that would help. Also, what does fw_printsys produce?

PPPS. Thanks @slh for the hint below, added mtd5 to list of partitions to investigate. :wink:

Disclaimer: I don’t own any of the switches in this model range, the below is just an educated guess.

I think /proc/mtd is misleading here, as it reflects the dynamic split between kernel+rootfs+overlay badly. The DTS is more helpful:

I’m pretty sure firmware: partition@300000(firmware) and partition@1180000(runtime2) are the relevant partitions here (14.5 MB each), dynamically split into kernel+rootfs+overlay.

1 Like

OpenWrt can only boot off the first partition (this is hardcoded in the DTS). The second partition is for booting into the stock firmware.

@stangri I don’t have any experience with using luci-app-advanced-reboot and would not have time to devote to a PR until early October. As per the wiki documentation for this device ā€œOpenWrt can only boot off the first partition (this is hardcoded in the DTS).ā€

@RaylynnKnight I’m guessing the user is requesting a WebUI wrapper to be able to boot into OEM partition, hence the questions.

1 Like

Happy to - but what's the command to use to grab these 1024 bytes? :face_with_peeking_eye:

output fw_printsys

root@OpenWrt:~# fw_printsys
SN=5GL19652007E4
bootpartition=0

The vendor firmware would allow me to choose bootpartition 1 and then flash software into it - haven't tried though. (bootpartition 0 is OpenWRT, bootpartition 1 is last stable vendor)

Booting on CLI into bootpartition1 is literally as simple as:

fw_setsys bootpartition 1
restart

I would defnitly do some testing.

Found this in sytemlog - maybe that helps as well?

Sun Aug 17 20:55:21 2025 kern.info kernel: [    0.861589] spi-nor spi0.0: mx25l25635e (32768 Kbytes)
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.867618] 7 fixed-partitions partitions found on MTD device spi0.0
Sun Aug 17 20:55:21 2025 kern.err kernel: [    0.875053] OF: Bad cell count for /soc/spi@1200/flash@0/partitions
Sun Aug 17 20:55:21 2025 kern.err kernel: [    0.882247] OF: Bad cell count for /soc/spi@1200/flash@0/partitions
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.890002] Creating 7 MTD partitions on "spi0.0":
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.895424] 0x000000000000-0x0000000e0000 : "u-boot"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.909896] 0x0000000e0000-0x0000000f0000 : "u-boot-env"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.922071] 0x0000000f0000-0x000000100000 : "u-boot-env2"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.934572] 0x000000100000-0x000000200000 : "jffs"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.946244] 0x000000200000-0x000000300000 : "jffs2"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.958114] 0x000000300000-0x000001180000 : "firmware"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.970915] 2 uimage-fw partitions found on MTD device firmware
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.977596] Creating 2 MTD partitions on "firmware":
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.983296] 0x000000000000-0x000000290000 : "kernel"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    0.994832] 0x000000290000-0x000000e80000 : "rootfs"
Sun Aug 17 20:55:21 2025 kern.info kernel: [    1.006451] mtd: setting mtd7 (rootfs) as root device
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    1.012403] 1 squashfs-split partitions found on MTD device rootfs
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    1.019488] 0x0000004f0000-0x000000e80000 : "rootfs_data"
Sun Aug 17 20:55:21 2025 kern.notice kernel: [    1.031800] 0x000001180000-0x000002000000 : "runtime2"

for i in mtd5 mtd6 mtd9; do dd if=/dev/${i} bs=1 count=1024 > /tmp/${i}; done

this would produce three files in /tmp/ which you can inspect with Hexdump and see if you can locate kernel info. You’re looking for the offset value (you can pass to skip=$offset added to command above) to start the output with something like: ARM64 OpenWrt Linux-6.6.93. Also, note which mtds have this label.

In the mean time, I’ve pushed the 1.1.1-r1 to both my repositories and github releases tab which has preliminary support for Netgear GS308T v1 as it now uses customizable commands to obtain and set environment variables.

I’ve only tested it on Linksys devices with both UBI and non-UBI volumes and it seems to work.

I’d appreciate testing on the ā€œnon-standardā€ devices like:

  • "d-link,dgs-1210-28"
  • "mercusys,mr90x-v1"
  • "xiaomi,ax3600"
  • "xiaomi,ax9000"
  • "zyxel,nbg6817"

I’ve converted the RPCD script to ucode and brought some sensible structure to the device json now instead of them being flat for the benefit/ease of parsing in the shell script.

I hope transition to ucode brings additional contributors as, looking back at it, the original json schema and RPCD shell script were garbage code. :wink:

Both of these are no longer dual-firmware capable (haven’t ever been in a stable release, only shortly in master snapshots). The flash partitioning was rather unfortunate, leaving around ~19 MB free flash, despite their physical 256 MB NAND. Accordingly OpenWrt changed the partitioning to use rootfs0 for the kernel and rootfs1+until_the_end_of_the_flash for the rootfs+overlay.

So yes, these devices are made with a/ b booting in mind by the vendor - but no, once you install OpenWrt (any version, unless you dive deep into main history) there is only a single boot slot left (and toggling to the b-slot would brick the device). Reverting to the OEM firmware with a/ b slots is possible via tftp recovery, but no released version of OpenWrt will leave the b-slot bootable.

root@ax3600:~# ubus call system board
{
        "kernel": "6.12.41",
        "hostname": "ax3600",
        "system": "ARMv8 Processor rev 4",
        "model": "Xiaomi AX3600",
        "board_name": "xiaomi,ax3600",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "SNAPSHOT",
                "firmware_url": "https://downloads.openwrt.org/",
                "revision": "r30767-d0c64a162a",
                "target": "qualcommax/ipq807x",
                "description": "OpenWrt SNAPSHOT r30767-d0c64a162a",
                "builddate": "1755087815"
        }
}

root@ax3600:~# apk add luci-app-advanced-reboot
(1/1) Installing luci-app-advanced-reboot (1.1.0-r1)
luci-app-advanced-reboot-1.1.0-r1.post-install: Executing script...
OK: 58 MiB in 318 packages

Once OpenWrt (any version) is installed, there’s only compressed garbage (ubi+squashfs of the OpenWrt rootfs) left in the b-slot for ax3600/ ax9000, so luci-app-advanced-reboot can’t work on this hardware.

1 Like

Thanks for your prompt reply, I really wanted to tag you due to the volume and effect of your contributions to this package, so I’m glad you saw this even without tagging.

PS. That was running 1.1.0-r1 which still uses shell RPCD script with old json schema. The new version is 1.1.1: https://github.com/openwrt/luci/pull/7919

13 posts were split to a new topic: Luci-app-advanced-reboot v1.1.x: ZyXEL NBG6817 debugging

Please add Linksys MR9000

ubus call system board

{
        "kernel": "6.6.93",
        "hostname": "MR9000X",
        "system": "ARMv7 Processor rev 5 (v7l)",
        "model": "Linksys MR9000 (Dallas)",
        "board_name": "linksys,mr9000",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "24.10.2",
                "revision": "r28739-d9340319c6",
                "target": "ipq40xx/generic",
                "description": "OpenWrt 24.10.2 r28739-d9340319c6",
                "builddate": "1750711236"
        }
}

cat /tmp/sysinfo/board_name

linksys,mr9000

cat /proc/mtd

dev:    size   erasesize  name
mtd0: 00100000 00020000 "sbl1"
mtd1: 00100000 00020000 "mibib"
mtd2: 00100000 00020000 "qsee"
mtd3: 00080000 00020000 "cdt"
mtd4: 00080000 00020000 "appsblenv"
mtd5: 00080000 00020000 "ART"
mtd6: 00200000 00020000 "appsbl"
mtd7: 00080000 00020000 "u_env"
mtd8: 00040000 00020000 "s_env"
mtd9: 00040000 00020000 "devinfo"
mtd10: 05800000 00020000 "kernel"
mtd11: 05300000 00020000 "rootfs"
mtd12: 05800000 00020000 "alt_kernel"
mtd13: 05300000 00020000 "alt_rootfs"
mtd14: 00100000 00020000 "sysdiag"
mtd15: 04680000 00020000 "syscfg"

fw_printenv

altkern=5f80000
auto_recovery=yes
baudrate=115200
boot_ver=1.4.0
bootargs=init=/sbin/init rootfstype=ubifs ubi.mtd=11,2048 root=ubi0:ubifs rootwait rw
bootdelay=2
bootpart1=set bootargs $partbootargs && nand read $loadaddr $prikern $kernsize && bootm $loadaddr
bootpart2=set bootargs $partbootargs2 && nand read $loadaddr $altkern $kernsize && bootm $loadaddr
ethact=eth0
ethaddr=00:03:7f:ba:db:ad
fdt_high=0x87000000
fileaddr=84000000
filesize=A80800
flash_type=2
flashimg=tftp $loadaddr $image && nand erase $prikern $imgsize && nand write $loadaddr $prikern $filesize
flashimg2=tftp $loadaddr $image && nand erase $altkern $imgsize && nand write $loadaddr $altkern $filesize
fsbootargs=ubi.mtd=rootfs root=mtd:ubi_rootfs rootfstype=squashfs
image=lion.img
imgsize=8000000
ipaddr=192.168.1.1
kernsize=500000
loadaddr=84000000
machid=8010006
mtddevname=fs
mtddevnum=0
mtdids=nand0=nand0
mtdparts=mtdparts=nand0:0x5500000@0xa80000(fs),
netmask=255.255.255.0
partbootargs=init=/sbin/init rootfstype=ubifs ubi.mtd=11,2048 root=ubi0:ubifs rootwait rw
partbootargs2=init=/sbin/init rootfstype=ubifs ubi.mtd=13,2048 root=ubi0:ubifs rootwait rw
partition=nand0,0
prikern=780000
serverip=192.168.1.254
stderr=serial
stdin=serial
stdout=serial
usbimage=mr9000-initramfs-zImage.itb
bootusb=usb start && load usb 0:1 $loadaddr $usbimage && bootm $loadaddr
bootcmd=run bootusb; if test $auto_recovery = no; then bootipq; elif test $boot_part = 1; then run bootpart1; else run bootpart2; fi
boot_part_ready=3
boot_part=2

Please link the ToH page and/or git commit adding support for this device in OpenWrt.

Created the dumps, with 1024 and 2048. Nothing. I also checked the other mtd's - nothing, just garbage.
sorry....

It can still be supported, it just won’t display anything meaningful on what’s on alternative partition.

Well, something is working ... using the commands in CLI I shared earlier works fine in terms of switching the boot device for next reboot and with that be able to go to manufacturer firmware on second boot partition and from there back again to OpenWRT.
Appreciate your help and still looking forward to at least switch boot partition from luci :slight_smile:

Hi,

Maybe this device can be added: Zyxel NWA55AXE

Techdata: https://openwrt.org/toh/hwdata/zyxel/zyxel_nwa55axe

Device page: https://openwrt.org/toh/zyxel/nwa55axe

For flashing openwrt the info of the sister device is important: https://openwrt.org/toh/zyxel/nwa50ax

root@NWA55AXE_WDS:~# ubus call system board
{
        "kernel": "6.6.104",
        "hostname": "NWA55AXE_WDS",
        "system": "MediaTek MT7621 ver:1 eco:3",
        "model": "Zyxel NWA55AXE",
        "board_name": "zyxel,nwa55axe",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "24.10.3",
                "revision": "r28872-daca7c049b",
                "target": "ramips/mt7621",
                "description": "OpenWrt 24.10.3 r28872-daca7c049b",
                "builddate": "1758316778"
        }
}
root@NWA55AXE_WDS:~# cat /tmp/sysinfo/board_name
zyxel,nwa55axe
root@NWA55AXE_WDS:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00080000 00020000 "u-boot"
mtd1: 00080000 00020000 "u-boot-env"
mtd2: 00080000 00020000 "factory"
mtd3: 02800000 00020000 "firmware"
mtd4: 00800000 00020000 "kernel"
mtd5: 02000000 00020000 "ubi"
mtd6: 02800000 00020000 "zy_firmware_1"
mtd7: 01400000 00020000 "zy_rootfs_data"
mtd8: 00d00000 00020000 "zy_logs"
mtd9: 00480000 00020000 "myzyxel"
mtd10: 00080000 00020000 "bootconfig"
mtd11: 00080000 00020000 "mrd"
root@NWA55AXE_WDS:~# fw_printenv
Cannot parse config file '/etc/fw_env.config': No such file or directory
Failed to find NVMEM device

Most likely. The new JSON data structure allows for various commands to get/set status and zyxel-bootconfig can be used for that.

What’s the output of zyxel-bootconfig /dev/mtd10 get-status ?

@stangri

root@NWA55AXE_WDS:~# zyxel-bootconfig /dev/mtd10 get-status
Active Image: 0
Image 0 Status: valid
Image 1 Status: valid

somebody with the device on hand should be able to add the support to luci-app-advanced-reboot 1.1.1.