Linux device drivers
May 12, 2017
Environment setup
You need linux headers to be able to compile new module.
To make sure you have linux headers, see if the following path exists:
$ ls /usr/src/linux-headers-`uname -r`
arch crypto drivers fs init Kbuild kernel
...
If the above directory is not present, you can install the headers using:
sudo apt-get update && sudo apt-get install linux-headers-$(uname -r)
Once the headers are installed you are good to go.
Writing hello module
To start off, create the following file in any directory.
// hello.c
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
Create the following Makefile to compile your module.
obj-m := hello.o
KDIR := /usr/src/linux-headers-3.2.0-23-generic
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
After running make
, you should see following:
# Check that *.ko is created.
vagrant@precise64:~$ ls
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile
...
# Install the module.
vagrant@precise64:~$ sudo insmod hello.ko
# Confirm the it's installed.
vagrant@precise64:~$ lsmod | grep hello
hello 8217 0
# Remove the module.
vagrant@precise64:~$ sudo rmmod hello
# Confirm that it's removed.
vagrant@precise64:~$ lsmod | grep hello
Expanding further, each module needs to have an init and exit method.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void) {
printk("<1> Hola Mundo!\n");
return 0;
}
static void hello_exit(void) {
printk("<1>Hasta Luego\n");
}
module_init(hello_init);
module_exit(hello_exit);
Again, use inmod
to install the command and you should see Hola Mundo! in dmesg
. printk
is important here; as kernel will print it to the syslog
. Pretty useful in understanding other drivers.