虚拟设备——globalmem

#define GLOBALMEM_MAJOR		230
#define GLOBALMEM_NAME		"GLOBALMEM"
#define GLOBALMEM_SIZE		0x1000

/*创建一个自己的设备类型 其中包含了一段内存*/
struct globalmem_dev = {
	struct cdev cdv;			//字符设备核心结构体
	int mem[GLOBALMEM_SIZE]			//自定义 这里定义为内存
}

static int globalmem_major = GLOBALMEM_MAJOR;
struct globalmem_dev globalmem_devp;

/*open*/
static int globalmem_open(struct *inode inode, struct *file filp)
{
	/*私有数据获取 获取设备结构体*/
	filp->private_data = globalmem_devp;
	return 0;
}
/*release*/
static int globalmem_release(struct *inode inode, struct *file filp)
{
	return 0;
}
/*read*/
static ssize_t globalmem_read(struct file *filp, char __user *buf, szie_t size, loff_t *ppos)
{
	unsigned long pos = *ppos;
	unsignend int count = size;
	int ret = 0;
	
	/*私有数据获取 获取设备结构体*/
	struct globalmem_dev *dev = filp->private_data;
	/*超出范围 自然退出*/
	if(pos >= GLOBALMEM_SIZE)
		return 0;
	/*内存不够*/
	if(count > GLOBALMEM_SIZE - pos)
		count = GLOBALMEM_SIZE - pos;
	/*从内核中拷贝*/
	if(copy_to_user(buf, dev-mem + p,count)){
		ret = -EFAULT;
	}else{
		*ppos += count;
		ret = count;
		
		printk(KERN_INFO "read %u bytes from %lu \r\n",count,pos);
	}
};
/*write*/
static ssize_t globalmem_write(struct file *filp, char __user *buf, szie_t size, loff_t *ppos)
{
	unsigned long pos = *ppos;
	unsignend int count = size;
	int ret = 0;
	
	/*私有数据获取 获取设备结构体*/
	struct globalmem_dev *dev = filp->private_data;
	
	/*超出范围 自然退出*/
	if(pos >= GLOBALMEM_SIZE)
		return 0;
	/*内存不够*/
	if(count > GLOBALMEM_SIZE - pos)
		count = GLOBALMEM_SIZE - pos;
	/*从用户中拷贝*/
	if(copy_from_user(dev-mem + p, buf, count)){
		ret = -EFAULT;
	}else{
		*ppos += count;
		ret = count;
		
		printk(KERN_INFO "write %u bytes from %lu \r\n",count,pos);
	}
};
/*globalmem 文件操作接口*/
static const struct file_operations globalmem_operations = {
    .owner = THIS_MODULE,
    .open = globalmem_open,
    .release = globalmem_release,
    .read = globalmem_read,
    .write = globalmem_write,
};
/*字符设备初始化并添加*/
static void globalmem_setuo_cdev(struct globalmem_dev *dev,int index)
{
	int err,devno = MKDEV(globalmem_major, index);
	/*初始化字符设备*/
	cdev_init(&dev->cdev,&globalmem_operations);
	
	dev->cdev.owner = THISMODULE;
	/*添加字符设备*/
	err = cdev_add(&dev->cdev,devno,1);
	if(err)
		printk(KERN_INFO "Error %d adding globalmem%d,err,index);
}

/*入口*/
static int __init globalmem_init(void)
{
	/*定义设备号*/
	int ret = 0;dev_t devno = MKDEV(globalmem_mahor, 0);
	
	/*申请设备号*/
	if(globalmem_major)
		ret = register_chrdev_region(devno, 1, "globalmem");
	else{
		ret = alloc_chrdev_region(&devno, 0, 1, "globalmem");
		globalmem_major = MAJOR(devno);
	}
	if(ret < 0)
		return ret;
	/*分配设备内存 该函数不是在基址分配内存 而是分配内存后绑定设备*/
	globalmem_devp = kzalloc(sizeof(struct globalmem_dev), GFP_KERNEL);
	if(!globalmem_devp){
		ret = -ENOMEM;
		goto fail_malloc;
	}
	/*初始化 添加字符设备*/
	globalmem_setuo_cdev(globalmem_devp,0);
	return 0;
fail_malloc:
	/*注销设备号*/
	unregister_chrdev_region(devno, 1);
	
}
/*出口*/
static void __exit globalmem_exit(void)
{
	/*删除字符设备*/
	cdev_del(&globalmem_devp->cdev);
	/*释放设备内存*/
	kfree(globalmem_devp);
	/*注销设备号*/
	unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);
}
module_init(globalmem_init);
module_exit(globalmem_exit);
MODULE_LICENSE("GPL");