设备驱动中分配的内存空间编译

为glmemory字符设备驱动分配大小为GLMEMORY_SIZE(4k)的内存空间:

实现函数有:

        glmemory_open              文件打开函数

        glmemory_release         文件释放函数

        glmemory_read              文件读函数

        glmemory_write              文件写函数

        glmemory_init                 设备驱动模块加载函数

        glmemory_exit                模块卸载函数

1.在/drivers/下建立glmemory.c文件:

#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>
#include <linux/slab.h>
#define GLMEMORY_SIZE 0x1000    /*全局内存大小4k*/
#define MEM_CLEAR 0x1         /*清零全局内存*/    


static int glmemory_major = 0;//GLMEMOERY_MAJOR;自动获取主设备号

/*glmemory设备结构体*/

struct glmemory_dev
{
    struct cdev cdev; /*cdev结构体*/
    unsigned char mem[GLMEMORY_SIZE]; /*全局内存*/
};

struct glmemory_dev *glmemory_devp; /*设备体指针*/




/*文件打开函数*/

int glmemory_open(struct inode *inode, struct file *filp)
{
    /*将设备结构体指针赋值给文件私有数据指针*/
    filp -> private_data = glmemory_devp;
    return 0;
}

/*文件释放函数*/

int glmemory_release(struct inode *inode, struct file *filp)
{
    return 0;
}

/*读函数*/

static ssize_t glmemory_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
    unsigned  long p = *ppos;
    int ret = 0;
    struct glmemory_dev *dev = filp -> private_data; /*获得设备结构体指针*/
    
    /*分析和获取有效的读长度*/
    if (p >= GLMEMORY_SIZE)
    {
        return count ? - ENXIO: 0;
    }
    if (count >GLMEMORY_SIZE - p)
    {
        count = GLMEMORY_SIZE - p;
    }
    
    /*内核空间————用户空间*/
    if (copy_to_user(buf, (void*)(dev->mem +p), count))
    {
        ret = - EFAULT;
    }
    else
    {
        *ppos += count;
        ret = count;
        printk(KERN_INFO "read %d bytes(s) from %ld \n",count, p);
    }
    
    return ret;
}

/*写函数*/

static ssize_t glmemory_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
{
    unsigned long p = *ppos;
    int ret = 0;
    struct glmemory_dev *dev = filp -> private_data; /*获得设备结构体指针*/
    
    /*分析和获取有效的写长度*/
    if (p >= GLMEMORY_SIZE)
    {
        return count ? - ENXIO : 0;
    }
    if (count >GLMEMORY_SIZE -p)
    {
        count = GLMEMORY_SIZE - p;
    }
    
    /*用户空间————内核空间*/
    if (copy_from_user(dev -> mem + p, buf, count))
    {
        ret = -EFAULT;
    }
    else
    {
        *ppos += count;
        ret = count;
        
        printk(KERN_INFO "written %d bytes(s) from %ld \n",count , p);
    }
    
    return ret ;
}

static const struct file_operations glmemory_fops ={
    .owner = THIS_MODULE,
//    .llseek = glmemory_llseek,
    .read = glmemory_read,
    .write = glmemory_write,
//    .ioctl = glmemory_ioctl,
    .open = glmemory_open,
    .release = glmemory_release,
};


/*初始化并添加cdev结构体*/
static void glmemory_setup_cdev(struct glmemory_dev *dev, int index)
{
    int err, devno = MKDEV(glmemory_major, index);
    
    cdev_init(&dev->cdev, &glmemory_fops);
    dev->cdev.owner = THIS_MODULE;
    dev->cdev.ops = &glmemory_fops;
    err = cdev_add(&dev->cdev, devno, 1);
    if (err)
    {
        printk(KERN_NOTICE "Error %d adding glmemory %d ", err, index);
    }
}



/*设备驱动模块加载函数*/

int glmemory_init(void)
{
    int result;
    dev_t devno = MKDEV(glmemory_major, 0);
    
    /*申请设备号*/
    if (glmemory_major)
        result = register_chrdev_region(devno, 1, "glmemory");
    else
    /*动态获得主设备号*/
    {
        result = alloc_chrdev_region(&devno, 0, 1, "glmemory");
        glmemory_major = MAJOR(devno);
    }
    if (result < 0)
    return result;

    /*动态申请设备结构体的内存*/
    glmemory_devp = kmalloc(sizeof(struct glmemory_dev), GFP_KERNEL);
    if (!glmemory_devp) /*申请失败*/
    {
        result = -ENOMEM;
        goto fail_malloc;
    }
    memset(glmemory_devp, 0, sizeof(struct glmemory_dev));
    
    glmemory_setup_cdev(glmemory_devp, 0);
    return 0;
    
    fail_malloc: unregister_chrdev_region(devno, 1);
    return result;
}


/*设备驱动模块卸载函数*/

void glmemory_exit(void)
{
    cdev_del(&glmemory_devp->cdev);  /*删除cdev结构*/
    kfree(glmemory_devp); /*释放设备结构体内存*/
    unregister_chrdev_region(MKDEV(glmemory_major, 0), 1);  /*释放设备号*/
}

MODULE_AUTHOR("Song Baohua");
MODULE_LICENSE("Dual BSD/GPL");

module_param(glmemory_major, int, S_IRUGO);

module_init(glmemory_init);
module_exit(glmemory_exit);

2.在/drivers/下建立Makefile文件:

obj-m :=glmemory.o

KERNELDIR :=/lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)

modules:
    $(MAKE) -C  $(KERNELDIR) M=$(PWD) modules

modules_install:
    $(MAKE) -C  $(KERNELDIR) M=$(PWD) modules_install
            

3.在drivers下执行make(以上代码检查过无错误)

XXX@ubuntu:~/linux/linux-kernel/drivers/glmemory$ make


3.    XXX@ubuntu:~/linux/linux-kernel/drivers/glmemory$ sudo insmod glmemory.ko

4.    XXX@ubuntu:~/linux/linux-kernel/drivers/glmemory$ rmmod glmemory









  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值