IDE-Treiber fest in den Kernel einbinden?

Diskussionen um Bootloader, Kernel, Busybox
wolgade
Semiprofi
Semiprofi
Beiträge: 1313
Registriert: Donnerstag 2. Dezember 2004, 00:18

IDE-Treiber fest in den Kernel einbinden?

Beitrag von wolgade »

Hintergrund: Festplattenzugriffe über das IDE-Interface erzeugen relativ hohe CPU-Last.

Idee: IDE-Treiber nicht als Kernelmodul laden, sondern fest einkompilieren. Geht das?

Ich hab vor ein paar Jahren mal einen Uralt-PC mit Eisfair als NFS-Server für die D-Box aufgesetzt. Die Performance der Mühle stieg signifikant, nachdem ich NFS nicht mehr als Kernelmodul geladen habe, sondern NFS fest in den Kernel einkompiliert war.
MPC823
Erleuchteter
Erleuchteter
Beiträge: 448
Registriert: Samstag 26. November 2005, 00:35

Beitrag von MPC823 »

Intressanter Aspekt. Ganz logisch wäre es nicht wenn das immer so wäre.
Hab mal zu dem Thema Dr.Google bemüht.
Unter http://www.linuxfibel.de/kmodule.htm steht
Auch die Vermutung, ein als Modul arbeitender Treiber verrichtet seine Tätigkeit weniger effizient als sein »fest angestellter Kollege«, ist falsch. Nur der erste Zugriff auf das Gerät wird, bedingt durch den jetzt anstehenden Ladevorgang, eine minimale Verzögerung mit sich bringen. Ist er einmal drin, ist kein Unterschied mehr festzustellen.
:gruebel: Vileicht müsste man das mal wirklich verifizieren , so manches kommt ja erst beim Probieren aus.

Gruss Martin
wolgade
Semiprofi
Semiprofi
Beiträge: 1313
Registriert: Donnerstag 2. Dezember 2004, 00:18

Beitrag von wolgade »

MPC823 hat geschrieben: :gruebel: Vileicht müsste man das mal wirklich verifizieren , so manches kommt ja erst beim Probieren aus.
Auf einem Pentium 133, den ich als NFS-Server laufen habe, habe ich das verifiziert.

NFS als Kernelmodul: 7,3 Mbit/s
NFS einkompiliert: 8,5 Mbit/s

Das war damals der Unterschied zwischen "geht gar nicht" und "läuft wie geschmiert". Wenn jemanden die alte Geschichte interessiert: http://tuxbox-forum.dreambox-fan.de/for ... hp?t=34724
wolgade
Semiprofi
Semiprofi
Beiträge: 1313
Registriert: Donnerstag 2. Dezember 2004, 00:18

Beitrag von wolgade »

Ich hab jetzt in den letzten Stunden einigen harten Stoff zum Thema Kernelmodule gelesen. Den Treiber für das IDE-Interface hab ich mir auch angesehen, zumindest seine Schnittstellen nach außen. Grundsätzlich kann man das Ding fest einkompilieren. Die Frage ist jetzt, wie?

Bei Treibern, die zum Vanilla-Kernel gehören, ist die Sache einfach. Da geb ich einfach in der Kernelconfig an, ob ich den Treiber gar nicht, fest eingebaut oder als ladbares Modul haben will. Das Buildsystem des Kernels weiß aber nichts vom IDE-Interface der D-Box. Da wäre also Handarbeit gefragt.

Hat dazu irgend jemand sachdienliche Hinweise? O'Reillys "Linux Kernel In A Nutshell" liegt neben mir und schweigt sich zu diesem Thema aus. Die diversen Artikel zum Thema Kernelprogrammierung haben mir erklärt, wie ich ein Kernelmodul schreiben kann und anschließend dynamisch lade. Also genau das, was ich nicht wissen will.

Verdammte Hacke! Irgendwo muß geschrieben stehen, wie man so etwas statisch einbindet.
Carjay
Developer
Beiträge: 122
Registriert: Sonntag 23. April 2006, 11:37

Beitrag von Carjay »

Mich wundert dieser Performancegewinn bei NFS, den du da beobachtet hast. Das muß an irgendeinem Nebeneffekt liegen.

Wenn ein Kernelmodul geladen wird, wird es zum laufenden Kernel dazugelinkt. Beim statischen Einbinden wird genau das eben schon vorher durchgeführt.

Der einzige Unterschied ist, daß beim statischen Linken die Initialisierung "irgendwo" im Kernelcode stattfinden muß. Also der Aufruf der module_init()-Routine, der bei modprobe beim Laden ausgeführt wird.

Zum Einbauen, das ist nicht schwierig: guck dir den Code in drivers/ide im Kernel an. Dort sieht das dann z.B. so aus:

Code: Alles auswählen

obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o
Die Variable $CONFIG_BLK_DEV_IDEDISK ist durch die Kernelconfig entweder "y" oder "m". Wenn sie "y" ist wird sie automatisch zum Kernel dazugelinkt, ansonsten wird daraus ein Modul.

Nur das Dazulinken reicht aber noch nicht, da wie eben beschrieben modprobe ja normalerweise noch die Initialisierung vornimmt. Das heißt, irgendwer muß nun (beim Beispiel) "idedisk_init" aufrufen.

Beim Beispielmodul findet dieser Aufruf im drivers/ide/ide.c statt. Der Aufruf ist durch ein #ifdef CONFIG_BLK_DEV_IDEDISK geschützt. Wenn man aus ide-disk ein Modul baut, dann ist die Variable nicht definiert.

Achtung: Das ist nicht die gleiche Variable, die im Shellskript verwendet wird.

An einem statischen Einbau ist daher nichts geheimnisvolles, ob es was bringt mußt du ausprobieren.

Dann muß nur noch die init-Routine irgendwo rein, gibt sicher entsprechende Aufrufe für andere IDE-Treiber, mußt du mal nach suchen.

Bei Tuxbox liegen die Treiberdateien ja in einem externen Verzeichnis, weiß gerade nicht, ob man die dort so einfach dem Kernel hinzulinken kann, ansonsten mußt du das in die Kernelsourcen reinkopieren und ein Makefile mit Config.in basteln, sollte nicht so kompliziert sein.

Ich wüßte allerdings nicht recht warum es dadurch performanter werden sollte. Aber wer weiß. ;)
wolgade
Semiprofi
Semiprofi
Beiträge: 1313
Registriert: Donnerstag 2. Dezember 2004, 00:18

Beitrag von wolgade »

Carjay hat geschrieben:Mich wundert dieser Performancegewinn bei NFS, den du da beobachtet hast. Das muß an irgendeinem Nebeneffekt liegen.
Ich zitier mal was:
"Ein monolithischer Aufbau verbessert gegenüber einem Mikro-Kernel die Leistung (heutzutage liegt der Unterschied zwischen monolithischen Kerneln und Mikro-Kerneln unter 5%).
Quelle: Welsh, Dalheimer, Dawson, Kaufman; Linux Praxishandbuch; O'Reilly Verlag; 4.Auflage 2003; ISBN 3-89721-416-4; S. 253

Mit heutzutage meinen die Autoren PC-Prozessoren von 2002/2003, die alle geringfügig performanter sind, als unser kleiner Power-PC.
Wenn ein Kernelmodul geladen wird, wird es zum laufenden Kernel dazugelinkt. Beim statischen Einbinden wird genau das eben schon vorher durchgeführt.
Beim Thema "dynamisches Linken" bin ich nicht ganz sattelfest, aber ich meine mich zu erinnern, daß das ein paar Klimmzüge erfordert, weil die Einsprungadressen der Funktionen eben nicht durch den Linker fest verdrahtet werden, sondern der Umweg über eine Tabelle gemacht werden muß.

Vielen Dank übrigens für die anderen Ausführungen. Mitlerweile habe ich selber schon einiges an Infos zum Kernelbau gefunden, zwar nicht im Netz, dafür aber auf meiner Festplatte im Kernel-Source-Tree.
Nur das Dazulinken reicht aber noch nicht, da wie eben beschrieben modprobe ja normalerweise noch die Initialisierung vornimmt. Das heißt, irgendwer muß nun (beim Beispiel) "idedisk_init" aufrufen.
Sicher? Ich dachte, genau dafür wären die Makros aus modules.h da. Die dienen eigentlich dazu, daß der gleiche Code als Modul oder fester Kernelbestandteil funktioniert.
Bei Tuxbox liegen die Treiberdateien ja in einem externen Verzeichnis,
Da liegt der Hund begraben, zumindest einer. Beim Bauen des CVS werden Kernel und die speziellen Module für die D-Box unabhängig voneinander gebaut. Das Buildsystem des Kernels weiß nix von der D-Box. Muß es aber, wenn es D-Box-Treiber in den Kernel integrieren soll.
ansonsten mußt du das in die Kernelsourcen reinkopieren und ein Makefile mit Config.in basteln,
Darauf wird es für einen Schnell-und-schmutzig-Test hinauslaufen. Zum Ausprobieren reicht das ja.
Carjay
Developer
Beiträge: 122
Registriert: Sonntag 23. April 2006, 11:37

Beitrag von Carjay »

wolgade hat geschrieben: Ich zitier mal was:
"Ein monolithischer Aufbau verbessert gegenüber einem Mikro-Kernel die Leistung (heutzutage liegt der Unterschied zwischen monolithischen Kerneln und Mikro-Kerneln unter 5%).
Das Zitat bezieht sich auf ein theoretisches Konzept. Der Linux-Kernel ist kein Mikro-Kernel, keines der bekannten OS ist das, aus genau dem Grund, den das Zitat anführt. Bei einem Mikro-Kernel laufen zum Beispiel die Gerätetreiber im Userspace.

Der Linux-Kernel ist ein monolithischer Kernel. Der Windows NT-Kernel ist das übrigens nicht (er ist eine Mischung aus beiden, manchmal auch Hybrid-Kernel genannt, weil z.B. das Win32-Subsystem im Userspace läuft)
Beim Thema "dynamisches Linken" bin ich nicht ganz sattelfest, aber ich meine mich zu erinnern, daß das ein paar Klimmzüge erfordert, weil die Einsprungadressen der Funktionen eben nicht durch den Linker fest verdrahtet werden, sondern der Umweg über eine Tabelle gemacht werden muß.
Müßte genau nachschauen aber ich denke nicht, daß der generierte Objektcode sich groß unterscheidet zwischen statisch eingelinktem Code und Kernelmodul. Das Kernelmodul ist ja keine dynamische Bibliothek, die gemeinsam von verschiedenen Programmen benutzt werden soll.
Sicher? Ich dachte, genau dafür wären die Makros aus modules.h da. Die dienen eigentlich dazu, daß der gleiche Code als Modul oder fester Kernelbestandteil funktioniert.
Stimmt, es gibt da wohl noch die Möglichkeit der Initialisierung über das Initcall-Segment. Das passiert aber scheinbar in der Reihenfolge des Linkens und ist vielleicht nicht immer das was man will.
wolgade
Semiprofi
Semiprofi
Beiträge: 1313
Registriert: Donnerstag 2. Dezember 2004, 00:18

Beitrag von wolgade »

Carjay hat geschrieben:Der Linux-Kernel ist kein Mikro-Kernel,
Weiß ich, Ich kenne auch den legendären Schlagabtausch zwischen Linus Torvalds und Andrew Tannenbaum.

Der von mir zitierte Satz steht in dem Buch aber in dem Kontext "Kernelmodul vs. fest einkompiliert". So ganz monolithisch ist ein modularisierter Linux-Kernel ja auch nicht mehr.

Wir müssen aber auch gar keine theoretische Debatte über Betriebssysteme führen. Davon verstehe ich viel zu wenig. Außerdem wird es nicht die Frage beantworten, ob mein Ansatz nun etwas bringt oder nicht. Das muß ich einfach ausprobieren. Versuch macht klug.
Stimmt, es gibt da wohl noch die Möglichkeit der Initialisierung über das Initcall-Segment. Das passiert aber scheinbar in der Reihenfolge des Linkens und ist vielleicht nicht immer das was man will.
Gut, dann habe ich den Abschnitt aus der Kerneldoku richtig verstanden. Danke.