日期:2014-05-16 浏览次数:20661 次
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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;