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 ![]()
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.