Compiling Kernel Modules for Raspberry Pi

image I tried loading rpi-pwm on my Raspberry Pi, but ran into some issues. After some tinkering I was able to compile rpi-pwm.c on the Raspberry Pi, but I kept running into Invalid Format issues anytime I tried to insmod rpi-pwm.ko which had the following dmesg:

rpi_pwm: disagrees about version of symbol module_layout

I guess this generally means I need to compile my module in the same way the kernel is compiled on the Raspberry Pi. Otherwise, the kernel will reject the module.

I've found that cross-compiling works best. This means, building your kernel and modules on a different platform rather than on the Raspberry Pi hardware directly. I did NOT have any luck compiling my kernel module directly on Raspberry Pi hardware.

In detail, first you'll want to cross-compile the Raspberry Pi Linux kernel so it builds Module.symvars and other intermediates. You won't actually use the kernel that is being cross-compiled, just the intermediates to compile your module. Next, you'll cross-compile your module using those intermediates. Once your module is cross-compiled, copy the .ko module to your running Raspberry Pi and you should be able to load it along with the stock kernel. The following is a quick how-to cross-compile the Raspberry Pi Kernel modules on Ubuntu 12.04:

First, know what version of RPi you're running:

uname -r and uname -a

[email protected]:/# uname -r
3.2.27+
[email protected]:/# uname -a
Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux

I've downloaded everything into a directory called ~/rpi on my Ubuntu machine.

1. Compile the Kernel

For 3.2.27+:

(instructions generally flow from: http://elinux.org/RPi_Kernel_Compilation)

  • Install Ubuntu
  • Get the rpi-3.2.27.tar.gz tarball
  • Get the tools tarball
  • tar xzf rpi-3.2.27.tar.gz and tar xzf master.tar.gz (tools)
  • Set the environment variable CCPREFIX:
    export CCPREFIX=
    /home/cowboy/rpi/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
  • Set the environment variable KERNEL_SRC:
    export KERNEL_SRC=/home/cowboy/rpi/linux-rpi-3.2.27
  • In KERNEL_SRC: execute "make mrproper" to ensure you have a clean kernel source tree.
  • Pull /proc/config.gz from your running Raspberry Pi and extract it into KERNEL_SRC on your Ubuntu machine.

    scp [email protected]:/proc/config.gz ./ (transfers it to Ubuntu)
    zcat config.gz > .config (uncompresses .config)
    mv .config $KERNEL_SRC (moves the uncompressed .config to KERNEL_SRC) 

  • On Ubuntu: Prime kernel with the old config:
    make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
  • On Ubuntu: Build the kernel:
    make ARCH=arm CROSS_COMPILE=${CCPREFIX}

This will produce a fresh Module.symvers and since you're using the cross-compile tools, the intermediates the tools generate should be binaurally compatible with Raspberry Pi.

2. Compile your kernel module

Next, make a separate directory outside of KERNEL_SRC (or example: ~/pwm) and write a quick Makefile for your kernel module:

obj-m += rpi-pwm.o

all:
    make ARCH=arm CROSS_COMPILE=${CCPREFIX} -C /home/cowboy/rpi/linux-rpi-3.2.27 M=$(PWD) modules

clean:
    make -C /home/cowboy/rpi/linux-rpi-3.2.27 M=$(PWD) clean

(learn more about compiling Linux kernel modules here)

When you're ready to compile your module, go ahead and execute "make" and you should be gold. Copy your rpi-pwm.ko to your RPI then use modinfo rpi-pwm.ko to review the module information:

[email protected]:/# modinfo rpi-pwm.ko
filename:       /home/pi/temp/rpi-pwm.ko
alias:          platform:bcm2708_pwm
author:         Sean Cross <[email protected]> for Adafruit Industries <www.adafruit.com>
license:        GPL
srcversion:     44D62553C321E91B0CB1996
depends:       
vermagic:       3.2.27 preempt mod_unload modversions ARMv6

Last but not least, you should be able to insmod rpi-pwm.ko without any problems. My dmesg:

[email protected]:/# dmesg | tail -5
[18852.504621] rpi_pwm: disagrees about version of symbol module_layout
[19043.461377] rpi_pwm: disagrees about version of symbol module_layout
[21401.160720] rpi_pwm: disagrees about version of symbol module_layout
[22026.927225] rpi_pwm: disagrees about version of symbol module_layout
[26733.475758] Adafruit Industries' Raspberry Pi PWM driver v1.0

If you want your module to auto start:

  • Copy your .ko module to /lib/modules/3.2.27+
  • Edit /etc/modules and append your module to the end of the list.
    Mine looks like:

    # /etc/modules: kernel modules to load at boot time.
    #
    # This file contains the names of kernel modules that should be loaded
    # at boot time, one per line. Lines beginning with "#" are ignored.
    # Parameters can be specified after the module name.

    snd-bcm2835
    spi-bcm2708
    i2c-bcm2708
    i2c-dev
    rpi-pwm

  • Next, run: depmod -a
  • Next, run: modprobe <yourmodulename>

Then reboot and your module should auto start on boot.

Hope that helps!
Brian Chavez

Comments

# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Brian, thank you very much for writing this!

Actually -with my limited knowledge in linux- i have been struggling for almost 6 days to compile a stk1160 Module for my new Raspberry Pi.
Following your explanation (simple copy and paste ;)) i was successful!!! I used a VM with Ubuntu 12.04 for cross-compiling.

I hope you don't mind that i tell you about a few things i stubled across:

1) Its not "tar xzf tools.tar.gz" but "tar xzf master.tar.gz"

2) "In KEREL_SRC": should be: "In KERNEL_SRC"

3) 2 things in this line:

scp [email protected]:/proc/config.gz ./; zcat config.gz > .config; mv .config $KEREL_SRC

did not work...

sudo scp [email protected]:/proc/config.gz ./; zcat config.gz > .config; mv .config $KERNEL_SRC

..did.

Thanks again

Joerg
Left by JoeDeb on 1/17/2013 11:30 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Thanks, updated with your edits/suggestions.

-cowboy
Left by Brian Chavez on 1/17/2013 11:54 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Brian, this is actually a concise explanation as to how to compile a kernel for the RPi, kudos.
However, the most recent O/S contains a WiFi driver module which is not suitable for the EDIMAX-EW7811 (requires Realtek rtl8192cu driver). Since compiling is not my forte, I wonder if you could expand your explanation to cover this issue in order to add or compile this driver to the Kernel.
I think that this would help quite few of us who struggle with the same predicament.
Left by Heri on 1/29/2013 2:21 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Great guide, thanks!

For those using a 64-bit install of Ubuntu, you have to have the ia32-libs package otherwise you get some very strange errors about missing files. For a fresh install of Ubuntu, its best to just do: "sudo apt-get install build-essential ia32-libs"
Left by Brain_ReCall on 1/29/2013 7:02 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Great guide, I was also stuck trying to compile a module on the rpi itself, but your guide works like a charm and cross compiling is better anyway for performance reasons.
Left by Martin on 2/22/2013 12:41 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Hi Brian,

I ran into a problem trying to follow your section 2. above.

The driver (directory) supplied by Realtek for the Edimax WiFi device contains a bunch of subdirectories and files such as:Makefile, include, clean,etc.

1. Would the driver directory be the equivalent of your example ~/pwm ?
2. Should the driver directory be part of the KERNEL_SRC directory?

The issue is somwhat confusing since the KERNEL_SRC and the WIFi driver directory contain a Makefile albeit dissimilar in contents.

Your help very much appreciated.
BTW-Compiling the Kernel, as per your instructions of para.1, went without problems.

Left by Heri on 2/23/2013 11:48 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Great guide. Martin, thanks a lot. I ran into the same issue on 64-bit ubuntu. your suggestion works fine. thanks
Left by rpi on 3/11/2013 12:16 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Thank you so much.
Left by Stacey on 9/15/2013 3:19 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar small typo remove .

zcat config.gz > .config
should be
zcat config.gz > config
Left by PeterK on 9/17/2013 11:07 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Sorry, pls forget previous post. No typo!
Left by PeterK on 9/17/2013 2:28 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar The instructions worked with 3.6.11 source as well when I replaced 3.2.27 with 3.6.y in the instructions given above. Thanks a ton for your guide!
Left by Krishna on 9/30/2013 3:11 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar works perfectly, thank you;)
Left by Sorin on 10/6/2013 6:24 AM
# Version ARM
Gravatar I did all the steps, but didn't work. I've noticed that my modinfo says 3.6.11 preempt mod_unload modversions ARMv5, instead of v6.

I used ubuntu 12.04
Left by fabrizio on 11/17/2013 4:18 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Hi, I have compiled a kernel successfully using cross tool chain.

I am using Ubuntu installed in VM and Raspbian V3.6.11 running in Raspberry pi board.

I have written a simple code for device driver and compiled it using make file.

I got following errors

make ARCH=arm CROSS_COMPILE= -C /home/saurabh/rpiRaspi M= modules
make[1]: Entering directory `/home/saurabh/rpiRaspi'
CHK include/linux/version.h
CHK include/generated/utsrelease.h
make[2]: `include/generated/mach-types.h' is up to date.
CC kernel/bounds.s
cc1: error: unrecognized command line option ‘-mlittle-endian’
cc1: error: unrecognized command line option ‘-mno-thumb-interwork’
kernel/bounds.c:1:0: error: unknown ABI (aapcs-linux) for -mabi= switch
kernel/bounds.c:1:0: error: bad value (armv5t) for -march= switch
kernel/bounds.c:1:0: error: bad value (strongarm) for -mtune= switch
make[2]: *** [kernel/bounds.s] Error 1
make[1]: *** [prepare0] Error 2
make[1]: Leaving directory `/home/saurabh/rpiRaspi'
make: *** [all] Error 2

Please provide suggestion to solve it!!
Left by Saurabh on 1/7/2014 12:51 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar I am using 64bit ubuntu 12.4 to cross compile rpi (3.6.11) kernel modules. I followed the above steps and compiled the kernel crc successfully. But, I am seeing errors when I compile kernel modules. Here is the errors I am seeing.

make ARCH=arm CROSS_COMPILE= -C /home/rppendya/rpi/linux-rpi-3.6.y M=/home/rppendya/workspace/ds1307 modules
make[1]: Entering directory `/home/rppendya/rpi/linux-rpi-3.6.y'
CC [M] /home/rppendya/workspace/ds1307/ds1307.o
cc1: error: unrecognized command line option ‘-mlittle-endian’
cc1: error: unrecognized command line option ‘-mno-thumb-interwork’
/home/rppendya/workspace/ds1307/ds1307.c:1:0: error: unknown ABI (aapcs-linux) for -mabi= switch
/home/rppendya/workspace/ds1307/ds1307.c:1:0: error: bad value (armv5t) for -march= switch
/home/rppendya/workspace/ds1307/ds1307.c:1:0: error: bad value (strongarm) for -mtune= switch
make[2]: *** [/home/rppendya/workspace/ds1307/ds1307.o] Error 1
make[1]: *** [_module_/home/rppendya/workspace/ds1307] Error 2
make[1]: Leaving directory `/home/rppendya/rpi/linux-rpi-3.6.y'
make: *** [all] Error 2

Any help and advise would be appreciated
Left by praneeth on 1/10/2014 1:30 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Excellent tutorial! I was having problems compiling a module on the rpi itself ...

Thanks!
Left by Andre Carvalhosa on 1/23/2014 3:50 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar For Saurabh, paraneeth, and others who find this page later and are looking for a solution to that problem,
The problem is you are invoking the standard, x86 gcc and asking it to compile for arm. Naturally, standard x86 gcc has no idea how to do this, so is throwing a bunch of errors back at you.
If you're coping Brian's Makefile, be sure you have your CCPREFIX set to point to your cross-toolkit, as Brian did in step 1. export CCPREFIX=
/home/cowboy/rpi/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi- (Your toolkit will probably be somewhere different! You should have downloaded it as part of the tools tarball)
Left by Simon on 6/9/2014 8:14 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar hi Brian and everyone:
thank you for this writing!!

I have some problem in the kernel building. After Build the kernel:
"make ARCH=arm CROSS_COMPILE=${CCPREFIX}"
([email protected]:/media/sf_F_DRIVE/TI_D/RaspberryPi/srcTree/linux-rpi-3.12.y$ sudo make ARCH=arm CROSS_COMPILE=/home/firmament/rpi/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
)


This error happened
---------------------------------
mkdir -p include/generated
scripts/kconfig/conf –silentoldconfig Kconfig

*** Error during update of the configuration.

make[2]: *** [silentoldconfig] Error 1
make[1]: *** [silentoldconfig] Error 2
make: *** No rule to make target `include/config/auto.conf’, needed by `include/config/kernel.release’.
------------------------------------

could you give me some suggestions or tell me which part I need to check first
Thank you very much
Left by TIK on 8/23/2014 6:51 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Hi Brian& everyone:
first time I tried to compile kernel was failed at
"make ARCH=arm CROSS_COMPILE=${CCPREFIX}"
with error:

scripts/kconfig/conf --silentoldconfig Kconfig

*** Error during update of the configuration.

make[2]: *** [silentoldconfig] Error 1
make[1]: *** [silentoldconfig] Error 2

The reason was related to the permission in my Ubuntu. After I moved the source tree to my home folder, this problem had been solved.

But after about an hour compiling, another error happened. Could you give me some suggestions? Thanks

make[1]: `include/generated/mach-types.h' is up to date.
CALL scripts/checksyscalls.sh
CHK include/generated/compile.h
CHK kernel/config_data.h
make[2]: *** No rule to make target `net/bridge/br_fdb.o', needed by `net/bridge/bridge.o'. Stop.
make[1]: *** [net/bridge] Error 2
make: *** [net] Error 2
Left by TIK on 8/23/2014 11:51 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Thanks!

FYI To get the latest 3.12.32+ source I did.
mkdir ~ray/meinberg
cd ~ray/meinberg
wget https://github.com/raspberrypi/tools/archive/master.zip
unzip master.zip

git clone https://github.com/raspberrypi/linux.git

export CCPREFIX=/home/ray/meinberg/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
export KERNEL_SRC=/home/ray/meinberg/linux
cd linux/
make mrproper

etc.

One hiccup for me. NEWBIE ALERT. When copying the Makefile example above, make sure that the character before 'make' is a TAB and not multiple spaces. Arrgh. Otherwise you get the error: "make: Nothing to be done for `all'." Took me ages to find that.
Left by Ray on 11/22/2014 8:48 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar cp [email protected]:/proc/config.gz ./
ssh: connect to host raspberrypi port 22: Connection timed out
How to solve this.

Thank you
Left by marvic on 4/9/2015 11:01 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Hello,
When I try to set up an environment it gives following error
bash: export: `/home/ganesh/RPICComp/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-': not a valid identifier

I have stored my tool master folder in home/ganesh/RPICComp/
and Kernel virsion is 3.18.y

I am using following command for setting up the Environment
export CCPREFIX= /home/ganesh/RPICComp/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-

Kindly Guide Me
Thank You
Left by Ganesh on 4/18/2015 12:16 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Have you any idea where to find the kernel version 3.10.25+ ??
Left by don on 4/27/2015 2:49 AM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar where do I find kernel version 3.18.14+
Left by John on 6/15/2015 11:18 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar This doesn't work at least not for building an rpi module for the edimax ew-7811uac ac600. i got a bunch of warnings/errors when i ran the ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig step. i have no clue how to configure the kernel so i accepted the defaults so i got a bunch of errors instead when i tried to build the kernel. but i was able to build the kernel (error free) merely by copying the proc/config.gz from my rpi and overwriting the .config in linux-rpi-3.18.y directory and skipping the above mentioned step.

I’m doing this on linux mint 17.1 (more or less ubuntu) which may or may-not (i suspect not) make a difference.

I put everything as indicated in my home directory
ls -1 ~/EDIMAX-COMPILE/RPI
linux-rpi-3.18.y
rtl8812au-master
tools-master

I created a directory outside the RPI directory and created the makefile as follows:
obj-m += 8812au.o

all:
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -C /home/maihoa/EDIMAX-COMPILE/RPI/linux-rpi-3.18.y M=$(PWD) modules

clean:
make -C /home/maihoa/EDIMAX-COMPILE/RPI/linux-rpi-3.18.y M=$(PWD) clean

and made sure i had the TAB before make

The evn vars appear to be correct
echo $CCPREFIX
/home/maihoa/EDIMAX-COMPILE/RPI/tools-master/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
[email protected] ~/EDIMAX-COMPILE/RPI-8812au-module $ echo $KERNEL_SRC
/home/maihoa/EDIMAX-COMPILE/RPI/linux-rpi-3.18.y

My rpi kernel is: uname -a
Linux raspberrypi 3.18.14+ #794 PREEMPT Sun Jun 7 12:02:04 BST 2015 armv6l GNU/Linux

what i don't understand in the Makefile script is how does it know that i want to build a module for rtl8812au-master. I can’t get it to work.

What am i doing wrong?

Thanks
John
Left by John on 6/20/2015 2:46 PM
# re: Compiling Kernel Modules for Raspberry Pi
Gravatar Thanks for this blog, it works, now i can able to compile module files on my PC and tested on rspi board.

thankyou.
Left by Sai on 7/16/2016 7:25 PM

Leave Your Comment

Title*
Name*
Email (never displayed)
 (will show your gravatar)
Url
Comment*

Please add 1 and 2 and type the answer here:

Preview Your Comment.