虚拟机跑linux,CentOS5.5 内核版本:
注:以下程序只是在我机器上测试通过,但代码不一定合理或高效,只是想了解一下内核模块的开发流程,以及工作流程
例子来源于网络,在此表示感谢
[root@localhost module]# cat /proc/version
Linux version 2.6.18-194.el5xen ([email protected]) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)) #1 SMP Fri Apr 2 16:16:54 EDT 2010
1、编写最简单的helloworld版本的内核模块
[root@localhost module]# cat hello.c
#ifndef _KERNEL_
#define _KERNEL_
#endif
#ifndef MODULE
#define MODULE
#endif
#include
#include
#include
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文件为
[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
卸载模块
rmmod hello.ko
查看加载和卸载信息
dmesg
2、学习调用模块
学习http://blog.csdn.net/firststp/article/details/395009
内核模块代码
[root@localhost module]# cat TestModule.c
#ifndef _KERNEL_
#define _KERNEL_
#endif
#ifndef MODULE
#define MODULE
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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里第一行修改为:
obj-m:=TestModule.o
同样
make
insmod TestModule.ko
dmesg
测试前,先看看是否已经建立了设备文件。 检查 /dev下是否有test设备文件,如果没有,那我们就手工建立一个。用前面看到的主设备号,使用命令: “mknod test c 268 0” --引用博文
编写调用程序
[root@localhost module]# cat TestApp.c
#include
#include
#include
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;
}
编译
gcc TestApp.c -o TestApp
运行
[root@localhost module]# ./TestApp
buf addr 3218386872i
==========
=========
========
=======
======
=====
====
===
==
=