Adding OpenWrt support for Zyxel XMG1930-30HP

Today a colleague of mine got a Zyxel XMG1930-30HP multi-gigabit 700W PoE switch and I’m trying to get OpenWrt running on it.

Ports:

  • 20x RJ-45 (100/​1000/​2.5GBase-T) with PoE+ (30W each)
  • 4x RJ-45 (100/​1000/​2.5GBase-T) with PoE++ (60W each)
  • 4x RJ-45 (1000/​2.5G/​5G/​10GBase-T) with PoE++ (60W each)
  • 2x SFP+ (1G/​10Gb/​s)
  • USB-C console port, directly accessible from the front panel, behind that port is a CP2102N USB-UART bridge, 115200 Baud, unsure if isolated or not (I used a laptop on battery power with no cables connected except the USB cable to the switch)

Bootloader is Bootbase+BootExt, operating system ZynOS.

The ATEN password sequence differs betwen Bootbase and BootExt:

  • Bootbase wants ATEN 1 password with a space between ATEN and 1 and another space beteen between 1 and the calculated password. Thanks to @jonasj for the hint with space instead of comma.
  • BootExt wants ATEN 1,password with a space between ATEN and 1 and a comma between 1 and the calculated password.
  • The password sequence for both bootloader parts is calculated with the usual formula which is identical for both parts. Please note that the password needs to be recalculated if the seed has changed.

Kernel log on client when connecting to the switch via plain USB-C cable:

usb 1-1: new full-speed USB device number 49 using xhci_hcd
usb 1-1: New USB device found, idVendor=10c4, idProduct=ea60, bcdDevice= 1.00
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Product: CP2102N USB to UART Bridge Controller
usb 1-1: Manufacturer: Silicon Labs
usb 1-1: SerialNumber: <redacted>
usbcore: registered new interface driver cp210x
usbserial: USB Serial support registered for cp210x
cp210x 1-1:1.0: cp210x converter detected
usb 1-1: cp210x converter now attached to ttyUSB0

Vanilla boot log:

Bootbase Version: V1.00 | 02/10/2022 09:42:14
RAM: Size = 262144 Kbytes
DRAM POST: Testing: 
262144K
DRAM Test SUCCESS !
FLASH: 32M
ZyNOS Version: V4.80(ACAS.4) | 08/23/2024 10:16:42
Press any key to enter debug mode within 1 second.
....................
Copyright (c) 2024 Zyxel and/or its affiliates. All Rights Reserved.
initialize switch, ethernet address: 70:49:a2:<redacted>
Initializing MSTP.............
Initializing VLAN Database...
Initializing IP Interface...
Initializing Advanced Applications...
Initializing Command Line Interface...
Initializing Web Interface...
Restore System Configuration...
Default IP Setting.................................
Press ENTER to continue...
                   Enter User Name : 
                   Enter Password : 
Password is not correct

Spamming `$` during DRAM init:

Bootbase Version: V1.00 | 02/10/2022 09:42:14
RAM: Size = 262144 Kbytes
DRAM POST: Testing:  262144K
OK
DRAM Test SUCCESS !

XS1930$ flshow
Unknown command 'flshow' - try 'help'
XS1930$ help
?         - alias for 'help'
aten      - set BootExtension debug flag
atse      - show the seed of password generator
gobootext - go to boot extension
help      - print command description/usage
reset     - Perform RESET of the CPU
upgrade   - Upgrade loader or ras image
upgradeK  - Upgrade loader or ras image over serial line (kermit mode)
upgradeY  - Upgrade loader or ras image over serial line (ymodem mode)
XS1930$ atse

5A26A2<redacted>
OK
XS1930$ aten 1 440895a3

OK
XS1930$ ?
?         - alias for 'help'
atbt      - block0 write enable (1=enable, other=disable)
atcb      - copy from FLASH ROM to working buffer
aten      - set BootExtension debug flag
atfl      - set EngDebugFlag in working buffer
atsb      - save working buffer to FLASH ROM
atse      - show the seed of password generator
base      - print or set address offset
bootm     - boot application image from memory
bootp     - boot image via network using BOOTP/TFTP protocol
cmp       - memory compare
cp        - memory copy
crc32     - checksum calculation
env       - environment handling commands
erase     - erase FLASH memory
flerase   - Erase flash partition
flinfo    - print FLASH memory information
flshow    - Show flash partition layout
go        - start application at address 'addr'
gobootext - go to boot extension
help      - print command description/usage
iminfo    - print header information for application image
loadb     - load binary file over serial line (kermit mode)
loads     - load S-Record file over serial line
loady     - load binary file over serial line (ymodem mode)
loop      - infinite loop on address range
md        - memory display
mm        - memory modify (auto-incrementing address)
mtest     - simple RAM read/write test
mw        - memory write (fill)
nm        - memory modify (constant address)
ping      - send ICMP ECHO_REQUEST to network host
printenv  - print environment variables
protect   - enable or disable FLASH write protection
reset     - Perform RESET of the CPU
reset_all - Perform whole chip RESET of the CPU
rtk       - rtk     - Realtek commands
run       - run commands in an environment variable
saveenv   - save environment variables to persistent storage
setenv    - set environment variables
sf        - SPI flash sub-system
sleep     - delay execution for some time
tftpboot  - boot image via network using TFTP protocol
upgrade   - Upgrade loader or ras image
upgradeK  - Upgrade loader or ras image over serial line (kermit mode)
upgradeY  - Upgrade loader or ras image over serial line (ymodem mode)
version   - print monitor, compiler and linker version
XS1930$ version

U-Boot 2011.12.(3.6.0.48) (Feb 10 2022 - 09:42:14)
mips-elf-xgcc (Realtek MSDK-4.4.7 Build 2458) 4.4.7
GNU ld (Realtek MSDK-4.4.7 Build 2458) 2.23.2
XS1930$ flinfo
XS1930$

Pressing space bar during the 1-second wait to press any key:

Bootbase Version: V1.00 | 02/10/2022 09:42:14
RAM: Size = 262144 Kbytes
DRAM POST: Testing:  262144K
OK
DRAM Test SUCCESS !
FLASH: 32M

ZyNOS Version: V4.80(ACAS.4) | 08/23/2024 10:16:42

Press any key to enter debug mode within 1 second.
............
Enter Debug Mode

XMG1930-30HP> athe
======= Debug Command Listing =======
AT            just answer OK
ATHE          print help
ATBAx         change baudrate. 1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y)     set BootExtension Debug Flag (y=password)
ATSE          show the seed of password generator
ATTI(h,m,s)   change system time to hour:min:sec or show current time
ATDA(y,m,d)   change system date to year/month/day or show current date
ATDS          dump RAS stack
ATDT          dump Boot Module Common Area
ATDUx,y       dump memory contents from address x for length y
ATRBx         display the  8-bit value of address x
ATRWx         display the 16-bit value of address x
ATRLx         display the 32-bit value of address x
ATGO(x)       run program at addr x or boot router
ATGR          boot router
ATGT          run Hardware Test Program
ATRTw,x,y(,z) RAM test level w, from address x to y (z iterations)
ATSH          dump manufacturer related data in ROM
ATDOx,y       download from address x for length y to PC via XMODEM
ATTD          download router configuration to PC via XMODEM
ATUR          upload router firmware to flash ROM

< press any key to continue >
ATLC          upload router configuration file to flash ROM
ATXSx         xmodem select: x=0: CRC mode(default); x=1: checksum mode
ATSR          system reboot
ATFT(x,y,z)     offset, pattern, len
ATPA(x)       Pause for x ms
ATCP       show CPU
ATGI         select boot image

OK

XMG1930-30HP> atse
95B2D8<redacted>
OK
XMG1930-30HP> aten 1,c4f424d6
OK

XMG1930-30HP> athe
======= Debug Command Listing =======
AT            just answer OK
ATHE          print help
ATBAx         change baudrate. 1:38.4k, 2:19.2k, 3:9.6k 4:57.6k 5:115.2k
ATENx,(y)     set BootExtension Debug Flag (y=password)
ATSE          show the seed of password generator
ATTI(h,m,s)   change system time to hour:min:sec or show current time
ATDA(y,m,d)   change system date to year/month/day or show current date
ATDS          dump RAS stack
ATDT          dump Boot Module Common Area
ATDUx,y       dump memory contents from address x for length y
ATWBx,y       write address x with  8-bit value y
ATWWx,y       write address x with 16-bit value y
ATWLx,y       write address x with 32-bit value y
ATRBx         display the  8-bit value of address x
ATRWx         display the 16-bit value of address x
ATRLx         display the 32-bit value of address x
ATGO(x)       run program at addr x or boot router
ATGR          boot router
ATGT          run Hardware Test Program
AT%Tx         Enable Hardware Test Program at boot up
ATBTx         block0 write enable (1=enable, other=disable)

< press any key to continue >
ATRTw,x,y(,z) RAM test level w, from address x to y (z iterations)
ATWEa(,b,c,d,e)
          write MAC addr, Country code, EngDbgFlag,
          FeatureBit, Serial Number to flash ROM
ATWZa(,b,c,d,e)
          write MAC addr, Country code, EngDbgFlag,
          FeatureBit, Serial Number to flash ROM
ATHVx         set hardware version in working buffer
ATSNx         set serial number in working buffer
ATCUx         write Country code to flash ROM
ATCB          copy from FLASH ROM to working buffer
ATCL          clear working buffer
ATSB          save working buffer to FLASH ROM
ATBU          dump manufacturer related data in working buffer
ATSH          dump manufacturer related data in ROM
ATWMx         set MAC address in working buffer
ATCOx         set country code in working buffer
ATFLx         set EngDebugFlag in working buffer
ATSTx         set ROMRAS address in working buffer
ATSYx         set system type in working buffer
ATVDx         set vendor name in working buffer
ATPNx         set product name in working buffer
ATFEx,y,...   set feature bits in working buffer
ATMP          check & dump memMapTab
ATDOx,y       download from address x for length y to PC via XMODEM
ATTD          download router configuration to PC via XMODEM

< press any key to continue >
ATUPx,y       upload to RAM address x for length y from PC via XMODEM
ATUR          upload router firmware to flash ROM
ATLC          upload router configuration file to flash ROM
ATUXx(,y)     xmodem upload from flash block x to y
ATERx,y       erase flash rom from block x to y
ATWFx,y,z     copy data from addr x to flash addr y, length z
ATXSx         xmodem select: x=0: CRC mode(default); x=1: checksum mode
ATLOa,b,c,d   Int/Trap Log Cmd
ATSR          system reboot
ATFT(x,y,z)     offset, pattern, len
ATBR          Reset to default Romfile
ATDR(x)           Reset to default Romfile x
ATPA(x)       Pause for x ms
ATCP       show CPU
ATGI         select boot image
ATRF          copy (R)am to (F)lash 

OK

XMG1930-30HP> atcpCPU clock 0 

XMG1930-30HP> atmp
ROMIO image start at 0xb4280000
code version: 
code start: 0x80220000
code length: 6229B2
memMapTab: 27 entries, start = 0xb42b0000, checksum = 74E3
$RAM Section:
  0: BootExt(RAMBOOT), start=0x80220000, len=50000
  1: BootData(RAM), start=0x80270000, len=4000
  2: RasCode(RAMCODE), start=0x80274000, len=4000000
  3: RasData(RAM), start=0x84274000, len=9C8C000
  4: BootExtA(RAMBOOT), start=0x80220000, len=50000
  5: RasCodeA(RAMCODE), start=0x80274000, len=4000000
$ROM Section:
  6: BootBas(ROMIMG), start=0xb4000000, len=A0000
  7: DbgArea(ROMIMG), start=0xb40a0000, len=20000
  8: RomDir2(ROMDIR), start=0xb40c0000, len=120000
  9: LogArea1(ROMIMG), start=0xb41e0000, len=20000
 10: LogArea2(ROMIMG), start=0xb4200000, len=20000
 11: License(ROMIMG), start=0xb4220000, len=10000
 12: GenFS(ROMIMG), start=0xb4230000, len=10000
 13: LogArea3(ROMIMG), start=0xb4240000, len=20000
< Press any key to Continue >
 14: Reserved(ROMIMG), start=0xb4260000, len=10000
 15: ramParam(ROMIMG), start=0xb4270000, len=10000
 16: BootExt(ROMIMG), start=0xb4280030, len=2FFD0
 17: MemMapT(ROMMAP), start=0xb42b0000, len=1400
 18: termcap(ROMIMG), start=0xb42b1400, len=400
 19: RomDefa(ROMBIN), start=0xb42b1800, len=180000
     (Compressed)
     Version: XMG1930, start: 0xb42b1830
     Length: 160000, Checksum: 962F
     Compressed Length: 53D1, Checksum: FCC0
 20: RasCode(ROMBIN), start=0xb4431800, len=BCE800
     (Compressed)
     Version: XMG1930, start: 0xb4431830
     Length: 20C0AE0, Checksum: 52DC
     Compressed Length: 4711B1, Checksum: 9921
 21: RomDir2A(ROMDIR), start=0xb50c0000, len=120000
 22: BootExtA(ROMIMG), start=0xb5280030, len=2FFD0
 23: MemMapTA(ROMMAP), start=0xb52b0000, len=1400
 24: termcapA(ROMIMG), start=0xb52b1400, len=400
< Press any key to Continue >
 25: RomDefaA(ROMBIN), start=0xb52b1800, len=180000
     (Compressed)
     Version: XMG1930, start: 0xb52b1830
     Length: 160000, Checksum: 962F
     Compressed Length: 53D1, Checksum: FCC0
 26: RasCodeA(ROMBIN), start=0xb5431800, len=BCE800
     (Compressed)
     Version: XMG1930, start: 0xb5431830
     Length: 20C0AE0, Checksum: 52DC
     Compressed Length: 4711B1, Checksum: 9921
$USER Section:
Msecs 128
Heap0 16 34816 4096
Heap1 32 24576 2048
Heap2 64 65520 8192
Heap3 128 16384 1024
Heap4 192 8192 1024
Heap5 256 2048 128
Heap6 320 2048 128
Heap7 384 576 128
< Press any key to Continue >
Heap8 448 512 64
Heap9 512 5120 2560
Heap10 576 1536 64
Heap11 1024 1088 64
Heap12 1536 1280 128
Heap13 2048 512 128
Heap14 4096 542 64
Heap15 8192 158 8
Heap16 10496 606 32 
Heap17 12288 94 16      
Heap18 13312 320 5
Heap19 17408 158 5
Heap20 26944 1200 5
Heap21 36864 30 3
Heap22 64000 20 3
MbufInt 400 400 400
MbufIO  256 2048 2048 0 0
Queue   128
Cbuf    40960
FuncId  50
Proc    128
< Press any key to Continue >
Timer   1024
DNS     128
FilterSet 12
IpRoute 65
IpxRoute 4
IpMaxRt 128
IpxMaxRt 128
IpxMaxSap 128
FwTos 1200 10 10 10
AclType0 51200 9 400
AclType1 2048 4 100
AclType2 2048 4 20
AclType3 2048 4 128
AclType4 2048 4 128
AclType5 32768 8 128
AppleTalkRoute 0
Bridge 4
RemoteNode 1
Profile 1
Endpoint 4
NATServerSet 1
< Press any key to Continue >
DHCPEntry 253
PoeSvrCnt 4
ScheduleSet 12
AclBuffer 1
IPSecManualSA 120
IPSecIkePeer 120
IPSecIkeSA 120
IPSecAclBuffer 1
IPSecSPD 120
NatAclBuffer 1
CustomPort 10
NatSessions 1024
IpPolicySet 12
PoeSvrCnt 0
ScheduleSet 0
MiscFirewallBuffer 1
AveBuffer 1
CyberPatrolBuffer 1
CyberPatrolListBuffer 1
TrustedIPNum 0
IPBUFixpart 1
< Press any key to Continue >
NatRulePerSet 12
DHCPMacNum 8
UPNPNum 1
IPSecExtendNum 120
Model 5 29698 29954 33026 33794 34050
CoeFixedPart    1
CbqSpecialClass         1
AccessSecHost 16
SwitchStpPort   52
Switch1QPort    52
Switch1QStaticEntry     4094
WebManagementUser 5
snmpManager     4
dot1xProfileEntry       5
swStaticMacEntry        256
swFilterEntry   256
swMirrorEntry   52
swBWEntry       52
swTrunkEntry    24
bcastDmEntry    17
CMMemberEntry   24
< Press any key to Continue >
swDSMarkEntry   0
OSPFArea        0
OSPFVL          0
VrrpRouterEntry 0
swClassifierEntry   384
swFilterActionEntry 384
sptFSGen 128 1024
genBuffer 1
rmonEventTable 64
rmonAlarmTable 64
l2InbandIpdrvIfEntry    64
IGMPMVREntry 5
IGMPMVRAddrEntry 261
IGMPFilteringPort 52
IGMPFilteringRecEntry 256
SyslogTypeEntry 5
SyslogServerEntry       4
swPBVlanEntry   0
swVlanProtoBasedEntry 364
cardTypeEntry   0
swMRStpEntry    4
< Press any key to Continue >
radiusServer    1 
SwitchMRStpPort 52
IGMPMVlanEntry 16
swVlanSubnetBasedEntry 16
TrTCMEntry 52
tacPlusAuthSvr 2
tacPlusAcctSvr 2
enablePassword 15
authTypeEntry 2
acctTypeEntry 4
dhcpSnpEntry 1
arpInspectEntry 1
ipSrcGuardEntry 512
authorTypeEntry 2
SnmpManagementUser 5
displayConf 1 
FwVersion       VHello%world%|%8/23/2024
FwVersion0      29698,V4.80(ABQE.4)%|%08/23/2024
FwVersion1      29954,V4.80(ABQF.4)%|%08/23/2024
FwVersion2      33026,V4.80(ABZV.4)%|%08/23/2024
FwVersion3      33794,V4.80(ACAR.4)%|%08/23/2024
< Press any key to Continue >
FwVersion4      34050,V4.80(ACAS.4)%|%08/23/2024

OK

XMG1930-30HP> atds
No Debug Information Available
OK

XMG1930-30HP> atdt

Flash type = 0x0
Reboot Cnt = 0x0
Debug Flag = 0x0
DRAM size  = 0x10000000
Stack Ptr  = 0x0
IDStr      = ZyXELRTR
No Debug Information Available
OK

XMG1930-30HP> atbu
ZyNOS Version          : V4.80(ACAS.4) | 08/23/2024 10:16:42
Bootbase Version       : V1.00 | 02/10/2022 09:42:14
Serial Number          : 
Hardware Version       : 
Vendor Name            : 
Product Model          : 
ZyNOS ROM address      : 0x0
System Type            : 0
First MAC Address      : 000000000000
Last  MAC Address      : 00000000001F
MAC Address Quantity   : 32
Default Country Code   : 00
Boot Module Debug Flag : 00
CPLD Version           : N/A
RomFile Version        : 6B
RomFile Checksum       : 7848
ZyNOS Checksum         : 5e46
SNMP MIB level & OID   : 060102030405060708091011121314151617181920
Main Feature Bits      : 00
Other Feature Bits     :
          00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   
          00 00 00 00 00 00 00 00-00 00 00 00 00 00           

OK

XMG1930-30HP> atsh
ZyNOS Version          : V4.80(ACAS.4) | 08/23/2024 10:16:42
Bootbase Version       : V1.00 | 02/10/2022 09:42:14
Serial Number          : S252L2100<redacted>
Hardware Version       : xxxxxxxxxxxxxxx
Vendor Name            : Zyxel
Product Model          : XMG1930-30HP
ZyNOS ROM address      : 0xb40a0000
System Type            : 8
First MAC Address      : 7049A2<redacted>
Last  MAC Address      : 7049A2<redacted>
MAC Address Quantity   : 32
Default Country Code   : FF
Boot Module Debug Flag : 00
CPLD Version           : N/A
RomFile Version        : 6B
RomFile Checksum       : 7848
ZyNOS Checksum         : 5e46
SNMP MIB level & OID   : 060102030405060708091011121314151617181920
Main Feature Bits      : C0
Other Feature Bits     :
          02 85 00 00 00 00 00 00-00 00 00 00 00 00 00 00   
          00 00 00 00 00 00 00 00-00 13 00 00 00 00           

OK

XMG1930-30HP> 

Grepping for interesting strings in the first MB of flash showed:

U-Boot 2011.12.(3.6.0.48) (Feb 10 2022 - 09:42:14)
boardversion=
boardmodel=RTL9313_12XGE
ledModeInitSkip=0
bootargs=
bootcmd=gobootext
bootdelay=1
ethaddr=00:E0:4C:86:70:01
ipaddr=192.168.1.1
serverip=192.168.1.111
baudrate=115200
postword=

Bootbase is U-Boot (with very restricted command set until you enter the correct password) which passes control to BootExt.

Overall, this looks very similar to the Zyxel XS1930 which @jonasj is working on.

What’s next? Try to boot a XS1930 image? @jonasj would you be willing to share the XS1930 image you used for boot testing with rt-loader in https://github.com/openwrt/openwrt/pull/21248 ?

EDIT: Updated logs with corrected password sequence

Great, had that device on my list too but quite expensive.

I can support with this quite good I think, as you mentioned the device seems very similar to XS1930 lineup.

Here are some of my findings:

  • see my work here: https://github.com/jonasjelonek/openwrt/tree/realtek/zyxel-xs1930 still somewhat messy but you should be able to take over needed parts.
  • while extracting the HWP from the flash dump for my XS1930, I also saw a profile for XMG1930-30/30HP. So they share the firmware. I extracted that too and saved it here. While still being in a bad format, I can translate it into a DTS snippet you can use.
  • be warned, Zyxel like to do some strange hardware quirks. For example, I had to enable all SFPs on my devices with dedicated GPIOs, and even had to write an upstream driver for SFP-GPIO muxing
  • the bootloader structure is a bit weird. Bootbase here is a masked U-Boot. As you found out, you can enter it while jamming $ during the DRAM test. When in there, you can unlock the Bootloader but not with aten 1,XXXXX instead use aten 1 XXXX (and the usual formula). So the comma is bad in there. With the correct password you should get a much better command list.
  • the U-Boot here is basically useless (except for recovery) as it doesn’t have the proper HWP and parts to setup the networking on it’s own

Regarding U-Boot: I didn’t made any use of that. We have now quite good support of booting an image out of BootExt, and I often had issues booting that from the U-Boot/Bootbase that’s on there. So I suggest to keep that completely untouched and just for recovery purposes if needed.

Probably just giving you an image is not the best idea. Usually, as soon as the MDIO/SMI stuff in the DTS doesn’t really match what’s on the board, there will be probing errors and somehow the DSA/Ethernet driver will blow up the kernel before you can even reach a shell.

1 Like

Here the DTS snippet:

&mdio_bus0 {

	/* 2.5G copper PHYs */
	phy0: ethernet-phy@0 {
		reg = <0>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 8>;
	};
	phy1: ethernet-phy@1 {
		reg = <1>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 9>;
	};
	phy4: ethernet-phy@4 {
		reg = <4>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 10>;
	};
	phy5: ethernet-phy@5 {
		reg = <5>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 11>;
	};
	phy8: ethernet-phy@8 {
		reg = <8>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 12>;
	};
	phy9: ethernet-phy@9 {
		reg = <9>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 13>;
	};
	phy12: ethernet-phy@12 {
		reg = <12>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 14>;
	};
	phy13: ethernet-phy@13 {
		reg = <13>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <0 15>;
	};
	phy16: ethernet-phy@16 {
		reg = <16>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 8>;
	};
	phy17: ethernet-phy@17 {
		reg = <17>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 9>;
	};
	phy20: ethernet-phy@20 {
		reg = <20>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 10>;
	}
	phy21: ethernet-phy@21 {
		reg = <21>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 11>;
	}
	phy24: ethernet-phy@24 {
		reg = <24>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 12>;
	};
	phy25: ethernet-phy@25 {
		reg = <25>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 13>;
	};
	phy28: ethernet-phy@28 {
		reg = <28>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 14>;
	};
	phy29: ethernet-phy@29 {
		reg = <29>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 15>;
	};
	phy32: ethernet-phy@32 {
		reg = <32>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 0>;
	};
	phy33: ethernet-phy@33 {
		reg = <33>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 1>;
	};
	phy36: ethernet-phy@36 {
		reg = <36>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 2>;
	};
	phy37: ethernet-phy@37 {
		reg = <37>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 3>;
	};
	phy40: ethernet-phy@40 {
		reg = <40>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 4>;
	};
	phy41: ethernet-phy@41 {
		reg = <41>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 5>;
	}
	phy44: ethernet-phy@44 {
		reg = <44>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 6>;
	};
	phy45: ethernet-phy@45 {
		reg = <45>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <1 7>;
	};

	/* 10G copper PHYs */
	phy48: ethernet-phy@48 {
		reg = <48>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <2 0>;
	};
	phy50: ethernet-phy@50 {
		reg = <50>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <2 1>;
	};
	phy52: ethernet-phy@52 {
		reg = <52>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <2 2>;
	};
	phy53: ethernet-phy@53 {
		reg = <53>;
		compatible = "ethernet-phy-ieee802.3-c45";
		realtek,smi-address = <2 3>;
	};
}

&switch0 {
	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		/* 2.5G copper ports */
		/* TODO: is this really 10g-qxgmii ?? */
		SWITCH_PORT_SDS(0, 1, 2, 10g-qxgmii)
		SWITCH_PORT_SDS(1, 2, 2, 10g-qxgmii)
		SWITCH_PORT_SDS(4, 3, 2, 10g-qxgmii)
		SWITCH_PORT_SDS(5, 4, 2, 10g-qxgmii)

		SWITCH_PORT_SDS(8, 5, 3, 10g-qxgmii)
		SWITCH_PORT_SDS(9, 6, 3, 10g-qxgmii)
		SWITCH_PORT_SDS(12, 7, 3, 10g-qxgmii)
		SWITCH_PORT_SDS(13, 8, 3, 10g-qxgmii)

		SWITCH_PORT_SDS(16, 9, 4, 10g-qxgmii)
		SWITCH_PORT_SDS(17, 10, 4, 10g-qxgmii)
		SWITCH_PORT_SDS(20, 11, 4, 10g-qxgmii)
		SWITCH_PORT_SDS(21, 12, 4, 10g-qxgmii)

		SWITCH_PORT_SDS(24, 13, 5, 10g-qxgmii)
		SWITCH_PORT_SDS(25, 14, 5, 10g-qxgmii)
		SWITCH_PORT_SDS(28, 15, 5, 10g-qxgmii)
		SWITCH_PORT_SDS(29, 16, 5, 10g-qxgmii)

		SWITCH_PORT_SDS(32, 17, 6, 10g-qxgmii)
		SWITCH_PORT_SDS(33, 18, 6, 10g-qxgmii)
		SWITCH_PORT_SDS(36, 19, 6, 10g-qxgmii)
		SWITCH_PORT_SDS(37, 20, 6, 10g-qxgmii)

		SWITCH_PORT_SDS(40, 21, 7, 10g-qxgmii)
		SWITCH_PORT_SDS(41, 22, 7, 10g-qxgmii)
		SWITCH_PORT_SDS(44, 23, 7, 10g-qxgmii)
		SWITCH_PORT_SDS(45, 24, 7, 10g-qxgmii)

		/* 10G copper ports */
		SWITCH_PORT_SDS(48, 25, 8, usxgmii)
		SWITCH_PORT_SDS(50, 26, 9, usxgmii)
		SWITCH_PORT_SDS(52, 27, 10, usxgmii)
		SWITCH_PORT_SDS(53, 28, 11, usxgmii)

		/* SFP ports */
		port@55 {
			reg = <55>;
			label = SWITCH_PORT_LABEL(29);
			pcs-handle = <&serdes12>;
			phy-mode = "1000base-x";
		//	sfp = <&sfp29>;
			managed = "in-band-status";	
		};
		port@55 {
			reg = <55>;
			label = SWITCH_PORT_LABEL(30);
			pcs-handle = <&serdes13>;
			phy-mode = "1000base-x";
		//	sfp = <&sfp30>;
			managed = "in-band-status";	
		};
	}
};

&serdes12 {
	realtek,pnswap-tx;
};

&serdes13 {
	realtek,pnswap-tx;
};

You still need to figure out quite some stuff, e.g. the SFP I2C + GPIO assignment. I had quite a hard time with this as you may see in the DTS for the XS1930 devices in my tree. But I'm ready to help wherever I can :). I even designed a small SFP breakout PCB for such purposes.

EDIT: This is extracted from the flash dump. Beside the Bootbase Partition, you'll find other LZMA partitions which are quite big seem to be the ZyNOS root partitions. After extracting and decompressing them, grepping for XMG-1930 or RTL9313 should give a few hits. Among those, there is a block which contains the hardware profiles we know from the SDK.

Just note that the 2.5G copper ports won't work right now. 10G-QXGMII setup is skipped because it's not properly implemented yet. Either you or someone else manages to add that, or I reach that point on my ToDo list earlier :slight_smile:

Thank you! I also have totally different partitions, so that part of the DTS needed to be modified as well.

                        partition@0 {
                                label="BootBas";
                                reg="<0x000000 0xa0000>;
                                read-only;
                        };
                        partition@1 {
                                label="DbgArea";
                                reg="<0x0a0000 0x20000>;
                                read-only;
                        };
                        partition@2 {
                                label="RomDir2";
                                reg="<0x0c0000 0x120000>;
                                read-only;
                        };
                        partition@3 {
                                label="LogArea1";
                                reg="<0x1e0000 0x20000>;
                                read-only;
                        };
                        partition@4 {
                                label="LogArea2";
                                reg="<0x200000 0x20000>;
                                read-only;
                        };
                        partition@5 {
                                label="License";
                                reg="<0x220000 0x10000>;
                                read-only;
                        };
                        partition@6 {
                                label="GenFS";
                                reg="<0x230000 0x10000>;
                                read-only;
                        };
                        partition@7 {
                                label="LogArea3";
                                reg="<0x240000 0x20000>;
                                read-only;
                        };
                        partition@8 {
                                label="Reserved";
                                reg="<0x260000 0x10000>;
                                read-only;
                        };
                        partition@9 {
                                label="ramParam";
                                reg="<0x270000 0x10000>;
                                read-only;
                        };
                        /* GAP: 0x280000 - 0x28002f */
                        partition@10 {
                                label = "GAP0";
                                reg="<0x280000 0x30>;
                                read-only;
                        };
                        partition@11 {
                                label="BootExt";
                                reg="<0x280030 0x2ffd0>;
                                read-only;
                        };
                        partition@12 {
                                label="MemMapT";
                                reg="<0x2b0000 0x1400>;
                                read-only;
                        };
                        partition@13 {
                                label="termcap";
                                reg="<0x2b1400 0x400>;
                                read-only;
                        };
                        partition@14 {
                                label="RomDefa";
                                reg="<0x2b1800 0x180000>;
                                read-only;
                        };
                        partition@15 {
                                label="RasCode";
                                reg="<0x431800 0xbce800>;
                                read-only;
                        };

I haven't yet really properly arranged the partitions in my DTS. In the end, it most likely boils down to keeping the first partitions and where the BootExt starts will be "loader" (for rt-loader) + "firmware" partition used by OpenWrt. Or one could keep the dual-boot layout, this should still run with the Bootbase/U-Boot. Looking at the code in the XS1930-GPL I have, the gobootext command includes handling a boot image index.

Which terminal tool do you use for uploading an initramfs image? It seems that everyone is using a slightly different tool. I don’t particularly care which as long as it works well.

I use picocom for everything now. Just note that the usual ymodem as U-boot has it, does not work here. BootExt only support xmodem. So you need to specify a different send command with —send-cmd, usually sx or lrzsz-sx.

The transfer sometimes just fails out of nowhere (while ymodem is rock stable) but in the end it usually works. xmodem seems to be a rather bad protocol but I didn‘t want to flash yet.

I noticed that I already tinkered with my layout long time ago and then forgot about it. I assume both are the same in the end since the device seem to share firmware files.

I tried to adapt your code and DTS to my flash layout. One change I’m unsure about:

You suggested port@55 for the SFPs, but that ID appears twice in your snippet. I changed the first one to port@54. Was that correct?

No, that was actually a c&p mistake. port@54 and reg = <54>; for the first is correct.

1 Like

Which values for ATUP and ATGO do you use for the XS1930 image and can I use the same ones? I saw this in https://github.com/openwrt/openwrt/pull/21248 :

ATUP80100000,file_length
ATGO80100000

You can use >= 80300000. I use 80300000 right now but something like 81000000 or 82000000 is fine too.

Below is too low, you'll end up overwriting into the BootExt RAM space and thus killing the transfer.

Thank you! I’ll try that tomorrow.

Yes indeed. I saw a boatload of new commands in Bootbase (U-Boot).

ymodem is supported, and rtk seems to be available as well. I’ll update my initial post with the corrected command and with the improved log.

rtk won't really help because the proper hardware profiles are most likely not included, at least that's the case on my devices.

But at least the ymodem is good, and the commands are much better than in the BootExt shell. I have not yet fully decided how to do this in the end, there are too options:

  • leave U-boot/Bootbase unmodified and use the Zyxel image format
  • change the bootcmd and try to boot plain uImage

At least when I started working with this, I had extreme issues getting an image to boot from within the u-boot, basically getting no real output from Linux. So I decided to stick with the BootExt way for now. Though I haven't digged too deep in that regard.

Unfortunately I didn’t have time to boot the generated image today, I only managed to get the new log with the corrected ATEN sequence for Bootbase.

Some minor hints you might add above:

  • BootExt doesn't need the space between ATEN and 1, both works. But for U-boot it is needed
  • not sure what you use to get the unlock code, I use this nice online tool https://akao.co.uk/tools/zyxel_unlocker/
  • I had some issues with the "unseeded" unlock code way (https://www.ixo.de/info/zyxel_uclinux/). This doesn't seem to work for me in BootExt, so I always generate the seed there, paste it into the online tool and then copy the ATEN command. In U-boot, both seems to work

I'll include them in my final commit message, and you should probably too when you reach a final state.

Weird. It didn’t work for me without space, BootExt always complained ERROR. That said, maybe it complained because the password was wrong in those cases. Will retest.

I translated the code in https://www.ixo.de/info/zyxel_uclinux/ (search for “unsigned long password“) to a short python script to calculate the values. That script is on my work computer, I can post it here tomorrow. Websites tend to disappear over time, so I’d rather have a solution which is available without requiring a network connection.

Good point, I’ll retest and update the commit message accordingly.

Agree. Would've probably done the same with the code of this web tool later, it's also just a JavaScript variant of that. I could imagine putting a script in openwrt repository in the scripts folder might be a good idea, then we have it there once and for all.