Ich habe zwei Linux-Kernel-Module, von denen eines einem anderen eine Funktion geben kann. Aber die Verwendung dieser Funktion ist nicht notwendig, das zweite Modul kann (und sollte) funktionieren, auch wenn das erste Modul nicht vorhanden ist.
Wenn ich die Funktion nur aus dem ersten Modul exportiert habe und sie im zweiten Modul verwende, hängt das zweite Modul von diesem Symbol ab und kann nicht ohne das erste Modul geladen werden.
Eine der Lösungen ist ein Benutzerskript, das in / proc / kallsym nach der Funktion im ersten Modul sucht. Wenn es dort vorhanden ist, übergibt das Skript seine Adresse als Parameter an das zweite Modul, das dann den Zeiger erzeugt heraus. Aber ich mag diese Lösung aus offensichtlichen Gründen nicht.
Wenn es eine korrektere und elegantere Lösung gibt, die es dem zweiten Modul erlaubt, die Adresse eines Symbols im ersten Modul zu bekommen, aber harte Abhängigkeit vermeiden?
Endlich habe ich die Lösung gefunden: Kernel hat symbol_get () und symbol_put (), was mir die Möglichkeit gibt, ein beliebiges Symbol in einem anderen Modul nachzuschlagen (es muss natürlich exportiert werden) und verhindern, dass das Modul entladen wird, während ich ' m mit seinem Symbol.
Ich denke, wenn Modul B von Modul A abhängt, kann das Modul B nicht erfolgreich geladen werden, ohne dass Modul A zuerst geladen wird.
Tatsächlich werden die Symbole, deren Modul B von Modul A exportiert wurde, erst nach dem Einfügen von Modul A in der Datei / proc / kallsym angezeigt.
Die Lösung für Ihre Situation: In Modul B sollte die Funktion module_init () einige Codes haben, um zu überprüfen, ob das Modul A bereits vorhanden ist oder nicht, wenn nicht, zuerst A laden. Verwenden Sie request_module (), um A zu laden, oder erstellen Sie eine elegantere Methode zur Verwendung von try_then_request_module ().
Es gibt elegantere Lösungen, die Kernel-Änderungen erfordern. Grundsätzlich wurde der Kernel erweitert, um Modulregistrierungen zu beherbergen. Wenn ein Modul geladen wird und sich anderen Modulen aussetzen will, wird er sich mit einem bekannten int im Kernel registrieren - was nur ein Index in das Kernel-Array ist, das Verweise auf registrierte Module speichert. Jedes Modul, das einen Verweis auf ein anderes Modul erhalten möchte, wird einfach den Kernel nach einem neuen Verweis auf dieses Modul fragen - mit demselben bekannten Int. Diese neuen Referenzen müssen kurzlebig sein (d. H. Sie erhalten einen Hinweis darauf, aber fügen Sie ihn in denselben Kontext zurück). Um langlebige Verbindungen zu ermöglichen, müssen Sie ein Protokoll zwischen den beiden erstellen, so dass, wenn eines der Module entladen wird, er / sie weiß, wie er das andere Modul darüber informiert, dass er weggeht.