Skip to content

helloworld

Rafael do Nascimento Pereira edited this page Jul 2, 2014 · 6 revisions

What is it for ?

Introduce the basic concepts and a simple driver "skeleton" with typical functions used to write a device driver and how to compile it.

Looking at the code

As the name says, this driver just "prints" (sends to syslog) a "hello, world" message. This a very simple piece of code that shows the very basic of the Linux device drivers development. First we include the necessary header files:

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

The next spet is to include the driver entry and exit point to the Kernel:

static int hello_init(void)
{
        pr_alert("Hello, world\n");
        return 0;
}

static void hello_exit(void)
{
        pr_alert("Goodbye, cruel world\n");
}

As we can see we use the printk function to print the hello, world message. The argument KERN_ALERT is used to inform how important the message to be printed is. The table bellow list all values:

Name Value Description
KERN_EMERG 0 system is unusable
KERN_ALERT 1 action must be taken immediately
KERN_CRIT 2 critical conditions
KERN_ERR 3 error conditions
KERN_WARNING 4 warning conditions
KERN_NOTICE 5 normal but significant condition
KERN_INFO 6 informational
KERN_DEBUG 7 debug-level messages

The printk funcion can be found in the file include/linux/printk.h and kernel/printk.c. In fact the kernel developers use macros as wrappers for printk, according to the message severity, e.g. pr_debug, pr_info, pr_notice and so on.

And in order to tell the Kernel the device driver's entry and exit point, we use the following macros:

module_init(hello_init);
module_exit(hello_exit);

And their corresponding declaration and implementation can be found at include/linux/module.h and kernel/module.c.

After compiling the driver, you execute sudo insmod helloworld.ko and you shall see at the syslog the hello, world message. To unload the driver from memory execute sudo rmmod helloworld.ko and you shall see the message Goodbye, cruel world.

And in order to compile the driver code the following Makefile is used:

TARGET = helloworld

ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m	:= $(TARGET).o

else

KERNELDIR ?= ~/src/linux
PWD := $(shell pwd)

default:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
endif

clean:
rm -rf *.o *.ko *~ core .depend *.mod.c .*.cmd .tmp_versions .*.o.d \
*.order *.symvers

depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend

ins: default rem
insmod $(TARGET).ko debug=1

rem:
@if [ -n "`lsmod | grep -s $(TARGET)`" ]; then \
rmmod $(TARGET); \
echo "rmmod $(TARGET)"; \
fi

ifeq (.depend,$(wildcard .depend))
include .depend
endif

Executing the code

Run make to compile it. Run sudo make ins or sudo insmod helloworld.ko to insert the driver (AKA module) in the Linux Kernel memory space. Then take a look at the kernel log and you should see the following lines:

Jun 16 21:09:19 localhost kernel: [42127.560470] Hello, world
Jun 16 21:09:25 localhost kernel: [42133.989496] Goodbye, cruel world
Clone this wiki locally