日期:2014-05-16 浏览次数:20818 次
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define CHRMEM_SIZE 0x1000
#define MEM_CLEAR 0x1
static int chr_major;
struct chr_dev
{
struct cdev cdev;
unsigned char mem[CHRMEM_SIZE];
};
struct chr_dev* char_devp;
int chr_open(struct inode* inode, struct file* filp)
{
filp->private_data = char_devp;
return 0;
}
int chr_release(struct inode* inode, struct file* filp)
{
return 0;
}
static int chr_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg)
{
struct chr_dev* dev = filp->private_data;
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem, 0, CHRMEM_SIZE);
break;
default:
return -EINVAL;
}
return 0;
}
static ssize_t chr_read(struct file* filp, char __user* buf, size_t size, loff_t* ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct chr_dev* dev = filp->private_data;
if(p >= CHRMEM_SIZE)
{
return 0;
}
if(count > CHRMEM_SIZE - p)
{
return 0;
}
if(copy_to_user(buf, (void*)(dev->mem + p), count))
{
return -EINVAL;
}
else
{
*ppos += count;
ret = count;
}
return ret;
}
static ssize_t chr_write(struct file* filp, const char __user* buf, ssize_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct chr_dev* dev = filp->private_data;
if(p >= CHRMEM_SIZE)
{
return 0;
}
if(count > CHRMEM_SIZE - p)
{
count = CHRMEM_SIZE - p;
}
if(copy_from_user(dev->mem + p, buf, count))
{
ret = -EINVAL;
}
else
{
*ppos += count;
ret = count;
}
return ret;
}
static loff_t chr_llseek(struct file* filp, loff_t offset, int orig)
{
loff_t ret = 0;
/* orig can be SEEK_SET, SEEK_CUR, SEEK_END */
switch(orig)
{
case 0:
if(offset < 0)
{
ret = -EINVAL;