2016-05-22 13 views
2

Ich bin neu in der Linux-Kernel-Modul-Programmierung und habe einen Dummy-Gerätetreiber zum Lesen und Schreiben auf ein Dummy-Gerät geschrieben (es ist eigentlich ein Beispielprogramm in seiner Dokumentation)). Das Programm läuft gut, wenn ich es mit nur einer Gerätedatei versuche, tritt das Problem auf, wenn ich eine zweite Dummy-Gerätedatei mit der gleichen Hauptnummer, aber anderen Nebennummer (in der Reihenfolge 1) erstellen. Wenn ich in eine Datei schreiben (sagen devfile0, major : 250, minor : 0) die Daten auch in die andere Datei geschrieben wird (sagen wir devfile1, major : 250, minor : 1), aber ich möchte nur Schreib und devfile0 nicht devfile1. Ist es möglich? Was mache ich möglicherweise falsch? HierUmgang mit mehreren Gerätedateien mit gleicher Major-Nummer, aber eindeutiger Minor-Nummer

ist das Kernel-Modul I erstellt haben:

#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); 

Userspace-Anwendung verwendet open syscall devfile0 zu öffnen und write syscall zu devfile0 zu schreiben.
Hier ist der Code für das:

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); 
+0

Sie müssen also mehrere zugrunde liegende Puffer erstellen, einen für jedes zugewiesene Gerät. [Diese Frage] (http://stackoverflow.com/q/36066635/3440745) beschreibt, wie sich Geräte von Dateioperationen unterscheiden. – Tsyvarev

Antwort

0

Die Major-Nummer erfahren Sie, welche Treiber verwendet wird, um die Hardware zuzugreifen. Jedem Fahrer ist eine eindeutige Major-Nummer zugeordnet; Alle Geräte Dateien mit der gleichen Major-Nummer werden von demselben Treiber gesteuert. Alle oben genannten Hauptnummern sind 3, weil sie alle von den gleichen Treiber gesteuert werden.

Die Minor-Nummer wird vom Treiber verwendet, um zwischen der verschiedenen Hardware, die er steuert, zu unterscheiden. Zurück zu dem obigen Beispiel, obwohl alle drei Geräte von dem gleichen Treiber behandelt werden, haben sie eindeutige Minor-Nummern, weil der Treiber sieht sie als unterschiedliche Teile der Hardware.

von The Linux Kernel Module Programming Guide, 3.1.6.1. Haupt- und Nebennummern