Successful cross-compile of rtl8192eu .ko for Mod Duo X

So, now it’s my turn to contribute to this wonderful community and the truly incredible MOD Audio devices. I was finally able to successfully build a working .ko for my rtl8192eu dongle! The .ko I built works for D-Link DWA-131 Rev. E and a TP-Link TL-WN823N V2 on a Mod Duo X with latest firmware 1.13 (modduox-v1.13.5.3316.tar) and it’s old 4.4 kernel.

But let me tell you this, it was not straight forward to say the least and required days after days of trial and error. Below I share as many steps as I can remember to get it working correctly. I’m not 100% sure if all steps below are really necessary. I’m not a developer, simply a simple human being who does not easily give up :wink:

And I also would like to give my sincerest appreciation to @ignis32, @Zavorra and @rah and their threads Cross-compiling a kernel module, Serial MIDI and Installing custom OS on Duo X since these threads were crucial for making it work in the end.

First I followed @ignis32 steps from the Serial Midi thread:

/*>>>on MDX: >>> */

/* -> obtain current  MDX kernel configuration from, for example:*/
 zcat /proc/config.gz  
/* save whole output somewhere. I used WinSCP for that actually.*/

/*On docker-host machine */

/*build image. **Note!** You cannot use modduox-new as the platform since it uses GCC 9 and is not playing well with the rk3399 repo/kernel.*/

git clone --depth 1 https://github.com/mod-audio/mod-plugin-builder.git
cd mod-plugin-builder/docker
docker build -t modduox-plugin-builder --build-arg platform=modduox .

/*run plugin builder docker container as a build environment, Note: without the -rm to actually keep the container for multiday work...*/
docker run -it --entrypoint bash modduox-plugin-builder
 
/* put config extracted from config.gz into running container, I used docker cp.*/
docker cp /tmp/config  2e0af363aa14:/home/builder/

/*>>> Inside container <<<*/
/*load environment variables stuff that points us to toolchain location*/

cd ~/mod-plugin-builder
. local.env modduox
cd

/* obtain current kernel sources */
git clone https://github.com/mod-audio/linux-rk3399.git
cd linux-rk3399
git checkout -b rt176 origin/develop-4.4-rt176 # seems like it is current kernel for modduox

/*Just to be sure */
make clean
make mrproper

/* insert config that we got from MDX */
cp  /home/builder/config  .config

I then looked for a patch for the rk3399 kernel and found @rah wonderful thread where @falkTX posted the pastebin for the only patch available from what I can gather. With this info i created a .dts file like this:

/*Copy the pastebin content to a new file inside the rk3399 folder.*/
wget https://paste.debian.net/plain/1386232 -O arch/arm64/boot/dts/rockchip/rk3399-modduox.dts

/*Verify its existence:*/
ls -l arch/arm64/boot/dts/rockchip/rk3399-modduox.dts

Then I continued as @ignis32 did in the Serial Midi thread:

/*In rk3399 folder*/
make olddefconfig

/*After days of trial and error I knew I would be hit by an "multiple definition of yylloc'" error when making scripts or modules_prepare, don't remember exactly which one. My memory is a bit vague regarding this now. But I'm pretty sure I somehow pinpointed that the multiple yylloc error came from this single _shipped file.*/
sed -i 's/YYLTYPE yylloc;/\/\/YYLTYPE yylloc;/g' scripts/dtc/dtc-lexer.lex.c_shipped 

/*Then prepare the kernel using exactly this order, one by one..*/

make ARCH=arm64 CROSS_COMPILE=aarch64-mod-linux-gnueabi- prepare 
make ARCH=arm64 CROSS_COMPILE=aarch64-mod-linux-gnueabi- modules_prepare 
make ARCH=arm64 CROSS_COMPILE=aarch64-mod-linux-gnueabi- scripts
/*For including the .dts file created previously...*/
make ARCH=arm64 CROSS_COMPILE=aarch64-mod-linux-gnueabi- dtbs 

/*Important unset CFLAGS and LDFLAGS before make modules. I got an wl01 error without doing this...*/
unset CFLAGS LDFLAGS

make ARCH=arm64 CROSS_COMPILE=aarch64-mod-linux-gnueabi- modules

Now, after a lot of trial and error, I had a fully prepared rk3399 folder, so I could move on to the mess of fixing the rtl8192eu folder…

cd ~
/*Make sure you select the 4.4.X kernel...*/
git clone https://github.com/Mange/rtl8192eu-linux-driver.git
cd rtl8192eu-linux-driver
nano Makefile

/*Then replace everything up to WIFI IC comment with this...*/

obj-m := 8192eu.o

8192eu-objs := \
  core/rtw_cmd.o \
  core/rtw_security.o \
  core/rtw_wlan_util.o \
  core/rtw_debug.o \
  core/rtw_io.o \
  core/rtw_ioctl_set.o \
  core/rtw_recv.o \
  core/rtw_mlme.o \
  core/rtw_mlme_ext.o \
  core/rtw_mi.o \
  core/rtw_pwrctrl.o \
  core/rtw_rf.o \
  core/rtw_chplan.o \
  core/rtw_ieee80211.o \
  core/rtw_sta_mgt.o \
  core/rtw_ap.o \
  core/mesh/rtw_mesh.o \
  core/mesh/rtw_mesh_pathtbl.o \
  core/mesh/rtw_mesh_hwmp.o \
  os_dep/linux/os_intfs.o \
  os_dep/linux/ioctl_cfg80211.o \
  os_dep/linux/mlme_linux.o \
  os_dep/linux/recv_linux.o \
  platform/platform_ops.o

EXTRA_CFLAGS := -O2 -std=gnu89 \
                -Wno-unused-variable -Wno-unused-label -Wno-unused-function \
                -Wno-attributes -Wno-error=unused-result -Wno-error=declaration-after-statement \
                -Wno-error=unused-but-set-variable

EXTRA_CFLAGS += -I$(src)/include
EXTRA_CFLAGS += -Wno-error=attributes -Wno-attributes
EXTRA_CFLAGS += -D'__has_attribute(x)=0'

########################## WIFI IC ############################
/*Rest of Makefile*/

/*Scroll down and set the platform in the Makefile by setting only this to =y, all other platforms as =n:*/
CONFIG_PLATFORM_ARM_AARCH64 = y

/*When I tried to make the rtl file with the above set, I got hit with __attribute__((__fallthrough__)) errors, and also the same -Wl,-O1 error from the rk3399 folder. I had to therefore comment out the fallthrough stuff and also unsset CFLAGS and LDFLAGS again in the rtl folder...*/

/*Comment out fallthrough stuff...*/

sed -i 's/^.*__attribute__((__fallthrough__));.*$/\/\/ __attribute__((__fallthrough__));/' core/rtw_mlme_ext.c

sed -i '2433s/^.*__attribute__((__fallthrough__));.*$/\/\/ __attribute__((__fallthrough__));/' os_dep/linux/ioctl_cfg80211.c

sed -i '2458s/^.*__attribute__((__fallthrough__));.*$/\/\/ __attribute__((__fallthrough__));/' os_dep/linux/ioctl_cfg80211.c


/*Unset CFLAGS and LDFLAGS...*/
unset CFLAGS LDFLAGS



/*Then comes the biggest headache... No matter what I did the built .ko file included calls to preempt_count_add and preempt_count_sub and preempt_schedule. And the MDX doesn't export these to modules (except the preempt_schedule i think). They are inlined from what I gather with my small knowledge... So after many days of trial and error again:*/

/*Create a patch file "preempt_patch.h" file inside rtl8192eu-linux-driver/include/linux/ with the following content:*/
#ifndef _PREEMPT_PATCH_H_
#define _PREEMPT_PATCH_H_

static inline void preempt_count_add(int x) { (void)x; }
static inline void preempt_count_sub(int x) { (void)x; }
static inline void preempt_schedule(void) { }

#endif /* _PREEMPT_PATCH_H_ */

/*Then adding this as the FIRST include in ALL .c files in the core, os_dep/linux and hal folders... The include must also the very first include in /rtl8192eu-linux-driver/os_dep/osdep_service.c. This last osdep_service.c was the culprit for not being able to remove the preempt_count_sub one...*/

#include "/root/rtl8192eu-linux-driver/include/linux/preempt_patch.h"

/*Then finally I was able to build the .ko that would work in the MDX...*/

make ARCH=arm64 CROSS_COMPILE=/root/mod-workdir/modduox/toolchain/bin/aarch64-mod-linux-gnueabi- KSRC=/root/linux-rk3399

Lastly…

  • I created the wpa_supplicant.conf file according to the instructions found here: WiFi - MOD Wiki

  • I then copied the rtl8192eu_nic.bin file from here: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/rtlwifi

  • Together with the freshly built 8192eu.ko file from my Docker container,

To /data/firmware/realtek/ on the MDX.

The I ran:

insmod ./8192eu.ko

And low and behold, it worked…

It was exhausting, but it was super fun!

Hope that this writeup can help anyone else out there, exactly as @ignis32, @Zavorra and @rah contributions have helped me immensely in this journey.

8 Likes

That sounds like a developer to me!

2 Likes

And some additional notes I did find out during this period of trying to make the 8192eu.ko file to work with the MDX:

In the Wifi Connectivity topic: https://forum.mod.audio/t/wifi-connectivity/
Some users reported success with simply adding the .bin file to the correct folder for the DWA-131 dongle to work. But there was never a mention about which revision of the dongle that worked, and also no mention of on which device.

So when investigating things I quite soon understood that they’ve had their success on a Mod Dwarf.

And the reason is simply because it runs on newer kernel, and the Realtek driver included in Dwarfs kernel is the rtl8xxxu driver (which is a multi-driver that started to support the rtl8192eu chip the same year as Mod Duo X 4.4 kernel, year 2016, but only later during 2016).

Mod Duo X also includes the rtl8xxxu driver, but unfortunately dated a few months prior to when the rtl8192eu started to be supported by that driver.

So with this in mind…
I went to and looked for commits for the rtl8xxxu folder in 2016 and found the commit for when the rtl8192eu started to be supported. I cloned that folder and built the rtl8xxxu driver and added the aliases from the RTL Mange driver.
It is untested by me, but if anyone is interested in testing if it works on the MDX, just let me know and I will share the rtl8xxxu.ko file. You can check in the alias lines below if you have a Wifi dongle that should be supported by this rtl8xxxu driver version.

Edit: Scratch the last part, I tested it myself now and it didn’t work. The rtl8xxxu driver expects ieee80211 symbols which are not exported by the MDX…