Wie können wir die Reihenfolge der integrierten Treiberladevorgänge anpassen (um zuerst einige integrierte Treibermodule zu laden und später die abhängigen Module zu laden)?
Eingebaute Treiber werden nicht geladen , daher eingebaut. Ihre Initialisierungsfunktionen werden aufgerufen und die Treiber werden aktiviert, wenn sich der Kernel selbst einrichtet. Diese init-Funktionen werden in init/main.c::do_initcalls()
aufgerufen. Alle Init-Aufrufe werden in Ebenen klassifiziert, die in initcall_levels
und include/linux/init.h
definiert sind.
Diese Ebenen sind tatsächlich Symbole, die im Linker-Skript (Arch/*/kernel/vmlinux.lds.*
) definiert sind. Zur Kernelkompilierungszeit erfasst der Linker alle Funktionen, die mit module_init()
oder anderen *_initcall()
gekennzeichnet sind, klassifiziert in Ebenen, fügt alle Funktionen auf derselben Ebene an derselben Stelle zusammen und erstellt wie ein Array von Funktionszeigern.
Do_initcall_level () macht zur Laufzeit jede Funktion, auf die die Zeiger im Array zeigen. In do_initcall_level gibt es keine aufrufenden Richtlinien mit Ausnahme der Ebenen. Die Reihenfolge im Array wird jedoch in der Verbindungszeit festgelegt.
Jetzt können Sie sehen, dass die Startreihenfolge des Treibers zur Verbindungszeit festgelegt ist. Was können Sie tun?
Makefile
auf die höhere Position.Der erste ist klar, wenn Sie das oben gelesen haben. dh, verwenden Sie early_initcall (), wenn es angebracht ist.
Der zweite braucht ein wenig mehr Erklärung. Der Grund für die Reihenfolge in einer Makefile
-Angelegenheit ist die Funktionsweise des aktuellen Kernel-Build-Systems und die Funktionsweise der Linker. Um es kurz zu machen, das Build-System nimmt alle Objektdateien in obj-y
und verknüpft sie miteinander. Es ist in hohem Maße von der Umgebung abhängig, aber es besteht eine hohe Wahrscheinlichkeit, dass der Linker die erste Objektdatei im obj-y
in der unteren Adresse platziert, also früher aufgerufen wird.
Wenn Sie lediglich möchten, dass Ihr Treiber früher aufgerufen wird als andere Treiber in demselben Verzeichnis, ist dies der einfachste Weg, dies zu tun.
depmod
untersucht die exportierten und von jedem Modul benötigten Symbole und führt eine topologische Sortierung durch, die modprobe
später zum Laden von Modulen in der richtigen Reihenfolge verwenden kann. Das Anfordern der Symbole von Modulen, auf die Sie angewiesen sein möchten, reicht aus, um das Richtige zu tun.
Vor kurzem bekam ich dieses Problem, dass mein Ladegerätetreiber eine Abhängigkeit vom ADC-Treiber hat. Vor dem Laden des ADC-Treiberladegerätetreibers wurde geprüft, ob ein ADC-Phandle vorhanden ist, der in der Datei DTS definiert ist und vom ADC-Treiber initialisiert werden muss. Es wurde behoben, indem die Reihenfolge des Moduls in Treiber/Makefile geändert wurde