Kernel modules
Hao-Ran Liu
Kernel modules
• Kernel modules can be loaded into or
unloaded from the kernel at runtime
– Extend the the functionality of the kernel
– Save memory (Unused feature are not
loaded)
– User do not have to recompile the kernel for
their hardware (a base kernel image plus a
set of binary modules works!)
Hello world! module
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, worldn");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel worldn");
}
module_init(hello_init);
module_exit(hello_exit);
Understanding the
Hello world! Module
• module_init()
– Register the function to be called when the module is loaded
• module_exit()
– Register the function to be called when the module is unloaded
– Exit function will not be compiled into the kernel if the module is
compiled into the kernel image
• MODULE_LICENSE()
– specifies the copyright license for this module
– Kernel complains when a GPL-incompatible module is loaded
– Non-GPL module cannot use GPL-only symbols
Kernel module programming
• Like event-driven programming, kernel modules
registers to the kernel the capability (functions) it
have.
• Kernel module can use only symbols (variables
and functions) kernel exports
• Your code must be reentrant; use the right
synchronization tools to deal with the
concurrency issue
• The task_struct of the current process can be
accessed via current MACRO
Compiling kernel modules in the
kernel tree
• At the parent directory of your driver, ex. /drivers/char/,
add a line in the Makefile
– obj-$(CONFIG_MYDRIVER) += mydriver/
– This like cause the kbuild system to go into your directory when
it compiles the kernel or kernel modules
• In your driver’s dir., you add a new Makefile with this line
– obj-$(CONFIG_MYDRIVER) += mydriver.o
– This line cause the kbuild to build a kernel module mydriver.ko
from mydriver.c
• If your driver contains more than one file, add one more
line
– mydriver-objs := file1.o file2.o
– This causes the kbuild to build mydriver.ko from file1.c and
file2.c
Compiling kernel modules outside
the kernel tree
# To build modules outside of the kernel tree, we run "make"
# in the kernel source tree; the Makefile these then includes this
# Makefile once again. This conditional selects whether we are being
# included from the kernel Makefile or not.
ifeq ($(KERNELRELEASE),)
# Assume the source tree is where the running kernel was built
# You should set KERNELDIR in the environment if it's elsewhere
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
# The current directory is passed to sub-makes as argument
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
else
# called from kernel build system: just declare what our modules
are
obj-m := mydriver.o
endif
Installing the module
• ‘make module_install’ will install your
module at /lib/modules/<kernel
version>/kernel
Module related tools
• insmod <module.ko> [module parameters]
– Load the module
• rmmod
– Unload the module
• modprobe [-r] <module name>
– Load the module specified and modules it depends
– Unload the module specified and other modules it depends if
they have no other user
• lsmod
– List all modules loaded into the kernel
• depmod
– Regenerate module dependency information
Kconfig
• Kconfig is a kernel configuration-option file
– make menuconfig read this file to give you a list of all
optional config items.
– make menuconfig saves user’s configuration at
<Kernel source root>/.config
• Creating Kconfig for your driver
– At the parent directory of your driver, ex drivers/char,
add a line to the Kconfig file there
• source "drivers/char/mydriver/Kconfig"
– This line tells the kbuild system to read your own
Kconfig file
Kconfig
• In your directory, /drivers/char/mydriver, create a
Kconfig file there
– Don’t write CONFIG_ prefix
– tristate means the module can be built into the kernel
(y), not built at all (n) or as a kernel module (m)
– Default is n
config FISHING_POLE
tristate "Fish Master XL support"
default n
help
If you say Y here, support for the Fish Master XL 2000 Titanium with
computer interface will be compiled into the kernel and accessible via
device node. You can also say M here and the driver will be built as a
module named fishing.ko.
If unsure, say N.
Other Kconfig directive
• bool: like tristate, but allows only (y/n)
• depends on: this option cannot be enabled
unless the other it depends is enabled
• select XXX: XXX is automatically enabled if this
option is selected
• bool, tristate and ‘depends on’ can be followed
by an ‘if’, which makes the entire option
conditional on another configuration option. If
the condition is not met, the configuration is not
only disabled but also disappear in the
menuconfig
Another Kconfig example
config NR_CPUS
int "Maximum number of CPUs (2-255)"
range 2 255
depends on SMP
default "32" if X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000
default "8"
help
This allows you to specify the maximum number of CPUs which this
kernel will support. The maximum supported value is 255 and the
minimum value which makes sense is 2.
This is purely to save memory - each supported CPU adds
approximately eight kilobytes to the kernel image.
Module parameters
• Defining module parameters
– module_param(name, type, perm);
• argument:
– name: the name of the exported parameter and
internal variable
– type: can be byte, short, ushort, int, uint, long, ulong,
charp, bool, invbool
– perm: the access permission for corresponding file in
sysfs
module parameter controlling the capability to allow live bait on the pole */
static int allow_live_bait = 1; /* default to on */
module_param(allow_live_bait, bool, 0644); /* a Boolean type */
Module parameters
• module_param_named(name, variable, type, perm);
– Different name for parameter and variable
• module_param(strptr, charp, 0)
– Kernel copy the string from the user space and assign strptr to
point to it
• module_param_string(name, string, len, perm);
– Kernel copy parameter string into the buffer you provide
• module_param_array(name, type, nump, perm);
– Comma-separated list of parameters can be stored in an array
static int fish[MAX_FISH];
static int nr_fish;
module_param_array(fish, int, &nr_fish, 0444);
static char species[BUF_LEN];
module_param_string(specifies, species, BUF_LEN, 0);
Exported symbols
• Kernel modules can only access symbols
explicitly exported
• EXPORT_SYMBOL()
• EXPORT_SYMBOL_GPL()
– This symbol can only be used by modules
licensed under GPL

Linux kernel modules

  • 1.
  • 2.
    Kernel modules • Kernelmodules can be loaded into or unloaded from the kernel at runtime – Extend the the functionality of the kernel – Save memory (Unused feature are not loaded) – User do not have to recompile the kernel for their hardware (a base kernel image plus a set of binary modules works!)
  • 3.
    Hello world! module #include<linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello, worldn"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, cruel worldn"); } module_init(hello_init); module_exit(hello_exit);
  • 4.
    Understanding the Hello world!Module • module_init() – Register the function to be called when the module is loaded • module_exit() – Register the function to be called when the module is unloaded – Exit function will not be compiled into the kernel if the module is compiled into the kernel image • MODULE_LICENSE() – specifies the copyright license for this module – Kernel complains when a GPL-incompatible module is loaded – Non-GPL module cannot use GPL-only symbols
  • 5.
    Kernel module programming •Like event-driven programming, kernel modules registers to the kernel the capability (functions) it have. • Kernel module can use only symbols (variables and functions) kernel exports • Your code must be reentrant; use the right synchronization tools to deal with the concurrency issue • The task_struct of the current process can be accessed via current MACRO
  • 6.
    Compiling kernel modulesin the kernel tree • At the parent directory of your driver, ex. /drivers/char/, add a line in the Makefile – obj-$(CONFIG_MYDRIVER) += mydriver/ – This like cause the kbuild system to go into your directory when it compiles the kernel or kernel modules • In your driver’s dir., you add a new Makefile with this line – obj-$(CONFIG_MYDRIVER) += mydriver.o – This line cause the kbuild to build a kernel module mydriver.ko from mydriver.c • If your driver contains more than one file, add one more line – mydriver-objs := file1.o file2.o – This causes the kbuild to build mydriver.ko from file1.c and file2.c
  • 7.
    Compiling kernel modulesoutside the kernel tree # To build modules outside of the kernel tree, we run "make" # in the kernel source tree; the Makefile these then includes this # Makefile once again. This conditional selects whether we are being # included from the kernel Makefile or not. ifeq ($(KERNELRELEASE),) # Assume the source tree is where the running kernel was built # You should set KERNELDIR in the environment if it's elsewhere KERNELDIR ?= /lib/modules/$(shell uname -r)/build # The current directory is passed to sub-makes as argument PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install else # called from kernel build system: just declare what our modules are obj-m := mydriver.o endif
  • 8.
    Installing the module •‘make module_install’ will install your module at /lib/modules/<kernel version>/kernel
  • 9.
    Module related tools •insmod <module.ko> [module parameters] – Load the module • rmmod – Unload the module • modprobe [-r] <module name> – Load the module specified and modules it depends – Unload the module specified and other modules it depends if they have no other user • lsmod – List all modules loaded into the kernel • depmod – Regenerate module dependency information
  • 10.
    Kconfig • Kconfig isa kernel configuration-option file – make menuconfig read this file to give you a list of all optional config items. – make menuconfig saves user’s configuration at <Kernel source root>/.config • Creating Kconfig for your driver – At the parent directory of your driver, ex drivers/char, add a line to the Kconfig file there • source "drivers/char/mydriver/Kconfig" – This line tells the kbuild system to read your own Kconfig file
  • 11.
    Kconfig • In yourdirectory, /drivers/char/mydriver, create a Kconfig file there – Don’t write CONFIG_ prefix – tristate means the module can be built into the kernel (y), not built at all (n) or as a kernel module (m) – Default is n config FISHING_POLE tristate "Fish Master XL support" default n help If you say Y here, support for the Fish Master XL 2000 Titanium with computer interface will be compiled into the kernel and accessible via device node. You can also say M here and the driver will be built as a module named fishing.ko. If unsure, say N.
  • 12.
    Other Kconfig directive •bool: like tristate, but allows only (y/n) • depends on: this option cannot be enabled unless the other it depends is enabled • select XXX: XXX is automatically enabled if this option is selected • bool, tristate and ‘depends on’ can be followed by an ‘if’, which makes the entire option conditional on another configuration option. If the condition is not met, the configuration is not only disabled but also disappear in the menuconfig
  • 13.
    Another Kconfig example configNR_CPUS int "Maximum number of CPUs (2-255)" range 2 255 depends on SMP default "32" if X86_NUMAQ || X86_SUMMIT || X86_BIGSMP || X86_ES7000 default "8" help This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 255 and the minimum value which makes sense is 2. This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image.
  • 14.
    Module parameters • Definingmodule parameters – module_param(name, type, perm); • argument: – name: the name of the exported parameter and internal variable – type: can be byte, short, ushort, int, uint, long, ulong, charp, bool, invbool – perm: the access permission for corresponding file in sysfs module parameter controlling the capability to allow live bait on the pole */ static int allow_live_bait = 1; /* default to on */ module_param(allow_live_bait, bool, 0644); /* a Boolean type */
  • 15.
    Module parameters • module_param_named(name,variable, type, perm); – Different name for parameter and variable • module_param(strptr, charp, 0) – Kernel copy the string from the user space and assign strptr to point to it • module_param_string(name, string, len, perm); – Kernel copy parameter string into the buffer you provide • module_param_array(name, type, nump, perm); – Comma-separated list of parameters can be stored in an array static int fish[MAX_FISH]; static int nr_fish; module_param_array(fish, int, &nr_fish, 0444); static char species[BUF_LEN]; module_param_string(specifies, species, BUF_LEN, 0);
  • 16.
    Exported symbols • Kernelmodules can only access symbols explicitly exported • EXPORT_SYMBOL() • EXPORT_SYMBOL_GPL() – This symbol can only be used by modules licensed under GPL