Title: Building%20and%20Running%20Modules
1Building and Running Modules
- Ted Baker ? Andy Wang
- CIS 4930 / COP 5641
2Setting Up Your Test System
- For Linux 2.6.x
- Building modules requires a configured and built
kernel tree - Can obtain one from kernel.org
- 2.6 modules are linked against object files found
in the kernel source tree
3The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
No main function
4The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
Invoked when the module is loaded
5The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
Invoked when the module is removed
6The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
Micros to indicate which module initialization
and exit functions to call
7The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
This module bears a free license
8The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
The ordering matters sometimes
9The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
printf in C library No floating-point
support
10The Hello World Module
- include ltlinux/init.hgt
- include ltlinux/module.hgt
- MODULE_LICENSE(Dual BSD/GPL)
- static int hello_init(void)
- printk(KERN_ALERT Hello, world\n)
- return 0
-
- static void hello_exit(void)
- printk(KERN_ALERT Goodbye, cruel world\n)
-
- module_init(hello_init)
- module_exit(hello_exit)
Indicates the message priority Note that no ,
after KERN_ALERT
11Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules
Notice the quote
12Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3
13Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3 - su
- Password
14Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3 - su
- Password
- root
15Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3 - su
- Password
- root /sbin/insmod ./module.ko
16Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3 - su
- Password
- root /sbin/insmod ./module.ko
- Hello, world
- root
Might be printed to /var/log/messages
17Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3 - su
- Password
- root /sbin/insmod ./module.ko
- Hello, world
- root /sbin/rmmod module.ko
Either module or module.ko
18Module Loading/Unloading
- make C /home/awang/linux-2.6.25.3 Mpwd
modules - make1 Entering directory /usr/src/linux-2.6.25
.3 - CC M /home/awang/hello/hello.o
- Building modules, stage 2.
- MODPOST
- CC /home/awang/hello/hello.mod.o
- LD M /home/awang/hello/hello.ko
- make1 Leaving directory /usr/src/linux-2.6.25.
3 - su
- Password
- root /sbin/insmod ./module.ko
- Hello, world
- root /sbin/rmmod module.ko
- Goodbye cruel world
- root
Might be printed to /var/log/messages
19Kernel Modules vs. Applications
- Applications
- Can access various functions in user-level
libraries (e.g., printf in C library) - Kernel modules
- No user-level libraries
- printk is defined within the kernel
- Exported to modules
- Should include only header files defined within
the kernel source tree
20Linking a Module to the Kernel
21Threads/Processes
- Thread A sequential execution stream
- Address space Chunks of memory and everything
needed to run a program - Process An address space thread(s)
22User Space and Kernel Space
- Kernel modules run in kernel space
- Execute in the supervisor mode
- Everything is allowed
- Share the same address space
- Applications run in user space
- Execute in the user mode
- Restricted access to hardware
- Each has its own address space
23System Calls
- System calls allow processes running at the user
mode to access kernel functions that run under
the kernel mode - Prevent processes from doing bad things, such as
- Halting the entire operating system
- Modifying the MBR
24Hardware Interrupts
- Can suspend user-level processes
- Transfers execution from user space to kernel
space - Interrupts are handled by separate threads
- Not related to any user-level processes
- Asynchronous
25Role of a Module
- Extend kernel functionality
- Modularized code running in kernel space
26Concurrency in the Kernel
- Sources of concurrency
- Hardware interrupts
- Kernel timers
- Multiple CPUs
- Preemption
27Handling Concurrency
- Kernel code needs to be reentrant
- Capable of running in more than one thread
execution context at the time - Prevent corruption of shared data
- Avoid race conditions
- Results depend on the timing of their executions
28The Current Process
- Most actions performed by the kernel are done on
behalf of a specific process - The current process
- Defined as a per CPU MACRO
- struct task_struct current
- include ltasm/current.hgt
- include ltlinux/sched.hgt
29The Current Process
- Print the current command name, process ID, and
task (thread) ID - include ltlinux/sched.hgt
- printk(KERN_INFO The process is \s\ (tgid i)
(pid i)\n, current-gtcomm, - current-gttgid, current-gtpid)
30A Few Other Details
- Limited address space for kernel
- Should dynamically allocate and deallocate space
for large data structures - Functions starting with __ should be used with
caution - Kernel does not support floating point arithmetic
31Compiling Modules
- Details on compiling the kernel
- Documentation/kbuild
- Required tools with matching versions
- Compiler, module utilities, and so on...
- If the version is too new can cause problems as
well - Documentation/Changes
32Simplest Makefile
- obj-m hello.o
- One module to be built from hello.o
- Resulting module is hello.ko
33More on Makefiles
- Suppose you have a module called module.ko
- Generated from file1.c and file2.c
- obj-m module.o
- module-objs file1.o file2.o
34More on Makefiles
- To make, type the following in the directory
containing the module source and Makefile - make C /home/awang/linux-2.6.25.3 Mpwd
modules
Changing to the kernel source directory
35More on Makefiles
- To make, type the following in the directory
containing the module source and Makefile - make C /home/awang/linux-2.6.25.3 Mpwd
modules
Move back to the module source directory
36A More Elaborate Makefile
- If KERNELRELEASE is defined, weve been invoked
from the - kernel build system and can use its language
- ifneq ((KERNELRELEASE),)
- obj-m hello.o
- Otherwise we were called directly from the
command - line invoke the kernel build system.
- else
- KERNELDIR ? /lib/modules/(shell uname
r)/build - PWD (shell pwd)
- modules
- (MAKE) C (KERNELDIR) M(PWD) modules
- clean
- rm fr .o core ..cmd .ko .mod.c
.tmp_versions - endif
If KERNELDIR is not defined, define it.
Kernel release version
37Loading/Unloading Modules
- insmod
- Links unresolved symbol in the module to the
symbol table of the kernel - more /proc/modules to see a list of currently
loaded modules - rmmod
- Removes a kernel module
38Loading/Unloading Modules
- rmmod
- Removes a kernel module
- Fails when the kernel believes that it is still
in use - Or, something has gone wrong
- Might need to reboot to remove the module
39Version Dependency
- Modules code has to be recompiled for each
version of the kernel - Sensitive to kernel version, compiler version,
and various configuration variables - If things dont match
- root /sbin/insmod hello.ko
- Error inserting ./hello.ko -1 Invalid module
format
40Version Dependency
- Possible remedies
- Check /var/log/messages for specific causes
- Change KERNELDIR as needed
41The Kernel Symbol Table
- Addresses of global functions and variables
- A module can export its symbols for other modules
to use - Module stacking
- E.g., MSDOS file system relies on symbols
exported by the FAT module
42Module Stacking Example
- Stacking of parallel port driver modules
- Can use modprobe to load all modules required by
a particular module
43Auto-loading
- Modify /etc/modprobe.conf
- Example
- alias eth0 e1000
- Whenever eth0 is referenced, the kernel module
e1000 is loaded
44Export Module Symbols
- In module header files
- Use the following macros
- EXPORT_SYMBOL(name)
- EXPORT_SYMBOL_GPL(name)
- _GPL makes the symbol available only to
GPL-licensed modules
45Defending against Namespace Problems
- Declare all functions and global variables static
unless you mean to export them - Use a module-unique prefix for all exported
symbols
46Preliminaries
- Just about all module code includes the following
header files - ltlinux/module.hgt
- Symbols and functions needed by modules
- ltlinux/init.hgt
- Allows you to specify initialization and cleanup
functions
47Initialization and Shutdown
- Initialization function
- Registers any facility, or functionality offered
by the module - static int __init initialization_function(void)
- / initialization code here /
-
- module_init(initialization_function)
48Initialization and Shutdown
- Initialization function
- Registers any facility, or functionality offered
by the module - static int __init initialization_function(void)
- / initialization code here /
-
- module_init(initialization_function)
Indicates that the module loader can drop this
function after the module is loaded, making its
memory available
49Initialization and Shutdown
- Initialization function
- Registers any facility, or functionality offered
by the module - static int __init initialization_function(void)
- / initialization code here /
-
- module_init(initialization_function)
Mandatory to specify the initialization function
50The Cleanup Function
- Unregisters various functionalities and returns
all resources - static void __exit cleanup_function(void)
- / Cleanup code here /
-
- module_exit(cleanup_function)
51The Cleanup Function
- Unregisters various functionalities and returns
all resources - static void __exit cleanup_function(void)
- / Cleanup code here /
-
- module_exit(cleanup_function)
Indicates that this function is for unloading only
52The Cleanup Function
- Unregisters various functionalities and returns
all resources - static void __exit cleanup_function(void)
- / Cleanup code here /
-
- module_exit(cleanup_function)
Needed to specify the cleanup function
53Error Handling During Initialization
- static int __init my_init_function(void)
- int err
- / registration takes a pointer and a name /
- err register_this(ptr1, skull)
- if (err) goto fail_this
- err register_that(ptr2, skull)
- if (err) goto fail_that
- err register_those(ptr3, skull)
- if (err) goto fail_those
- return 0 / success /
- fail_those unregister_that(ptr2, skull)
- fail_that unregister_this(ptr1, skull)
- fail_this return err / propagate the error
/ -
54Error Handling During Initialization
- static int __init my_init_function(void)
- int err
- / registration takes a pointer and a name /
- err register_this(ptr1, skull)
- if (err) goto fail_this
- err register_that(ptr2, skull)
- if (err) goto fail_that
- err register_those(ptr3, skull)
- if (err) goto fail_those
- return 0 / success /
- fail_those unregister_that(ptr2, skull)
- fail_that unregister_this(ptr1, skull)
- fail_this return err / propagate the error
/ -
Check ltlinux/errno.hgt for error codes
55Cleanup Function
- static void __exit my_cleanup_function(void)
- unregister_those(ptr3, skull)
- unregister_that(ptr2, skull)
- unregister_this(ptr1, skull)
- return err
-
56Other Code Patterns
- int __init my_init(void)
- int err -ENOMEM
- item1 allocate_thing(arg1)
- item2 allocate_thing2(arg2)
- if (!item1 !item2) goto fail
- err register_stuff(item1, item2)
- if (!err)
- stuff_ok 1
- else
- goto fail
-
- return 0
- fail
- my_cleanup()
- return err
57Other Code Patterns
- void my_cleanup(void)
- if (item1) release_thing(item1)
- if (item2) release_thing2(item2)
- if (stuff_ok) unregister_stuff()
- return
-
- No __exit when it is called by nonexit code
58Module-Loading Races
- A facility is available once a register call is
completed - Kernel can make calls to registered functions
before the initialization function completes - Obtain and initialize all critical resources
before calling the register function
59Module Parameters
- Include moduleparam.h, stat.h
- Need to use the following macros
- module_param(name, type, permission)
- module_param_array(name, type, num, permission)
60Example Use of Module Parameters
- Allow the hello world module to say hello to
someone a number of times - /sbin/insmod ./hello.ko someoneMom times2
- Hello Mom
- Hello Mom
-
61Example Use of Module Parameters
- Need to use the module_param macro
-
- static char someone world
- static int times 1
- module_param(times, int, S_IRUGO)
- module_param(someone, charp, S_IRUGO)
Read-only flag, defined in stat.h
62Support Parameter Types
- bool
- charp
- Memory allocated for user provide strings
- int, long, short, uint, ulong, ushort
- Basic integers
63User Level Facilities
- X server
- Some USB drivers
- Various daemons/threads
64User Level Facilities
- Fast development
- C library support
- Conventional debugger
- Fault isolation
- Portability
- Interrupts not available
- Privileged access required for direct memory
access - Poor performance