The codes on the post are from the Linux kernel module programming guide 1.
A Linux kernel module is a piece of compiled binary code that is inserted directly into the Linux kernel 2. The important kernel module commands are as follows:
insmod
: Install a modulermmod
: Remove a modulelsmod
: Show status of loaded modules by reading/proc/modules
modprobe
: Add/remove modules from the kernel (consider dependency)depmod
: Generatemodules.dep
andmap
files
Now let’s start playing with some kernel modules!
// m_hello_1.c
#include <linux/module.h> // for kernel module
#include <linux/kernel.h> // for KERN_INFO
int init_module(void) {
printk(KERN_INFO "Hello world 1\n");
return 0; // init_module module succeeded
}
void cleanup_module(void) {
printk(KERN_INFO "Goodbye world 1\n");
}
This is old style kernel module. init_module()
is called when the module is loaded (by executing insmod
), and cleanup_module()
is called when the module is removed (by executing rmmod
). A Makefile for the source code is as follows.
obj-m += m_hello_1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
After writing Makefile, I can generate m_hello_1.ko
by running make
(run make clean
to remove it).
Installing and removing m_hello_1
module is done by running insmod
and rmmod
.
shnoh@shnoh-p6-2270kr:~/kmod$ sudo insmod m_hello_1.ko
shnoh@shnoh-p6-2270kr:~/kmod$ dmesg | grep Hello
[6000342.646421] Hello world 1
shnoh@shnoh-p6-2270kr:~/kmod$ sudo rmmod m_hello_1
shnoh@shnoh-p6-2270kr:~/kmod$ dmesg | grep Goodbye
[6000365.592283] Goodbye world 1
We can rename init_module()
and cleanup_module()
using __init
and __exit
macros, respectively. The code is shown in m_hello_2.c
.
#include <linux/module.h> // for kernel module
#include <linux/kernel.h> // for KERN_INFO
#include <linux/init.h> // for macros
static int __init hello_2_init(void)
{
printk(KERN_INFO "Hello world 2\n");
return 0;
}
static void __exit hello_2_exit(void)
{
printk(KERN_INFO "Goodbye world 2\n");
}
module_init(hello_2_init);
module_exit(hello_2_exit)
Building, installing and removing the module m_hello_2
are as same as m_hello_1
.
In m_hello_3
, I added __initdata
which is only used in the initialization process. Also, I added license and driver information.
#include <linux/module.h> // for kernel module
#include <linux/kernel.h> // for KERN_INFO
#include <linux/init.h> // for macros
#define DRIVER_AUTHOR "Soonhyun Noh <xxxxx@redwood.snu.ac.kr>"
#define DRIVER_DESC "Sample driver"
static int hello3_data __initdata = 3;
static int __init hello_3_init(void)
{
printk(KERN_INFO "Hello world %d\n", hello3_data);
return 0;
}
static void __exit hello_3_exit(void)
{
printk(KERN_INFO "Goodbye world 3\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
module_init(hello_3_init);
module_exit(hello_3_exit);
-
Peter Jay Salzman, Micheal Burian and Ori Pomerantz, “The Linux Kernel Module Programming Guide,” 2001. ↩
-
https://blog.sourcerer.io/writing-a-simple-linux-kernel-module-d9dc3762c234 ↩
Comments