Chapter 2. Building and Running Modules
Hello World Module
π‘ Full code in Chapter 2
Here, we are implementing the easiest form of scull module by mimicking the one shown in the book.
main.c
/*
* Gaby Kim -- Linux Device Driver with linux 6.7.0
*
* Original Code from "main.c -- the bare scull char module"
* Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
* Copyright (C) 2001 O'Reilly & Associates
*
* This file includes modifications by Gaby, Kim
* on 12/23/2023
*
* The source code in this file is based on code from the book "Linux Device
* Drivers" by Alessandro Rubini and Jonathan Corbet, published by O'Reilly & Associates.
* The original code can be freely used, adapted, and redistributed in source or binary form,
* so long as an acknowledgment appears in derived source files.
*
* No warranty is attached to the original code and this modified version;
* neither the original authors nor [Your Name or Your Organization] can take
* responsibility for errors or fitness for use.
*
*/
#include <linux/init.h>
#include <linux/module.h>
MODULE_AUTHOR("Gaby, Kim");
MODULE_DESCRIPTION("scull device driver in Linux Device Driver with linux 6.7.0");
MODULE_LICENSE("GPL v2");
static int __init scull_init_module(void)
{
pr_debug("scull module loaded\n");
return 0;
}
// cleanup function can't be marked as __exit, if it's used else where other than module_exit
static void __exit scull_cleanup_module(void)
{
pr_debug("scull module unloaded\n");
};
module_init(scull_init_module);
module_exit(scull_cleanup_module);Notes
scull_clean_upfunction is marked__exithere, since it is only called duringmodule_exit- Followings are the two methods I used to monitor the
printkmessagesthrough sudo dmesg | tail command, withkernel.printk = 7 4 1 7is set in/etc/sysctl.conf- default
rsyslogrule dumps all the kernel messages into/var/log/kern.log, hence kernel messages can also be monitored throughcat /var/log/kern.log | tailcommand
- If you still canβt see the
printkmessages or the messages seem delayed, you might have forget the\ncharacter. https://unix.stackexchange.com/questions/167655/module-prints-to-kernel-log-with-delay
Modern Linux kbuild
Now comes the fun part regarding Makefile. Modern Linux kernel has a more complex build system called kbuild. References for the related documents are as below.
Kconfig
There are three Kconfig files in total to make our device driver into a loadable module of the Linux source tree.
{YOUR LINUX SOURCE TREE}/drivers/{LDD DIRECTORY}/scull/Kconfigdefine the configuration symbols for your scull device driver
config SCULL
tristate "Scull driver by Gaby, Kim"
depends on LDD
help
This is scull device driver based on Linux Device Drvier, 3rd edition,
compatible with linux 6.7.0, Authored by Gaby, Kim.{YOUR LINUX SOURCE TREE}/drivers/{LDD DIRECTORY}/Kconfigwill source all theKconfigfiles in subdirectories
menuconfig LDD
bool "Linux Device Driver by Gaby Kim"
help
This is the menu for drivers related to
Linux Device Driver 3rd edition, compatible with
linux 6.7.0
source "drivers/gakim/scull/Kconfig"- Lastly,
{YOUR LINUX SOURCE TREE}/drivers/Kconfigwill source the LDDKconfigso that all the configurations do appear in yourmenuconfig
...
source "drivers/{LDD DIRECTORY}/Kconfig"
...
endmenuAfter all the above Kconfigs are set, you will be able to find and change the configuration symbols in make menuconfig as below

Makefile
We are now ready to implement the Makefile, and it looks quiet different from the one shown in the book
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-$(CONFIG_SCULL) += scull.o
scull-y := main.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KDIR ?= ~/kernels/staging
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
endif
# dependency tracking in modern kernel is document in
# https://github.com/torvalds/linux/blob/master/Documentation/kbuild/makefiles.rst#dependency-trackingscull-ydefines all the required source codes to buildscull.oobj-$(CONFIG_SCULL)symbol will handle the module configuration for usKDIRvariable should be set to the directory of our kernel source tree
With above Makefile, we can execute make or make clean directly in the directory of scull device driver, and it will find the kernel build system and then trigger corresponding targets for us.
I have tested the
Makefileshown in the book and it also worked. However, codes from now on are all made through the modernkbuildsystem.
Notes
- If modules are not built with
makecommand, make sureCONFIG_SCULLandCONFIG_LDDare properly set in your.configfile