Support for RTL838x based managed switches

I'm trying to add support for the Netgear GS308T which is similar to the GS108Tv3 but without the PD port. The firmware uses a different UIMAGE_MAGIC, but otherwise essentially no changes from the GS108Tv3. I can successfully upload OpenWrt firmware from the stock web interface and boot into OpenWrt. As far as I can tell everything appears to function properly with the uploaded initramfs kernel. I then scp the sysupgrade file to the device. I then run sysupgrade without keeping the config. The result is that after the system reboots it successfully reloads the OpenWrt firmware and gets to this point:

[    5.252514] rtl83xx-switch switch@bb000000: Link is Up - 1Gbps/Full - flow co
ntrol off
[    5.262180] /dev/root: Can't open blockdev
[    5.266896] VFS: Cannot open root device "(null)" or unknown-block(0,0): erro
r -6
[    5.275333] Please append a correct "root=" boot option; here are the availab
le partitions:
[    5.284764] 0100            4096 ram0 
[    5.284774]  (driver?)
[    5.291682] 0101            4096 ram1 
[    5.291690]  (driver?)
[    5.298660] 0102            4096 ram2 
[    5.298669]  (driver?)
[    5.305634] 0103            4096 ram3 
[    5.305642]  (driver?)
[    5.312613] 0104            4096 ram4 
[    5.312622]  (driver?)
[    5.319525] 0105            4096 ram5 
[    5.319533]  (driver?)
[    5.326442] 0106            4096 ram6 
[    5.326450]  (driver?)
[    5.333415] 0107            4096 ram7 
[    5.333424]  (driver?)
[    5.340394] 0108            4096 ram8 
[    5.340402]  (driver?)
[    5.347306] 0109            4096 ram9 
[    5.347314]  (driver?)
[    5.354280] 010a            4096 ram10 
[    5.354289]  (driver?)
[    5.361356] 010b            4096 ram11 
[    5.361365]  (driver?)
[    5.368432] 010c            4096 ram12 
[    5.368441]  (driver?)
[    5.375440] 010d            4096 ram13 
[    5.375449]  (driver?)
[    5.382454] 010e            4096 ram14 
[    5.382462]  (driver?)
[    5.389524] 010f            4096 ram15 
[    5.389533]  (driver?)
[    5.396601] 1f00             896 mtdblock0 
[    5.396609]  (driver?)
[    5.404064] 1f01              64 mtdblock1 
[    5.404072]  (driver?)
[    5.411468] 1f02              64 mtdblock2 
[    5.411476]  (driver?)
[    5.418869] 1f03            1024 mtdblock3 
[    5.418877]  (driver?)
[    5.426339] 1f04            1024 mtdblock4 
[    5.426348]  (driver?)
[    5.433809] 1f05           14848 mtdblock5 
[    5.433817]  (driver?)
[    5.441279] 1f06           14848 mtdblock6 
[    5.441287]  (driver?)
[    5.448736] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[    5.457973] Rebooting in 1 seconds..
[    6.457341] System restart.

Any clues to what might be the cause?

1 Like

Looking at adding support for the Netgear GS310TP and have a couple of questions. What is the preferred way to define the SFP ports in the DTS? In the D-Link DGS-1210-10P I see SWITCH_SFP_PORT used, but this appears to be the only place it is used. The Netgear GS110TPP which has some similarity to the GS310TP doesn't even have the SFP ports defined!

Are you sure that you installed to the correct firmware slot (mtd5 (no idea how Netgear calls this in their GUI) and selected it for booting (setsys bootpartition 0, respectively from the Netgear GUI).

I would expect that the initramfs image will boot from the wrong slot (1), but the sysupgrade code will probably only write at the intended one (0).

You can only upload OpenWrt initramfs images in the stock web UI.

Unfortunately, the Netgear UI accepts any image with an U-Boot image header and correct magic. But it silently drops data following the U-Boot image. So it will write the kernel but not the rootfs if you try to upload a sysupgrade image, resulting in missing rootfs errors.

The ZyXEL GS1900-10HP behaves in pretty much the same way, so I assume this could be a generic Realtek SDK issue. ZyXEL has added their own validation code to the web UI, though, requiring a list of model identifiers inside (at the end of) the U-Boot image. So we can use that to create valid initramfs images, but drop it on any other image. This will prevent the problem by making the stock web UI refuse sysugrade images. Their U-Boot only validates the header, so it will still accept kernels without the ZyXEL model identifiers (in fact, they have also disabled the magic validation in U-Boot)

I don't know how to do something similar on Netgear. So we will probably have to put big warnings in the docs.

EDIT: Just to make it clear: You can still upgrade to a real image with rootfs using the stock web UI. You just need to flash the initramfs from stock first, and then sysupgrade after booting OpenWrt from the ramfs


Do you have any idea why the console output is that sparse (just the bootutil, two info lines and login promp)? Is this expected on this kind of devices?

Can this be caused by a uboot build disabling all detail output or do you think there is another UART on the board where a typical bootlog can be captured?

Hi there,
i have DGS-1210-28 F2 switch and i have installed OpenWRT snapshot sysupgradeimage on it.
So i have tried switch from luci with default switch configuration. All ports(1-28) attached untagged to VLAN1 So when i plug wan cable for example port27 and lan cable to port26 switch gains IP from Firewall and access internet but PC connected to port26 gains no IP no internet. What can be the problem?
any help would be appreciated.

cat /etc/config/network

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr ''
	option netmask ''

config globals 'globals'
	option ula_prefix 'fd72:41ee:6d64::/48'

config device 'switch'
	option name 'switch'
	option type 'bridge'
	option macaddr 'a0:a3:f0:28:67:b0'

config bridge-vlan 'wan_vlan'
	option device 'switch'
	option vlan '1'
	option ports ' lan1 lan10 lan11 lan12 lan13 lan14 lan15 lan16 lan17 lan18 lan19 lan2 lan20 lan21 lan22 lan23 lan24 lan25 lan26 lan27 lan28 lan3 lan4 lan5 lan6 lan7 lan8 lan9'

config interface 'wan'
	option ifname 'switch.1'
	option proto 'dhcp'

config device 'wan_switch_1_dev'
	option name 'switch.1'
	option macaddr 'a0:a3:f0:28:67:b0'

config interface 'wan6'
	option ifname 'switch.1'
	option proto 'dhcpv6'

config bridge-vlan 'lan_vlan'
	option device 'switch'
	option vlan '100'
	option ports 'lan1:t'

config interface 'lan'
	option ifname 'switch.100'
	option proto 'static'
	option ipaddr ''
	option netmask ''
	option ip6assign '60'

config device 'lan_switch_100_dev'
	option name 'switch.100'
	option macaddr 'a2:a3:f0:28:67:b0'

Yes, it's a customisation TP-Link does to uboot. Someone even obtained the GPL source for it: (stupid forum insists on Github previews, remove "" from "ht*tps")

Edit: Relevant by @kobi earlier in this thread: Support for RTL838x based managed switches - #73 by kobi

1 Like

Awesome, thank you so much for pointing me to the post from @kobi. I must have glanced over it.

I'll try to get a full uboot build going for the T1600G-28TS also. I should also have a way to backup and reprogram the flash directly. You think that it can be programmed in-circuit, or will the SoC try to power up and mess with the flash?

Seems very similar to the way the T1600G-52PS behaved (I can't work on it any longer, sorry).
It was very easy to compile U-Boot and flash it via an SOIC-16 clip. Just make sure to not power the board while flashing the IC. I got the basics working, but failed to set some important GPIOs that control fan speed. Also, I never figured out how to configure the PoE chips via i2c.
Most of the things I learned, including GPIO mapping, can be found on the Wiki:

I also did a dump of the flash and had a look at some of the TP-Link binaries using Ghidra. Some, if not all, GPIOs were hardcoded in one of the binaries.

Yes, the T1600G-28TS is basically a slimmed down version of the T1600G-52PS with lower port count, no PoE and no fans.

Still hitting some roadblocks building the uboot with merged T2500G-10TS GPL source code like @kobi described here for a fully fledged uboot. The T2500G-10TS sources are ldk_realtek/realtek_v2.1.4 and the T1600G-28TS sources are already ldk_realtek/realtek-V2.1.6.pre2. Getting some undefined references which probably need some additional fixes. Edit: Got a successful build, just missed a UBOOT_DEBUG define.

I only have a SOIC-8 clip which doesn't reach all required pins at once on a SOIC-16. Tomorrow I'll solder some enameled copper wire from the flash pins to a pin socket and try to dump it. Edit: and try to flash the new uboot.

I'm sure I have the correct firmware slot on initial install with the initramfs image. I can reboot multiple times successfully. I can also manipulate the bootpartition and reboot into the stock web ui where I can view the Dual Image Status and see the following:

|MIPS OpenWrt Linux-5.4.109||image2|image2|

I can then change the bootpartition again and boot into OpenWrt. The problem only occurs when within OpenWrt I run the command "sysupgrade -v -i openwrt-realtek-generic-netgear_gs308t-v1-squashfs-sysupgrade.bin". Which results in:

Sun Apr 11 07:58:00 UTC 2021 upgrade: Commencing upgrade. Closing all shell sessions.
killall: telnetd: no process killed
Sun Apr 11 07:58:01 UTC 2021 upgrade: Sending TERM to remaining processes ... ubusd urngd uhttpd logd rpcd netifd odhcpd ntpd dnsmasq
Sun Apr 11 07:58:04 UTC 2021 upgrade: Sending KILL to remaining processes ...
[  901.285944] sh (3688): drop_caches: 3
Sun Apr 11 07:58:05 UTC 2021 upgrade: Switching to ramdisk...
Sun Apr 11 07:58:10 UTC 2021 upgrade: Performing system upgrade...
[  905.907827] sh (3688): drop_caches: 3
Unlocking firmware ...

Writing from <stdin> to firmware ...     
Sun Apr 11 07:58:31 UTC 2021 upgrade: Upgrade completed
Sun Apr 11 07:58:32 UTC 2021 

Followed by the switch re-booting and then resulting in the above "Unable to mount root fs" and then restarting again. I have the complete bootlog I'm only posting the section near the end where the failure occurs. If there is something else from the bootlog that might be important I can provide the full bootlog.

This is exactly what I did. I installed via the stock web ui using the initramfs image and then ran sysupgrade after booting OpenWrt. The issue only occurs after running the sysupgrade from within OpenWrt ramfs image. I originally built my images with Luci enabled. I rebuilt using default configuration and I get the same results.

Did you adjust openwrt,ih-magic property in the dts for your device?


Thank you for the hint! I used the existing rtl8380_netgear_gigabit.dtsi file which sets this and did not notice that this would need to change! So apparently the flash config will need to be moved from the dtsi file into the individual dts files as it will be different on the GS308T and GS310TP than what the GS108TV3 and GS110TPP use!

1 Like

Right. Sorry for not thinking about that problem, being the one who introduced it....

It's a bit inconvenient that this magic has to be updated in two completely different places. Obviously only a developer problem, but still. Maybe we should let the image creation code pull the value from the DTS? Or maybe we could let the image makefile generate a header include for the DTS? Hmm, don't think I like that last idea.

1 Like

What programmer did you use? I just noticed that my MiniPro hardware revision can only read up to 128M flashes. Next I tried my old BeagleBone (since it already has 3V3 level GPIOs) in combination with flashrom v1.2 using the GD25Q256D preset although it's a GD25Q256C but I get no data back.

root@beaglebone:/home/debian/flashrom-v1.2# ./flashrom -p linux_spi:dev=/dev/spidev0.0 -r dumpfile.bin --chip GD25Q256D
flashrom v1.2 on Linux 4.19.94-ti-r42 (armv7l)
flashrom is free software, get the source code at

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
Using default 2000kHz clock. Use 'spispeed' parameter to override.
No EEPROM/flash device found.
Note: flashrom can never write if the flash chip isn't found automatically.

Also tried differend speeds. I hooked up:

Beaglebone        < --- > SPI Flash
P9_17 (SPI0_CS0)  < --- > Pin7  (#CS)
P9_18 (SPIO_D1)   < --- > Pin15 (SI)
P9_21 (SPIO_D0)   < --- > Pin8  (SO)
P9_22 (SPIO_SCLK) < --- > Pin16 (SCLK)
P9_1  (DGND)      < --- > Pin10 (VSS)
P9_3  (VDD_3V3)   < --- > Pin2  (VCC)

I used a cheap and slightly modified (for safe 3.3V operations) CH341A-based programmer along with an SOIC16 clip and flashrom.

Did you try to lower the SPI speed?

I simply cannot find my modded CH341A. I can go as low as about 2kHz clock. I'm not sure if it is a flashrom issue since when I use 2kHz clock it sends 0x3F 0x00 and with 20kHz clock I get 0x3F 0x00 0x00 0x00 on the trace.

Edit: My protocol deocder latched data at the falling edge, flashrom correctly sends data expected to be latched at raising edge which is also specified in the datasheet for this flash. Now transmission makes sense: 0x9F (Read Identification (RDID) (9FH) 8-bit manufacturer identification, followed by two
bytes of device identification)
those 3 bytes are expected and MOSI goes low but MISO stays high the entire time resulting in a readback of 0xFF 0xFF 0xFF which understandably makes flashrom unhappy.

Edit2: Tried dumping with my MiniPro in forced GD25Q128C mode (since it does not support 32MB variants) to at least get the first 16MB and confirm my hookup is correct. It almost worked. Noticed some missing data chunks which I could quickly determine to be caused by a mid rail floating reset line I left not connected. After pulling it high read was successful.

On the captured traces I noticed something interesting. The MiniPro seems to pulldown MOSI default low and let MISO float highZ. The BeagleBone on the other hand pulls both MOSI and MISO default high. The pullup on MOSI should not matter much but maybe the flash does not want do drive its SO if it is pulled high.

I was not able to supply 3V3 from the MiniPro programmer since its overcurrent protection is too tight not wanting to power up the whole 3V3 rail on the switch.

Edit 3: It was a power supply issue all the time. After I switched to external power due to the overcurrent protection on the MiniPro also flashrom via the BeagleBone is now able to read the flash in its full capacity. Finally!

I've modified the DTS file now to fix the magic required by the firmware partition and everything is now working on the GS308T. I'd appreciate if you could review the changes on my GitHub @ Branch for the changes is realtek-netgear. I'm now working on adding GS310TP before I do a merge request.

1 Like

Got the full u-boot flashed and running not sure about tftpboot though.

After exiting the u-boot menu and activating network

RTL838x# # rtk network on
Enable network
Force port28 link up 1G
Please wait for PHY init-time ...

shouldn't I be able to ping my tftp server (default at But I have no link up on any of the 24 ethernet ports and port28 is one of the SFP ports?