Yes they both use the exact same firmware. The only difference is in the DTS, where the Ethernet and switch parameters would need to be updated to support SFP+. Since I don't have one on hand I'll leave that to someone else
Alright, I thought I was done and wouldn’t need help anymore… but here I am again.
This time, the issue is with booting the image.
As a starting point I tried the following conf
define Build/append-xikestor-8t-header
$(STAGING_DIR_HOST)/bin/xikestor-8t-header -a 0x80000000 -e 0x80387400 -c lzma -i $@ -o $@.new
mv $@.new $@
endef
define Device/xikestor_sks8300-8t
SOC := rtl9303
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-8T
IMAGE_SIZE := 13312k
KERNEL_INITRAMFS := \
kernel-bin | \
append-dtb | \
lzma | \
uImage lzma | \
append-xikestor-8t-header
endef
TARGET_DEVICES += xikestor_sks8300-8t
But when I try to boot it, I get the following error
QRTL9300# # upgrade runtime openwrt-realtek-rtl930x-xikestor_sks8300-8t-initramfs-kernel.bin
...
## Booting image from partition ... 0
## Booting kernel from Legacy Image at 81000000 ...
Image Name: OpenWrt
Created: 2025-08-03 7:08:13 UTC
Image Type: MIPS Linux Kernel Image (lzma compressed)
Data Size: 4854429 Bytes = 4.6 MB
Load Address: 80000000
Entry Point: 80387400
Verifying Checksum ... OK
Uncompressing Kernel Image ... LZMA: uncompress or overwrite error 1 - must RESET board to recover
Then I tried this slightly different recipe (removed uImage lzma):
define Build/append-xikestor-8t-header
$(STAGING_DIR_HOST)/bin/xikestor-8t-header -a 0x80000000 -e 0x80387400 -c lzma -i $@ -o $@.new
mv $@.new $@
endef
define Device/xikestor_sks8300-8t
SOC := rtl9303
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-8T
IMAGE_SIZE := 13312k
KERNEL_INITRAMFS := \
kernel-bin | \
append-dtb | \
lzma | \
append-xikestor-8t-header
endef
TARGET_DEVICES += xikestor_sks8300-8t
And this time decompression succeeds but it just gets stuck at "Starting kernel ..."
QRTL9300# # upgrade runtime openwrt-realtek-rtl930x-xikestor_sks8300-8t-initramfs-kernel.bin
...
## Booting image from partition ... 0
## Booting kernel from Legacy Image at 81000000 ...
Image Name: OpenWrt
Created: 2025-08-03 7:23:32 UTC
Image Type: MIPS Linux Kernel Image (lzma compressed)
Data Size: 4854202 Bytes = 4.6 MB
Load Address: 80000000
Entry Point: 80387400
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Starting kernel ...
I've tried many other variations of the build recipe but all of them fail. Either with an LZMA uncompress/overwrite error or by hanging at "Starting kernel".
I also checked the stock firmware update procedure and tried to follow the same architecture layer-by-layer (LZMA->GZIP->CPIO->FILESYSTEME) but it still hangs on boot.
Here's the current DTS file I'm using
// SPDX-License-Identifier: GPL-2.0-or-later
#include "rtl930x.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
/ {
compatible = "xikestor,sks8300-8t", "realtek,rtl930x-soc";
model = "XikeStor SKS8300-8T";
chosen {
stdout-path = "serial0:115200n8";
};
i2c_master: i2c@1b00036c {
compatible = "realtek,rtl9300-i2c";
reg = <0x1b00036c 0x3c>;
#address-cells = <1>;
#size-cells = <0>;
scl-pin = <8>;
sda-pin = <9>;
clock-frequency = <100000>;
temp_sensor: temp-sensor@48 {
compatible = "national,lm75";
reg = <0x48>;
};
};
keys {
compatible = "gpio-keys";
button-reset {
label = "reset";
gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
led_set {
compatible = "realtek,rtl9300-leds";
active-low;
/*
* LED set 0
*
* - LED[0](Green): 10G/LINK/ACT
* - LED[1](Amber): 10M/100M/1G/2.5G/5G/LINK/ACT
*/
led_set0 = <0x0baa 0x0a01>;
};
};
&mdio_aux {
status = "okay";
gpio1: gpio@0 {
compatible = "realtek,rtl8231";
reg = <0>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&gpio1 0 0 37>;
status = "okay";
led-controller {
compatible = "realtek,rtl8231-leds";
status = "disabled";
};
};
};
&spi0 {
status = "okay";
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <10000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "u-boot";
reg = <0x00000000 0x001c0000>;
read-only;
};
partition@1c0000 {
label = "board-info";
reg = <0x001c0000 0x00010000>;
read-only;
};
partition@1d0000 {
label = "syslog";
reg = <0x001d0000 0x00010000>;
read-only;
};
partition@1e0000 {
label = "factorydata";
reg = <0x001e0000 0x00010000>;
read-only;
};
partition@1f0000 {
label = "sysdata";
reg = <0x001f0000 0x00010000>;
read-only;
};
partition@200000 {
label = "filesystem";
reg = <0x00200000 0x00a00000>;
read-only;
};
partition@c00000 {
compatible = "openwrt,uimage", "denx,uimage";
label = "firmware";
reg = <0x00c00000 0x01400000> ;
openwrt,ih-magic = <0x93000000>;
};
};
};
};
ðernet0 {
mdio: mdio-bus {
compatible = "realtek,rtl838x-mdio";
regmap = <ðernet0>;
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <0>;
sds = <2>;
rtl9300,smi-address = <0 0>;
};
phy8: ethernet-phy@8 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <8>;
sds = <3>;
rtl9300,smi-address = <0 1>;
};
phy16: ethernet-phy@16 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <16>;
sds = <4>;
rtl9300,smi-address = <0 2>;
};
phy20: ethernet-phy@20 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <20>;
sds = <5>;
rtl9300,smi-address = <0 3>;
};
phy24: ethernet-phy@24 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <24>;
sds = <6>;
rtl9300,smi-address = <1 0>;
};
phy25: ethernet-phy@25 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <25>;
sds = <7>;
rtl9300,smi-address = <1 1>;
};
phy26: ethernet-phy@26 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <26>;
sds = <8>;
rtl9300,smi-address = <1 2>;
};
phy27: ethernet-phy@27 {
compatible = "ethernet-phy-ieee802.3-c45";
reg = <27>;
sds = <9>;
rtl9300,smi-address = <1 3>;
};
};
};
&switch0 {
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan1";
phy-handle = <&phy0>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@8 {
reg = <8>;
label = "lan2";
phy-handle = <&phy8>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@16 {
reg = <16>;
label = "lan3";
phy-handle = <&phy16>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@20 {
reg = <20>;
label = "lan4";
phy-handle = <&phy20>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@24 {
reg = <24>;
label = "lan5";
phy-handle = <&phy24>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@25 {
reg = <25>;
label = "lan6";
phy-handle = <&phy25>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@26 {
reg = <26>;
label = "lan7";
phy-handle = <&phy26>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@27 {
reg = <27>;
label = "lan8";
phy-handle = <&phy27>;
phy-mode = "usxgmii";
led-set = <0>;
};
port@28 {
ethernet = <ðernet0>;
reg = <28>;
phy-mode = "internal";
fixed-link {
speed = <10000>;
full-duplex;
};
};
};
};
If you have any suggestions or spot something obviously wrong in the image definition or DTS, I'd again really appreciate the help
This will result in two uimage headers if I read your code correctly. I believe it would be better to keep this recipe and remove all the uimage header generation from your xikestor-8t specific tool. That will clearly document the findings in this thread, showing that the image is a pretty standard RTK_SDK uimage with a device specifc 16 byte header prepended
I assume your entry point is wrong. This should be fixed automatically if you simply reuse the uImage lzma
recipe as suggested.
Note that you need to set
UIMAGE_MAGIC := 0x93000000
to get the header magic right, as @plappermaul said
Well if I use the recipe you recommended to me it results in a "Bad Header Checksum" error.
define Device/xikestor_sks8300-8t
SOC := rtl9303
UIMAGE_MAGIC := 0x93000000
DEVICE_VENDOR := XikeStor
DEVICE_MODEL := SKS8300-8T
IMAGE_SIZE := 13312k
KERNEL_INITRAMFS := \
kernel-bin | \
append-dtb | \
lzma | \
uImage lzma
endef
TARGET_DEVICES += xikestor_sks8300-8t
TFTP from server 10.42.0.1; our IP address is 10.42.0.2
Filename 'openwrt-realtek-rtl930x-xikestor_sks8300-8t-initramfs-kernel.bin'.
Load address: 0x81000000
Loading: T #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
######
done
Bytes transferred = 4853939 (4a10b3 hex)
Bad Header Checksum
RTL9300# # upgrade runtime openwrt-realtek-rtl930x-xikestor_sks8300-8t-squashfs-sysupgrade.bin
Upgrade runtime image [openwrt-realtek-rtl930x-xikestor_sks8300-8t-squashfs-sysupgrade.bin]......
Enable network
Please wait for PHY init-time ...
Using rtl9300#0 device
TFTP from server 10.42.0.1; our IP address is 10.42.0.2
Filename 'openwrt-realtek-rtl930x-xikestor_sks8300-8t-squashfs-sysupgrade.bin'.
Load address: 0x81000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#######################################
done
Bytes transferred = 6291741 (60011d hex)
Bad Header Checksum
Am I missing something?
Based on the vendor's stock firmware the image follows this structure: HEADER + LZMA → GZIP → CPIO → FILE_SYSTEM.
So I assumed that if I placed everything inside a compressed LZMA file, I would just need to append the correct header to bypass the U-Boot checksum validation.
After that I expected U-Boot to decompress the LZMA layer and proceed to access the rest of the image.
The recommended recipe was
kernel-bin | append-dtb | lzma | uImage lzma | vendor-stuff-here
You do obviously still need some "vendor-stuff-here" rule, aka "append-xikestor-8t-header"
What I suggested was to simplify your tool by adapting it to that rule, creating only the first 16 bytes of the image. Those are what's unique here. The rest of the header is added by "uImage lzma". There is no need to reinvent that part.
Note that you might want to mmap the files instead of mallocing big buffers.
Makes more sense indeed... Thanks for pointing me toward the simpler approach.
This has been a great learning experience
@plappermaul - I'll submit a PR soon to add support for this device.
Thanks again!
Now I'm facing an issue with the network not coming up properly depending on how U-Boot boots.
When I manually interrupt U-Boot and run the following:
rtk network on
boota
OpenWrt boots normally and the network is working fine.
But if I set this as the bootcmd like so:
setenv bootcmd 'rtk network on ; boota'
saveenv
Then reboot, OpenWrt still boots but I do not get any network connectivity.
To help debug, I dumped the memory around 0xbb000000
and I ran this after on boot with no network and then again after rtk network on
@svanheule if I can get your light on this please!
rtk network on usually produces at least minimal output. if bootcmd really works it should be the same for both cases (auto & manual). Are you sure that your UBoot really evaluates bootcmd?
Yes bootcmd
is definitely being executed, I've verified it by inserting sleep
and some other commands and they behave as expected.
But there's a clear behavioral difference between auto and manual boot and that's where the problem seems to be...
In manual mode, when I interrupt autoboot and run rtk network on -> boota
manually, everything works and the network initializes correctly inside the image. But in auto mode (using bootcmd='rtk network on; boota'
), the rtk network on still runs (but seems already been initialized) and the network is not working once the openwrt booted.
A concrete difference I observed is in manual mode the fan does not start but in auto mode the fan does start. So I guess that some additional initialization happens during the automatic boot flow and I suspect it's related to the r9300_i2c_init()
function or some other early init hook.
Manual boot (working network):
U-Boot 2011.12.(3.6.11.55242) (Jan 06 2025 - 14:39:46)
Board: RTL9300 CPU:800MHz LX:175MHz DDR:400MHz
DRAM: 512 MB
SPI-F: MXIC/C22019/MMIO32-4/ModeC 1x32 MB (plr_flash_info @ 83fc14a4)
Loading(93) 65536B env. variables from offset 0x1c0000
boardId_init
Net: Net Initialization Skipped
No ethernet found.
Press A to stop autoboot: -1
RTL9300# # rtk network on
Enable network
RTCORE Driver Module Initialize
IOAL init
Hardware-profile probe (RTL9303_8X8261BE_V1)
Hardware-profile init
GPIO probe (unit 0): (found)
GPIO Init
SPI init (unit 0)
I2C probe (unit 0)
I2C init (unit 0)
RTL8231 probe (unit 0): (found)
RTL8231 init (unit 0)
NIC probe (unit 0)
Loader RTNIC Driver Module Initialize
IOAL init
RTK Driver Module Initialize
MAC probe (unit 0)
Chip 9303 (found)
MAC init (unit 0)
SMI protocol probe (unit 0)
PHY probe (unit 0)
Chip Construct (unit 0)
Chip Construct
Disable PHY Polling
PHY Reset
MAC Construct
Turn Off Serdes
Serdes Construct
PHY Construct
Turn On Serdes
Mac_Polling_PHY Config
Enable PHY Polling
Misc
PHY init (unit 0)
Mgmt_dev init (unit 0)
Please wait for PHY init-time ...
RTL9300# # boota
## Booting image from partition ... 0
## Booting kernel from Legacy Image at 81000000 ...
Image Name: MIPS OpenWrt Linux-6.12.40
Created: 2025-08-03 19:55:12 UTC
Image Type: MIPS Linux Kernel Image (lzma compressed)
Data Size: 4851697 Bytes = 4.6 MB
Load Address: 80100000
Entry Point: 80100000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Starting kernel ...
[ 0.000000] Linux version 6.12.40 (nero@unknown) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 14.3.0 r30667-7d570a489b) 14.3.5
[ 0.000000] RTL838X model is 0
[ 0.000000] RTL839X model is 0
[ 0.000000] RTL93XX model is 93030001
[ 0.000000] SoC Type: RTL9303
...
Auto boot whith bootcmd 'rtk network on; boota'
(network broken):
Board: RTL9300 CPU:800MHz LX:175MHz DDR:400MHz
DRAM: 512 MB
SPI-F: MXIC/C22019/MMIO32-4/ModeC 1x32 MB (plr_flash_info @ 83fc14a4)
Loading(93) 65536B env. variables from offset 0x1c0000
boardId_init
Net: Net Initialization Skipped
No ethernet found.
Press A to stop autoboot: 0
RTCORE Driver Module Initialize
IOAL init
Hardware-profile probe (RTL9303_8X8261BE_V1)
Hardware-profile init
GPIO probe (unit 0): (found)
GPIO Init
SPI init (unit 0)
I2C probe (unit 0)
I2C init (unit 0)
RTL8231 probe (unit 0): (found)
RTL8231 init (unit 0)
NIC probe (unit 0)
Loader RTNIC Driver Module Initialize
IOAL init
RTK Driver Module Initialize
MAC probe (unit 0)
Chip 9303 (found)
MAC init (unit 0)
r9300_i2c_init had already been initialized!
Enable network # -> From bootcmd
rtcore_init had already been initialized!
rtk_init had already been initialized!
Please wait for PHY init-time ...
## Booting image from partition ... 0
## Booting kernel from Legacy Image at 81000000 ...
Image Name: MIPS OpenWrt Linux-6.12.40
Created: 2025-08-03 19:55:12 UTC
Image Type: MIPS Linux Kernel Image (lzma compressed)
Data Size: 4851697 Bytes = 4.6 MB
Load Address: 80100000
Entry Point: 80100000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
Starting kernel ...
[ 0.000000] Linux version 6.12.40 (nero@unknown) (mips-openwrt-linux-musl-gcc (OpenWrt GCC 14.3.0 r30667-7d570a489b) 14.3.5
[ 0.000000] RTL838X model is 0
[ 0.000000] RTL839X model is 0
[ 0.000000] RTL93XX model is 93030001
[ 0.000000] SoC Type: RTL9303
...
I also ran a memory dump in both cases, manual mode rtk network on -> md.l 0xbb000000 0x4096
then auto mode with setenv bootcmd 'md.l 0xbb000000 0x4096; rtk network on; boota'
. The results differ and which supports the idea that something is being initialized differently in auto vs manual mode before it hit the U-Boot env bootcmd.
Then play around with “rtk init” or “rtk rtcore-init” or … See https://github.com/plappermaul/realtek-doc/blob/54589ff0afa70045abfdc71a3133aa55c76257bc/sources/rtk-dms1250/system/uboot/cmd/uboot_cmd.c#L151
SKS8310-8X has been merged: https://github.com/openwrt/openwrt/pull/19782
Should have everything you need to get your PR ready to go.
Hi, i was looking on ali and i found jt-fg6700-8ftm switch even cheaper, do someone have it already? It’s tempting.
Does inter-VLAN routing work well with the OpenWrt firmware on the XikeStor 8300 (8x) for you? I was only able to get it working with the original firmware. Port forwarding combined with NAT works, but it seems that offloading to the Realtek chip is not functioning correctly. Since port forwarding happens in kernel space, that part works fine
Do not expect any L3 offloading, so performance will be abysmal.
There are known issues with L3 offloading. It's not usable right now.
See e.g. https://github.com/openwrt/openwrt/pull/19568
Thank you.
By the way: if you don’t want to set up a TFTP server first, you can also upload the kernel directly over the serial connection.
Just follow these instructions:
1. On Linux
Connect to the serial port:
screen /dev/ttyS0 9600
2. On the router (via screen
)
Shortcuts: Ctrl+B, then Ctrl+F
Enter debug modes:
diagshell_unipoe_env (password)
debug_unish_env
Prepare to receive the kernel:
loady 0x82000000 115200
3. On Linux (new terminal)
Set serial parameters:
stty -F /dev/ttyS0 115200 cs8 -cstopb -parenb -ixon -ixoff
Important: after changing the speed, go back to the router terminal and press ENTER once, otherwise the transfer won’t start.
Send the kernel (slow transfer):
sz -y openwrt-realtek-rtl930x-xikestor_sks8300-8x-initramfs-kernel.bin > /dev/ttyS0 < /dev/ttyS0
Restore serial speed:
stty -F /dev/ttyS0 9600 cs8 -cstopb -parenb -ixon -ixoff
4. On the router
After upload, run the kernel:
press ESC
bootm 0x82000000
5. Continue install as usual
Ps: we may need to install refered tools in the preferred Linux distro .
If you like that you can look over in the Zyxel GS1920 thread for a script to automate this process. And a small binary that can raise the transfer speed even more. (have not looked if the UART is the same)