Skip to content

Instantly share code, notes, and snippets.

@kerie
Created November 19, 2010 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kerie/706745 to your computer and use it in GitHub Desktop.
Save kerie/706745 to your computer and use it in GitHub Desktop.
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/errno.h>
#include<linux/uaccess.h>
#include<linux/init.h>
#define RWBUF_SIZE 2048
#define DEVICE_NAME "ChrDev" //修改为自己喜欢的名字
#define RWBUF_CLEAR 0x909090
#define RWBUF_LENGTH 0x808080
#define RWBUF_NUM 0x707070
//全局变量
static char rwbuf[RWBUF_SIZE]="13081070"; //buffer 修改为自己的学号
static int inuse = 0; //only one process is permited once
static int rwlen = 8; //the current length of buffer
static int writenum = 0; //the number of write
//函数向前声明
static int rwbuf_open(struct inode *node, struct file *filep);
static int rwbuf_close(struct inode *node, struct file *filep);
static ssize_t rwbuf_write(struct file *filep, const char *buf, size_t count, loff_t *ppos);
static ssize_t rwbuf_read(struct file* filp, char *buf , size_t count, loff_t *ppos);
static int rwbuf_ioctl(struct inode *node, struct file * filep, unsigned int cmd, unsigned long arg);
//以下是2.6内核在文件操作结构的定义,老师给的是2.4的,编译通不过滴
static struct file_operations rwbuf_fops =
{
read: rwbuf_read,
write: rwbuf_write,
ioctl: rwbuf_ioctl,
open: rwbuf_open,
release: rwbuf_close,
};
/*******************************************
init_module_rwbuf向系统的字符设备表登记了一个字符设备。
老师ppt上说设备号在1~255之间,应该/proc/devices里面Character devices下没有被注册过的都可以,我测试过277也是可以的。
******************************************/
int init_module_rwbuf()
{
register_chrdev(277,DEVICE_NAME,&rwbuf_fops);
printk(KERN_ALERT "register ok\n");
return 0;
}
//cleanup_module_rwbuf释放字符设备在系统字符设备表中占有的表项。
void cleanup_module_rwbuf()
{
unregister_chrdev(277,DEVICE_NAME);
printk(KERN_ALERT "unreg ok\n");
}
//inuse保证设备关闭前不能被多次打开
static int rwbuf_open(struct inode *node, struct file *filep)
{
if(inuse==1)
return -1;
inuse=1;
printk(KERN_ALERT "open ok\n");
return 0;
}
static int rwbuf_close(struct inode *node, struct file *filep)
{
inuse = 0;
printk(KERN_ALERT "close ok\n");
return 0;
}
//设备支持每次写入字符不超过1024个,超过部分被丢弃
static ssize_t rwbuf_write(struct file *filep, const char *buf, size_t count, loff_t *ppos)
{
if(count<=1024)
{
writenum++;
//printk(KERN_ALERT "write1\n");
copy_from_user(rwbuf,buf,count);
//printk(KERN_ALERT "write2\n");
rwlen = count;
//printk(KERN_ALERT "write ok\n");
return rwlen;
}
else
{
writenum++;
copy_from_user(rwbuf,buf,1024);
rwlen = 1024;
printk(KERN_ALERT "write overflow\n");
return rwlen;
}
}
//用户可以读出最近写入到设备中的字符
static ssize_t rwbuf_read(struct file* filp, char *buf , size_t count, loff_t *ppos)
{
printk(KERN_ALERT "read\n");
count=rwlen;
copy_to_user(buf,rwbuf,count);
printk(KERN_ALERT "read ok\n");
return count;
}
//设备支持系统调用ioctl(int d, int req,…)
static int rwbuf_ioctl(struct inode *node, struct file * filep, unsigned int cmd, unsigned long arg)
{
if(cmd==RWBUF_CLEAR)
{
rwlen = 0;
printk(KERN_ALERT "rwbuf in kernel zero-ed\n");
return 0;
}
else if(cmd==RWBUF_LENGTH)
{
printk(KERN_ALERT "length of buffer\n");
return rwlen;
}
else if(cmd==RWBUF_NUM)
{
printk(KERN_ALERT "num of writing\n");
return writenum;
}
return 0;
}
module_init(init_module_rwbuf);
module_exit(cleanup_module_rwbuf);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment