Write kernel modules

From wiki.network-crawler.de
Jump to: navigation, search

Just for the sake of fun

I think every linux nerd should know how to write a "Hello, World" kernel module. Here is it to copy and paste it right into your shell:

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

static int hello_init(void) {
 printk(KERN_ALERT "I feel like DOS did!\n");
}

static void hello_exit(void) {
 printk(KERN_ALERT "Fire!, fire!, help me!"); //From the IT Crowd :)
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("IT Crowd");

If you don't know what "IT Crowd is" look here for your own pleasure.

Ok now some explanation

The functions are registered via module_init() and module_exit() as entry and exit point. They should have the form xx_init or xx_exit where xx - you know! We don't need to export the functions therefor it's ok to set them static. There are not directly called by external code.
The init function should return 0 if initialisation was successful else return nonzero.

How to build the module

In the source Tree

Drivers live in

drivers/

In drivers/ are subdirectories organized by class, type, ...
Character devises are in

drivers/char/

Block devises in

drivers/block

and so on

You will find the right place for your driver!

In this example we create our own subdirectory:

cd /usr/src/linux/drivers/char/
mkdir hello

Then we must edit the Makefile at drivers/char/

echo "obj-m += hello/" >> Makefile

The build system will chdir to hello/ when compiling the modules
If the compilation of our driver is contingent an a specific configuration option we could add something like this:

obj-$(CONFIG_HELLO) += hello/

Good now we create a new makefile inside drivers/char/hello/

echo "obj-m += hello.o" > hello/Makefile

If we want to compile is conditional to a configuration option:

echo "obj-$(CONFIG_HELLO) += hello.o" >> hello/Makefile

In case there are more dependencies simply add

echo "hello-objs := module1.o module2.o" >> hello/Makefile

Then the Modules will be also compiled into hello.ko
To pass gcc additional compile flags we can do:

echo "EXTRA_FLAGS += -Dxxx" >> hello/Makefile

Where xxx are the flags.

Externally

This is more simple. We just add to our makefile in our prefered source path

echo "obj-m := hello.o" >> Makefile

Or with more dependecies again

echo "hello-objs := module1.o module2.o" >> Makefile

and so on
To instruct the kernel build system to compile these outsiders do something like this

make -C /usr/src/linux SUBDIRS=/your_source modules

or if your sources are in your actual directory

make -C /usr/src/linux SUBDIRS=$PWD modules

How to install the module

This is the most difficult thing about kernel modules. Do

make modules_install

To load them as you already know as a geek do (in our scenario)

insmod hello

With dependecy resolution do

modprobe hello

Removing modules:

rmmod hello

To remove with modprobe do

modprobe -r hello

Thats it - I hope you have fun!