Adding OpenWrt support for Zyxel EX5601-T0

Hi community,

I have this router:

Dual-Band Wireless AX6000 2.5G Ethernet IAD/Gateway - EX5601/EX5600-T Series | Global | Zyxel

I'm able to compile and flash the firmware from zyxel source files but I'd like to have a clean Owrt build.

I've been building the openwrt image from the openwrt git repo but I'm not able to flash because I think it's expecting a different partition table.

Too the bootloader seems locked because even if i change the bootdelay envs I can't stop it to boot the zyxel loader (zloader ZHAL).

Bootloader log:

F0: 102B 0000

FA: 1040 0000

FA: 1040 0000 [0200]

F9: 0000 0000

V0: 0000 0000 [0001]

00: 0000 0000

BP: 2400 0041 [0000]

G0: 1190 0000

EC: 0000 0000 [1000]

T0: 0000 0228 [010F]

Jump to BL


NOTICE:  BL2: v2.6(release):1b03fb11
NOTICE:  BL2: Built : 10:18:01, Jul 21 2022
NOTICE:  WDT: disabled
NOTICE:  CPU: MT7986 (2000MHz)
NOTICE:  EMI: Using DDR4 settings
NOTICE:  EMI: Detected DRAM size: 1024MB
NOTICE:  EMI: complex R/W mem test passed
NOTICE:  SPI_NAND parses attributes from parameter page.
NOTICE:  SPI_NAND Detected ID 0x2c
NOTICE:  Page size 4096, Block size 262144, size 536870912
NOTICE:  Initializing NMBM ...
NOTICE:  Signature found at block 2047 [0x1ffc0000]
NOTICE:  First info table with writecount 0 found in block 1920
NOTICE:  Second info table with writecount 0 found in block 1923
NOTICE:  NMBM has been successfully attached in read-only mode
NOTICE:  BL2: Booting BL31
NOTICE:  BL31: v2.6(release):1b03fb11
NOTICE:  BL31: Built : 10:18:06, Jul 21 2022


U-Boot 2022.01-rc4 (Jul 21 2022 - 10:16:56 +0000)

CPU:   MediaTek MT7986
Model: ZYXEL EX5601-T0
DRAM:  1 GiB

Initializing NMBM ...
spi-nand: spi_nand spi_nand@1: Micron SPI NAND was found.
spi-nand: spi_nand spi_nand@1: 512 MiB, block size: 256 KiB, page size: 4096, OOB size: 256
Could not find a valid device for nmbm0
Signature found at block 2047 [0x1ffc0000]
First info table with writecount 0 found in block 1920
Second info table with writecount 0 found in block 1923
NMBM has been successfully attached 

MMC:   mmc@11230000: 0
Loading Environment from MTD... OK
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Net:   eth0: ethernet@15100000
Reading 262144 byte(s) at offset 0x00000000
## Booting kernel from Legacy Image at 46000000 ...
   Image Name:   zld-2.3 07/21/2022 10:17:53
   Image Type:   AArch64 U-Boot Standalone Program (gzip compressed)
   Data Size:    21708 Bytes = 21.2 KiB
   Load Address: 41e00200
   Entry Point:  41e003f4
   Verifying Checksum ... OK
   Uncompressing Standalone Program


ZYXEL zloader v2.3.9 (07/21/2022 - 10:17:53)
ubi0: attaching mtd7
ubi0: scanning is finished
ubi0: attached mtd7 (name "ubi", size 64 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 34/7, WL threshold: 4096, image sequence number: 1658393161
ubi0: available PEBs: 1, total reserved PEBs: 255, PEBs reserved for bad PEB handling: 38
Reading from volume 'zyfwinfo' to 0x7fb34760, size 0x100 ... OK
ubi0: detaching mtd7
ubi0: mtd7 is detached
zyfwinfo->seq_num   : 70
ubi0: attaching mtd8
ubi0: scanning is finished
ubi0: attached mtd8 (name "ubi2", size 64 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 38/30, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 0, total reserved PEBs: 256, PEBs reserved for bad PEB handling: 38
Reading from volume 'zyfwinfo' to 0x7fb360d0, size 0x100 ... OK
ubi0: detaching mtd8
ubi0: mtd8 is detached
zyfwinfo->seq_num   : 69
Current bootflag is 0
BOARD_DETECT_BY_GPIO=>result=0
ubi0: attaching mtd7
ubi0: scanning is finished
ubi0: attached mtd7 (name "ubi", size 64 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 34/7, WL threshold: 4096, image sequence number: 1658393161
ubi0: available PEBs: 1, total reserved PEBs: 255, PEBs reserved for bad PEB handling: 38
Reading from volume 'zyfwinfo' to 0x7fb47590, size 0x100 ... OK
ubi0: detaching mtd7
ubi0: mtd7 is detached
Multiboot clinent version: 2.7

Hit any key to stop autoboot:  5...4...3...2...1...0

I can't list this router on the ToH because registrations are closed but I think this is an easy addition given the already existing support for filogic830

I'd like to understand how much interest and efforts we can put into this. (maybe building a new unlocked u-boot bootloader from sources?)

[    1.594029] Creating 8 MTD partitions on "nmbm_spim_nand":
[    1.599500] 0x000000000000-0x000000100000 : "BL2"
[    1.604609] 0x000000100000-0x000000180000 : "u-boot-env"
[    1.610207] 0x000000180000-0x000000380000 : "Factory"
[    1.615530] 0x000000380000-0x000000540000 : "FIP"
[    1.620503] 0x000000540000-0x000000580000 : "zloader"
[    1.625838] 0x000000580000-0x000004580000 : "ubi"
[    1.630843] 0x000004580000-0x000008580000 : "ubi2"
[    1.635956] 0x000008580000-0x00001e000000 : "zyubi"

fw_printenv


root@EX5601-T0:/tmp/var/home/root# fw_printenv
EngDebugFlag=1
FeatureBit=0
FeatureBits=040A0005ffffffff0000000000000000ffffffffffffffffffffffffa2f7
ProductName=EX5601-T0
SerialNumber=
VendorName=ZYXEL Communication Corp
WpaPskKey=
admin=
baudrate=115200
countryCode=0
d2key=
ethact=ethernet@15100000
ethaddr=10:71:b3:75:64:10
fdtcontroladdr=7ffc5c80
initrd_end=0
initrd_start=0
ipaddr=192.168.1.1
loadaddr=0x46000000
mtdids=nmbm0=nmbm0
mtdparts=nmbm0:1024k(bl2),512k(u-boot-env),2048k(factory),1792k(fip),256k(zloader),65536k(ubi),65536k(ubi2),354816k(zyubi)
netmask=255.255.255.0
nummacaddrs=11
serverip=192.168.1.99
sn81=
stderr=serial@11002000
stdin=serial@11002000
stdout=serial@11002000
supervisor=
zld_date=07/21/2022
zld_time=10:17:53
zld_ver=2.3
bootdelay=10
root@EX5601-T0:/tmp/var/home/root#

root@EX5601-T0:/tmp/var/home/root# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 20000000 00040000 "spi0.1"
mtd1: 00100000 00040000 "BL2"
mtd2: 00080000 00040000 "u-boot-env"
mtd3: 00200000 00040000 "Factory"
mtd4: 001c0000 00040000 "FIP"
mtd5: 00040000 00040000 "zloader"
mtd6: 04000000 00040000 "ubi"
mtd7: 04000000 00040000 "ubi2"
mtd8: 15a80000 00040000 "zyubi"
root@EX5601-T0:/tmp/var/home/root# cat /proc/cmdline
console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000 rootubi=ubi

ZHAL:

ZHAL> ATHE
ATER    x,y       erase flash from offset x whith length y
ATRF    x,y,z     read data flash to ram(x=flash offset, y=len, z=ram address)
ATWF    x,y,z     write data from RAM to flash(x=flash offset, y=len, z=ram address)
ATDS    x,y       dump data of spare area in page y of block x
ATUR    [y:]x     upgrade RAS image (x=file name, y=host ip)
ATUB    [y:]x     upgrade ZLD image (x=file name, y=host ip)
ATUD    [y:]x     upgrade ROMD image (x=file name, y=host ip)
ATUM    [y:]x     upgrade ROMFILE image (x=file name, y=host ip)
ATCD              erase RomD partition
ATCM              erase ROMFILE partition
ATCR              erase data partition
ATCMISC           erase misc partition
ATCMP   x,y,z     compare two memory space x and y with length is z
ATDU    x,y       dump memory or registers(x=ram address, y=length)
ATWW    x,y,z     set memory or registers(x=address, y=value, z=len)
ATRT    [x,y,z,u] ATRT RAM read/write test (x=level, y=start addr, z=end addr, u=iterations
ATCB              copy from FLASH to working buffer
ATSB              save working buffer to FLASH
ATWM    x         set MAC address in working buffer
ATWZ    x,y,z,u,v set zyxel MAC address, Country code, EngDbgFlag, FeatureBit and MAC number to FLASH
ATSH              dump manufacturer related data in ROM
ATCO    x         set country code in working buffer
ATSN    x         set serial number to FLASH
ATCK    [x,y,z]   show, write or reset psk, admin and supervisor key
ATBT    x         block0 write enable (1=enable, 0=disable)
ATEN    x[,y]     set BootExtension Debug Flag (y=password)
ATSE    x         show the seed of password generator
ATDC              disable check model mechanism
ATSR    [x]       system reboot
ATGU              go back to U-Boot command line mode
ATGO              boot up whole system
ATLD    x,[y]     load file x to memory address y via TFTP
ATMB    [x,y]     upgrade firmware image by multiboot
ATSW              swap boot image to another partition (must reboot to make it take effect)
ATLED   [x,y]     set LED (x=led no, y=blink mode(0(off)|1(on)|2(fast)|3(slow))
ATPIO   x,y[,z]   set GPIO (x={s|w|r}, y=pio num, z=write data)
ATD2    [x]       show or write D2 key
ATHE              show command list
ZHAL>

Thank you

Interesting!

I just sent the first pull request for The ZyXEL EX5700, also filogic based: https://github.com/openwrt/openwrt/pull/12276

Unfortunately, the device I have does not run ZyXEL firmware or bootloader. But I still expect OpenWrt support for these to be very similar, with the exception of the bootloader hacks/workarounds.

The ZyXEL zloader applications running under U-Boot are usually controlled by some magic U-Boot environment vars in my experience. There's probably something like that controlling U-Boot access here too. But I see that you already have

EngDebugFlag=1

which definitely would be a candidate, so I guess that didn't work? Maybe poke around in the OEM /etc/init.d scripts. They often leave some clues there, testing for specific variables/settings etc.

EDIT: BTW, did you try

ATGU

in the zloader shell? That's usually a way back to the U-Boot shell, but it could be restricted too of course

I did put EngDebugFlag=1 to unlock ZHAL, hence the ZHAL command list I showed in my first post. Without that when pressing enter at boot it will ask you a password.

So EngDebugFlag=1 in my case ulocked ZHAL without password.
I tried ATGU without any parameters but it's falling back to ZHAL... I guess it's locked
The thing is that in my fw_printenv I have loadaddr=0x46000000 which is Zloader MTD.

Anyways I've been dumping all the MTDs and with ghidra I managed to see that inside MTD4 (FIP) there is the MT7986> prompt and it's talking about secure boot.

Still trying to figure out how to reach that.

How about if you try to press 4 immediately after AGTU+enter?

This is how it looks on the MT7621 based ZyXEL NR7101:

ZLB> atgu


=>## Application terminated, rc = 0x0

Skip image checking!

Please choose the operation: 
   1: Load system code to SDRAM via TFTP. 
   2: Load system code then write to Flash via TFTP. 
   3: Boot system code via Flash (default).
   4: Entr boot command line interface.
   7: Load Boot Loader code then write to Flash via Serial. 
   9: Load Boot Loader code then write to Flash via TFTP. 
default: 3

I've also see the same menu hidden, but still responding to the choices. But usually with almost no delay, which could be a problem on the really fast MT7986.

FWIW, this is how the boot-loader looks on my EX5700. Obviously based on the same mediatek code, but without any of the ZyXEL specific zloader parts:

F0: 102B 0000
FA: 1040 0000
FA: 1040 0000 [0200]
F9: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 2400 0041 [0000]
G0: 1190 0000
EC: 0000 0000 [1000]
T0: 0000 0221 [010F]
Jump to BL

NOTICE:  BL2: v2.6(release):v2.6-234-ge6fff8ecc
NOTICE:  BL2: Built : 15:01:34, Aug  4 2022
NOTICE:  WDT: disabled
NOTICE:  CPU: MT7986 (2000MHz)
NOTICE:  EMI: Using DDR4 settings
NOTICE:  EMI: Detected DRAM size: 1024MB
NOTICE:  EMI: complex R/W mem test passed
NOTICE:  SPI_NAND parses attributes from parameter page.
NOTICE:  SPI_NAND Detected ID 0x75
NOTICE:  Page size 4096, Block size 262144, size 536870912
NOTICE:  Initializing NMBM ...
NOTICE:  Signature found at block 2047 [0x1ffc0000]
NOTICE:  First info table with writecount 1 found in block 1920
NOTICE:  Second info table with writecount 1 found in block 1923
NOTICE:  NMBM has been successfully attached in read-only mode
NOTICE:  BL2: Booting BL31
NOTICE:  BL31: v2.6(release):v2.6-234-ge6fff8ecc
NOTICE:  BL31: Built : 15:23:24, Aug  4 2022


U-Boot 2022.04 (Aug 04 2022 - 13:34:01 +0000)

CPU:   MediaTek MT7986
Model: ex5700-t0
DRAM:  1023.9 MiB
Core:  34 devices, 14 uclasses, devicetree: separate

Initializing NMBM ...
Could not find a valid device for nmbm0
Signature found at block 2047 [0x1ffc0000]
First info table with writecount 1 found in block 1920
Second info table with writecount 1 found in block 1923
NMBM has been successfully attached 

Loading Environment from NVRAM... OK
In:    serial@11002000
Out:   serial@11002000
Err:   serial@11002000
Model: ex5700-t0
tpl_env not found in U-Boot DTB [-1]
tpl-version not found in U-Boot DTB [-1]
mtd: partition "ubi" extends beyond the end of device "nmbm0" -- size truncated to 0x1da80000
ubi0: attaching mtd6
ubi0: scanning is finished
ubi0: attached mtd6 (name "ubi", size 474 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 1898, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 12, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 22/13, WL threshold: 4096, image sequence number: 1659616596
ubi0: available PEBs: 2, total reserved PEBs: 1896, PEBs reserved for bad PEB handling: 38
Read 40 bytes from volume factoryparams to 0000000077bfddb8
Read 5124 bytes from volume factoryparams to 0000000077f72810
Saving Environment to NVRAM... OK
Net:   eth0: ethernet@15100000
Hit any key to stop autoboot:  0 
=> env print
arch=arm
baudrate=115200
board=mt7986
board_name=mt7986
bootcmd=secure_boot
bootcount=1
bootdelay=2
bootlimit=3
cpu=armv8
ethaddr=f0:87:56:cc:52:30
fdtcontroladdr=77bfde80
filesize=1404
ipaddr=192.168.1.1
loadaddr=0x41e00000
mtdids=nmbm0=nmbm0
mtdparts=nmbm0:1024k(bl2),512k(u-boot-env),2048k(factory),2048k(fip),491520k(ubi)
netmask=255.255.255.0
serverip=192.168.1.2
soc=mediatek
stderr=serial@11002000
stdin=serial@11002000
stdout=serial@11002000
uboot_bootcount=0
vendor=mediatek

Environment size: 485/16380 bytes
=> mtd list
List of MTD devices:
* spi-nand0
  - device: spi_nand@1
  - parent: spi@1100a000
  - driver: spi_nand
  - path: /spi@1100a000/spi_nand@1
  - type: NAND flash
  - block size: 0x40000 bytes
  - min I/O: 0x1000 bytes
  - OOB size: 256 bytes
  - OOB available: 126 bytes
  - 0x000000000000-0x000020000000 : "spi-nand0"
* nmbm0
  - type: Unknown
  - block size: 0x40000 bytes
  - min I/O: 0x1000 bytes
  - OOB size: 256 bytes
  - OOB available: 126 bytes
  - 0x000000000000-0x00001e000000 : "nmbm0"
          - 0x000000000000-0x000000100000 : "bl2"
          - 0x000000100000-0x000000180000 : "u-boot-env"
          - 0x000000180000-0x000000380000 : "factory"
          - 0x000000380000-0x000000580000 : "fip"
          - 0x000000580000-0x00001e000000 : "ubi"

You'll notice that they've kept the 3 first parts from ZyXEL, but replaced the FIP+zloader with their own FIP, and merged all the ubi parts to one single one. Which makes a lot more sense than splitting it up like ZyXEL does, IMHO.

I assume ZyXEL does that because the have a dual boot shceme selecting between ubi and ubi2, probably re-using the same volume names for kernel and rootfs.

Flashing is most likely as easy as writing the OpenWrt kernel and rootfs to UBI volumes with the names expected by the boot-loader. But you obvously shouldn't try that without figuring out the bootloader access first. Bricking is too likely otherwise.

1 Like

It works!!!! It seems like that after ATGU you have very very very short time to react.

So what I did was to write ATGU and keep ENTER pressed. It enters than MT7986>

Great!

Nice! Then you should be able to boot an initramfs image from memory, and experiment without any risk at all

1 Like

I managed to boot via tftp an initramfs image. Everything seems good now the problem still is the bootloader which is not allowing me to boot directly these images from flash. The zloader has a check on the firmware zyfwid when loading it and it's not going to work.

I think something like the xiaomi ax6000 is needed to replace the stock u-boot with custom one and possibly a procedure to go back to stock.

stock layout https://github.com/openwrt/openwrt/pull/11115
u-boot mod layout https://github.com/openwrt/openwrt/pull/11565

If not there should be a way to skip zloader at all.

What is this? How is it checked? Can we somehow pass that check, or is this a crypto signature?

Replacing the bootloader is of course possible, but I believe that should be the absolute last resort. It's impossible to eliminate all risk. And it's too advanced for most end users.

I believe that is something completely different, where the vendor has tried to lock down the device and the only way in is through one of the numerous bugs in the vendor firmware. So you have to replace the bootloader.

ZyXEL devices normally aren't that stupid. And you have full admin access to the vendor firmware? So installing OpenWrt directly from vendor firmware is an option, if we only can figure out what format and wrapping the bootloader wants. We've done that many times before.

Ok so the way that the firmware upgrade works with the zyxel firmware (branded or not branded) I've a ubi0 with brabded isp firmware (root access too) and no-brand firmware built from me from zyxel sources (root access too here).

So the way I do flash the firmware is the following:

I enter as admin (root is the same) and i type : zycli zyfwidcheck off and zycli modelcheck off.
thank i jump back to the web interface and i load the firmware from the web interface.

If i load a firmware that I build from zyxel sources everything is good because the checks are good.

If I load a firmware that I built from sources (the one that works from tftp boot) here is the serial log.

same when entering ZHAL you read these lines:

ZYXEL zloader v2.3.9 (07/21/2022 - 10:17:53)
ubi0: attaching mtd7
ubi0: scanning is finished
ubi0: attached mtd7 (name "ubi", size 64 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 37/8, WL threshold: 4096, image sequence number: 1658393161
ubi0: available PEBs: 1, total reserved PEBs: 255, PEBs reserved for bad PEB handling: 38
Reading from volume 'zyfwinfo' to 0x7fb48850, size 0x100 ... OK
ubi0: detaching mtd7
ubi0: mtd7 is detached
zyfwinfo->seq_num   : 70
ubi0: attaching mtd8
ubi0: scanning is finished
ubi0: attached mtd8 (name "ubi2", size 64 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 39/31, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 0, total reserved PEBs: 256, PEBs reserved for bad PEB handling: 38
Reading from volume 'zyfwinfo' to 0x7fb498d0, size 0x100 ... OK
ubi0: detaching mtd8
ubi0: mtd8 is detached
zyfwinfo->seq_num   : 71
Current bootflag is 1
BOARD_DETECT_BY_GPIO=>result=0
ubi0: attaching mtd8
ubi0: scanning is finished
ubi0: attached mtd8 (name "ubi2", size 64 MiB)
ubi0: PEB size: 262144 bytes (256 KiB), LEB size: 253952 bytes
ubi0: min./max. I/O unit sizes: 4096/4096, sub-page size 4096
ubi0: VID header offset: 4096 (aligned 4096), data offset: 8192
ubi0: good PEBs: 256, bad PEBs: 0, corrupted PEBs: 0
ubi0: user volume: 5, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 39/31, WL threshold: 4096, image sequence number: 0
ubi0: available PEBs: 0, total reserved PEBs: 256, PEBs reserved for bad PEB handling: 38
Reading from volume 'zyfwinfo' to 0x7fb4a950, size 0x100 ... OK
ubi0: detaching mtd8
ubi0: mtd8 is detached
Multiboot clinent version: 2.7

Especially this : Reading from volume 'zyfwinfo' to 0x7fb48850, size 0x100 ... OK

Wouldn't it be possible to bypass zloader, and boot OpenWrt directly from uboot ?

Or does it start before uboot ?

1 Like

How. :smiley: any hints? I've the dumps of everything done with dd

It starts after uboot... I guess the loadaddres in fw_printenv is pointing to zloader

Too like I said at the beginning of the boot process I can't stop it to reach zloader no matter what button i press.

So we have this route:

BL2, BL2 loads BL31 which is uboot which than loads zloader
Image Name: zld-2.3 07/21/2022 10:17:53
Image Type: AArch64 U-Boot Standalone Program (gzip compressed)
Data Size: 21708 Bytes = 21.2 KiB
Load Address: 41e00200
Entry Point: 41e003f4
Verifying Checksum ... OK
Uncompressing Standalone Program

That looks like the zyfwinfo might just be some metadata? Don't you have some examples of this file from the different images you have? Did you try to untar them?

And the error you got was primarily because the file was missing, not because it was wrong. How about just including a dummy one from one of the working images and see what happens?

Since you are building from ZyXEL sources, I guess you have all the tools to create working images. I assume those tools are in binary form only, but I believe it should be easy to re-implement enough of it unless key material is required. And I am pretty sure it isn't, since that would mean that you got it as part of the ZyXEL GPL dump (even if binary only). They are not stupid.

Any chance you can share the GPL sources, and possibly the valid images you have?

I did and there is a file indeed

zydefault is a tar containing default jsons for the startup of the router
zyfwinfo contains i guess metadata regarding the version of the firmware:

Let's say that I repack the owrt by adding that file and it works... what about with the overlay partition?

with zyxel firmware you have ubi1 and ubi2 (the slots for flashing the firmware 64 megs each) and zyubi (340megs about) as overlay.

I don't think that the firmware built from owrt sources have that kind of logic built-into.

The metadata looks similar to what they often have put into the uimage header, for that sort of images. Probably including file sizes and checksums. So you might have to figure that out and create the proper checksums.

Well, you could make the OpenWrt boot follow that scheme. Probably best for full compatibility with stock firmware.

Or change the layout for OpenWrt. Or something else.

I assume the bootloader will be happy as long as it finds the expected kernel and rootfs volumes in ubi1 or ubi2. But the stock firmware probably won't be very happy if you try to change any of these.

That's why I was looking at the Xiaomi procedure to put a clean U-Boot. With possibility to revert to stock.

At this stage it's too risky imho to try even changing the load address... That could create a bootloop without any way to go back into zloader hence U-Boot.

Ok so given that I've the zyxel sources I'm able to reproduce the partition structure that zloader needs.

What I'm trying to do is importing the DTS files from the Zyxel sources into openwrt sources.
I'm making them available at the following git repo:
pameruoso/OpenWRT-Zyxel-EX5601-T0: Porting openwrt to Zyxel-EX5601-T0 (github.com)

Now the problem is that during compilation i keep getting this error:

Error: ../dts/mt7986a-ex5601-t0-zyxel-router-ax6000.dtsi:237.23-24 syntax error                    │mt7622-ubnt-unifi-6-lr-v2.dts           mt7986a-xiaomi-redmi-router-ax6000-stock.dts
FATAL ERROR: Unable to parse input tree

Never had this kind of error so I don't really know what to look for.

I just copied the files and I can confirm that the very same files from Zyxel sources don't give me any error.

##Edit
Nevermind, solved. I had to edit dt-include.

Now I'm reversing the zyfwinfo build scripts and It should be done.

I managed to get a working initramfs with the right zyfwinfo additional files and paritions.

I can't get past this bootlog. Any hint on possible troubleshooting steps?

## Loading kernel from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'kernel-1' kernel subimage
     Description:  ARM64 OpenWrt Linux-5.15.104
     Type:         Kernel Image
     Compression:  lzma compressed
     Data Start:   0x460000ec
     Data Size:    3905036 Bytes = 3.7 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x48000000
     Entry Point:  0x48000000
     Hash algo:    crc32
     Hash value:   38a00b49
     Hash algo:    sha1
     Hash value:   9f91e242366533345f3fb15f85f2a2f6fa642b5b
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading ramdisk from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'initrd-1' ramdisk subimage
     Description:  ARM64 OpenWrt ex5601-t0-nozyfwid initrd
     Type:         RAMDisk Image
     Compression:  Unknown Compression
     Data Start:   0x463b9834
     Data Size:    19235156 Bytes = 18.3 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    crc32
     Hash value:   11dff6ac
     Hash algo:    sha1
     Hash value:   7088fcbf301a9b66d27935f4c4cd047d01addc50
   Verifying Hash Integrity ... crc32+ sha1+ OK
WARNING: 'compression' nodes for ramdisks are deprecated, please fix your .its file!
## Loading fdt from FIT Image at 46000000 ...
   Using 'config-1' configuration
   Trying 'fdt-1' fdt subimage
     Description:  ARM64 OpenWrt ex5601-t0-nozyfwid device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x47611a98
     Data Size:    32768 Bytes = 32 KiB
     Architecture: AArch64
     Hash algo:    crc32
     Hash value:   1b56e22e
     Hash algo:    sha1
     Hash value:   606138c11c33c91683fd354771b91c037f4b692b
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x47611a98
   Uncompressing Kernel Image
   Loading Ramdisk to 7e5a1000, end 7f7f9154 ... OK
   Loading Device Tree to 000000007e596000, end 000000007e5a0fff ... OK

Starting kernel ...

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.15.104  (aarch64-openwrt-linux-musl-gcc (OpenWrt GCC 12.2.0 r22419-42a5917786) 12.2.0, GNU ld (GNU Binutils) 2.40.0) #0 SMP Mon Mar 27 16:15:13 2023
[    0.000000] Machine model: ZYXEL EX5601-T0
[    0.000000] earlycon: uart8250 at MMIO32 0x0000000011002000 (options '')
[    0.000000] printk: bootconsole [uart8250] enabled
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000040000000-0x000000007fffffff]
[    0.000000]   DMA32    empty
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000040000000-0x0000000042ffffff]
[    0.000000]   node   0: [mem 0x0000000043000000-0x000000004302ffff]
[    0.000000]   node   0: [mem 0x0000000043030000-0x000000004fbfffff]
[    0.000000]   node   0: [mem 0x000000004fc00000-0x000000004ffbffff]
[    0.000000]   node   0: [mem 0x000000004ffc0000-0x000000007fffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000007fffffff]
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv1.1 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: MIGRATE_INFO_TYPE not supported.
[    0.000000] psci: SMC Calling Convention v1.2
[    0.000000] percpu: Embedded 17 pages/cpu s29656 r8192 d31784 u69632
[    0.000000] pcpu-alloc: s29656 r8192 d31784 u69632 alloc=17*4096
[    0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: detected: GIC system register CPU interface
[    0.000000] CPU features: kernel page table isolation disabled by kernel configuration
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 258048
[    0.000000] Kernel command line: console=ttyS0,115200n1 loglevel=8 earlycon=uart8250,mmio32,0x11002000
[    0.000000] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.000000] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Memory: 993248K/1048576K available (8256K kernel code, 888K rwdata, 2152K rodata, 384K init, 292K bss, 55328K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] 	Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 10 jiffies.
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[    0.000000] GICv3: 640 SPIs implemented
[    0.000000] GICv3: 0 Extended SPIs implemented
[    0.000000] GICv3: Distributor has no Range Selector support
[    0.000000] Root IRQ handler: gic_handle_irq
[    0.000000] GICv3: 16 PPIs implemented
[    0.000000] GICv3: CPU0: found redistributor 0 region 0:0x000000000c080000
[    0.000000] arch_timer: cp15 timer(s) running at 13.00MHz (phys).
[    0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x2ff89eacb, max_idle_ns: 440795202429 ns
[    0.000001] sched_clock: 56 bits at 13MHz, resolution 76ns, wraps every 4398046511101ns
[    0.008191] Calibrating delay loop (skipped), value calculated using timer frequency.. 26.00 BogoMIPS (lpj=130000)
[    0.018596] pid_max: default: 32768 minimum: 301
[    0.023312] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.030750] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.039512] rcu: Hierarchical SRCU implementation.
[    0.044425] dyndbg: Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build
[    0.052328] smp: Bringing up secondary CPUs ...
[    0.057127] Detected VIPT I-cache on CPU1
[    0.057151] GICv3: CPU1: found redistributor 1 region 0:0x000000000c0a0000
[    0.057176] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[    0.057434] Detected VIPT I-cache on CPU2
[    0.057446] GICv3: CPU2: found redistributor 2 region 0:0x000000000c0c0000
[    0.057456] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
[    0.057681] Detected VIPT I-cache on CPU3
[    0.057690] GICv3: CPU3: found redistributor 3 region 0:0x000000000c0e0000
[    0.057699] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
[    0.057728] smp: Brought up 1 node, 4 CPUs
[    0.114268] SMP: Total of 4 processors activated.
[    0.118989] CPU features: detected: 32-bit EL0 Support
[    0.124144] CPU features: detected: CRC32 instructions
[    0.129375] CPU: All CPU(s) started at EL2
[    0.133491] alternatives: patching kernel code
[    0.140239] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.150138] futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
[    0.157152] pinctrl core: initialized pinctrl subsystem
[    0.162847] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.168999] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
[    0.176100] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
[    0.183892] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[    0.192067] thermal_sys: Registered thermal governor 'fair_share'
[    0.192070] thermal_sys: Registered thermal governor 'bang_bang'
[    0.198188] thermal_sys: Registered thermal governor 'step_wise'
[    0.204224] thermal_sys: Registered thermal governor 'user_space'
[    0.210351] ASID allocator initialised with 65536 entries
[    0.233389] cryptd: max_cpu_qlen set to 1000
[    0.239064] SCSI subsystem initialized
[    0.242895] libata version 3.00 loaded.
[    0.247499] clocksource: Switched to clocksource arch_sys_counter
[    0.253995] NET: Registered PF_INET protocol family
[    0.258977] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.266820] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
[    0.275227] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    0.283010] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.290830] TCP bind hash table entries: 8192 (order: 5, 131072 bytes, linear)
[    0.298164] TCP: Hash tables configured (established 8192 bind 8192)
[    0.304609] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
[    0.311268] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
[    0.318436] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.324131] PCI: CLS 0 bytes, default 64
[    0.328196] Unpacking initramfs...
[    0.339444] workingset: timestamp_bits=46 max_order=18 bucket_order=0
[    0.347948] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.353817] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.389205] Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled
[    0.396481] mtk_rng 1020f000.trng: no clock for device: -517
[    0.402342] cacheinfo: Unable to detect cache hierarchy for CPU 0
[    0.410268] loop: module loaded
[    0.414998] of_clk_src_onecell_get: invalid clock index 75
[    0.420552] clk: couldn't get assigned clock 0 for /ethernet@15100000
[    0.427044] mtk_soc_eth: probe of 15100000.ethernet failed with error -22
[    0.434102] i2c_dev: i2c /dev entries driver
[    0.438916] mtk-wdt 1001c000.watchdog: Watchdog enabled (timeout=31 sec, nowayout=0)
[    0.447343] NET: Registered PF_INET6 protocol family
[    0.452932] Segment Routing with IPv6
[    0.456631] In-situ OAM (IOAM) with IPv6
[    0.460653] NET: Registered PF_PACKET protocol family
[    0.465794] bridge: filtering via arp/ip/ip6tables is no longer available by default. Update your scripts to load br_netfilter if you need this.
[    0.478980] 8021q: 802.1Q VLAN Support v1.8
[    0.488512] mtk_rng 1020f000.trng: no clock for device: -517
[    0.494475] mt6577-uart 11003000.serial: deferred probe timeout, ignoring dependency
[    0.502379] mt6577-uart 11004000.serial: deferred probe timeout, ignoring dependency
[    0.510301] mtk_rng 1020f000.trng: no clock for device: -517
[    0.516136] i2c-mt65xx 11008000.i2c: deferred probe timeout, ignoring dependency

This doesn't look good. Can't remember having any such issues, neither on OpenWrt nor mainline. All the basic stuff just works with the default mt7986a.dtsi

You started out with the vendor device tree, did you? I believe that's going to be just so screwed up as you can expect from any vendor/chipset source.... It's usable as a rough guide for LEDs, buttons and other board specifics. But that's all. The rest is chaos.

I suggest starting with one of the working devices trees in OpenWrt instead, and then modify only the parts that are different for your board. Maybe just remove everything you don't need at first, to make things simpler. It's easier to add stuff back after you have a base that boots, than to fixup a complete but broken device tree.

I suspect the end result will be pretty much the same as this, except for the partition layout and the redundant bootargs:

While i was keen to do that and just fix the partition layout i than discovered that the 2.5 ports are not working at all. The ex5601 has 3 lan gbit ports, 1lan 2.5gbit baseT, 1 combo SFP/baseT 2.5 port(xor). Well the only working ports are the 3 gigabit ones and the wifi...

After this I don't know what path would be less painful :frowning:

The EX5700 has two 2.5G ports as well, but no SFP slot. My guess is that the PHYs and MDIO addresses are the same on both. Try it and see. If you have the same PHYs then you will need the excessive mdio reset delay at least, or the PHYs won't work by the time they are probed.

@daniel recently fixed the remaining issues with multigig in the mt7530 and mtk_eth_soc drivers. Both Maxlinear GPY211Cs on my EX5700 are now working perfectly in 2500/1000/100/10. One of them is connected to the SoC and the other to port 5 of the switch, as shown by the DTS.

Do you have the same PHYs? If so, the datasheet is public:

How is the SFP slot multiplexed? Is it connected to the SoC or switch? Or chained off one of the PHYs (don't think that's possible with the GPY211, but in case you have something different)?