2 Stimmen

Wie kann ich testen, ob mein Treiber geladen ist, und dann auf meine Treiberfunktionen im Linux-Kernel zugreifen?

Ich habe einen Treiber, der erfolgreich in den Linux-Kernel kompiliert und geladen wird. In diesem Treiber befinden sich einige Funktionen, auf die ich vom Kernel-Datei 'fs/readdir.c' aus zugreifen möchte. Darüber hinaus, wie kann ich testen, ob ein Treiber geladen ist?

Ich brauche etwas Ähnliches wie das Folgende.

if(meinTreiber geladen ist){
    meinTreiber.functionCall();
}

Alle Beispiele, die ich bei Internetrecherchen gefunden habe, führen dies von Benutzeranwendungen aus durch.

2voto

Dipstick Punkte 9546

Die andere Möglichkeit besteht darin, in Ihrem Modul EXPORT_SYMBOL(functionCall); zu verwenden, was Ihre Funktion im Kernel-Symboltabelle erscheinen lässt. Sie können dann find_symbol("functionCall", blah, blah) verwenden, um zu überprüfen, ob das Symbol vorhanden ist und um seinen Wert/Standort dynamisch zu finden.

Siehe linux/kernel/module.c und module.h

1voto

Nikolai Fetissov Punkte 79627

fs/readdir.c würde keine Verbindung herstellen, wenn das functionCall-Symbol im Kernel noch nicht vorhanden ist. Dies kann nur durch Indirektion erfolgen. Richten Sie einige ops-Strukturen im Hauptkernelcode ein, initialisieren Sie diese mit Dummy-Funktionen oder einfach mit NULL, um dem Rest des Kernels mitzuteilen, dass Ihr Treiber noch nicht geladen ist. Im Treiber-Initialisierungsprozess setzen Sie die Funktionszeiger in dieser Struktur auf Funktionen in Ihrem Modul (zurücksetzen auf Voreinstellungen beim De-Initialisieren). Die Struktur wird jedoch eine Art von Rennschutz benötigen, sodass Sie wahrscheinlich ein Semaphor als eines seiner Elemente haben werden. Dies kann auf Struktur pro Gerät usw. erweitert werden.

0voto

ctuffli Punkte 3509

Sie könnten einen Funktionszeiger auf functionCall im Kernel hinzufügen, initialisieren Sie ihn mit NULL und warten Sie darauf, dass das Modul den Zeiger auf einen nicht NULL-Wert setzt. Der Code in readdir würde überprüfen, ob der Zeiger nicht NULL ist, bevor er ihn dereferenziert. Dafür muss das Modul über den Funktionszeiger im Kernel Bescheid wissen, indem der Zeiger global gemacht wird oder ähnlich einfach aus einem Modul erreichbar ist.

Wenn der Treiber nichts von dieser Änderung am Kernel wissen soll, könnten Sie readdir ändern, um nach dem Treiber zum Laden zu suchen, dann find_symbol verwenden (wie von @chrisharris erwähnt), um die Adresse von functionCall zu erhalten, und den zurückgegebenen Wert einem privaten Funktionszeiger irgendwo in readdir zuzuweisen.

Eine Möglichkeit, die Frage "Ist der Treiber geladen" zu beantworten, wäre die Verwendung von register_module_notifier()

static int
my_load_notify(struct notifier_block *self, unsigned long val, void *data)
{
 struct module *m = data;
 if (0 == strcmp(m->name, "myDriver")) {
  // set function pointer(s)
 }
}
static struct notifier_block module_load_nb = {
 .notifier_call = my_load_notify,
};

static int
my_init(void)
{
 ...
 register_module_notifier(&module_load_nb);
 ...
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X