Support for XikeStor SKS8300-8T (RTL9300)

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 :slight_smile:

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>;
      };
    };
  };
};



&ethernet0 {
    mdio: mdio-bus {
        compatible = "realtek,rtl838x-mdio";
        regmap = <&ethernet0>;
        #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 = <&ethernet0>;
            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.

1 Like

Makes more sense indeed... Thanks for pointing me toward the simpler approach.
This has been a great learning experience :smiley:

@plappermaul - I'll submit a PR soon to add support for this device.

Thanks again!

1 Like

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.

2 Likes

Hi, i was looking on ali and i found jt-fg6700-8ftm switch even cheaper, do someone have it already? It’s tempting.

Yep, https://github.com/openwrt/openwrt/pull/19994

1 Like

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

:warning: 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)

1 Like