Skip to content

Kernel Module 1 Hello World

Frank Bauernöppel edited this page Oct 27, 2018 · 10 revisions

My module version 1: "Hello world"

Kernel modules are mostly written in C, but the usual library functions like malloc, fopen, close, must not be used because their implementation is targeted to user space. Several more restrictions apply.

The build process is executed on the much more powerful Build Host from within a bitbake shell. A working Yocto image and therefore the Linux kernel should already have been built from that bitbake shell.

On the build host create a new, empty folder my_module and remember the absolute path to this folder, something like /home/user/my_module.

In that folder create two files:

  • a source code file my_module.c
  • a Makefile

my_module.c

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

static int __init my_init(void)
{
    printk(KERN_INFO "hello, my module\n");
    return 0;
}

static void __exit my_exit(void)
{
    printk(KERN_INFO "good bye, my module\n" );
}

module_init(my_init);
module_exit(my_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("F.B.");
MODULE_DESCRIPTION("My First Kernel Module");

Makefile

This can be a one liner:

obj-m += my_module.o

build module

On the build host, open a bitbake shell and launch a kernel development shell for cross-compilation:

$ bitbake -c devshell virtual/kernel

The last command opens a new shell. This is the kernel development shell (devshell) which is used for the next steps. The kernel development shell has a number of environment variables set for cross-compilation. You can test this by invoking the gcc cross-compiler for the board:

root:kernel-source$ arm-poky-linux-gnueabi-gcc --version
arm-poky-linux-gnueabi-gcc (GCC) 6.2.0
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Next module will be build (compiled and linked) "out-of-tree" in its own folder, say /home/user/my_module as created above. Note that make must be executed from the kernel source directory, so don't change the current devshell directory!

root:kernel-source$ make modules M=/home/user/my_module

The make command generates several files in the module directory. The resulting kernel module is my_module.ko (.ko = "kernel object").

Test the kernel module

Copy my_module.ko to the target board.

On the target board, load the module into the currently running Linux kernel space:

root@raspberrypi:~ $ insmod my_module.ko
root@raspberrypi:~ $ dmesg | tail
hello, my module

and unload it:

root@raspberrypi:~ $ rmmod my_module.ko
root@raspberrypi:~ $ dmesg | tail
good bye, my module

useful commands:

| lsmod | list currently installed (loaded) modules | | modinfo my_module.ko | output module info | | insmod my_module.ko | install (load) module | init function will be executed | | rmmod my_module | uninstall (unload) module | exit function will be executed | | modprobe | convenience function, see man page |

Kernel Module 2 - Char Device shows how to communicate with the kernel module from a user mode process.