Ich programmiere einen einfachen Linux-Zeichengerätetreiber, um Daten über I/O-Ports an eine Hardware auszugeben. Ich habe eine Funktion, die Fließkommaoperationen ausführt, um die korrekte Ausgabe für die Hardware zu berechnen; Das bedeutet leider, dass ich diese Funktion im Userspace behalten muss, da der Linux-Kernel keine Fließkommaoperationen sehr gut beherrscht.Aufruf einer Userspace-Funktion innerhalb eines Linux-Kernel-Moduls
Hier ist eine Pseudo-Darstellung des Setup (beachten Sie, dass dieser Code nicht etwas Bestimmtes tut, es zeigt nur die relative Layout meines Codes):
Userspace-Funktion:
char calculate_output(char x){
double y = 2.5*x;
double z = sqrt(y);
char output = 0xA3;
if(z > 35.67){
output = 0xC0;
}
return output;
}
Kernelcode:
unsigned i;
for(i = 0; i < 300; i++){
if(inb(INPUT_PORT) & NEED_DATA){
char seed = inb(SEED_PORT);
char output = calculate_output(seed);
outb(output, OUTPUT_PORT);
}
/* do some random stuff here */
}
ich dachte über 01 mit, um die Daten von der Userspace-Funktion zu übergeben, aber ich bin mir nicht sicher, wie die Tatsache behandelt wird, dass der Funktionsaufruf in einer Schleife ist und mehr Code ausgeführt wird, bevor der nächste Aufruf an calculate_output
auftritt.
Die Art, wie ich diese Arbeit vorstellen, ist:
- Haupt User-Space-Programm wird den Kernel- Code (vielleicht über
ioctl
) - Userspace-Programm Blöcke und wartet auf Kernel- Code
- Kernel- Programm starten fragt Userspace-Programm für Ausgabedaten und Blöcke warten
- Anwenderseite Programm entblockiert, berechnet und sendet Daten (
ioctl
?), Dann Blöcke wieder - Kernel- Programm und setzt
- Anwenderseite Anwenderseite entblockiert
- Kernel- Programm beendet und benachrichtigtentsperrt und fährt mit der nächsten Aufgabe fort
Also, wie habe ich die Kommunikation zwischen Kernelspace und Userspace, und auch Blockierung, so dass ich den Userspace nicht ständig eine Gerätedatei abfragen, um zu sehen, ob es Daten senden muss?
Ein Nachteil: Während Festkommaarithmetik würde in meinem Beispiel Code recht gut funktionieren, es ist keine Option in dem realen Code; Ich benötige den großen Bereich, den der Gleitkomma-Punkt bietet, und - selbst wenn nicht - ich befürchte, den Code neu schreiben zu müssen, um Festkommaarithmetik zu verwenden, würde den Algorithmus für zukünftige Betreuer verdecken.
Jede Möglichkeit, Sie können fast alles im Benutzerbereich haben, und nur eine dünne Schnittstelle Enabler im Kernel? –
@ChrisStratton Das versuche ich zu erreichen. Das Zeug, das innerhalb der for-Schleife auftritt, ist mehr verschiedene Hardware-Ausgabe (einfache Outb-Aufrufe und nichts anderes). –
@ChrisStratta Oh, warte, meinst du die 'for' -Schleife außerhalb des Kernels verschieben? –