My Raspberry Pi currently runs 3.6.11+ #538 (obtained from uname -a), which may be the source of my issues. I'm starting to write a kernel module using the following "Hello World" code:

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>

static int __init gotemp_init(void)
    printk(KERN_INFO "Hello from the kernel!\n");
    return 0;

static void __exit gotemp_exit(void)


MODULE_AUTHOR("My name here");
MODULE_DESCRIPTION("Simple driver");

And a make file:

obj-m   := hello.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

    $(MAKE) -C $(KERNELDIR) M=$(PWD)

    rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c

Source slides/demo code here

I ran into an issue that 3.6.11+'s Linux headers were not released nor installable via apt-get, but I did find with Google that there were .deb files with the needed headers found here. Kernel modules obviously cannot be compiled without the kernel headers, so this seems to have been a fix.

Until I run:

insmod ./hello.ko

which spits out a segmentation fault. I read that is can be due to a mismatch of the running kernel and the kenel compiled against, but as far as I know, the two match up. Is there something I am missing?

I attempted to download the latest kernel from github.com/raspberrypi/linux and build from that. The kernel version I got from git fetch git@github.com:raspberrypi/linux rpi-3.6.y:refs/remotes/origin/rpi-3.6.y ended up being 3.6.11 #1. I attempted to compile and run with the new kernel and ended up with:

Error: could not insert module hello.ko: Invalid module format.

I know I want to run with 3.6 and not 3.4, because according to Linux Programming, <3.4 has bad drivers for USB. I need the working version of these drivers in 3.6.

After rebuilding the kernel again, I finally have the module running, but I don't know what version of the kernel I am running, ref. How to tell if I am running the latest version of the raspbian kernel.

It seems that by building the kernel from the repository myself, I don't get the benefit of knowing exactly what version of the kernel I am running, except that it is the bleeding edge of the 3.6.11+ branch according to https://raspberrypi.stackexchange.com/a/10432/10085. Yay?

  • You can catch these errors somehow- I forgot how, hence the comment instead of answer. Segmentation fault can mean anything and should never happen. When they do its a very specific error that needs to be debugged. Sometimes its corruption, permissions or something else. – Piotr Kula Oct 24 '13 at 13:57

Could you be more specific on the kernel version (use uname -a, some of the 3.6.11+ kernels are not compatible with each other, for example #538 and onwards do not match earlier revisions).

The code you have there seems fine, but I think the build instruction for all needs to have modules after it, e.g. $(MAKE) -C $(KERNELDIR) M=$(PWD) modules.

For reference the makefile I use for doing this is as follows:

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
obj-m := ledborg.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:    driver

rebuild:    clean driver

    rm -rf .tmp_versions
    rm -f .*.cmd
    rm -f Module.symvers
    rm -f modules.order
    rm -f *.ko
    rm -f *.o
    rm -f *.mod.*
    rm -f ../ledborg.ko

    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    cp ledborg.ko ../ledborg.ko

it does a couple of extra bits, but I think you may also need the conditional lines ifneq ($(KERNELRELEASE),), else, and endif in the same places (the build gets double-invoked for kernel modules...)

If you are using the latest kernel (sudo apt-get update followed by sudo apt-get upgrade) then you should be able to use the following to pull the correct headers and symbol file from the version control system used to generate the builds in the first place:

cd /usr/src
wget -O rpi-`uname -r`.tar.gz https://github.com/raspberrypi/linux/tarball/rpi-3.6.y
rm -rf raspberrypi-*
tar xzf rpi-`uname -r`.tar.gz
cd raspberrypi-*
pushd /lib/modules/`uname -r`
rm source
rm build
ln -s ${KSRC} source
ln -s ${KSRC} build
pushd /usr/src
rm linux-`uname -r`
rm linux
ln -s ${KSRC} linux-`uname -r`
ln -s ${KSRC} linux
zcat /proc/config.gz > .config
make oldconfig
make modules_prepare
wget -O Module.symvers https://github.com/raspberrypi/firmware/raw/master/extra/Module.symvers

I have used this for building the LedBorg kernel drivers when they release new versions, I have made a script out of the commands that you can download and run using

cd ~
wget -O get-kernel-source.sh http://piborg.org/downloads/get-kernel-source.txt
chmod +x get-kernel-source.sh
sudo ~/get-kernel-source.sh

which should leave you with a script to run again if you update the kernel and need to rebuild the kernel module.

  • I was looking around for how one even generates the headers, but most documentation skips over generating them and just tells you to get them from the distribution repo. – Nielsvh Oct 24 '13 at 15:12
  • 1
    The thing is that it works the other way around, the kernel itself is built using those headers, the idea is that your module should be built against the exact same headers. – PiBorg Oct 24 '13 at 20:00
  • I should have been more specific. 'Extracting the headers' would have been a better phrasing, since I have the release code for the kernel. – Nielsvh Oct 24 '13 at 20:34
  • Welp, now I have 3.6.11+ #1 instead of #358 and I get the error: "Error: could not insert module hello.ko: Invalid module format" – Nielsvh Oct 28 '13 at 19:09
  • #1 sounds odd, not to mention it implies an old copy, could you show the whole version details from uname -a... – PiBorg Oct 29 '13 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.