注:以下程序只是在我机器上测试通过,但代码不一定合理或高效,只是想了解一下内核模块的开发流程,以及工作流程
例子来源于网络,在此表示感谢
[cpp] view plain copy [root@localhost module]# cat /proc/version Linux version 2.6.18-194.el5xen (mockbuild@builder16.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)) #1 SMP Fri Apr 2 16:16:54 EDT 20101、编写最简单的helloworld版本的内核模块
[cpp] view plain copy [root@localhost module]# cat hello.c #ifndef _KERNEL_ #define _KERNEL_ #endif #ifndef MODULE #define MODULE #endif #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> static int hello_init(void) { printk(KERN_ALERT "hello, I am Tuotuo\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "googbye Kernel mymodule n"); } module_init(hello_init); module_exit(hello_exit);Makefile文件为
[cpp] view plain copy [root@localhost module]# cat Makefile obj-m:=hello.o VERSION_NUM:=$(shell uname -r) KERNELBUILD := /lib/modules/`uname -r`/build CURRENT_PATH:=$(shell pwd) all: make -C $(KERNELBUILD) M=$(CURRENT_PATH) modules clean: make -C $(KERNELBUILD) M=$(CURRENT_PATH) clean编译
make
加载模块
insmod hello.ko
卸载模块
[cpp] view plain copy rmmod hello.ko查看加载和卸载信息
dmesg
2、学习调用模块
学习http://blog.csdn.net/firststp/article/details/395009
内核模块代码
[cpp] view plain copy [root@localhost module]# cat TestModule.c #ifndef _KERNEL_ #define _KERNEL_ #endif #ifndef MODULE #define MODULE #endif #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/version.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/errno.h> #include <asm/segment.h> #include <linux/sched.h> #include <asm/uaccess.h> #include <linux/utsrelease.h> #define DATA_LENGTH 10 MODULE_LICENSE("GPL"); MODULE_AUTHOR("TUO LI HENG"); char kernel_version[] = UTS_RELEASE; unsigned int test_major = 0; ssize_t read_test(struct file *file, char * buf, size_t count, loff_t *f_ops) { int left, i, *p; int data[DATA_LENGTH]; p = data; for(i=0; i<10; ++i) data[i] = 61; for(left=count; left>0; --left) { copy_to_user(buf, p, 1); ++buf; ++p; } return 0; } ssize_t write_test(struct file *file, char * buf, size_t count, loff_t *f_ops) { return 0; } static int open_test(struct inode* inode, struct file *file) { // MOD_INC_USE_COUNT; return 0; } static int release_test(struct inode *inode, struct file *file) { // MOD_DEC_USE_COUNT; return 0; } struct file_operations test_fops = { read: read_test, write: write_test, open: open_test, release: release_test }; static int hello_init(void) { printk(KERN_ALERT "hello, I am Tuotuo\n"); int result = 0; result = register_chrdev (0, "test", &test_fops); if(result < 0) { printk(KERN_ALERT "test:can't get major number\n"); return result; } if(test_major == 0) test_major = result; printk(KERN_ALERT "test major:%d/r/n", result); return 0; } static void hello_exit(void) { unregister_chrdev(test_major, "test"); printk(KERN_ALERT "googbye Kernel module tuotuo\n"); } module_init(hello_init); module_exit(hello_exit);在以上的Makefile里第一行修改为:
[cpp] view plain copy obj-m:=TestModule.o同样
[html] view plain copy make insmod TestModule.ko dmesg测试前,先看看是否已经建立了设备文件。 检查 /dev下是否有test设备文件,如果没有,那我们就手工建立一个。用前面看到的主设备号,使用命令: “mknod test c 268 0” --引用博文
编写调用程序
[html] view plain copy [root@localhost module]# cat TestApp.c #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> int main() { char buf[20] = {0,}; int i = 0; int p = open("/dev/test", O_RDWR); if(p == -1) { printf("cannot open\n"); exit(0); } printf("buf addr %ui\r\n",buf); read(p, buf, 10); for(i = 0; i<10; i++) { printf("%s\r\n",buf+i); } close(p); return 1; }编译
[html] view plain copy gcc TestApp.c -o TestApp运行
[cpp] view plain copy [root@localhost module]# ./TestApp buf addr 3218386872i ========== ========= ======== ======= ====== ===== ==== === == =