Add support for Datto L8, E24v3, E48 switches

The Datto (now Kaseya) L8, E24v3, and E48 switches are Realtek gigabit switches with PoE output. They are cloud managed but Datto EOL’d support several years ago and they can be purchased for a reasonable price ($20-$50) used online.

Datto L8 is based on the RTL8380M with 256MB of RAM and 32MB of SPI (SOIC16) flash:

U-Boot 2011.12.48956-1.0.4 (Aug 23 2018 - 16:40:18)

Board: * CPU:500MHz LXB:200MHz MEM:300MHz
DRAM:  256 MB
SPI-F: 1x32 MB
Loading 65536B env. variables from offset 0x80000
Switch Model: RTL8380M_INTPHY_1G_DEMO (Port Count: 10)
Switch Chip: RTL8380M
**************************************************
#### phy config - MAC ID = 8 ####
Now Internal PHY
Net:   Net Initialization Skipped
ethname#0
Enter correct key to stop autoboot:  3

The L8 is powered from an external 54V, 1.2A power supply. 5.5x2.1mm center positive.

The 3.3V UART header is just above the SPI flash in the photo (to the right of the CPU heat sink), pinout (from left→right): GND, Rx, Tx, Vcc (Don’t connect). 115200 baud


Datto E24v3 is based on the RTL8396 with 2 SFP+ ports, 256MB of RAM and 32MB of SPI (SOIC16) flash:

U-Boot 2011.12.48956-1.0.4 (Aug 23 2018 - 15:45:43)

Board: * CPU:700MHz LXB:200MHz MEM:400MHz
DRAM:  256 MB
SPI-F: 1x32 MB
Loading 65536B env. variables from offset 0x80000
chip_index=      24
Switch Model: RTL8396M_DEMO (Port Count: 26)
Switch Chip: RTL8396
Model Info: 83966806
### RTL8218B config - MAC ID = 0 ###
### RTL8218B config - MAC ID = 8 ###
### RTL8218B config - MAC ID = 16 ###
### RTL8295R config - MAC ID = 24 ###
_phy_8295_patch_a_init_rtl8295r            FIXME remove dbg
### RTL8295R config - MAC ID = 36 ###
_phy_8295_patch_a_init_rtl8295r            FIXME remove dbg
PHY[0]: disable EEE
PHY[1]: disable EEE
PHY[2]: disable EEE
PHY[3]: not supported in EEE
PHY[4]: not supported in EEE
Net:   Net Initialization Skipped
ethname#0
Enter correct key to stop autoboot:  3

Console is an RJ-45 port on the front, use a Cisco roll-over cable. 115200 baud


Datto E48 is based on the RTL8393 with 4 SFP ports, 256MB of RAM and 32MB of SPI (SOIC16) flash:

U-Boot 2011.12.48956-1.0.4 (Aug 23 2018 - 17:09:16)

Board: * CPU:700MHz LXB:200MHz MEM:400MHz
DRAM:  256 MB
SPI-F: 1x32 MB
Loading 65536B env. variables from offset 0x80000
Switch Model: RTL8393M_DEMO (Port Count: 52)
Switch Chip: RTL8393M
Model Info: 83936802
### RTL8218B config - MAC ID = 0 ###
### RTL8218B config - MAC ID = 8 ###
### RTL8218B config - MAC ID = 16 ###
### RTL8218B config - MAC ID = 24 ###
### RTL8218B config - MAC ID = 32 ###
### RTL8218B config - MAC ID = 40 ###
### RTL8214FC config - MAC ID = 48 ###
PHY[0]: disable EEE
PHY[1]: disable EEE
PHY[2]: disable EEE
PHY[3]: disable EEE
PHY[4]: disable EEE
PHY[5]: disable EEE
PHY[6]: disable EEE
Net:   Net Initialization Skipped
ethname#0
Enter correct key to stop autoboot:  3

Console is an RJ-45 port on the front, use a Cisco roll-over cable. 115200 baud


U-Boot autoboot speculation

Unfortunately, the key to interrupt auto boot is unknown:

Enter correct key to stop autoboot: 3

I tried to brute force this, but without success. Desoldering flash and setting bootstopkey and bootdelaykey in the environment have no effect, so I think they modified U-Boot on production devices to prevent interrupting the boot and just didn’t remove the delay.

Enter pac to stop the U-Boot autoboot timer. Run rtkon to enable networking and then you can tftpboot. Note that $load_addr is set to some invalid address that causes TFTP timeouts. I have been using 0x81000000

U-Boot enviroment

Change bootcmd=boota to bootcmd=sleep 1 and reflash the U-Boot environment to prevent the switch from auto-booting and drop you to a shell:

mkenvimage -b -s 65536 -o e24v3-env.bin e24v3.txt

Note: flashing in-circuit did not work for me. I have socketed the SOIC16.


I have managed to get the rtl838x/rtl839x targets booting, but a lot doesn’t work (fans, LEDs, SFP, POE). If anyone else owns this hardware and would like to contribute to development, please reply or send me a message :slight_smile:

1 Like

I've never even heard about this manufacturer, but we can surely assist you in getting this supported and in figuring out the proper key.

Could you post the U-Boot dump somewhere so that others can have a look?

There are several approaches how to get this supported. Usually, I do

  • examine the boog log of the OEM firmware if there are any hints
  • check the OEM firmware, if login is possible, for useful programs/hints
  • examine the PCB to figure out if there are GPIO expanders, fan controllers and/or other ICs or MCUs
  • probe the GPIOs, this usually gives you (some) of the LEDs + keys
  • probe the i2c GPIOs on the ICs connected via i2c, if any
  • PoE is in most cases controlled via a MCU connected over serial. You might just run realtek-poe and see if it detects the controller

I've never probed an SFP port, I've seen reports that people use a sacrificed SFP module for that purpose.

Upon closer inspection of the pictures you posted, the Nuvoton MCU (likely for PoE management) is clearly visible and so are some other Realtek ICs that look like RTL8231 GPIO expanders.

Flash layout:

Creating 7 MTD partitions on "Total SPI FLASH":
0x00000000-0x00080000 : "LOADER"
0x00080000-0x00090000 : "BDINFO"
0x00090000-0x000a0000 : "SYSINFO"
0x000a0000-0x004a0000 : "JFFS2 CFG"
0x004a0000-0x005a0000 : "JFFS2 LOG"
0x005a0000-0x012d0000 : "RUNTIME"
0x012d0000-0x02000000 : "RUNTIME2"

They were originally Open Mesh, which was acquired by Datto, which was acquired by Kaseya.


The PSE on the L8 appears to be the Broadcom BCM59121 (extreme lower left). But this does appear to be connected to a Nuvoton M0516LDE. There are also two RTL8231 present on the board (though unrelated to PoE).


The OEM bootlog is very minimalist:

Linux version 2.6.19 (senao@debian) (gcc version 3.4.4 mipssde-6.03.00-20051020) #10 PREEMPT Thu Aug 23 16:40:17 CST 2018
CPU revision is: 00019070
Determined physical RAM map:
 memory: 10000000 @ 00000000 (usable)
User-defined physical RAM map:
 memory: 10000000 @ 00000000 (usable)
Built 1 zonelists.  Total pages: 65024
Kernel command line: console=ttyS0,115200 mem=256M
Primary instruction cache 16kB, physically tagged, 4-way, linesize 16 bytes.
Primary data cache 16kB, 2-way, linesize 16 bytes.
Synthesized TLB refill handler (20 instructions).
Synthesized TLB load handler fastpath (32 instructions).
Synthesized TLB store handler fastpath (32 instructions).
Synthesized TLB modify handler fastpath (31 instructions).
PID hash table entries: 1024 (order: 10, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 251648k/262144k available (2057k kernel code, 10348k reserved, 423k data, 5536k init, 0k highmem)
Mount-cache hash table entries: 512
Checking for 'wait' instruction...  available.
NET: Registered protocol family 16
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 3, 32768 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 8192 bind 4096)
TCP reno registered
squashfs: version 3.3 (2007/10/31) Phillip Lougher
squashfs: LZMA suppport for slax.org by jro
JFFS2 version 2.2. (NAND) (C) 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver $Revision: 1.90 $ 1 ports, IRQ sharing disabled
serial8250: ttyS0 at MMIO 0x0 (irq = 31) is a 16550A
loop: loaded (max 8 devices)

Probe: SPI CS1 Flash Type MX25L25635F
Creating 7 MTD partitions on "Total SPI FLASH":
0x00000000-0x00080000 : "LOADER"
0x00080000-0x00090000 : "BDINFO"
0x00090000-0x000a0000 : "SYSINFO"
0x000a0000-0x004a0000 : "JFFS2 CFG"
0x004a0000-0x005a0000 : "JFFS2 LOG"
0x005a0000-0x012d0000 : "RUNTIME"
0x012d0000-0x02000000 : "RUNTIME2"
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 10
IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
Freeing unused kernel memory: 5536k freed
Mount DEV File System....OK
Mount PROC File System....OK
Mount Main SQFS File System....OK
Mount Module SQFS File System....OK
Mount CFG JFFS2 File System....OK
Mount LOG JFFS2 File System....OK
Init RTCORE Driver Module....OK
Init RTK Driver Module....OK
Init SYS NIC Driver Module....OK
Init RTDRV Driver Module....OK
Init Board Configuration Module....OK
Init KSI Core Driver Module....OK
Init SKI Core Driver Module....OK
Init Board Module....OK
Init VLAN Aware Module....OK
Init Board Vendor Module....OK
Init Switch GVRP Module....OK
Init Switch STP Module....OK
Init Switch LACP Module....OK
Init Switch IGMP/MLD Snooping Module....OK
Init Switch 802.1X Module....OK
Init Switch ISG Module....OK
Init Switch DHCP Module....OK
Init Switch DAI Module....OK
Init Switch Voice VLAN Module....OK
Init Switch LLDP Module....OK
Init Custom Module....OK

====== Defaults Initial [Start] ======
Init Switch Factory Default....OK
Init VLAN Factory Default....OK
Init Mirror Factory Default....OK
Init L2 Factory Default....OK
Init Trunk Factory Default....OK
Init Rate Factory Default....OK
Init QoS Factory Default....OK
Init LACP Factory Default....OK
Init EEE Factory Default....OK
Init 802.1x Factory Default....OK
Init DoS Factory Default....OK
Init IGMP Factory Default....OK
Init MLD Factory Default....OK
Init STP Factory Default....OK
Init LLDP Factory Default....OK
Init System Factory Default....OK
Init SNMP Factory Default....OK
Init Port Factory Default....OK
Init Port Security Factory Default....OK
Init Syslog Factory Default....OK
Init AAA Factory Default....OK
Init Radius Factory Default....OK
Init Custom Factory Default....OK
Init IP Source Guard Factory Default....OK
Init DHCP Snooping Factory Default....OK
Init Dynamic ARP Inspection Factory Default....OK
Init GVRP Factory Default....OK
Init MGMT ACL Factory Default....OK
Init PoE Factory Default....OK
Init RMA Factory Default....OK
Init OM Cloud Factory Default....OK
====== Defaults Initial [Done] ======

====== Initial from startup-config [Start] ======
Initialing.....OK                        
====== Initial from startup-config [Done] ======

====== Post Initial [Start] ======
System Post Initial....OK
Port Post Initial....OK
Custom System Post Initial....OK
====== Post Initial [Done] ======
*Jan 01 2000 08:00:37: %System-5: Logging is enabled 
*Jan 01 2000 08:00:37: %System-5: System Startup! 
Init Cloud....OK
Press any key to continue

If you factory reset the switch, the default credentials (at least for version 1.03.24) are admin / 0p3nm3$h!

There is a cli in the stock firmware:

S8-L# 
  clear             Clear configuration
  clock             Manage the system clock
  configure         Configuration Mode
  copy              Copy from one file to another
  end               End current mode and change to enable mode
  exit              Exit current mode and down to previous mode
  ping              Send ICMP ECHO_REQUEST to network hosts
  reboot            Halt and perform a cold restart
  restore-defaults  Restore to default
  save              Save running configuration to flash
  show              Show running system information
  ssl               Setup SSL host keys
  terminal          Terminal configuration
  traceroute        Trace route to network hosts
S8-L#

Unpacking the Datto firmware (obtain from here), there are hidden commands in libcustom.so.0 starting with mphidden:

mphiddenpoe poe power-budget <1-999>
mphiddenmac A:B:C:D:E:F
mphiddensn WORD
mphiddenled sys (on|off)
mphiddenforcelink speed (10|100|1000)
mphiddenled port (green|amber|off|auto|linkAct|linkSpeed)
mphiddenbtnfunc rst (on|off)
mphiddenbtn rst status
mphiddensfp show sfp

omcloud debug will also print out the (extremely verbose) configuration that it tries to upload to the cloud: https://cloud-switch.cloudtrax.com/cloud-switch/00:11:22:33:44:55/checkin

The switch also appears to have a local web management UI, although there is nothing really interesting there. You can do some basic port management, as well as upload a firmware update. Note that I configured the IP address via the cli first configip address 192.168.1.100

Have a look at the function abortboot in common/main.c in the U-Boot source. It looks like you need to enter the keys "a", "p", "c" (in any order).

4 Likes

Great find! I can confirm it works on all three devices :sign_of_the_horns:

It also looks like Datto have modified the image header magic of the U-Boot legacy image:

$ hexdump -C oms48_fw_01.03.24_180823-1708.bix | head -10
00000000  00 70 22 01 8d 4b 68 a6  5b 7e ea 75 00 64 f6 78  |.p"..Kh.[~.u.d.x|
00000010  80 00 00 00 80 26 d0 00  91 f9 26 e3 05 05 02 01  |.....&....&.....|
00000020  49 4d 47 2d 30 31 2e 30  33 2e 32 34 00 00 00 00  |IMG-01.03.24....|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  1f 8b 08 08 f4 79 7e 5b  02 03 76 6d 6c 69 6e 75  |.....y~[..vmlinu|
00000050  78 5f 6f 72 67 2e 62 69  6e 00 ec 5b 0f 70 1c e5  |x_org.bin..[.p..|

The typical IH_MAGIC is 0x27051956, but I am not finding 0x00702201 in the U-Boot source provided by Kaseya.

All this reminds me of https://openwrt.org/toh/linksys/lgs352c

2 Likes

This is interesting, as I hadn't seen any RTL8396 devices up to now. @plappermaul would the current drivers support 10G on these SoCs?

The show command may be able to give you info on the GPIOs. Note that this hasn't always been correct/complete, but at the very least it should be a good starting point.

I do not know if U-Boot does initialization for us on these devices. But basically we need:

  • Port 24 / SerDes 8
  • Port 36 / SerDes 12
  • SerDes setup in the new PCS driver like this
  • 1G/10G mode switching during module insertion in the new PCS driver like this

I have just purchased a Datto E24v3 on eBay and will be able to assist with development and testing once it arrives :slightly_smiling_face:

It seems like the switch chip is RTL8396M-VC-CG based on the configuration and capabilities.

1 Like

For the copper ports yes, for the SFP+ ports it does not seem to. I put in a 1Gbit copper interface and running rtkon in U-Boot did not result in any link lights or connectivity.

I have just pushed my WIP to this branch: https://github.com/halmartin/openwrt/tree/rtl83xx-datto

Summary:

  • Copper ports work
  • SFP/SFP+ ports do not work
  • POE does not work
  • Fans do not work (Do not run the E24v3/E48 without any active cooling!!)
  • LEDs/Buttons do not work

I’ve got an L24 and have already emailed Datto asking for the GPL sources. Not expecting much however…

It looks to be pretty much the same as the E24, but SFP non-plus, none of the chips have heat sinks, and it’s missing the top right chip.

  • RTL8382M Main chip
  • Nanya NT5CC256M8IN-D1 256MiB SDRAM
  • MXIC MXL24L25635FMI-10G 32MiB Flash
  • 2x RTL8218B Ethernet transceivers
  • 2x RTL8231 LED controller
  • STM32F100C8T68 on PoE board
  • 6x (?) BCM59111KMLG 4 channel PoE controller

This is in the u-boot envs: boardmodel=RTL8382M_8218B_INTPHY_8218B_2FIB_1G_DEMO googling that gets this post which seems to have that exact board: Support for RTL838x based managed switches - #445 by johnd2

I didn’t have any success getting a root prompt yet, init=/bin/sh didn’t seem to cut it.

I already have some incomplete GPL sources from Datto, and it includes the relevant file for your switch:

$ ls -l board/Realtek/switch/rtk/conf/rtl8382m_8218b_intphy_8218b_2fib_1g_demo_board.c 
-rwxr-xr-x 1 hmartin hmartin 3486 Sep  5 04:21 board/Realtek/switch/rtk/conf/rtl8382m_8218b_intphy_8218b_2fib_1g_demo_board.c

I have already shared this GPL archive with @svanheule who can hopefully add it to the wiki. I will also send you a link to the archive in a private message.

Regarding the root shell, you need rdinit=/bin/sh but it dumps you to the shell so early in boot, you don’t even have /sys, /proc, /dev created, etc. I have notes somewhere to create these filesystems but I don’t think it works for a 2.6 kernel…

1 Like

Done! See the GPL archive page.

4 Likes

Regarding the root shell, you need rdinit=/bin/sh

Weirdly that doesn’t work for me:

Even setting “mem=64M” seems to be picked up in the log but then ignored:
Memory: 251648k/262144k available (2057k kernel code, 10352k reserved, 423k data, 5540k init, 0k highmem)

Don’t quote bootargs:

switch# # sf probe 0;sf read $(freemem) $(flashoffset_linux) $(ssize_linux)
switch# # setenv bootargs console=ttyS0,115200 mem=256M rdinit=/bin/sh
switch# # bootm $(freemem)
## Booting kernel from Legacy Image at 81000000 ...
   Image Name:   IMG-01.03.24
   Created:      2018-08-23  15:46:08 UTC
   Image Type:   MIPS Linux Kernel Image (gzip compressed)
   Data Size:    6810916 Bytes = 6.5 MB
   Load Address: 80000000
   Entry Point:  8026d000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

Linux version 2.6.19 (senao@debian) (gcc version 3.4.4 mipssde-6.03.00-20051020) #24 PREEMPT Thu Aug 23 15:45:41 CST 2018
CPU revision is: 00019555
Determined physical RAM map:
 memory: 10000000 @ 00000000 (usable)
User-defined physical RAM map:
 memory: 10000000 @ 00000000 (usable)
Built 1 zonelists.  Total pages: 65024
Kernel command line: console=ttyS0,115200 mem=256M rdinit=/bin/sh 
Primary instruction cache 32kB, physically tagged, 4-way, linesize 32 bytes.
Primary data cache 32kB, 4-way, linesize 32 bytes.
Synthesized TLB refill handler (20 instructions).
Synthesized TLB load handler fastpath (32 instructions).
Synthesized TLB store handler fastpath (32 instructions).
Synthesized TLB modify handler fastpath (31 instructions).
Cache parity protection disabled
PID hash table entries: 1024 (order: 10, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 251520k/262144k available (2057k kernel code, 10544k reserved, 423k data, 5732k init, 0k highmem)
Mount-cache hash table entries: 512
Checking for 'wait' instruction...  available.
NET: Registered protocol family 16
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 3, 32768 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 8192 bind 4096)
TCP reno registered
squashfs: version 3.3 (2007/10/31) Phillip Lougher
squashfs: LZMA suppport for slax.org by jro
JFFS2 version 2.2. (NAND) (C) 2001-2006 Red Hat, Inc.
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver $Revision: 1.90 $ 1 ports, IRQ sharing disabled
serial8250: ttyS0 at MMIO 0x0 (irq = 31) is a 16550A
loop: loaded (max 8 devices)
Probe: SPI CS1 Flash Type MX25L25635F
Creating 7 MTD partitions on "Total SPI FLASH":
0x00000000-0x00080000 : "LOADER"
0x00080000-0x00090000 : "BDINFO"
0x00090000-0x000a0000 : "SYSINFO"
0x000a0000-0x004a0000 : "JFFS2 CFG"
0x004a0000-0x005a0000 : "JFFS2 LOG"
0x005a0000-0x012d0000 : "RUNTIME"
0x012d0000-0x02000000 : "RUNTIME2"
TCP cubic registered
NET: Registered protocol family 1
NET: Registered protocol family 10
IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
Freeing unused kernel memory: 5732k freed
#

I’ve recently acquired a Datto L8 and an Open Mesh OM S8 which appears to be what was later called the Datto E8 according to the Datto page Switches: Manually flashing the firmware on your Datto Switch. I’ve added an entry for the OM S8 Switch on https://svanheule.net/switches/om_s8.

1 Like