22
Sogang University Advanced Operating Advanced Operating Systems Systems (Linux Module Programming) (Linux Module Programming) Sang Gue Oh, Ph.D. Sang Gue Oh, Ph.D. Email : [email protected] Email : [email protected] m m

Sogang University Advanced Operating Systems (Linux Module Programming) Sang Gue Oh, Ph.D. Email : [email protected] Email : [email protected]

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.