下面就开始写子程序。
#include 《linux/types.h》 基本的类型定义
#include 《linux/fs.h》 文件系统使用相关的头文件
#include 《linux/mm.h》
#include 《linux/errno.h》
#include 《asm/segment.h》
unsigned int test_major = 0;
static int read_test(struct inode *inode,struct file *file,char *buf,int count)
{
int left; 用户空间和内核空间
if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT )
return -EFAULT;
for(left = count ; left 》 0 ; left--)
{
__put_user(1,buf,1);
buf++;
}
return count;
}
这个函数是为 read 调用准备的。当调用 read 时,read_test()被调用,它把用户的缓冲区全部写 1。buf 是 read 调用的一个参数。它是用户进程空间的一个地址。但是在 read_test 被调用时,系统进入核心态。所以不能使用 buf 这个地址,必须用 __put_user(),这是 kernel 提供的一个函数,用于向用户传送数据。另外还有很多类似功能的函数。请参考,在向用户空间拷贝数据之前,必须验证 buf 是否可用。这就用到函数 verify_area。为了验证 BUF 是否可以用。
static int write_test(struct inode *inode,struct file *file,const char *buf,int count)
{
return count;
}
static int open_test(struct inode *inode,struct file *file )
{
MOD_INC_USE_COUNT; 模块计数加以,表示当前内核有个设备加载内核当中去
return 0;
}
static void release_test(struct inode *inode,struct file *file )
{
MOD_DEC_USE_COUNT;
}
这几个函数都是空操作。实际调用发生时什么也不做,他们仅仅为下面的结构提供函数指针。
struct file_operations test_fops = {?
read_test,
write_test,
open_test,
release_test,