Support for Zyxel GS1920 series (GS1920-24HP)

I have a couple of GS1920-24HP units that I would like to add support for. This thread is meant to collect all information about the switch and, ultimately, to bring OpenWrt suppor to the whole series.

There are some noteworthy differences between the GS1900 series and the GS1920 series:

  • RTL839x instead of RTL838x for all models
  • BootBase instead of U-Boot
  • ZynOS instead of Linux
  • PoE controller attached via i2c (the management MCU, not the individual controllers) instead of UART

Detailed information in @svanheule's Wiki: https://svanheule.net/switches/zyxel_gs1920_series

Status:

This is a bit more work than expected (as always) and I can only do serious work on the weekend where I have access to my development device (I desoldered the flash IC and put it into a socket for easier flashing).

Option 1) The ZyXEL bootloader "BootBase" needs to be replaced by U-Boot. This can be done by attaching serial console, creating a backup and transferring the U-Boot binary to flash.

At the moment, this is all very rough and more a proof of concept than anything else.

U-Boot Code: https://github.com/andyboeh/u-boot-gs1920/tree/standalone

Option 2) I'm investigating the feasibility to run OpenWrt from BootBase/BootExt. I can boot initramfs images from BootExt, the next step will be flashing it and see if it can be booted from Bootbase.

Log:

  • 2023/03/26: Attached serial, BootBase access is working; BootBase password from http://www.ixo.de/info/zyxel_uclinux/ working properly. No network support in BootBase, so I will need to use XModem for the time being

  • 2023/03/27: Tried to read flash via CH341A/SOIC-8 clip, but it didn't work. The flash map can be extracted from BootBase by calling ATMP:

ROMIO image start at b40b0000
code version: 
code start: 80014000
code length: 3028C2
memMapTab: 21 entries, start = b40e0000, checksum = 3EBC
$RAM Section:
  0: BootExt(RAMBOOT), start=80014000, len=30000
  1: BootData(RAM), start=80044000, len=4000
  2: RasCode(RAMCODE), start=80048000, len=13B8000
  3: RasData(RAM), start=81500000, len=6000000
  4: BootExtA(RAMBOOT), start=80014000, len=30000
  5: RasCodeA(RAMCODE), start=80048000, len=12B8000
$ROM Section:
  6: BootBas(ROMIMG), start=b4000000, len=20000
  7: DbgArea(ROMIMG), start=b4020000, len=10000
  8: RomDir2(ROMDIR), start=b4030000, len=80000
  9: BootExt(ROMIMG), start=b40b0030, len=2FFD0
 10: MemMapT(ROMMAP), start=b40e0000, len=2000
 11: termcap(ROMIMG), start=b40e2000, len=400
 12: RomDefa(ROMBIN), start=b40e2400, len=80000
     (Compressed)
     Version: RAS GS1920, start: b40e2430
     Length: 80000, Checksum: 1BC5
     Compressed Length: 254F, Checksum: 543B
 13: RasCode(ROMBIN), start=b4162400, len=69DC00
     (Compressed)
     Version: GS1920, start: b4162430
     Length: 1261CC0, Checksum: 02F7
     Compressed Length: 2504C2, Checksum: 73D4
 14: LogArea1(ROMIMG), start=b47c0000, len=10000
 15: LogArea2(ROMIMG), start=b47e0000, len=10000
 16: BootExtA(ROMIMG), start=b48b0030, len=2FFD0
 17: MemMapTA(ROMMAP), start=b48e0000, len=2000
 18: termcapA(ROMIMG), start=b48e2000, len=400
 19: RomDefaA(ROMBIN), start=b48e2400, len=80000
signature error!
 20: RasCodeA(ROMBIN), start=b4962400, len=69DC00
signature error!
$USER Section:
Msecs 128
Heap0 16 34816 4096
Heap1 32 24576 2048
Heap2 64 65520 8192
Heap3 128 6144 1024
Heap4 192 1024 512
Heap5 256 512 128
Heap6 320 384 64
Heap7 384 576 128
Heap8 448 512 64
Heap9 512 256 128
Heap10 576 128 32
Heap11 1024 640 16
Heap12 2048 160 128
Heap13 4096 256 32
Heap14 8192 128 8
Heap15 10496 64 5 
Heap16 17408 128 5
Heap17 26944 90 5
MbufInt 20 20 60
MbufIO  96 96 300 0 0
Queue   128
Cbuf    4096
FuncId  50
Proc    96
Timer   1024
DNS     128
FilterSet 12
IpRoute 51
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
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
NatRulePerSet 12
DHCPMacNum 8
UPNPNum 1
IPSecExtendNum 120
Model 4 20482 20738 20994 21250
CoeFixedPart	1
CbqSpecialClass		1
AccessSecHost 16
SwitchStpPort	50
Switch1QPort	50
Switch1QStaticEntry	1024
WebManagementUser 5
snmpManager	4
dot1xProfileEntry	5
swStaticMacEntry	256
swFilterEntry	256
swMirrorEntry	50
swBWEntry	50
swTrunkEntry	8
ipdrvIfEntry	64
bcastDmEntry	17
CMMemberEntry	24
swDSMarkEntry	0
OSPFArea	0
OSPFVL		0
VrrpRouterEntry	0
swClassifierEntry   256
swFilterActionEntry 128
sptFSGen 128 1024
genBuffer 1
rmonEventTable 64
rmonAlarmTable 64
l2InbandIpdrvIfEntry	64
IGMPMVREntry 5
IGMPMVRAddrEntry 261
IGMPFilteringPort 50
IGMPFilteringRecEntry 256
SyslogTypeEntry	5
SyslogServerEntry	4
swPBVlanEntry	0
swVlanProtoBasedEntry 364
cardTypeEntry	0
swMRStpEntry	2
radiusServer	1 
SwitchMRStpPort 50
IfIGMPEntry 65
IGMPMVlanEntry 16
swVlanSubnetBasedEntry 16
TrTCMEntry 50
tacPlusAuthSvr 2
tacPlusAcctSvr 2
enablePassword 15
authTypeEntry 2
acctTypeEntry 4
dhcpSnpEntry 1
arpInspectEntry 1
ipSrcGuardEntry 512
authorTypeEntry 2
SnmpManagementUser 5
displayConf 1 
FwVersion	VDemoFwVer%|%03/27/2014
FwVersion0	20482,V4.10(AANZ.0)%|%03/27/2014
FwVersion1	20738,V4.10(AAOA.0)%|%03/27/2014
FwVersion2	20994,V4.10(AAOB.0)%|%03/27/2014
FwVersion3	21250,V4.10(AAOC.0)%|%03/27/2014

OK

From what I gathered, the boot process consists of BootBase -> BootExt -> RasCode. I had a look at support for various older ZyXEL devices based on ZyNOS and it looks like BootExt should be replaced with U-Boot in order to allow proper booting of the Linux kernel. Luckily, most of the tools are already available (e.g. mkzynfw). More problematic: Compiling U-Boot for this switch (I once compile the TP-Link code for the T1600G-52PS, maybe I'll use this as a starting point).

  • 2023/04/30: Flashed my first self-compiled U-Boot to the device. I do get a ton of errors, but I can reach a usable U-Boot prompt via serial. NB: At this point, I wanted to verify that my self-compiled U-Boot works. I flashed it directly to the chip and overwrote the ZyXEL loader. The next step is to trick Bootbase into loading my U-Boot.

  • 2023/05/01: I figured out how to transfer and flash U-Boot to the device via XMODEM so it stays persistent - and a backup can also be done. I don't see any other way than replacing BootBase with U-Boot. Network doesn't work yet in U-Boot, but I was able to boot OpenWrt that I transferred manually to the flash.

  • 2023/05/02: Ported lzma-loader to the realtek platform, this allows uploading an initramfs image via XMODEM to the switch within a few minutes.

  • 2023/05/07: I played a lot with my firmware signing utility and succeeded to flash an lzma-loader (unfortunately, just the lzma-loader) via the web interface. The loader is also executed, so this is quite some progress. I haven't figured out how to create a valid image that includes an OpenWrt initramfs image. There are some more checks in place that I haven't yet figured out.

  • 2023/05/08: Finally, I have an installation procedure that does not require desoldering of the flash chip - but it requires UART. Basically, an OpenWrt initramfs version is uploaded via XMODEM, executed and used to flash OpenWrt. The image is considered valid by BootBase, but not by the web interface, hence it cannot be installed via the web interface. However, I was able to patch lzma-loader to support loading BootExt from the backup partition as a means to recover the system.

  • 2024/03/14: I'm finally continuing work on this switch model. lzma-loader is now patched for dual-image support and can be used to boot either OpenWrt or the backup OEM firmware. This leaves us with 7,3M of usable space when allowing easy restore via Dual-Boot - not much. If the second image is sacrificed, this doubles the amount of usable space. It might be possible to just use RasCodeA to extend our image and leave BootExtA as-is to be able to flash back to stock.

ToDo:

7 Likes

Thanks for looking at this.

I have a couple of GS1920-24 (i.e. non PoE model), one in use, one that can be used for testing. I'm not a developer...but I can usuall follow instructions :grin:, so if it would be helpful to do testing then let me know.

Great - unfortunately, it's not as easy as I first thought and I'm not sure if we can fit a chainloaded U-Boot into flash. If not, there is always the option of replacing the entire bootloader, but this is usually not accepted by OpenWrt.

1 Like

@svanheule Do you think it's acceptable if BootBase needs to be replaced by U-Boot in order to support OpenWrt? The U-Boot in question is based on the GS1900 U-Boot and modified for the GS1920 (not yet published).

Users would be instructed to attach serial, then do a backup of the whole flash using XMODEM. Afterwards, BootBase is replaced by U-Boot, again using XMODEM and then OpenWrt can be installed.

And another thing: Do you have any explanation why the RTL8231 in MDIO mode is not detected if I configure MAC and PHY in U-Boot (with or with RTL8231 support doesn't make a difference)? If I omit it in U-Boot, the boot log does not complain about the RTL8231 not being found.

I know that you tried OpenWrt once on this switch, do you still have your test DTS and/or GPIO mappings? Unfortunately, the Wiki page does not contain any GPIO mappings.

Replacing the bootloader has not typically been seen as acceptable. As painfully slow as XMODEM may be, if it works to load the initial initramfs/factory image once, that should be sufficient.

If a chainloaded bootloader brings other benefits, we could also consider this. It shouldn't take up more than a few 64k blocks, right? Can't remember if the GS1920 is dual image or not, but you could always span both firmware partitions to have more usable space.

As I recall, I quite quickly got put off by the bootloader on this device. So I'm not sure if I actually ever got around to running OpenWrt. Could you remind me where I mentioned this? :slight_smile:

As for the RTL8231, maybe MAC/PHY configuration changes or resets some registers that are required for RTL8231 support over MDIO? The pin muxes need to be set up correctly, and there's also some other control bits for the auxiliary MDIO controller.

I remember the ZyXEL P2812HNU-F1 (https://openwrt.org/toh/zyxel/p-2812hnu-f1) that requires a comlete U-Boot replacement, but that device is relatively old.

I will try again with the stock BootBase and BootExt, it should be possible to get the signature right. The existing mkzynfw tool in firmware-utils contains most of the needed code, but doesn't generate valid images.

Puh, I think it was somewhere in the big rtl83xx thread, but it's already very cumbersome to dig through it. No worries though, I'll figure out the GPIOs myself, I just wanted to avoid duplicate work.

I'll investigate that later, I'll try to create an image that works from BootBase/BootExt first. Yes, the GS1920 is dual-image and I definitely need to span both partitions in order to have enough space.

@svanheule I've made quite a bit of progress and I have the following suggestion for this switch series:

So far, I can boot OpenWrt from flash with the stock BootBase and a port of lzma-loader to the realtek-target (I screwed something up today and ATM the kernel doesn't boot, but it was already running).

However, I have once again hit a set up problem: If I boot that way, Ethernet doesn't work. U-Boot probably does some initialization step that OpenWrt doesn't - do you have any hints what that might be? The good news is that the GPIO expander is working fine in this configuration.

Initial installation would be performed the following:

  • Upload initramfs image via XModem
  • Flash "factory.bin" via mtd write
  • OpenWrt boots from flash and uses only the first image partition - that's about 0x700000 bytes for OpenWrt.
  • Users can restore stock by switiching to the alternate partition from within OpenWrt

There is one drawback: All is going to work fine as long as OpenWrt boots. However, if it doesn't boot, there is no way to switch to the second firmware image. BootBase is so limited that it doesn't have a UI and will still consider OpenWrt as working as long as the lzma-loader is fine. And lzma-loader does not have any recovery / dual image options.

IMHO there are several options involving (quite some) work:

  • Use U-Boot instead of lzma-loader to load OpenWrt. U-Boot provides recovery support. However, I haven't succeeded in chainloading U-Boot, for now it only works in standalone mode. And we lose more flash space due to the size of U-Boot.
  • Patch lzma-loader with dual-firmware support. It could be sufficient to force it to chainload the recovery BootExt file instead of an OpenWrt kernel. This could be achieved by pressing a button during boot.

I will probably investigate the lzma-loader variant: The only required bit of the OEM firmware is a working BootExt, requiring 0x30000 bytes of size. This BootExt provides recovery options and can be used to flash back to stock. The remaining bytes of image 2 could be used for OpenWrt, increasing the available size by another 6M.

EDIT: Extending lzma-loader to support booting BootExt from the backup partition wasn't very hard and seems like a good option.

2 Likes

Are there any news? The switch has not shown up in the Wiki. If I get it right, you've solved most of the boot issues, but ethernet ports etc aren't working, correct?

Unfortunately, I had to postpone this project a bit. Yes, I have a patched lzma-loader and I'm quite sure that we have a way to install OpenWrt and return back to stock without too much trouble.

Your post made me finally commit and push my WiP tree, in case you want to have a look at it: https://github.com/andyboeh/openwrt/tree/zyxel_gs1920-24hp

4 Likes

Thank you for your quick reply and your efforts in bringing OpenWRT to the GS1920 series from Zyxel. As I am not skilled enough to improve or develop the code further I believe pushing it to the main tree will give your work the credit it deserves and the chance of helping others to complete the conversion.

1 Like

Thank you for your efforts!

I just bought GS1920-48 from eBay, and was researching if was possible to be flashed with OpenWrt (searching for clues about Bootbase with the the model number GS1920 lead me to this thread).

I'm unsure with what I can contribute, because I was having trouble with the the simplest of tasks - connecting to the UART. The only time a was able to receive clean and readable data is when I've connected a simple logic analyzer.

Anyhow, I will follow the development of your work with interest.

Which serial cable did you try? This is a real RS232 port with +-5.6V levels, you need a level shifter if you use a TTL serial cable.

The most important task for now is figuring out what needs to be added to the switch driver so that the LAN ports work. I know that the OpenWrt driver omits some initialization steps, but I have yet to find out which exactly.

FWIW, I had the same issue on a GS1920-24. The output from the RS-232 header was total garbage.

I went out and bought an FTDI RS-232 cable that supports signal inversion (because for some reason, the GS1920-24 I had was outputting inverted signals) and still got garbage from the RS-232 header. The only way I was ever able to get usable UART was by connecting a TTL serial to the upstream of the SP3232.

Unfortunately a datasheet derp and the closeness of the RS-232/UART pins on the SP3232 lead to me crossing pins and frying the TTL adapter and the UART transceiver in the Realtek by sending +-5.6V into the UART :sob:

If I were to do it again, I'd remove the SP3232 with hot air and solder permanent connections to the Realtek UART, as that was the only reliable method I found.