Kann mir jemand erklären,
- Was ist
IOCTL
? - Was wird es verwendet?
- Wie kann ich es benutzen?
- Warum kann ich keine neue Funktion definieren, die genauso funktioniert wie
IOCTL
?
quelle
Kann mir jemand erklären,
IOCTL
?IOCTL
?Ein ioctl
, was "Eingabe-Ausgabe-Steuerung" bedeutet, ist eine Art gerätespezifischer Systemaufruf. Unter Linux (300-400) gibt es nur wenige Systemaufrufe, die nicht ausreichen, um alle einzigartigen Funktionen auszudrücken, die Geräte möglicherweise haben. So kann ein Treiber ein ioctl definieren, mit dem eine Userspace-Anwendung Bestellungen senden kann. Ioctls sind jedoch nicht sehr flexibel und neigen dazu, etwas überladen zu werden (Dutzende von "magischen Zahlen", die einfach funktionieren ... oder nicht) und können auch unsicher sein, wenn Sie einen Puffer in den Kernel übergeben - eine schlechte Handhabung kann brechen Dinge leicht.
Eine Alternative ist die sysfs
Schnittstelle, über die Sie eine Datei einrichten /sys/
und diese lesen / schreiben, um Informationen vom und zum Treiber abzurufen. Ein Beispiel für die Einrichtung:
static ssize_t mydrvr_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", DRIVER_RELEASE);
}
static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);
Und während der Treibereinrichtung:
device_create_file(dev, &dev_attr_version);
Sie hätten dann eine Datei für Ihr Gerät /sys/
, beispielsweise /sys/block/myblk/version
für einen Blocktreiber.
Eine andere Methode für eine stärkere Nutzung ist Netlink, eine IPC-Methode (Inter-Process Communication), mit der Sie über eine BSD-Socket-Schnittstelle mit Ihrem Treiber kommunizieren können. Dies wird beispielsweise von den WiFi-Treibern verwendet. Anschließend kommunizieren Sie über die libnl
oder libnl3
Bibliotheken mit dem Benutzerbereich.
Die
ioctl
Funktion ist nützlich, um einen Gerätetreiber zu implementieren, um die Konfiguration auf dem Gerät festzulegen. Beispielsweise kann ein Drucker mit Konfigurationsoptionen zum Überprüfen und Einstellen der Schriftfamilie, Schriftgröße usw.ioctl
verwendet werden, um die aktuelle Schriftart abzurufen und die Schriftart auf eine neue einzustellen. Eine Benutzeranwendungioctl
sendet einen Code an einen Drucker, der ihn auffordert, die aktuelle Schriftart zurückzugeben oder die Schriftart auf eine neue festzulegen.fd
ist der Dateideskriptor, der von zurückgegeben wirdopen
;request
ist Anforderungscode. zBGETFONT
wird die aktuelle Schriftart vom DruckerSETFONT
abgerufen, die Schriftart wird auf dem Drucker eingestellt;void *
. Abhängig vom zweiten Argument kann das dritte vorhanden sein oder nicht, z. B. wenn das zweite Argument istSETFONT
, kann das dritte Argument der Schriftname sein, wie z"Arial"
.int request
ist nicht nur ein Makro. Eine Benutzeranwendung muss einen Anforderungscode generieren und das Gerätetreibermodul bestimmen, mit welcher Konfiguration auf dem Gerät gespielt werden muss. Die Anwendung sendet den Anforderungscode mitioctl
und verwendet dann den Anforderungscode im Gerätetreibermodul, um zu bestimmen, welche Aktion ausgeführt werden soll.Ein Anforderungscode besteht aus 4 Hauptteilen
Wenn der Anforderungscode
SETFONT
die Schriftart auf einem Drucker festlegen soll, lautet die Richtung für die Datenübertragung von der Benutzeranwendung zum Gerätetreibermodul (die Benutzeranwendung sendet den Schriftartnamen"Arial"
an den Drucker). Wenn der Anforderungscode lautetGETFONT
, erfolgt die Richtung vom Drucker zur Benutzeranwendung.Um einen Anforderungscode zu generieren, stellt Linux einige vordefinierte funktionsähnliche Makros zur Verfügung.
1.
_IO(MAGIC, SEQ_NO)
Beide sind 8 Bit, 0 bis 255, z. B. sagen wir, wir möchten den Drucker anhalten. Dies erfordert keine Datenübertragung. Wir würden also den Anforderungscode wie folgt generierenund jetzt verwenden
ioctl
alsDer entsprechende Systemaufruf im Treibermodul empfängt den Code und hält den Drucker an.
__IOW(MAGIC, SEQ_NO, TYPE)
MAGIC
undSEQ_NO
sind die gleichen wie oben undTYPE
geben den Typ des nächsten Arguments an, erinnern Sie sich an das dritte Argument vonioctl
isvoid *
. W in__IOW
zeigt an, dass der Datenfluss von der Benutzeranwendung zum Treibermodul erfolgt. Angenommen, wir möchten die Schriftart des Druckers auf festlegen"Arial"
.des Weiteren,
Jetzt
font
ist ein Zeiger, was bedeutet, dass es sich um eine Adresse handelt, die am besten als dargestellt wirdunsigned long
, daher der dritte Teil des_IOW
Erwähnungstyps als solcher. Außerdem wird diese Schriftartadresse an den entsprechenden Systemaufruf übergeben, der im Gerätetreibermodul als implementiert ist,unsigned long
und wir müssen sie vor der Verwendung in den richtigen Typ umwandeln. Der Kernel-Speicherplatz kann auf den Benutzerbereich zugreifen, und dies funktioniert daher. beiden anderen Funktionsmakros sind__IOR(MAGIC, SEQ_NO, TYPE)
und__IORW(MAGIC, SEQ_NO, TYPE)
wo der Datenfluss bzw. den User - Space und beide Arten von Kernel - Space sein.Bitte lassen Sie mich wissen, ob dies hilft!
quelle