[Rux Robot] WLAN Driver Setup on Debian


This guide describes how to build and install the AIC8800 wireless LAN driver for the Rux robot running Debian (ARM64). Rux is a robot developed by LeTianPai. The driver must be cross-compiled for ARM64 and loaded manually for testing.

Note: These instructions are experimental. Proceed with caution and at your own risk.


0. Prerequisites and Verification

Before starting, make sure your kernel matches the tested environment.

(1) Install ADB tools on your host

Please follow the first section of the official guide to install ADB tools.

Reference: Rux official installation guide.

(2) Connect to Rux via ADB and check the kernel version

> adb shell
(On Android) $ uname -a
Linux localhost 4.19.232-ab351 #219 SMP PREEMPT Tue Feb 27 15:49:29 CST 2024 aarch64

Make sure it matches your Rux environment.


1. Flash the Android ROOT Image

Follow the official documentation to flash the full ROOT ROM.

Reference: Rux official installation guide

Then, switch to the debian environment by running adb root and adb shell bootdebian.sh.

(On Debian) # uname -a
Linux linaro-alip 4.19.232 #3 SMP Sat Apr 22 18:43:58 CST 2023 aarch64 GNU/Linux

Check again that the environment matches in the Debian system as well.


2. Cross-Compile the Wi-Fi Driver (AIC8800)

(1) Download Toolchain and Sources

(2) Preparing the Kernel Source for Cross Compilation

Before building the AIC8800 driver, you need to prepare the Linux kernel source tree so that it matches the configuration of your Rux device.

a) Extract the current kernel configuration from the device

Transfer /proc/config.gz from Rux with adb pull, then run:

$ zcat config.gz > .config

Move this .config into the kernel source directory.

b) Prepare the kernel for external module builds

Inside the kernel source directory, run the following commands.

(Replace /path/to/* with the actual directory where you downloaded.)

$ export ARCH=arm64
$ export CROSS_COMPILE=/path/to/aarch64-none-linux-gnu-

$ cd /path/to/kernel
$ make olddefconfig
$ make modules_prepare

After this step, the kernel source tree will contain the necessary headers and generated files (include/generated/*), and you can proceed with building the driver.

(3) Apply Patch to the Driver Source

In the driver source, patch the set_ios handling: If host->ops->set_ios is NULL, skip the call and print a WARNING instead of crashing.

--- ./src/SDIO/driver_fw/driver/aic8800/aic8800_bsp/aicsdio.c.org
+++ ./src/SDIO/driver_fw/driver/aic8800/aic8800_bsp/aicsdio.c
@@ -1705,12 +1705,24 @@
         return ret;
     }
     udelay(100);
-#if 1//SDIO CLOCK SETTING
+#if 0//SDIO CLOCK SETTING
     if (feature.sdio_clock > 0) {
         host->ios.clock = feature.sdio_clock;
         host->ops->set_ios(host, &host->ios);
         sdio_dbg("Set SDIO Clock %d MHz\n", host->ios.clock/1000000);
     }
+#else
+	if (feature.sdio_clock > 0) {
+	  if (host && host->ops && host->ops->set_ios) {
+	    host->ios.clock = feature.sdio_clock;
+	    host->ops->set_ios(host, &host->ios);
+	    sdio_dbg("Set SDIO Clock %d MHz\n", host->ios.clock/1000000);
+	    AICWFDBG(LOGINFO, "Set SDIO Clock %d MHz\n",
+		     host->ios.clock/1000000);
+	  } else {
+	    AICWFDBG(LOGINFO, "Skipped clock change: set_ios unavailable!\n");
+	  }
+	}
 #endif
     sdio_release_host(sdiodev->func);
 
--- ./src/SDIO/driver_fw/driver/aic8800/aic8800_fdrv/aicwf_sdio.c.org
+++ ./src/SDIO/driver_fw/driver/aic8800/aic8800_fdrv/aicwf_sdio.c
@@ -2266,12 +2266,24 @@
         return ret;
     }
 
-#if 1//SDIO CLOCK SETTING
+#if 0//SDIO CLOCK SETTING
     if (feature.sdio_clock > 0) {
         host->ios.clock = feature.sdio_clock;
         host->ops->set_ios(host, &host->ios);
         AICWFDBG(LOGINFO, "Set SDIO Clock %d MHz\n", host->ios.clock/1000000);
     }
+#else
+	if (feature.sdio_clock > 0) {
+	  if (host && host->ops && host->ops->set_ios) {
+	    host->ios.clock = feature.sdio_clock;
+	    host->ops->set_ios(host, &host->ios);
+	    sdio_dbg("Set SDIO Clock %d MHz\n", host->ios.clock/1000000);
+	    AICWFDBG(LOGINFO, "Set SDIO Clock %d MHz\n",
+		     host->ios.clock/1000000);
+	  } else {
+	    AICWFDBG(LOGINFO, "Skipped clock change: set_ios unavailable!\n");
+	  }
+	}
 #endif
 
     sdio_release_host(sdiodev->func);

(4) Build with Cross Compiler

Export the cross-compiler and build the driver:

$ export ARCH=arm64
$ export CROSS_COMPILE=/path/to/aarch64-none-linux-gnu-

$ cd /path/to/aic8800/src/SDIO/driver_fw/driver/aic8800
$ make -C /path/to/kernel M=$PWD CONFIG_PLATFORM_UBUNTU=y CONFIG_USE_FW_REQUEST=y EXTRA_CFLAGS="-DCONFIG_PLATFORM_ROCKCHIP" modules -j"$(nproc)"

3. Install the Driver

(1) Transfer Modules

Copy the built .ko files (e.g., aic8800_bsp.ko, aic8800_fdrv.ko) to the Debian filesystem on Rux using adb push, typically under:

/lib/modules/$(uname -r)/kernel/drivers/net/wireless/aic8800/

(2) Reset the SDIO Host

The Wi-Fi chip is connected via dwmmc@fe2c0000. Reset it by unbinding and rebinding:

# echo fe2c0000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/unbind
# sleep 0.6
# echo fe2c0000.dwmmc > /sys/bus/platform/drivers/dwmmc_rockchip/bind

Tip: You can identify the correct SDIO host device name (e.g., fe2c0000.dwmmc) by checking the boot log:

# dmesg | grep mmc-pwrseq

(3) Load the Driver

Insert the driver:

# depmod -a
# modprobe -v aic8800_fdrv

If successful, the wlan0 device should appear in:

# ip a

4. Configure Wi-Fi Client

Use NetworkManager (nmcli) for connection:

# nmcli radio wifi on
# nmcli -w 60 dev wifi list ifname wlan0 --rescan yes
# nmcli dev wifi connect "SSID" ifname wlan0

(After the first time: the saved connection can be brought up directly)
# nmcli con up id "SSID" ifname wlan0

Notes / Disclaimer