linux内核模块编译及动态加载
一个简单的内核模块程序:
#include <linux/module.h> /* Defines the license for this linux kernel module */ MODULE_LICENSE("GPL"); /* Init function called on module entry */ int my_module_init( void ) { printk(KERN_INFO "my_module_init called. Module is now loaded.\n"); return 0; } /* Cleanup function called on module exit */ void my_module_cleanup( void ) { printk(KERN_INFO "my_module_cleanup called. Module is now unloaded.\n"); return; } /* Declare entry and exit functions */ module_init( my_module_init ); module_exit( my_module_cleanup );函数printk() 会把日志打印到内核日志文件中(/var/log/message)
动态查看内核日志方法:# tail -f /var/log/message
makefile文件:
obj-m += my_module.o
编译命令:
make -C /usr/src/linux-2.6.13-15 SUBDIRS=$PWD modules
/usr/src/linux-2.6.13-15 为内核源码路径
SUBDIRS=$PWD为当前文件所在路径
安装内核源码:
linux安装时默认不安装内核源码,而内核模块编译需要用到内核源码。否则会出现如下错误:
WARNING: Symbol version dump /usr/src/linux-2.6.13-15/Module.symvers is missing;
modules will have no dependencies and modversions.
内核源码安装方法
- 首先找到安装包(从网上下载和内核版本匹配的源码包或者在安装盘里找。我用的suse,安装包为D:\SUSE-10.0-EvalDVD-i386-GM\suse\i586\kernel-source-2.6.13-15.i586.rpm)
- 安装内核源码:rpm -ivh /tmp/kernel-source-2.6.13-15.i586.rpm (安装文件所在路径,我放在/tmp/下)
- 源码安装后是不可以直接使用的,需要先编译一下:
直接执行下面命令就可以。
cd /usr/src/linux
make clean
make mrproper
make cloneconfig
make prepare-all
内核模块编译可能出现的错误:
- Makefile:494: .config: 没有那个文件或目录(或者会提示找不到config.h)。找不到.config文件。
这个文件里面其实没有什么东西,
2.6.9.22的内源代码里include/linux/config.h的内容如下:#ifndef _LINUX_CONFIG_H #define _LINUX_CONFIG_H #include <linux/autoconf.h> #if !defined (__KERNEL__) && !defined(__KERNGLUE__) #error including kernel header in userspace; use the glibc headers instead! #endif #endif所以可以在/usr/src/linux/目录下直接touch一个就可以了:#touch .config
模块加载及卸载:
模块加载:
执行:# ismod my_module.ko
日志打印:Mar 16 23:05:46 linux kernel: my_module_init called. Module is now loaded.
模块查看:
执行:# lsmod
终端打印:
linux:/mnt/hgfs/vmware-share/module # lsmod
Module Size Used by
my_module 1280 0
hfsplus 75140 0
vfat 12800 0
fat 49692 1 vfat
。。。。。。
模块卸载:
执行:# rmmod my_module.ko
日志打印:Mar 16 23:06:19 linux kernel: my_module_cleanup called. Module is now unloaded.