Chapter 3
Chapter 3
[ 61 ]
The Simplest Drivers Chapter 3
There is a collection of macros used to identify various attributes of a module. These strings get
packaged into the module and can be accessed by various tools. The most important module
description macro is the MODULE_LICENSE macro. If this macro is not set to some sort of GPL
license tag, then the kernel will become tainted when you load your module. When the kernel
is tainted, it means that it is in a state that is not supported by the community. Most kernel
developers will ignore bug reports involving tainted kernels, and community members may ask
that you correct the tainting condition before they can proceed with diagnosing problems related
to the kernel. In addition, some debugging functionality and API calls may be disabled when the
kernel is tainted.
Licensing
The Linux kernel is licensed under the GNU General Public License version 2. This license gives
you the right to use, study, modify and share the software freely. However, when the software is
redistributed, modified or unmodified, the GPL requires that you redistribute the software under
the same license, with the source code. If modifications are made to the Linux kernel (for example
to adapt it to your hardware), it is a derivative work of the kernel and therefore must be released
under GPLv2. However, you're only required to do so at the time the device starts to be distributed
to your customers, not to the entire world.
The kernel modules provided in this book are released under the GPL license. For more
information on open source software licenses, please see http://opensource.org/licenses.
Where KERN_ERR is one of the eight different log levels defined in include/linux/kern_levels.h in
the kernel source tree and specifies the severity of the error message. The pr_* macros (defined in
include/linux/printk.h in the kernel source tree) are simple shorthand definitions for their respective
printk calls and should be used in newer drivers.
In the home folder of your host PC, you will create the linux_5.4_rpi3_drivers folder, where you are
going to store all the drivers and applications developed through this book.
~$ mkdir linux_5.4_rpi3_drivers
[ 62 ]
Chapter 3 The Simplest Drivers
Create the helloworld_rpi3.c and Makefile files using your favorite text editor, and save them in
the linux_5.4_rpi3_drivers folder. Write the Listing 3-1 code and the Listing 3-2 code to these files.
Secure Copy (SCP) will be added to the Makefile to transfer the modules from the host PC to the
Raspberry Pi filesystem via Ethernet:
scp *.ko root@10.0.0.10:
The same Makefile will be reused for many of the labs by simply adding the new <module name>.o
to the Makefile variable obj-m.
Compile the helloworld_rpi3.c driver, and deploy it to the Raspberry Pi:
~/linux_5.4_rpi3_drivers$ make
~/linux_5.4_rpi3_drivers$ make deploy
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alberto Liberal <aliberal@arroweurope.com>");
KERNEL_DIR ?= $(HOME)/linux_rpi3/linux
all:
make -C $(KERNEL_DIR) \
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \
M=$(PWD) modules
[ 63 ]
The Simplest Drivers Chapter 3
clean:
make -C $(KERNEL_DIR) \
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \
M=$(PWD) clean
deploy:
scp *.ko root@10.0.0.10:/home/pi
helloworld_rpi3.ko demonstration
Load the module:
root@raspberrypi:/home/pi# insmod helloworld_rpi3.ko
Hello world init
See the MODULE macros defined in your module:
root@raspberrypi:/home/pi# modinfo helloworld_rpi3.ko
filename: /home/pi/helloworld_rpi3.ko
description: This is a print out Hello World module
author: Alberto Liberal <aliberal@arroweurope.com>
license: GPL
srcversion: F329256EE5AE6A9F62F65DF
depends:
name: helloworld_rpi3
vermagic: 5.4.83-v7+ SMP mod_unload modversions ARMv7 p2v8
An externally-built (“out-of-tree”) untainted module has been loaded:
root@raspberrypi:/home/pi# cat /sys/module/helloworld_rpi3/taint
O
Remove the module:
root@raspberrypi:/home/pi# rmmod helloworld_rpi3.ko
Hello world exit
Comment out the MODULE_LICENSE macro in the helloworld_rpi3.c file. Build, deploy and load the
module again. Reboot the Pi!. Work with your tainted module (PO):
root@raspberrypi:/home/pi# reboot
root@raspberrypi:/home/pi# insmod helloworld_rpi3.ko
helloworld_rpi3: module license 'unspecified' taints kernel.
Disabling lock debugging due to kernel taint
Hello world init
root@raspberrypi:/home/pi# cat /proc/sys/kernel/tainted
PO
root@raspberrypi:/home/pi# cat /proc/modules
helloworld_rpi3 16384 0 - Live 0x7f1b6000 (PO)
Find your module in the sysfs:
root@raspberrypi:/home/pi# find /sys -name "*helloworld*"
/sys/module/helloworld_rpi3
[ 64 ]
Chapter 3 The Simplest Drivers
root@raspberrypi:/home/pi# ls /sys/module/helloworld_rpi3/
coresize initsize notes sections taint
holders initstate refcnt srcversion uevent
Remove the module:
root@raspberrypi:/home/pi# rmmod helloworld_rpi3.ko
Hello world exit
[ 65 ]
The Simplest Drivers Chapter 3
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alberto Liberal <aliberal@arroweurope.com>");
MODULE_DESCRIPTION("This is a module that accepts parameters");
KERNEL_DIR ?= $(HOME)/linux_rpi3/linux
all:
make -C $(KERNEL_DIR) \
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \
M=$(PWD) modules
clean:
make -C $(KERNEL_DIR) \
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \
M=$(PWD) clean
deploy:
scp *.ko root@10.0.0.10:/home/pi
[ 66 ]
Chapter 3 The Simplest Drivers
helloworld_rpi3_with_parameters.ko demonstration
Load the module:
root@raspberrypi:/home/pi# insmod helloworld_rpi3_with_parameters.ko
parameter num = 5
Remove the module:
root@raspberrypi:/home/pi# rmmod helloworld_rpi3_with_parameters.ko
Hello world with parameter exit
Load the module with a parameter:
root@raspberrypi:/home/pi# insmod helloworld_rpi3_with_parameters.ko num=10
parameter num = 10
root@raspberrypi:/home/pi# cat /sys/module/helloworld_rpi3_with_parameters/param
eters/num
10
Remove the module:
root@raspberrypi:/home/pi# rmmod helloworld_rpi3_with_parameters.ko
Hello world with parameter exit
[ 67 ]