Building a module

Hi Guys,

I have a problem with a wireless usb adapter. it is the tp-link WN725N V2 . I have bought a couple of those earlier(bad choice) but managed to get them to work on a RPi in two other boards using these driver from here

Now the 3.12.26 is not in the list as you can see so I tried to build the module myself.

First the header issue i used rpi-source from here

Use the source code now the module compiled on the pi running the navio immage, installed it but still the same issue:

pi@navio ~/wireless/rtl8188eu-master $ sudo modprobe 8188eu  
ERROR: could not insert '8188eu': Exec format error

the build process ended ok, with two warnings like so:

WARNING: "sub_preempt_count" [/home/pi/wireless/rtl8188eu-master/8188eu.ko] undefined!  
WARNING: "add_preempt_count" [/home/pi/wireless/rtl8188eu-master/8188eu.ko] undefined!  
  CC      /home/pi/wireless/rtl8188eu-master/8188eu.mod.o  
  LD [M]  /home/pi/wireless/rtl8188eu-master/8188eu.ko  
make[1]: Leaving directory '/root/linux-c256eb9968c8997dce47350d2075e42f1b3991d3'

Any suggestions for being able to build any module on the provided image? Or am I doing something wrong here?

thx

hugo

ok maybe intersting:
dmesg says:
[ 3657.197880] 8188eu: disagrees about version of symbol module_layout
[ 5128.183862] 8188eu: no symbol version for module_layout

seems it has something to do with different kernel versions?
but i build the module on the kernel version that is currently running?

do i need to set the realtime part ("-rt40+") somewhere?

thx

hugo

Hello Hugo,
The image that we provide has a kernel patched with rt-patch, so it’s sources are different from the ones in the repo. The source code for the actual kernel is located in /usr/src/.
I’d recommend to obtain an adapter with rtl8188cus or rtl8192cu as they are supported out of the box and since you would probably have to recompile the kernel module for yours most of the times when kernel updates.

you are right, this will be a pain forever.
I bought a different wifi dongle …

hugo

I’ve learnt the key to rebuilding “new” Wifi (or any other) device driver module is availability of the correct headers. So as we’re using a special Linux distribution with Navio we also need access to a “linux-headers-*” build directory with which to recompile the drivers.

I’ve had a look at the source on GitHub but cannot see any obvious mapping between from what is usually installed by a downloaded “linux-headers-*” package. We just need to populate the /lib/modules/3.18.9-rt5-v7+/build and …/source directories I guess? The workaround to create a symbolic link to version 3.10-3-rpi doesn’t work because it’s the wrong version so leads to the “Exec format message” message reported here.

@Emild Can you please create a headers package/zip for us to download and/or provide instructions how to extract the same from your GitHub soruce?

I’ve got a EW-7811USC which is a variant of the other Edimax AC600 USB Wifi adapter with a removable aerial, so I can replace with a circularly polarized antenna.

p.s. I think I just found it here after cross-compiling on Ubuntu as described in the README.MD file: “/kernel-rt/lib/modules/”. I’ll give that a try…

SOLVED! This took me weeks! :frowning:

So it’s not in anyway intuitive or easy or documented 100%. Here is how you compile a module for a custom Linux build and install it:

Requirements:

  1. Must build on a normal Linux PC/kernel. The redirection of the RT kernel on Navio+ seems to prevent proper version calculation hence the never ending “Bad EXE format/symbol version mismatch” errors if you try. Wasted loads of time with that.
  2. Forget building on the Raspberry Pi it takes too long. In order to build the relatively small driver (“module”) you need access to the a copy of the source with the “Module.symvers” file specifically plus the other prepared headers. That means you have to run a “make modules” on the Emlid RT kernel source.
  3. Follow the instructions on the Emlid LINUX-RT-RPI GitHub repository to download and build the source (and download the cross compiler also used for the driver).
  4. If using a 64bit development PC make sure you use the 64bit raspbian tools (cross-compiler). It may work on Ubuntu 14 (Linux 3.18) but will fail on Ubuntu 15 (Linux 3.19) with weird “command not found” errors.
  5. Download and re-(cross-)compile your driver. Usually this means editing the Makefile, selecting the ARM and Raspberry Pi build options and providing paths to the (Emlid) source and the cross-compiler (Raspbian Tools). There should be instructions with the driver on how to build. The target of the build is a “.ko” file, a Linux module.

Sometimes the original drivers won’t work because they’re written for older kernel versions with depreciated functions. This is the case currently with the newer 802.11AC models from Edimax, what I was trying to get working. Luckily others have does this work for them, the “gnab” user on GitHub is one example. He’s created a “rtl8812au” repository with fixed source code so all the new AC wireless adapters will work!

I’m going to write all this up into a detailed article, but for now people wishing to play with the newer WiFi adapters with a Raspberry Pi 2 on the current “3.18.9-rt5-v7+” kernel build (exactly as downloaded from the Emlid web site) can try this driver:

http://1drv.ms/1QglyoF

It’s a ZIP containing two versions of a built 8812au.ko module (driver), one with power saving on and one with those functions disabled (probably what you want for a drone). To install it do the following:

  1. Download and extract the ZIP. You only need the 8812au.ko file from the directory named after the configuration you want (“Power Save” or “No Power Save”).

  2. Copy the file to the SD card of the Raspberry Pi, using the “sudo” elevation because it’s in a system path (if you have the SD card mounted in another Linux machine you would prefix “/lib/…” with the mount path, e.g. on Ubuntu it’s “/media///”):

    sudo cp 8812au.ko /lib/modules/3.18.9-rt5-v7+/kernel/drivers/net/wireless/
    sudo chmod 644 /lib/modules/3.18.9-rt5-v7+/kernel/drivers/net/wireless/8812au.ko

  3. Boot the Raspberry Pi and run the following command to install the driver:

    sudo insmod /lib/modules/3.18.9-rt5-v7+/kernel/drivers/net/wireless/8812au.ko
    sudo depmod -a $(uname -r)

  4. Check the driver loaded, you should see 8812au in the list:

    lsmod

  5. Check the WLAN adapter has initialized:

    iwconfig

  6. Follow instructions to configure the WLAN0 interface and WPA_SUPPLICANT. I’m writing an article on that too, but for now you can get a quick start here:

Note: This modified version by GNAB is not perfect. Although it seems to run reliably when configured correctly, when playing with settings you may find a kernel fault occurs and the system locks-up, specifically when editing the “wpa_supplicant.conf” file. To correct this, remove the adapter, power-cycle then correct the configuration before re-inserting it.

One example I found is when configuring Ad-Hoc/IBSS/P2P mode but not specifying a frequency. Looking at the source shows he did not convert all the functions to the newer kernel, so there are some special cases when it’s trying to print debug messages and falling-over because it contains the old code. I plan to get the latest code from Realtek somehow and re-implement this later, but hope Edimax do the right thing and update their Linux drivers first.

2 Likes

Hi, build it for 3.18.9-rt5 (RPI 1) please. I try for several days, but in vain.

Hi CodeChief,

I was wondering if you made the tutorial for compiling modules with the real time kernel.

Thanks

Hi everybody,

well, I figured out how to compile the module.

First, you have to download kernel source from, GitHub - emlid/linux-rt-rpi: Real-time preemptible kernel for Raspberry Pi

Then, you have to follow their instructions and compile kernel and modules.

I was confused at this point and It took me two days to clarify that my raspberry was Rpi 1 not Rpi 2.

The next step is to download rt8188eu source, I did it from, GitHub - lwfinger/rtl8188eu: Repository for stand-alone RTL8188EU driver. and extracted in /home/eugenio//src_pi/rtl8188eu-master

To complile you have to change some lines in Makefile,

I changed

ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=
KVER := $(shell uname -r)
KSRC ?= /lib/modules/$(KVER)/build
MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless

to

ARCH = arm
CROSS_COMPILE = /home/eugenio/bin/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-
KVER = 3.18.9-rt5+
KSRC = /home/eugenio/src_pi/linux-rt-rpi-rpi-3.18.9-rt5
MODDESTDIR = $(KSRC)/kernel-rt/lib/modules/kernel/drivers/net/wireless

After that, I compile the module with

make all

That was all with compilation stage, the result was a module, 8188eu.ko located in my directory /home/eugenio/src_pi/rtl8188eu-master/8188eu.ko

The nex stage was intalling this kernel module in the micro sd.

I mounted the sd in /home/eugenio/mountpoint2 with

mount /dev/sdb2 /home/eugenio/mountpoint2

Then I check Makefile and reply the commands in console,

install:
install -p -m 644 8188eu.ko $(MODDESTDIR)
@if [ -a /lib/modules/$(KVER)/kernel/drivers/staging/rtl8188eu/r8188eu.ko ] ; then modprobe -r r8188eu; fi;
@echo “blacklist r8188eu” > /etc/modprobe.d/50-8188eu.conf
cp rtl8188eufw.bin /lib/firmware/.
/sbin/depmod -a ${KVER}
mkdir -p /lib/firmware/rtlwifi
cp rtl8188eufw.bin /lib/firmware/rtlwifi/.

First I copy 8188eu.ko to /lib/modules/3.18.9-rt5+/drivers/net/wireles with chmod to 644

Then, create a file 50-8188eu.conf in directory /etc/modprobe.d with only one line: blacklist r8188eu

After that, copy the firmware rtl8188eufw.bin to directories /lib/firmware and /lib/firmware/rtlwifi

Now its time to boot raspberry,

After booting I verified that r8188eu is not running in modules with command lsmod

now, it is time to actualize modules with,

sudo /sbin/depmod -a 3.18.9-rt5+

my last step was to include another lines in 50-8188eu.conf

blacklist r8188eu
options 8188eu rtw_power_mgnt=0 rtw_enusbss=0

and last reboot

That was all

Thanks for posting that back, it’ll be useful for others searching. It’s a while since I went through that process as the main reason I wanted to compile a module was to support a new AC600 USB WiFi adapter for “mesh” mode networking. But after all the effort discovered the state of the open source code base prevented usage of the features I wanted. It was impossible to track-down official vendor versions, just people’s own hacks here and there.

Some claimed it was the manufacturer’s fault, but from what I saw most of the source code was stock Linux code so that appeared to be lacking the features and stability more than the manufacturer’s policy for the device.

So realistically I think getting a WPA2 or at least basic WPA connection working with self-made drivers is achievable. But the advanced features appear to be disabled for most of them (I must have read like 100+ blogs at the time with people suffering the same limitation).

Not sure if that’s the fault of Linux or the driver. Basically the effort was way higher than it should be. It seems like almost all blog articles I found directed people to just buy a different WiFI adapter than bother to get it working or acknowledge the necessity for a fix in the central Linux code!

One important point you might have missed, unless you were compiling on an X86 machine. You are supposed to use the 64bit cross-compiler when cross-compiling on a 64bit machine. Strangely it will still work on distributions like Ubuntu 14 but not on 15. Try it, maybe it reduces errors, but it won’t add any and will ensure compatibility. It’s just a small change in the tools path:

Anyway well done and I hope your WiFI adapter works better than mine :smile:

@CodeChief Is the rtl8812au driver still available? Link to OneDrive reports ‘might not exist or no longer available’

@cyberpilot yes here it is:

https://onedrive.live.com/redir?resid=DB5819BE35EE64C8!178219&authkey=!ABKGM-IrBQYYjII&ithint=file%2Czip

1 Like

Thanks mate. Will let you know if it works for my set-up.

1 Like

@codechief Now have a working Edimax EW-7811UAC in my RPi/Navio+. Been ‘googling’ and reading man pages for information on how to configure the wireless mode to 802.11a but haven’t come up with anything. I’m using the No Power Save driver so you’ve already solved that problem for me :slight_smile:
Also been reading your posts on ‘WiFi Telemetry’ and ‘What’s Your FPV’ topics which have been a great help.
Would appreciate your insights on configuring the wireless mode. Cheers.

Glad it helped :smile:

The closest I got to controlling the frequency was to list them via iwlist and then it tells you the channel number, which could be added to the configuration if I remember correctly. But I’ve been busy with other stuff for quite a while and left the default.

This may help: WiFi Tools for Raspberry Pi | Raspberry Pi Adventures

@codechief Thanks for the reply; iwconfig did the job.
Following your Windows IoT posts with interest.

I have the kernel:

Linux navio 4.1.6-v7+ #2 SMP PREEMPT Thu Jan 28 19:58:25 MSK 2016 armv7l GNU/Linux

Which branch on GitHub - emlid/linux-rt-rpi: Real-time preemptible kernel for Raspberry Pi should I use for kernel module compilation ?

I try to use branch for 4.1.6 and get next error:

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [scripts/kconfig/mconf] Error 1
make: *** [menuconfig] Error 2

@Dmytro

What module do you compile?
It seems like you are trying to cross compile, but you lack some environment variables like CROSS_COMPILE and ARCH.

The former points to the path of your cross compiler and a prefix and the latter is target architecture.

I guess this set of commands should help.
export CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf- in case of your cross-compiler is installed in /usr/bin. If it’s installed elsewhere, you need to adjust.
export ARCH=arm

Sorry for delay with answer. Can You add support for DWA-172 WiFi adapter ? This is the way You can do this : SOLVED: D-Link DWA-172 & Debian - Debian User Forums

I have tried to do this myself, but think this will be useful for many of us.