Since it took me quite some time, to find out how to compile a single loadable kernel module (lkm), I decided to share my knowledge with others.
I'm gonna show you how to do it with a real life example.
I happen to own a wireless usb-stick, which has a supported chipset, but is not supported in the current stable kernel (2.6.27-9-generic)
My wireless stick is a sitecom WL-168 v1 004, which happens to have the realtek 8187B-chipset.
Linux actually showed me this
Code:
# lsusb
...
Bus 001 Device 006: ID 0df6:0028 Sitecom Europe B.V.
...
# lsub -vd 0df6:0028
...
iManufacturer 1 Manufacturer_Realtek
iProduct 2 RTL8187B_WLAN_Adapter
...
explanation : -d shows only information for the specified device, and -v is for verbose output, so you can get the extra information you'll need.
First you'll need the latest kernel headers and the kernel source.
Code:
# sudo apt-get install linux-source linux-headers-`uname -r`
Then we need to unpack the source code.
Code:
# cd /usr/src
# tar -xvjf linux-source-2.6.27.tar.bz2
Let's find the source of the module and go to the directory.
Code:
# find | grep rtl8187
./linux-headers-2.6.27-9-generic/include/config/rtl8187.h
./linux-source-2.6.27/drivers/net/wireless/rtl8187_rtl8225.h
./linux-source-2.6.27/drivers/net/wireless/rtl8187_rtl8225.c
./linux-source-2.6.27/drivers/net/wireless/rtl8187.h
./linux-source-2.6.27/drivers/net/wireless/rtl8187_dev.c
# cd linux-source-2.6.27/drivers/net/wireless/
Now you want to check the makefile to find the information about the files we'll need.
Code:
s# cat Makefile | grep 8187
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
obj-$(CONFIG_RTL8187) += rtl8187.o
So now we know the files which we need are rtl8187_dev.c and rtl8187_rtl8225.c and of course the corresponding .h file(s).
FYI: the makefile in this folder is not standalone, but is meant to be used by /usr/src/linux-source-2.6.27/Makefile
Since I only want to compile one module and not mess up the makefile in the directory I'm in, I will create a new directory
in my home folder for testing and compiling and copy all the necessary files to it.
Code:
# mkdir ~/rtl8187
# cp rtl8187* ~/rtl8187
# cd ~/rtl8187
We're gonna create our own makefile to build the module.
Use you're favorite editor to edit the file.
I'm running xubuntu, so mine is mousepad.
This is what's going to be in it:
Code:
obj-m := rtl8187.o
# this is the object, we're gonna make (actually rtl8187.ko)
# normally make would look for rtl8187.c to compile it.
# since it needs different files for input, we need to tell it:
rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o
# make knows to compile these it needs rtl8187_dev.c and rtl8187_rtl8225.c
# then we need a few basic rules for cleaning and compiling.
all:
$(MAKE) -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
$(MAKE) -C /lib/modules/`uname -r`/build M=`pwd` clean
$(RM) Module.markers modules.order
# -C tells it to switch to the specified directory
# uname -r gives the current kernel
# -M is the output directory,
# pwd outputs the current directory
Let's test it, since it's the first makefile I ever made.
Code:
#ls
Makefile rtl8187_dev.c rtl8187_rtl8225.c
Makefile~ rtl8187.h rtl8187_rtl8225.h
#make
error: rtl818x.h: No such file or directory
and a whole lot more errors, oops we're missing a file
# cp /usr/src/linux-headers-2.6.27-9-generic/include/config/rtl818x.h
# make clean
# make
#ls
Makefile Module.symvers rtl8187.ko rtl8187_rtl8225.c
Makefile~ rtl8187_dev.c rtl8187.mod.c rtl8187_rtl8225.h
Module.markers rtl8187_dev.o rtl8187.mod.o rtl8187_rtl8225.o
modules.order rtl8187.h rtl8187.o rtl818x.h
#make clean
#ls
Makefile rtl8187_dev.c rtl8187_rtl8225.c rtl818x.h
Makefile~ rtl8187.h rtl8187_rtl8225.c
Everything is working.
FYI: just wanted to add this little trial and error-example above, it took me a whole lot more to create a proper working makefile.
Now we need to add our device. Let's use my favorite editor.
Code:
# mousepad rtl8187_dev.c
and add our device. Just open the file and start scrolling down, you will soon see where you need to add the device.
Code:
{USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
save and exit
If everything is working fine, you now have rtl8187.ko in your directory.
First let's see where the lkm is located.
Code:
#locate rtl8187.ko
/lib/modules/2.6.24-21-generic/kernel/drivers/net/wireless/rtl8187.ko
/lib/modules/2.6.27-3-rt/kernel/drivers/net/wireless/rtl8187.ko
/lib/modules/2.6.27-9-generic/kernel/drivers/net/wireless/rtl8187.ko
I'm running 2.6.27-9, so that's where I need to copy it to, but lets first make a backup of the original module.
Code:
# cd /lib/modules/2.6.27-9-generic/kernel/drivers/net/wireless
# sudo mv rtl8187.ko rtl8187.org
# sudo cp ~/rtl8187/rtl8187.ko
Finally we can test the module. So plug in the stick and enter the following command (in random order).
Code:
# sudo modprobe rtl8187
Check if your device is up and running.
Code:
# iwconfig
wmaster0 no wireless extensions.
wlan0 IEEE 802.11bg ESSID:""
Mode:Managed Frequency:2.412 GHz Access Point: Not-Associated
Tx-Power=0 dBm
Retry min limit:7 RTS thr:off Fragment thr=2352 B
Encryption key:off
Power Management:off
Link Quality:0 Signal level:0 Noise level:0
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
If all went well, everything should work now. Now it's time to clean up the mess.
Code:
# cd ~/rtl8187
# make clean
# sudo rm /usr/src/linux-source-2.6.27 -r
If it's working and you want it to start automatically, just add it to /etc/modules
For troubleshooting modinfo is quite nice.
It should show:
Code:
# modinfo rtl8187
filename: /lib/modules/2.6.27-9-generic/kernel/drivers/net/wireless/rtl8187.ko
license: GPL
description: RTL8187/RTL8187B USB wireless driver
author: Andrea Merello <andreamrl@tiscali.it>
author: Michael Wu <flamingice@sourmilk.net>
srcversion: A1FCBC06E2195A653B7E975
alias: usb:v0DF6p0028d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0DF6p000Dd*dc*dsc*dp*ic*isc*ip*
alias: usb:v03F0pCA02d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0846p4260d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0846p6A00d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0846p6100d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp8197d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp8189d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BDAp8187d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0B05p171Dd*dc*dsc*dp*ic*isc*ip*
depends: mac80211,eeprom_93cx6,cfg80211,usbcore
vermagic: 2.6.27-9-generic SMP mod_unload modversions 586
Make especially sure your device is in it (v0DF6p0028d in this case)
FYI:
This device will be included in the 2.6.27-10 ubuntu version of the kernel. So I could have just downloaded it
from svn and used that one, or wait till that kernel came as an automatic update, but I prefer a stable
kernel instead of a testing release and besides I wanted to know how to compile a single kernel module.
Bookmarks