Linux设备驱动程序学习(二)虚拟字符设备globalmem

来源:互联网 发布:淘宝网流量 编辑:程序博客网 时间:2024/06/07 06:12

虚拟字符设备globalmem是一块大小为GLOBALMEM_SIZE的内存空间,在设备驱动程序中进行分配。

首先,需要定义虚拟字符设备globalmem的设备结构体相关的宏:

#define GLOBALMEM_SIZE 0x1000#define MEM_CLEAR 0x1#define GLOBALMEM_MAJOR 250static int globalmem_major = GLOBALMEM_MAJOR;struct globalmem_dev{struct cdev cdev;unsigned char mem[GLOBALMEM_SIZE];};struct globalmem_dev dev;

当然,在这之前,还需要包含相应的头文件:

#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 <uaccess.h>

然后是设备驱动程序的模块加载函数和卸载函数:
static void globalmem_setup_cdev(void){int err = 0;int devno = 0;devno = MKDEV(globalmem_major, 0);cdev_init(&dev.cdev, &globalmem_fops);dev.cdev.owner = THIS_MODULE;err = cdev_add(&dev.cdev, devno, 1);if(err){printk(KERN_NOTICE "error %d adding globalmem", err);}}static int __init globalmem_init(void){int result = 0;dev_t devno = MKDEV(globalmem_major, 0);if(globalmem_major == 0){result = alloc_chrdev_region(&devno, 0, 1, "globalmem");globalmem_major = MAJOR(devno);}else{result = register_chrdev_region(devno, 1, "globalmem");}if(result < 0){return result;}globalmem_setup_cdev();return 0;}static void __exit globalmem_exit(void){cdev_del(&dev.cdev);unregister_chrdev_region(MKDEV(globalmem_major, 0), 1);}

之后,需要注册驱动程序与文件系统之间的接口:

static const struct file_operations globalmem_fops ={        .owner = THIS_MODULE,        .llseek = globalmem_llseek,        .read = globalmem_read,        .write = globalmem_write,        .ioctl = globalmem_ioctl,};

下面,我们就需要分别实现这个接口中的每一个函数:

globalmem_read:

static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos){        unsigned long p = *ppos;        int ret = 0;        if(p >= GLOBALMEM_SIZE)        {                return 0;        }        if(count > GLOBALMEM_SIZE - p)        {                count = GLOBALMEM_SIZE - p;        }        if(copy_to_user(buf, (void*)(dev.mem + p), count);        {                ret = -EFAULT;        }        else        {                *ppos = *ppos + count;                ret = count;                printk(KERN_INFO "read %d bytes(s) from %d\n", count, p);        }        return ret;}

globalmem_write:

static ssize_t globalmem_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos){        unsigned long p = *ppos;        int ret = 0;        if(p >= GLOBALMEM_SIZE)        {                return 0;        }        if(count > GLOBALMEM_SIZE - p)        {                count = GLOBALMEM_SIZE - p;        }        if(copy_from_user((void*)(dev.mem + p), buf, count)        {                ret = -EFAULT;        }        else        {                *ppos = *ppos + count;                ret = count;                printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);        }        return ret;}




原创粉丝点击