This is an old revision of the document!
Zyxel XS1930 series
The XS1930 series is a line of managed multi-gigabit Ethernet switches.
Switch name | multi-gigabit RJ45 ports | SFP+ ports | PoE ports |
---|---|---|---|
XS1930-10 | 8 | 2 | - |
XS1930-12HP | 10 | 2 | 8 |
Models
XS1930-10
Hardware
- SoC: RTL9313
- Ethernet: Aquantia AQR813
- RAM: Winbond W632GU6MB 256MiB DDR3
- Flash: Macronix MX25L25645G, 32MiB SPI NOR
- GPIO: 1× RTL8231
- HC164 shift register for device status LEDs
- 3-pin fan
The serial port is accessible via pins from from the outside on the right side of the device. Pins are front to back: GND, TX, RX, Vcc. Port settings are 115200 baud, 8n1, with 3.3 logic level.
Photos
Firmware
The firmware of the Zyxel 1930 devices is based on Zynos https://github.com/dev-zzo/router-tools/blob/master/zynos.md, itself a descendant of ThreadX. There is no Linux Kernel running. The initial configuration of the hardware is performed by U-Boot, which then boots a second stage Zynos bootloader and finally ZynOS itself. The second stage bootloader is merely there for flashing the device, define capabilities and setting up Zynos in memory. There is no hardware configuration done at this point. Zynos seems to simply be a big blob loaded from flash to memory with all functionality linked together. The normal startup sequence is
Bootbase Version: V1.00 | 08/26/2019 16:03:22 RAM: Size = 262144 Kbytes DRAM POST: Testing: 262144K OK DRAM Test SUCCESS ! FLASH: 32M ZyNOS Version: V4.60(ABQE.0)C0 | 12/20/2019 14:53:53 Press any key to enter debug mode within 1 second. ....... Enter Debug Mode XS1930-10> 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 XS1930-10> aten1,C621E14A OK OKXS1930-10> atsh ZyNOS Version : V4.60(ABQE.0)C0 | 12/20/2019 14:53:53 Bootbase Version : V1.00 | 08/26/2019 16:03:22 Serial Number : S202L10080128 Vendor Name : Zyxel Product Model : XS1930-10 ZyNOS ROM address : 0xb40a0000 System Type : 8 First MAC Address : BCCFXXXXXXC7 Last MAC Address : BCCFXXXXXXD2 MAC Address Quantity : 12 Default Country Code : FF Boot Module Debug Flag : 00 CPLD Version : N/A RomFile Version : 67 RomFile Checksum : ebd1 ZyNOS Checksum : eeee SNMP MIB level & OID : 060102030405060708091011121314151617181920 Main Feature Bits : C0 Other Feature Bits : 02 74 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 XS1930-10> ATMP ROMIO image start at 0xb4280000 code version: code start: 0x80220000 code length: 5745CA memMapTab: 27 entries, start = 0xb42b0000, checksum = 75B9 $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 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: RAS XS1930, start: 0xb42b1830 Length: 160000, Checksum: 962F Compressed Length: 53D1, Checksum: FCC0 20: RasCode(ROMBIN), start=0xb4431800, len=BCE800 (Compressed) Version: XS1930, start: 0xb4431830 Length: 1F06778, Checksum: 6F84 Compressed Length: 3C2DC9, Checksum: E874 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 25: RomDefaA(ROMBIN), start=0xb52b1800, len=180000 (Compressed) Version: RAS XS1930, start: 0xb52b1830 Length: 160000, Checksum: 962F Compressed Length: 53D1, Checksum: FCC0 26: RasCodeA(ROMBIN), start=0xb5431800, len=BCE800 (Compressed) Version: XS1930, start: 0xb5431830 Length: 1F06778, Checksum: 6F84 Compressed Length: 3C2DC9, Checksum: E874 $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 Heap8 448 512 64 Heap9 512 256 128 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 Timer 1024 DNS 128 FilterSet 12 IpRoute 33 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 2 29698 29954 CoeFixedPart 1 CbqSpecialClass 1 AccessSecHost 16 SwitchStpPort 52 Switch1QPort 52 Switch1QStaticEntry 1024 WebManagementUser 5 snmpManager 4 dot1xProfileEntry 5 swStaticMacEntry 256 swFilterEntry 256 swMirrorEntry 52 swBWEntry 52 swTrunkEntry 24 bcastDmEntry 17 CMMemberEntry 24 swDSMarkEntry 0 OSPFArea 0 OSPFVL 0 VrrpRouterEntry 0 swClassifierEntry 256 swFilterActionEntry 256 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 2 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%|%12/20/2019 FwVersion0 29698,V4.60(ABQE.0)C0%|%12/20/2019 FwVersion1 29954,V4.60(ABQF.0)C0%|%12/20/2019 OK
In the above sequence, the second stage ZynOS loader was interrupted by pressing a key. In order to get into the initial U-Boot, the "$" key needs to be pressed until the end of the DRAM test routine. Both U-Boot and the ZynOS loader have crippled functionality until they are unlocked. For this, there is an unlock code, which depends on the last digit of the MAC-Address, as described here: http://www.ixo.de/info/zyxel_uclinux/. In the above example, the ZynOS bootloader was unlocked with the aten1,C621E14A
command, unlocking U-Boot is done by aten 1 C621E14A
for this MAC address. Unfortunately U-Boot is not able to set up the Aquantia PHY, nor does it set up the fibre ports, even though rtk network on
does seem to do something. Therefore development needs to be done through uploading images via the serial connection. Once U-Boot is unlocked, the following information is available:
XS1930$ flshow =============== FLASH Partition Layout =============== Index Name Size Address ------------------------------------------------------ 0 BootLoader 0x9e000 0xb4000000-0xb409dfff 1 BootEnvCfg 0x1000 0xb409e000-0xb409efff 2 MRD 0x1000 0xb409f000-0xb409ffff 3 DbgArea 0x20000 0xb40a0000-0xb40bffff 4 RomDir2 0x120000 0xb40c0000-0xb41dffff 5 LogArea1 0x20000 0xb41e0000-0xb41fffff 6 LogArea2 0x20000 0xb4200000-0xb421ffff 7 License 0x10000 0xb4220000-0xb422ffff 8 GenFS 0x10000 0xb4230000-0xb423ffff 9 LogArea3 0x20000 0xb4240000-0xb425ffff 10 Reserved 0x10000 0xb4260000-0xb426ffff 11 RamParam 0x10000 0xb4270000-0xb427ffff 12 BootExt 0x30000 0xb4280000-0xb42affff 13 MemMapT 0x1400 0xb42b0000-0xb42b13ff 14 Termcap 0x400 0xb42b1400-0xb42b17ff 15 RomDefa 0x180000 0xb42b1800-0xb44317ff 16 RasCode 0xbce800 0xb4431800-0xb4ffffff 17 RomDir2A 0x120000 0xb50c0000-0xb51dffff 18 BootExtA 0x30000 0xb5280000-0xb52affff 19 MemMapTA 0x1400 0xb52b0000-0xb52b13ff 20 TermcapA 0x400 0xb52b1400-0xb52b17ff 21 RomDefaA 0x180000 0xb52b1800-0xb54317ff 22 RasCodeA 0xbce800 0xb5431800-0xb5ffffff ====================================================== XS1930$ gobootext # starts the second stage ZynOS bootloader
The unlocked U-Boot allows disabling autoboot of the second stage. The flash layout is also found in the memory layout information obtained by the atmp command in the ZynOS bootloader.
The Flash chip can be read out via a SOIC-clamp when the device is off. After splitting the image into the partitions, the ZynOS kernel and all the user-land code sit in
$ hd 16_RasCode.bin|head 00000000 00 00 00 00 00 00 53 49 47 04 01 f0 67 78 00 3c |......SIG...gx.<| 00000010 2d c9 e0 00 6f 84 e8 74 58 53 31 39 33 30 00 00 |-...o..tXS1930..| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 5d 00 00 80 00 78 67 f0 01 00 00 00 00 00 20 02 |]....xg....... .| 00000040 08 61 15 9e dc b2 69 e3 6d 0a d6 19 ab 9f 87 dd |.a....i.m.......| 00000050 60 1f b5 d1 d0 e4 62 e8 0a 8a 8b 58 c4 9d fa 3c |`.....b....X...<| 00000060 e6 b9 60 2b 3a 06 fb a2 98 bd 0d f0 b4 30 46 b8 |..`+:........0F.| 00000070 a9 2c 67 f7 97 9d 56 51 44 f6 e5 c9 df 6c 2f 51 |.,g...VQD....l/Q| 00000080 47 1d 24 9c e7 c8 82 97 9e 3f 9a 6c 6a fc 2f 30 |G.$......?.lj./0| 00000090 a3 2c cb b7 b0 b3 85 1d aa 0b 48 ab 9c 01 cd d3 |.,........H.....| 0a: 01f06778 Length (uncompressed) 0e: 003c2dc9 Length 14: 6f84 Checksum (before uncompression) 18: e874 Other Checksum
You can compare the header informtion in the first 0x30 bytes with the output of ATMP in the ZynOS bootloader to identify some data fields. The image is lzma compressed, but there seem to be some trailer that cannot be decompressed with standard tools, nevertheless the RAM image can be obtained by:
$ dd if=16_RasCode.bin bs=16 skip=3 of=16_RasCode_headerless.bin $ mv 16_RasCode_headerless.bin 16_RasCode_headerless.lzma $ xz -c -d 16_RasCode_headerless.lzma >RasCode_image.bin # ignore errors
You can directly load RasCode_image.bin into a disassembler at memory location 0x80274000 for analysis (see above: 2: RasCode(RAMCODE), start=0x80274000, len=4000000). Add a RAM segment after this: (3: RasData(RAM), start=0x84274000, len=9C8C000).