处理具有相同主号但唯一次号的多个设备文件

时间:2016-05-22 22:09:51

标签: c linux linux-kernel kernel-module

我是Linux内核模块编程的新手,并编写了一个虚拟字符设备驱动程序来读取和写入虚拟设备(它实际上是文档中给出的示例程序)。当我只用一个设备文件尝试它时,程序运行正常,当我创建一个具有相同主号但不同次要号码的第二个虚拟设备文件时,问题出现了(按顺序排列,即1)。当我写入一个文件(比如devfile0,major : 250minor : 0)时,数据也写入另一个文件(比如devfile1,major : 250minor : 1)但我只是想要写入devfile0 不要写入devfile1 。可能吗?我可能做错了什么?

这是我创建的内核模块:

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/cdev.h>
#include<linux/fs.h>
#include<linux/semaphore.h>
#include<asm/uaccess.h>
#include<linux/kmod.h>

struct cdev *newDev;
int maj_no;
int ret;
dev_t crdev;
#define DEVICE_NAME "CryptoDevCHARDEVDRVR" 
struct dummy{
    char string[100];
    int length;
    struct semaphore sem;
    }device;

int device_open(struct inode *node,struct file *fp)
{
    printk(KERN_ALERT "Atempting to open device file\n");
    if(down_interruptible(&device.sem) != 0)
    {
        printk(KERN_ALERT "%s : Unable to Lock file while open\n",DEVICE_NAME);
        return -1;
    }
    printk(KERN_ALERT "File open operation Complete\n");
    return 0;
}

ssize_t device_read(struct file* fp,char* buffer, size_t bufsize, loff_t* buffoff)
{
    printk(KERN_ALERT "Reading from the device...\n");
    ret = copy_to_user(buffer,device.string,bufsize);
    device.length = bufsize;
    return ret;
}

ssize_t device_write(struct file* fp,const char* buffer, size_t bufsize, loff_t* buffoff)
{
    printk(KERN_ALERT "Writing to the device...\n");
    ret = copy_from_user(device.string,buffer,bufsize);
    printk(KERN_ALERT "%s\n",device.string);
    printk(KERN_ALERT "Written\n");
    device.length = bufsize;
    return ret;
}

int device_close(struct inode* node, struct file* fp)
{
    printk(KERN_ALERT "Closing Device File");
    up(&device.sem);
    printk(KERN_ALERT "Device Close Successfully");
    return 0;
}

struct file_operations fop = {
    .owner = THIS_MODULE,
    .open = device_open,
    .release = device_close,
    .read = device_read,
    .write = device_write
};


static int hello_init(void)
{
    ret = alloc_chrdev_region(&crdev,0,50,DEVICE_NAME);
    if(ret < 0)
    {
        printk(KERN_ALERT "\n%s : Unable to assign Character Device Driver Region",DEVICE_NAME);
        return ret;
    }
    maj_no = MAJOR(crdev);
    printk(KERN_ALERT "%s : Major Number:%d\n",DEVICE_NAME,maj_no);
    newDev = cdev_alloc();
    newDev->ops = &fop;
    newDev->owner = THIS_MODULE;
    ret = cdev_add(newDev,crdev,50);
    if(ret < 0)
    {
        printk(KERN_ALERT "%s : Unable to Register Device Driver\n",DEVICE_NAME);
    }
    sema_init(&device.sem,1);
    printk(KERN_ALERT "Successfully Initialised Device Driver\n");
    printk(KERN_ALERT "Test caller");
    return 0;
}

static void hello_destroy(void)
{
    printk(KERN_ALERT "Killing Hello-Start.c ... Byeeee\n");
    cdev_del(newDev);
    unregister_chrdev_region(crdev,50);
    printk(KERN_ALERT "%s : Successfully Unregistered Driver\n",DEVICE_NAME);
    printk(KERN_ALERT "Done");
}

module_init(hello_init);
module_exit(hello_destroy);

用户空间应用程序使用open系统调用打开devfile0和write系统调用来写入devfile0。
这是代码:

fp = open(DEVICE , O_RDWR);
if(fp == -1)
{
    printf("%s cann't be accessed right now try after sometime\n",DEVICE);
    exit(-1);
}

printf("Enter any Character String to transmit to Device:");
            fgets(buff,100,stdin);
            write(fp,buff,sizeof(buff));
            printf("\nWritten: %s\n",buff);

1 个答案:

答案 0 :(得分:-1)

  

主要编号告诉您使用哪个驱动程序访问   硬件。每个驱动程序都分配有唯一的主编号;所有设备   具有相同主编号的文件由同一驱动程序控制。   所有上述主要数字均为3,因为它们全部受到控制   同一个司机。

     

驾驶员使用次要号码来区分   它控制的各种硬件。回到上面的例子,虽然   所有这三个设备都由它们独有的相同驱动程序处理   次要数字,因为司机认为它们是不同的部分   硬件。

来自The Linux Kernel Module Programming Guide,3.1.6.1。主要和次要数字