5

Momentan lerne ich Linux-Gerätetreiber. Und wie ist das Öffnen einer Gerätedatei?Wie funktioniert Open für normale Datei- und Gerätetreiber?

Was ich bis jetzt hätte ... das Betrachten sich eine einfache Code, der eine normale Datei öffnet ..

#incldue<stdio.h> 
int main() { 
    FILE fp; 
    char buffer[20]; 
    fp = fopen(/home/yoggi/foo.txt, "r"); 
    fread(buffer, 5, 1, fp); 
} 

In obigem Programm, The fopen(), c-Library-Funktion, eine Funktion Wrapper an den Systemaufruf open(), die intern ruft sys_open() oder file_open() in VFS-Layer Funktion. Da Linux eine Reihe von Dateisystemen unterstützt, überträgt das virtuelle Dateisystem das Steuerelement an den tatsächlichen Dateisystem-Handler, um diese Datei zu öffnen.

1) How does virtual file system(VFS) get to know on which file system the 
    underline file resides? 
2) How does it then calls the file_open or open function of that particular 
    filesystem to open file. 

Bei Gerätetreibern passiert ähnliches. Angenommen, ein einfacher Gerätetreiber.

#include <linux/module.h> 
// othher includes... 
static dev_t first; // Global variable for the first device number 
static struct cdev c_dev; // Global variable for the character device structure 
static struct class *cl; // Global variable for the device class 
static int my_open(struct inode *i, struct file *f) 
{ 
    printk(KERN_INFO "Driver: open()\n"); 
    return 0; 
} 
static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off) 
{ 
    printk(KERN_INFO "Driver: read()\n"); 
    return 0; 
} 
struct file_operations pugs_fops = 
{ 
.owner = THIS_MODULE, 
.open = my_open, 
.read = my_read, 
}; 

static int __init ofcd_init(void) /* Constructor */ 
{ 
    printk(KERN_INFO "Namaskar: ofcd registered"); 
    if (alloc_chrdev_region(&first, 0, 1, "Shweta") < 0) 
    { 
    return -1; 
    } 
    if ((cl = class_create(THIS_MODULE, "chardrv")) == NULL) 
    { 
    unregister_chrdev_region(first, 1); 
    return -1; 
} 
if (device_create(cl, NULL, first, NULL, "mynull") == NULL) 
{ 
    class_destroy(cl); 
    unregister_chrdev_region(first, 1); 
    return -1; 
} 
    cdev_init(&c_dev, &pugs_fops); 
if (cdev_add(&c_dev, first, 1) == -1) 
{ 
    device_destroy(cl, first); 
    class_destroy(cl); 
    unregister_chrdev_region(first, 1); 
    return -1; 
} 
    return 0; 
} 

static void __exit ofcd_exit(void) /* Destructor */ 
{ 
cdev_del(&c_dev); 
device_destroy(cl, first); 
class_destroy(cl); 
unregister_chrdev_region(first, 1); 
printk(KERN_INFO "Alvida: ofcd unregistered"); 
} 
module_init(ofcd_init); 
module_exit(ofcd_exit); 
MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>"); 
MODULE_DESCRIPTION("Our First Character Driver"); 

Zuerst ordnen wir Major-Minor-Nummern für das Gerät zu. Registrieren Sie sich für den Bereich der Gerätedateien und verknüpfen Sie die Gerätedateioperationen mit den Gerätetreiberfunktionen.

Einige der Begriff, den ich nicht sind hast ..

1) What does actually cdev_add() do? in terms of registering a device to the 
    kernel. 
2) Registering a device to the kernel means? 
3) How does a open(/dev/mynull, O_RONLY); called on a device file actually calls 
    the open function of driver which is mapped while initializing the device 
    by calling routine cdev_init(&c_dev, &pugs_fops); ? 

Antwort

7

1) Wie funktioniert virtuelles Dateisystem (VFS) erhalten auf wissen, welches Dateisystem die Unterstrichen Datei befindet?

Sie haben die Datei angeben Sie durch seinen vollständigen Pfadnamen (oder das aktuellen Arbeitsverzeichnis) zu öffnen versuchen.
Wenn Sie also diesen Verzeichnispfad rückwärts durchlaufen, liefert die erste Übereinstimmung (der tiefste Pfad) zu einem Bereitstellungspunkt das gemountete Dateisystem, den Typ des Dateisystems und das Gerät.

Jedes Dateisystem stellt diese Informationen bereit, wenn es bereitgestellt und in den Mount-Tabellen gespeichert wird.
Sie können diese (aktuellen Status) Informationen mit dem Befehl mount anzeigen.

2) Wie ruft es dann die Funktion file_open oder open dieses speziellen Dateisystems auf, um die Datei zu öffnen.

Sobald das Dateisystem bekannt ist, die ops Struktur für die fs abgerufen und der open() Einstiegspunkt aufgerufen werden.

1) Was macht eigentlich cdev_add()? in Bezug auf die Registrierung eines Geräts für den Kernel .

Treiber Registrierung (z.B cdev_init() für eine char device) installiert die ops Struktur des Fahrers, welche die Einstiegspunkte von Funktionen aufgelistet, die der Fahrer durchführen kann.
cdev_add() benachrichtigt den Kernel, dass der Treiber eine bestimmte Instanz dieses Char-Gerätetyps steuern kann.Dieser Geräteinstanz wird eine Minor-Nummer zugewiesen, die den Gerätenamen in /dev den Statusinformationen im Treiber zuordnet.
Beachten Sie, dass andere Gerätetypen als char (wie ein Netzwerk oder Plattform (Bus) -Geräte) zu einem anderen Subsystem gehören und unterschiedliche Registrierungsverfahren verwenden.

2) Ein Gerät auf dem Kernel registrieren bedeutet?

Der Zugriff auf dieses Gerät ist jetzt aktiviert.

3) Wie öffnet sich (/ dev/mynull, O_RONLY); aufgerufen auf eine Gerätedatei tatsächlich ruft die offene Funktion des Treibers, die während der Initialisierung des Geräts zugeordnet ist, indem Routine cdev_init (& c_dev, & pugs_fops) aufrufen; ?

Die Routine init() des Treibers sollte nur einmal aufgerufen werden, wenn der Treiber geladen wird. Diese Routine sollte nach dem Vorhandensein und dem Betriebszustand aller Instanzen des Geräts suchen. Ressourcen wie Interrupt-Leitungen, DMA-Kanäle und I/O-Port und/oder Speicherplatz sollten erworben werden. Der Treiber registriert seine ops Struktur mit Kernel. Der Treiber registriert jede Instanz des Geräts mit dem Kernel.

Der open() Aufruf in Benutzerbereich wird von der C-Bibliothek behandelt. Der Gerätename /dev wird in die Geräte-Major-Nummer übersetzt (die angibt, welches Gerätesubsystem oder welche Geräteklasse, z. B. oder Audio, die Anforderung verarbeiten muss) und die Minor-Nummer (die angibt, welcher Gerätetreiber verwendet werden soll und welche Instanz auf das Gerät zugegriffen wird). Der Prozessor wird in den Supervisor-Modus geschaltet, so dass die open()-Routine des Kernel-Treibers aufgerufen werden kann, die aus der Struktur des Treibers ops abgerufen wird. Für ein bisschen mehr auf der ops Struktur sehen Sie diese other answer.