Upload
jesse-logan-cox
View
224
Download
8
Embed Size (px)
Citation preview
Sogang University
Advanced Operating SystemsAdvanced Operating Systems
(Linux Module Programming)(Linux Module Programming)
Sang Gue Oh, Ph.D.Sang Gue Oh, Ph.D.
Email : [email protected] : [email protected]
Page 2Sogang University
Linux Module Programming
Motivation of ModulesMotivation of Modules Motivation of ModulesMotivation of Modules
Linux kernel is a monolithic kernel.
The limitation of a monolithic kernel. When the configuration is changed, the kernel has to be compiled.
The rarely used file systems and drivers occupy memory permanently.
The kernel code modification results in creating the new kernel and
rebooting the system
This leads to the development of modules.
Page 3Sogang University
Linux Module Programming
What is a Module ?What is a Module ?What is a Module ?What is a Module ?
Linux module : is a functional unit such as file system or driver.
can be dynamically linked into the kernel at any point after the system has booted. => the loaded modules are regarded as the kernel.
can be removed from the kernel when it is no longer needed.
When a module is loaded, it is same as a kernel.
This results in small and compact kernel size and the ability of trying out new kernel code without rebuilding and rebooting the kernel.
CONFIG_KERNELD and System V IPC options should be enabled to use modules in Linux .
Page 4Sogang University
Linux Module Programming
Module Data Structure (1)Module Data Structure (1)Module Data Structure (1)Module Data Structure (1)
The loaded modules are maintained by module data structure.
Each module data structure points to the symbol table
structure that contains all symbols of the module.
The kernel symbol table is pointed by the first module data
structure.
Page 5Sogang University
Linux Module Programming
The list of kernel modules
modulenextref
symtab
size
references
kernel symbol table
“kernel symbol table module”
modulenextref
symtab
size
references
“sysv module”
sysv symbol table
module_list
Module Data Structure (2)Module Data Structure (2)Module Data Structure (2)Module Data Structure (2)
Page 6Sogang University
Linux Module Programming
Minimum Module InterfaceMinimum Module Interface Minimum Module InterfaceMinimum Module Interface
#include <linux/kernel.h>
#include <linux/module.h>
…..
int init_module()
{
/* Code to initialize the module when it is installed */
}
void cleanup_module()
{
/* Code to clean up when the module is removed */
}
Page 7Sogang University
Linux Module Programming
Using Macros (After Linux 2.4)Using Macros (After Linux 2.4) Using Macros (After Linux 2.4)Using Macros (After Linux 2.4)
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> // Needed for the macros
…..
static int hello_init_(void)
{
/* Code to initialize the module when it is installed */
}
static void hello_exit(void)
{
/* Code to clean up when the module is removed */
}
module_init(hello_init); // hello_init should be defined before this macro
module_exit(hello_exit); // hello_exit should be defined before this macro
Page 8Sogang University
Linux Module Programming
Compiling a ModuleCompiling a Module Compiling a ModuleCompiling a Module
A Kernel module is not an independent executable, but an object file which will be linked into the kernel in runtime.
As a result, they should be compiled with the -c flag.
Also use –W option (turn on warnings) and –O option (optimize).
All kernel modules have to be compiled with certain symbols defined (i.e., with -D option).
__KERNEL__ - This tells the header files that this code will be run in
kernel mode, not as part of a user process (i.e., -D__KERNEL__).
MODULE - This tells the header files that this file is a module rather
than an ordinary file (i.e., -DMODULE).
Page 9Sogang University
Linux Module Programming
Version DependencyVersion Dependency Version DependencyVersion Dependency
Module’s code has to be recompiled for each version of the kernel that it will be linked to.
Each module defines a symbol called kernel-version, which insmod mat
ches against the version number of the current kernel. Recent kernels
define the symbol for you in <linux/module.h>.
Sometimes it makes sense to divide a kernel module between several
source files. In this case, you need to do the following: In all source files but one, add the line #define __NO_VERSION__ because
of the global variable declaration of module.h. Compile all the source files as usual.
Combine all the object files into a single one. Under x86, do it with ld -m elf i386 -r -o name-of-module.o 1st-file.o 2nd-file.o
Page 10Sogang University
Linux Module Programming
Loading a Module (1)Loading a Module (1) Loading a Module (1)Loading a Module (1)
Two ways of loading a module Manual loading : uses insmod command (e.g., insmod <name.o>). On-demand loading : if the kernel discovers the need for loading a
module (e.g., user mounts a file system), it requests kerneld daemon to load the needed module using message queue. kerneld loads that module using modprobe command.
Mechanism of loading Fixes up unresolved references to kernel routines and resources u
sing the exported symbols from the kernel. Requests the kernel for enough space to hold the new kernel. The kernel allocates a new module data structure and enough kern
el memory to hold the new module and puts it at the end of the kernel modules list.
Page 11Sogang University
Linux Module Programming
Loading a Module (2)Loading a Module (2) Loading a Module (2)Loading a Module (2)
insmod copies the module into the allocated space and relocates it s
o that it will run from the kernel address that it has been allocated.
The new module exports symbols to the kernel and insmod builds a
table of these exported symbols.
The new module depends on another module, that module has the r
eference of the new module.
The kernel calls the modules initialization routine (init_module())and
carries on installing the module.
Page 12Sogang University
Linux Module Programming
Communication between Kernel and KerneldCommunication between Kernel and Kerneld Communication between Kernel and KerneldCommunication between Kernel and Kerneld
KernelKernel KernelKernel KernelKernel
kerneldkerneld kerneldkerneld kerneldkerneld
modprobe fat
KERNELD_REQUEST_MODULE fat
Module loaded
fat
Page 13Sogang University
Linux Module Programming
Unloading a ModuleUnloading a ModuleUnloading a ModuleUnloading a Module
Two ways of unloading a module Manual unloading : uses rmmod command.
On-demand unloading : when idle timer expires, the kerneld calls the se
rvice routines for all unused loaded modules.
Mechanism of unloading If the module can be unloaded, its cleanup routine (cleanup_module()) i
s called to free up the kernel resources that it has allocated.
The module data structure is unlinked from the list of kernel modules.
All of the kernel memory that the module needed is de-allocated.
Page 14Sogang University
Linux Module Programming
Listing Current Modules (/proc/modules)Listing Current Modules (/proc/modules) Listing Current Modules (/proc/modules)Listing Current Modules (/proc/modules)
dcclab# insmod fat
dcclab# lsmod
Module: #pages (or Size) Used by:
fat 6 0
dcclab# rmmod fat
dcclab# lsmod
Module: #pages Used by:
dcclab# lsmod
Module: #pages Used by:
dcclab# mount -t msdos /dev/fd0 /mnt
dcclab# lsmod
Module: #pages Used by:
msdos 2 1 (autoclean)
fat 6 [msdos] 1 (autoclean)
dcclab# ls -al /mnt
……..
dcclab# unmount /mnt
dcclab# lsmod
Module: #pages Used by:
msdos 2 0 (autoclean)
fat 6 [msdos] 0 (autoclean)
dcclab# sleep 60
dcclab# lsmod
Module: #pages Used by:
Page 15Sogang University
Linux Module Programming
Exporting Symbols (1)Exporting Symbols (1) Exporting Symbols (1)Exporting Symbols (1)
The public symbol table (kernel symbol table) can be read from /proc/ksyms.
When a module is loaded, any global symbol we declare becomes part of the kernel symbol table by default.
An alternative to exporting all the global symbols of a module is to use the function register_symtab.
static struct symbol_table syms = {
#include <linux/symtab_begin.h>
X(fn1),
X(fn2),
X(variable1),
#include <linux/symtab_end.h>
};
register_symtab(&syms);
Page 16Sogang University
Linux Module Programming
Exporting Symbols (2)Exporting Symbols (2) Exporting Symbols (2)Exporting Symbols (2)
register_symtab replaces the public symbols exported by default for the current module with the explicit symbol table.
If we don’t want to declare everything as static, just hide global symbols by adding register_symtab(NULL) to the init_module().
If the source file does not offer hooks for additional modules to be stacked on it, it’s always a good idea to hide all the symbols by using the line above.
New macros in the newer kernel (after 2.1.8) REGISTER_SYMTAB(&name) -> register_symtab(&name); EXPORT_SYMBOL(name) -> register name in the symbol table. EXPORT_NO_SYMBOLS -> register_symtab(NULL);
Page 17Sogang University
Linux Module Programming
Module Usage CounterModule Usage Counter Module Usage CounterModule Usage Counter
Each module has a usage counter to determine whether the module can be safely removed.
A module can’t be unloaded if it is busy. The usage counter is maintained by three macros:
MOD_INC_USE_COUNT : increments the count for the current module. MOD_DEC_USE_COUNT : decrements the count. MOD_IN_USE : evaluates to true if the count is not zero.
There is not need to check for MOD_IN_USE from within cleanup_module, because the check is performed by the system.
Can’t unload a module if we lose track of the usage counter. Completely disable the usage count during the debugging cycle. Force the counter to zero (by ioctl).
Page 18Sogang University
Linux Module Programming
Module DependencyModule Dependency Module DependencyModule Dependency A module (B) can refer to the symbols exported by another
module (A). In this case, we say that B is loaded on top of A, or equivalent
that A is used by B. In order to link module B, module A must have already been
linked; otherwise, the references to the symbols exported by A cannot be properly linked by B.
In short, there is a dependency between modules. In order to ensure that module A is not removed before B, A’s
usage counter is incremented for each module loaded on top of it.
Stacking modules is an effective way to modularize the kernel source code to speed up its development and improve its portability.
Page 19Sogang University
Linux Module Programming
Example (hello.c) (1)Example (hello.c) (1)Example (hello.c) (1)Example (hello.c) (1)
/* The necessary header files */
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h> => version management for the exported symbols
#endif
Page 20Sogang University
Linux Module Programming
Example (hello.c) (2)Example (hello.c) (2)Example (hello.c) (2)Example (hello.c) (2)
/* Initialize the module */
int init_module()
{
printk("Hello, world - this is the kernel speaking\n");
/* If we return a non zero value, it means that init_module failed and the
kernel module can't be loaded */
return 0;
}
/* Cleanup - undid whatever init_module did */
void cleanup_module()
{
printk("Short is the life of a kernel module\n");
}
Page 21Sogang University
Linux Module Programming
Makefile for hello.cMakefile for hello.c Makefile for hello.cMakefile for hello.c
# Makefile for a basic kernel module
CC = gcc
MODFLAGS = -Wall -DMODULE -D__KERNEL__
hello.o : hello.c /usr/include/linux/version.h
$(CC) $(MODFLAGS) -c hello.c
echo insmod hello.o to turn it on
echo rmmod hello to turn it off
echo X and kernel programming do not mix.
echo Do the insmod and rmmod from outside of X.
Page 22Sogang University
Linux Module Programming
Use of ModulesUse of Modules Use of ModulesUse of Modules
Modules are usually used to implement device drivers. However, they can be used to implement any desired functions. Two types of interfaces are available to the designer to use
with modules: device driver. /proc file system.