Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: FlashBurn am 19. September 2010, 18:05

Titel: Treiber "Management"
Beitrag von: FlashBurn am 19. September 2010, 18:05
Ich mache mir gerade Gedanken darüber wie man Treiber performant "managen" kann.

Damit meine ich, das z.B. nicht jeder Treiber geladen und ausgeführt wird und dann guckt ob ein Gerät, das er unterstützt, vorhanden ist, sondern das ein Treiber auch immer nur dann ausgeführt wird, wenn ein Gerät für ihn vorhanden ist.

Ich hatte mir da folgendes überlegt. Ich könnte als Anforderung für einen Treiber sagen, dass dieser eine bestimmte ELF-Sektion haben muss, wo in einer genau definierten Datenstruktur die Geräte drin stehen, die er unterstützt.
Problem wäre hier, das ich das ganze dann für jedes Bussystem (ISA, PCI, USB, ...) extra machen müsste.
Vorgestellt habe ich mir das so, dass der Device-Server das Verzeichnis wo die ganzen Treiber drin sind "beobachtet" (also benachrichtigt wird, wenn eine Änderung aufgetreten ist) und dann alle Dateien in dem Verzeichnis "parst" (also den ELF-Header laden und die spezielle Sektion, wo die Daten drin sind) und sich eine Liste anlegt.

Soweit so gut. Wie könnte man es machen, das die Liste nicht bei jeder Änderung neu erstellt wird? Ich dachte, das man vielleicht neben dem Dateinamen, noch die Zeit der letzten Änderung speichert. Damit kann ein Treiber gegebenenfalls neugeladen werden, wenn eine neuere Version in das Verzeichnis kopiert wurde.

Was haltet ihr davon, was würdet ihr anders/besser machen?
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 19. September 2010, 18:16
Du könntest eine sortierte statische Liste machen, in der alle unterstützten Hersteller-/Gerätenummern aufgeführt sind und darin suchen, wenn du ein Gerät findest. So eine Art Datenbank.

Statisch, weil du diese nur aktualisieren musst, wenn ein Treiber aktualisiert wurde und nun neue/zusätzliche IDs unterstützt oder ein neuer Treiber da ist.

Die Liste kannst du semi-manuell aktualisieren, wenn du einen neuen Treiber einspielst (sowas wie "depmod -a") oder du schaust einfach nach Datum/Uhrzeit im Dateisystem, d.h. ob die Liste neuer ist als alle Treiber oder nicht. Das dürfte wesentlich schneller sein, als jeden Treiber erstmal zu öffnen und dann festzustellen, dass er total sinnlos auf diesem System ist. :-)

Treiber neu laden würde ich jedenfalls nie automatisch machen; sonst kann jemand einen Server zum Absturz bringen, indem er Schreibzugriff auf das Treiberverzeichnis erlangt. Ungünstig. ;-)

Für PCI/USB kannst du ja vom Devicemapper (der die Bussysteme verwaltet) die Treiber laden lassen, ISA wäre manuell relativ sinnvoll (eine feste Liste zu ladender Treiber), da man ISA-Geräte nur proben kann.

Gruß,
Sebastian
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 19. September 2010, 18:33
Zitat von: svenska
Du könntest eine sortierte statische Liste machen, in der alle unterstützten Hersteller-/Gerätenummern aufgeführt sind und darin suchen, wenn du ein Gerät findest. So eine Art Datenbank.
Das ist nicht ganz das was ich erreichen will. Die Frage ist dann wann wird diese Datenbank erstellt und wo bekommt sie wie ihre Daten her?

Zitat von: svenska
Statisch, weil du diese nur aktualisieren musst, wenn ein Treiber aktualisiert wurde und nun neue/zusätzliche IDs unterstützt oder ein neuer Treiber da ist.
Da triffst du schon eher das was ich erreichen will. Diese Datenbank sollte jedes Mal aktualisiert werden, wenn eine Veränderung im Treiberverzeichnis (löschen/neu/geändert) stattgefunden hat.

Zitat von: svenska
Das dürfte wesentlich schneller sein, als jeden Treiber erstmal zu öffnen und dann festzustellen, dass er total sinnlos auf diesem System ist.
Wo wir wieder bei der Frage wäre, wo bekommt die Datenbank die Daten her? Ich muss die Datei öffnen um zu wissen welche Geräte der Treiber unterstützt.
Steht die Datei schon in der Datenbank, würde ich aufs letzte Änderungsdatum gucken und schauen ob der Treiber eventuell neuer ist als der der in der Datenbank eingetragen wurde.

Zitat von: svenska
Treiber neu laden würde ich jedenfalls nie automatisch machen; sonst kann jemand einen Server zum Absturz bringen, indem er Schreibzugriff auf das Treiberverzeichnis erlangt.
Aber genau das möchte ich (nicht den Absturz ;) ). Ein Treiberupdate wäre dann einfach, neuen Treiber über alten Treiber kopieren und dem alten Treiber signalisieren das er "runtergefahren" wird und neuen Treiber laden.
Genauso einfach sind dann Installation/Deinstallation, einfach in das Verzeichnis kopieren bzw. einfach daraus löschen/verschieben.

Wie genau stellst du dir das vor, dass ein Server abstürzt, weil jemand Schreibzugriff auf das Treiberverzeichnis bekommen hat?

Zitat von: svenska
Für PCI/USB kannst du ja vom Devicemapper (der die Bussysteme verwaltet) die Treiber laden lassen, ISA wäre manuell relativ sinnvoll (eine feste Liste zu ladender Treiber), da man ISA-Geräte nur proben kann.
Wollte ich genauso machen, sprich der Busmanager (außer ISA) hat ne Liste mit Geräten die im System vorhanden sind und dann wird in der Datenbank nachgeguckt ob ein Treiber vorhanden ist (falls ja -> wird dieser geladen) und wenn der Treiber geladen ist, muss dieses Gerät in eine Liste "Geräte mit laufenden Treiber" gepackt werden.

Ziel ist es vorallem meinen Bootvorgang (für mich) zu vereinfachen und die Installation/Deinstallation/Update zu vereinfachen.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 19. September 2010, 19:42
Zitat von: svenska
Du könntest eine sortierte statische Liste machen, in der alle unterstützten Hersteller-/Gerätenummern aufgeführt sind und darin suchen, wenn du ein Gerät findest. So eine Art Datenbank.
Das ist nicht ganz das was ich erreichen will. Die Frage ist dann wann wird diese Datenbank erstellt und wo bekommt sie wie ihre Daten her?
Naja, du schaust beim Systemstart nach, ob die Liste existiert. Wenn nein, erzeugst du sie. Wenn ja, schaust du nach, ob eine Treiberdatei neuer ist als deine Liste (damit sparst du dir, die Dateien zu öffnen).  Ist deine Liste veraltet, erzeugst du eine neue.

Zitat von: svenska
Statisch, weil du diese nur aktualisieren musst, wenn ein Treiber aktualisiert wurde und nun neue/zusätzliche IDs unterstützt oder ein neuer Treiber da ist.
Da triffst du schon eher das was ich erreichen will. Diese Datenbank sollte jedes Mal aktualisiert werden, wenn eine Veränderung im Treiberverzeichnis (löschen/neu/geändert) stattgefunden hat.
Finde ich unelegant, weil du damit quasi einen Daemon im Hintergrund laufen hast, der ständig ein (unwahrscheinliches) Ereignis abprüft. Treiber werden normalerweise nur selten aktualisiert.

Zitat von: svenska
Treiber neu laden würde ich jedenfalls nie automatisch machen; sonst kann jemand einen Server zum Absturz bringen, indem er Schreibzugriff auf das Treiberverzeichnis erlangt.
Aber genau das möchte ich (nicht den Absturz ;) ). Ein Treiberupdate wäre dann einfach, neuen Treiber über alten Treiber kopieren und dem alten Treiber signalisieren das er "runtergefahren" wird und neuen Treiber laden.
Genauso einfach sind dann Installation/Deinstallation, einfach in das Verzeichnis kopieren bzw. einfach daraus löschen/verschieben.
Betone, dass der alte Treiber (im RAM) manuell ein Signal zum "runterfahren" kriegt und wir sind uns einig. ;-)

Wie genau stellst du dir das vor, dass ein Server abstürzt, weil jemand Schreibzugriff auf das Treiberverzeichnis bekommen hat?
Betrifft den automatischen Restart von aktualisierten Treibern: Wenn dein Devicemanager neue Treiberversionen direkt automatisch startet, kannst du damit dein System zerschießen.

Wir sind uns da ziemlich einig.

Wo die Liste herkommt? Naja, wie von dir beschrieben: Ist die Liste nicht vorhanden oder veraltet, so musst du sie aus den Treiberdateien erzeugen. Es geht mir halt nur um die Masse an Neustarts, bei denen keine Treiberinstallation stattgefunden hat - da reicht die prägenerierte Liste.

Gruß,
Sebastian
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 19. September 2010, 21:07
Zitat von: svenska
Naja, du schaust beim Systemstart nach, ob die Liste existiert. Wenn nein, erzeugst du sie. Wenn ja, schaust du nach, ob eine Treiberdatei neuer ist als deine Liste (damit sparst du dir, die Dateien zu öffnen).  Ist deine Liste veraltet, erzeugst du eine neue.
Da sind wir dann bei dem Problem mit dem Booten meines Systems, das ist leider nicht so einfach. Außerdem möchte ich einfach auch bei jedem Systemstart die Liste dynamisch erzeugen.
Der Grund dafür ist, ich lade nur die wichtigsten Treiber mit meinem Loader und nur diese tauchen am Anfang im Treiberverzeichnis auf und können genutzt werden. Würden da schon alle Treiber drin stehen, hätte ich das Problem das ich sie nicht laden kann, da der Treiber zum Laden wahrscheinlich noch gar nicht gestartet wurde.
Mit meiner dynamisch erzeugten Liste umgehe ich dieses Dilemma.

Zitat von: svenska
inde ich unelegant, weil du damit quasi einen Daemon im Hintergrund laufen hast, der ständig ein (unwahrscheinliches) Ereignis abprüft.
Das ist so nicht richtig. Ich will in meinen Storage-Server sowas wie nen Node-Monitor einbauen, sprich du registrierst dich als Empfänger, dass du ne Nachricht bekommen willst wenn sich ein einer bestimmten Node was ändert. Da läuft dann kein Daemon im Hintergrund, sondern das macht alles der Storage-Server.

Zitat von: svenska
Betone, dass der alte Treiber (im RAM) manuell ein Signal zum "runterfahren" kriegt und wir sind uns einig.
Genau, das (den Treiber runterfahren und den neuen starten) macht natürlich der Device-Server.

Zitat von: svenska
Betrifft den automatischen Restart von aktualisierten Treibern: Wenn dein Devicemanager neue Treiberversionen direkt automatisch startet, kannst du damit dein System zerschießen.
Das Problem würde sich dann (wenn ich das nicht machen würde) ja nur auf den nächsten Systemstart verschieben. Außerdem müsste man das dann irgendwie elegant lösen, ich meine ich möchte nicht, das ein Treiber einfach so von jedem Prozess überschrieben werden kann. Da müsste dann jedes mal was "aufleuchten", so wie das UAC ;)

Du hast nur noch nichts zu der Idee gesagt, das ich eine spezielle Sektion in der ELF-Datei haben möchte wo drinsteht welche Geräte der Treiber unterstützt. Ich finde das so halt besser/performanter als wenn ich den Treiber erstmal starte (muss nen neuer Prozess für erzeugt werden) und ihn dann sozusagen berichten lasse.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 19. September 2010, 21:14
Die Idee mit der speziellen Sektion in der ELF-Datei würde ich so nicht machen, aber die Idee ist realistisch, nicht kompliziert und nachvollziehbar. Darum hab ich das nicht weiter kommentiert. Gut und so. ;-)

Zum Rest hab ich alles gesagt, was ich zu sagen hatte. Besonders die Sache mit dem automatischen(!) Treiberneustart finde ich sehr unschön, den (Re-)Ladevorgang selbst würde ich immer manuell anstoßen lassen müssen.
Titel: Re:Treiber "Management"
Beitrag von: kevin am 19. September 2010, 22:20
Für tyndur hatte ich mir das so gedacht, dass das Treiberpaket nicht nur die Binary mitliefert, sondern gesondert noch die Einträge für die Datenbank. Entweder als eine Datei pro Treiber (die Dateien aller Treiber landen dann in einem Verzeichnis), oder irgendein Verwaltungstool, das im Postinstallskript vom Treiber aufgerufen wird und eine komplette Datenbank hat.
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 19. September 2010, 22:27
@taljeth

Was passiert, wenn ein Treiber in der Datenbank steht, aber physisch, sprich als Datei, nicht mehr vorhanden ist?

Ich würde halt die ganze Geschichte (Liste der unterstützen Geräte) gerne in der eigentlichen Treiberdatei drin haben.
Einen neuen Prozess erstellen nur am an diese Liste zu kommen ist mir zu langsam und die Liste irgendwo in der Datei zu haben (durch irgendeine Magic-Konstante markiert) ist mir auch zu aufwendig und langsam. Daher die Idee mit der extra ELF-Sektion.

Ich bin aber gerne offen für Vorschläge oder Gegenargumente.

Zitat von: svenska
Besonders die Sache mit dem automatischen(!) Treiberneustart finde ich sehr unschön, den (Re-)Ladevorgang selbst würde ich immer manuell anstoßen lassen müssen.
Was würdest du vorschlagen, wie man das sonst macht, weil ich da ja dann irgendeine Art Interface für haben müsste und da müsste dann auch sichergestellt werden, dass das nicht jeder machen kann.
Meine Variante ist natürlich besonders für Treiberentwickler sehr vorteilhaft.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 19. September 2010, 22:38
Du bräuchtest einen Syscall, der dem Devicemanager mitteilt, dass ein Treiber neu geladen/gestartet werden soll.

Alternativ, da du ja ohnehin Funktionen zum Laden und Entladen von Treibern brauchst, kannst du diese beiden Funktionen auch exportieren und dafür benutzen. Der Fall von "rmmod blubber; modprobe blubber". Diese Sequenz kannst du dann ja auch von deinen Bau-/Installationsscripten aufrufen lassen.

Die Sicherheitsregelung lässt sich über die Nutzer-ID (bei Mehrbenutzersystemen) machen. Oder, wie es die BSDs haben, über einen Security Level: Du hast eine Konstante, die du nur nach oben zählen lassen kannst (beim Booten ist sie null). Überschreitet sie einen gewissen Wert, sind bestimmte APIs deaktiviert - auch für root. Damit kann niemals (für diesen Boot) ein Programm ein Kernelmodul entladen oder etwas anderes potentiell gefährliches tun.

Deine Variante ist für Treiberentwickler vorteilhaft, aber für den Produktionseinsatz wäre es mir zu ... gefährlich. Gut, dein OS wird eher kein Produktionseinsatzsystem sein, aber ich denke halt immer an sowas.

Gruß,
Sebastian
Titel: Re:Treiber "Management"
Beitrag von: kevin am 20. September 2010, 09:29
Was passiert, wenn ein Treiber in der Datenbank steht, aber physisch, sprich als Datei, nicht mehr vorhanden ist?
Dann hast du von Hand am System rumgepfuscht und bist selber schuld. ;)

Was passieren würde ist wohl, dass er versucht, den nicht vorhandenen Treiber zu starten wenn du passende Hardware hast, und dabei auf die Schnauze fliegt. Dann kannst du die Hardware eben nicht benutzen. Geht aber ohne Treiber sowieso nicht, insofern ist das eigentlich egal...

Zitat
Ich würde halt die ganze Geschichte (Liste der unterstützen Geräte) gerne in der eigentlichen Treiberdatei drin haben.
Einen echten Grund dazu sehe ich nicht. Aber wenn man das unbedingt machen will, dann ist die ELF-Sektion wohl das vernünftigste.
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 20. September 2010, 10:25
Zitat von: svenska
Du bräuchtest einen Syscall, der dem Devicemanager mitteilt, dass ein Treiber neu geladen/gestartet werden soll.
Das ist nicht böse gemeint, aber damit hast du mal wieder (für mich) bestätigt das du nur im Unix-mäßig denkst.
Ich habe einen Device-Server, dem müsste man irgendwie ne Nachricht schicken.

Zitat von: svenska
Alternativ, da du ja ohnehin Funktionen zum Laden und Entladen von Treibern brauchst, kannst du diese beiden Funktionen auch exportieren und dafür benutzen. Der Fall von "rmmod blubber; modprobe blubber". Diese Sequenz kannst du dann ja auch von deinen Bau-/Installationsscripten aufrufen lassen.
Ist mir wieder viel zu Unix-mäßig. Ich will Skripte soweit es geht vermeiden und schon gar nicht soll sich ein User mit einem Skript beschäftigen müssen (wenn er das will, ist das ne ganz andere Geschichte).

Zitat von: svenska
Deine Variante ist für Treiberentwickler vorteilhaft, aber für den Produktionseinsatz wäre es mir zu ... gefährlich. Gut, dein OS wird eher kein Produktionseinsatzsystem sein, aber ich denke halt immer an sowas.
Ich vermute mal mit Produktionseinsatz meinst du sowas wie Server und mehr geschäftlich genutzt?! Ich habe mir als "Ziel" (es sei mal dahin gestellt ob ich es jemals erreiche) gesetzt ein Consumer-OS zu schreiben, wenn man das ganze auch als Server-OS nutzen könnte ist das auch Ok, aber es ist kein Ziel.

Zitat von: taljeth
Einen echten Grund dazu sehe ich nicht. Aber wenn man das unbedingt machen will, dann ist die ELF-Sektion wohl das vernünftigste.
Der Grund (für mich) ist die Einfachheit. Eine andere Möglichkeit wäre ein Package-System zu nutzen oder zu entwickeln, mit dem man nicht nur Programme, sondern auch Treiber installieren/deinstallieren kann.
Obwohl ich da dann wieder vor dem Problem stehe, wie ich mein OS vernünftig booten kann ohne alzu viele Ausnahmeregelungen dafür zu schaffen.

Ich werd dann also die ELF-Sektion Variante nutzen.

Noch was zum ISA-Bus, ich habe mir überlegt nur ISA-Hardware zu unterstützen die Plug&Play fähig ist, damit dürfte dann doch eigentlich das Proben entfallen oder?
Titel: Re:Treiber "Management"
Beitrag von: erik.vikinger am 20. September 2010, 11:45
Hallo,


Zu dem Thema des Treibermanagement hab ich mir auch mal ein paar wenige Gedanken gemacht und bin der Meinung das ich einen Driver-Loader-Service implementieren möchte der vom PCI- und USB-Basis-System benutzt wird um anhand des Class-Code oder den Vendor/Product-IDs den richtigen Treiber zu laden. Dieser Service soll eine Art primitive Datenbank benutzen in der alle Treiber drin sind. Wenn ein Treiber nicht mehr existiert oder seine Check-Summe nicht mehr stimmt dann ist es eben einfach so als wäre kein passender Treiber vorhanden. Dieser Service soll in meinem Konzept sehr früh im Boot-prozess gestartet werden und ein paar Basis-Treiber direkt enthalten (per simpler interner ROM-Disk) und erst später von INIT einen Zugriff auf ein dann gemountetes Dateisystem erhalten (und dann die interne ROM-Disk freigeben).

Automatisches Neuladen von Treibern würde ich persönlich auch als extrem riskant (oder schlimmeres) betrachten, so könnte man dem System einfach mal ein fehlerhaftes oder bösartiges Programm unterschieben das dann auch noch mit den Privilegien eines Treibers gestartet wird. Zum ändern meiner Datenbank soll auf jeden Fall eine Passwortabfrage (oder was ähnliches) gehören damit das auf keinen Fall ohne explizites Einverständnis eines berechtigten Users geschieht. Ein weiteres Problem beim automatischen Neustart sind Treiber die das Systen permanent braucht, z.B. HDD-Treiber oder Dateisystem-Treiber. QNX hat wimre ein paar Möglichkeiten gecraschte Treiber automatisch neu zu starten aber auch das ist sehr begrenzt. Zum Neustart eines Treibers gehört auch immer das die zugehörige HW deaktiviert und dann mit dem neuen Treiber reaktiviert wird und auch alle angebotenen Dienste beendet werden (also keine offenen Handles o.ä. existieren dürfen), damit bleibt nicht mehr viel HW übrig für die das möglich ist (wohl vor allem USB-Sticks usw).


Noch was zum ISA-Bus, ich habe mir überlegt nur ISA-Hardware zu unterstützen die Plug&Play fähig ist
Nenne doch mal ISA-Hardware die PnP-fähig ist. Das trifft nur ISA-HW die auf Karten verbaut ist (z.B. Soundkarten), alles was heutzutage noch an ISA-Ruinen in den Chipsätzen schlummert ist ja fest integriert und daher dem BIOS-Programmierer wohl bekannt und benötigt demzufolge auch kein PnP. Ich kann nur empfehlen ISA-HW wie PCI-HW zu behandeln die nach der Enumeration händisch (also schon anhand bestimmter Automatismen, z.B. die Zahl/Ressourcen der seriellen Schnittstellen sollte das BIOS nennen können) der PCI-Device-Liste hinzugefügt wird.


Grüße
Erik
Titel: Re:Treiber "Management"
Beitrag von: kevin am 20. September 2010, 11:48
Der Grund (für mich) ist die Einfachheit. Eine andere Möglichkeit wäre ein Package-System zu nutzen oder zu entwickeln, mit dem man nicht nur Programme, sondern auch Treiber installieren/deinstallieren kann.
Will man das nicht sowieso haben? :)

Zitat
Obwohl ich da dann wieder vor dem Problem stehe, wie ich mein OS vernünftig booten kann ohne alzu viele Ausnahmeregelungen dafür zu schaffen.
Hm, inwiefern ist dein OS in dieser Hinsicht speziell? Und warum hast du dieses Problem nicht, wenn du ELF-Sektionen nimmst? Ich glaube, das musst du etwas ausführlicher beschreiben, damit ich es verstehe.

Zitat
Noch was zum ISA-Bus, ich habe mir überlegt nur ISA-Hardware zu unterstützen die Plug&Play fähig ist, damit dürfte dann doch eigentlich das Proben entfallen oder?
Hm, keine Unterstützung für PIC, PIT, PS/2-Tastatur und -Maus, Floppy, ...?
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 20. September 2010, 12:13
Zitat von: taljeth
Will man das nicht sowieso haben?
Klar, aber eigentlich noch nicht jetzt, das wäre dann doch ein wenig zu viel Aufwand.

Zitat von: taljeth
Hm, inwiefern ist dein OS in dieser Hinsicht speziell? Und warum hast du dieses Problem nicht, wenn du ELF-Sektionen nimmst? Ich glaube, das musst du etwas ausführlicher beschreiben, damit ich es verstehe.
Naja, jeder Mikrokernel der die Treiber und vorallem die Device-Verwaltung im UserSpace hat, muss sich ja irgendetwas einfallen lassen wie man vernünftig booten kann.

Problem bei mir wäre halt, das ich meinen Device-Server gerne so geschrieben hätte, das er halt nur die Treiber verwendet die auch da sind und wenn später mehr Treiber hinzu kommen (damit meine ich während der Laufzeit) dann guckt er ob er dafür nicht auch Verwendung hat.

Mit diesem Konzept vereinfacht sich das Starten dieses Servers (und von meinem OS allgemein) enorm. Denn wenn ich nur die Treiber im VFS stehen habe die auch als Modul von meinem Bootloader geladen wurden, dann versucht er auch erst gar nicht andere Treiber "nachzuladen", sondern das wird erst dann gemacht, wenn das System so weit ist, dass es Dateien von außen (HDD, USB, CD-ROM, ...) nachladen kann. Deswegen auch die dynamische Erzeugung der Liste zur Laufzeit.

Würde ich das nicht so machen, müsste ich mir was einfallen lassen um den Bootvorgang speziell zu behandeln und das könnte dann ein wenig rumgeeiere werden und das wollte ich eigentlich vermeiden.

Zitat von: taljeth
Hm, keine Unterstützung für PIC, PIT, PS/2-Tastatur und -Maus, Floppy, ...?
Erwischt ;)

Nein, diese "feste" Hardware wird natürlich unterstützt. Aber du hast da natürlich was sehr interessantes angesprochen. Wie findet man eigentlich raus, ob noch PS/2-Ports vorhanden sind?
Ich meine der PIC und der PIT fallen raus, weil sie in dem Sinne keine Treiber benötigen (die sind fest in meinem Kernel drin), Floppy würde ich dann so machen wie erik es schon vorgeschlagen hat (bekannte Sachen aus dem BIOS als Pseudo-PCI-Geräte in eine Liste packen) und was gibt es sonst noch?

Zitat von: erik
Automatisches Neuladen von Treibern würde ich persönlich auch als extrem riskant (oder schlimmeres) betrachten, so könnte man dem System einfach mal ein fehlerhaftes oder bösartiges Programm unterschieben das dann auch noch mit den Privilegien eines Treibers gestartet wird.
Naja, wie gesagt, damit schiebt sich das Problem, des bösartigen Programms nur bis in den nächsten Bootvorgang.
Außerdem habe ich gerade keine Vorstellung welche besonderen Rechte ein Treiber gegenüber normalen Programmen hat (was natürlich jetzt nur mein OS betrifft, auf anderen OSs kann das wieder anders aussehen).
Das Problem eines fehlerhaften Treibers kannst du sowieso nicht aus der Welt schaffen (es sei denn du machst es wie MS, das nur noch signierte Treiber gestartet werden dürfen).

Zitat von: erik
Ein weiteres Problem beim automatischen Neustart sind Treiber die das Systen permanent braucht, z.B. HDD-Treiber oder Dateisystem-Treiber.
Also bei sowas LowLevel wie dem HDD-Treiber seh ich da eher weniger Probleme. Wenn man sich ein vernünftiges Protokoll einfallen lässt sollte das relativ schmerzlos und schnell über die Bühne gehen. Aber auch ein VFS-Modul sollte man entladen können und das fällt bei mir auch nicht in die Kategorie Treiber, sondern wird als ne Art Add-On für den Storage-Server verwendet (ich bin da ziemlich BeOS/Haiku belastet ;) ).
Zumal man jeden Treiber "runterfahren" können sollte und dann wird er einfach neu gestartet. Ob und wie das jetzt genau funktioniert kann ich mir immer noch Gedanken machen, wenn es dann soweit ist.

Ich hätte es nur schon gerne, das man mein OS nicht neustarten muss, nur um einen neuen Treiber zu laden bzw. einen zu updaten.

Was natürlich ausfällt ist Busmanager neu zu laden, zumal diese wiederum bei mir unter die Kategorie Add-On des Device-Servers fallen (also PCI, ISA, USB, ...).
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 20. September 2010, 16:53
Zitat von: svenska
Du bräuchtest einen Syscall, der dem Devicemanager mitteilt, dass ein Treiber neu geladen/gestartet werden soll.
Das ist nicht böse gemeint, aber damit hast du mal wieder (für mich) bestätigt das du nur im Unix-mäßig denkst.
Ich habe einen Device-Server, dem müsste man irgendwie ne Nachricht schicken.
s/"einen Syscall"/"eine Nachricht"/g

Zitat von: svenska
Deine Variante ist für Treiberentwickler vorteilhaft, aber für den Produktionseinsatz wäre es mir zu ... gefährlich. Gut, dein OS wird eher kein Produktionseinsatzsystem sein, aber ich denke halt immer an sowas.
Ich vermute mal mit Produktionseinsatz meinst du sowas wie Server und mehr geschäftlich genutzt?! Ich habe mir als "Ziel" (es sei mal dahin gestellt ob ich es jemals erreiche) gesetzt ein Consumer-OS zu schreiben, wenn man das ganze auch als Server-OS nutzen könnte ist das auch Ok, aber es ist kein Ziel.
Das schrieb ich bereits und nahm mir die Freiheit, mich bereits vorauseilend für diese Aussage zu entschuldigen.

Minix als Mikrokernel besteht auch aus solchen Servern (MM, FS, INET). Wenn du allerdings MM beendest, kannst du ihn mangels Speicherverwaltung nicht neustarten. Beendest du FS, kannst du die Treiberdatei nicht mehr laden, da du kein VFS mehr hast. Bei INET gilt entsprechendes, wenn das System für die Treiberdatei Netzwerkzugriff braucht (geschenkt, geht unter Minix nicht). Will heißen: Du kannst nicht jeden Treiber neustarten, zumindest nicht unkonditionell.

Zweite Sache, und ja ich hacke gern darauf rum, es muss ja nichtmal ein böserartiges Programm sein, welches sich da in dein Treiberverzeichnis schreibt. Wer sagt denn, dass es nicht ein Fehler ist, den du beim Programmieren (Kompilieren) gemacht hast und ihn noch VOR dem Neustart beheben kannst? Oder wer verrät dir, dass beim Kopieren via Netzwerk der Dateistrom nicht abgerissen ist und die Datei unter Umständen nicht vollständig oder (UDP) fehlerhaft ist?

Das kann man zwar mit Prüf-/Signatursummen umgehen, ist aber trotzdem ein valider Punkt.

Und ja, ich merke schon, dass ich zu sehr Unix denke und du genau deswegen das, was ich sage, ohnehin ablehnst.

Gruß,
Sebastian
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 20. September 2010, 17:10
Zitat von: svenska
Und ja, ich merke schon, dass ich zu sehr Unix denke und du genau deswegen das, was ich sage, ohnehin ablehnst.
Dem muss ich absolut widersprechen, denn ihr habt mich fast soweit, das ich das mit dem automatisch neuladen der Treiber doch lasse.

Zitat von: svenska
Das schrieb ich bereits und nahm mir die Freiheit, mich bereits vorauseilend für diese Aussage zu entschuldigen.
Dafür brauchst du dich nicht entschuldigen, aber ich denke mal ein Server-OS hat dann doch noch ein paar mehr Anforderungen als ein "einfaches" Consumer-OS und irgendwo muss man ja mal Abstriche machen ;)

Zitat von: svenska
Zweite Sache, und ja ich hacke gern darauf rum, es muss ja nichtmal ein böserartiges Programm sein, welches sich da in dein Treiberverzeichnis schreibt. Wer sagt denn, dass es nicht ein Fehler ist, den du beim Programmieren (Kompilieren) gemacht hast und ihn noch VOR dem Neustart beheben kannst? Oder wer verrät dir, dass beim Kopieren via Netzwerk der Dateistrom nicht abgerissen ist und die Datei unter Umständen nicht vollständig oder (UDP) fehlerhaft ist?
Naja, ich sehe das Problem durchaus ein. Was ich aber auch sehe ist, dass man dieses Problem (fehlerhafter/bösartiger Code) eher schwierig bis gar nicht umgehen kann :(

Zitat von: svenska
Minix als Mikrokernel besteht auch aus solchen Servern (MM, FS, INET). Wenn du allerdings MM beendest, kannst du ihn mangels Speicherverwaltung nicht neustarten. Beendest du FS, kannst du die Treiberdatei nicht mehr laden, da du kein VFS mehr hast. Bei INET gilt entsprechendes, wenn das System für die Treiberdatei Netzwerkzugriff braucht (geschenkt, geht unter Minix nicht). Will heißen: Du kannst nicht jeden Treiber neustarten, zumindest nicht unkonditionell.
Naja, mit diesem Neustarten willst du ja "nur" nen abgestürzten Server neustarten und die Daten sind schon im Speicher vorhanden.
Wenn ich nen Treiber neustarten/updaten würde, dann muss natürlich der neue Treiber auch schon geladen sein. Deswegen sagte ich ja, das man dafür ein vernünftigen Weg braucht, damit das ganze klappt.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 20. September 2010, 17:19
Wenn der Treiber wegen Speicherfehlern (und ja, die treten auf!) abstürzt, dann nutzt dir dein Speicherabbild mal garnichts. Außerdem hast du ja nur einen Memdump des Treibers - und nicht die Treiberdatei im Speicher. Dazu musst du also Speicher verschwenden, indem du (zur Laufzeit überflüssige) Zusatzinformation im Speicher hältst.

Mal abgesehen davon brauchst du ne gute Abstraktion, dass dir ein Neuladen des HDD-Treibers nicht die Dateisysteme entreißt. Das würde Userspace-Programme stark verwirren. Außerdem - was machst du, wenn in diesem Zeitfenster ein Programm (Dateisystemtreiber!) gerade etwas auf Platte schreiben möchte und fsync() aufruft? Pufferst du das im RAM zwischen oder riskierst du das Dateisystem?

Ähnliches mit der Netzwerkhardware - wird ein Neuladen des Treibers die Karte auch neu initialisieren (eher ja, weil sonst is doof), aber was passiert, wenn die Karte gerade fleißig arbeitet und du ihr den Treiber entreißt? Nicht jede Hardware lässt sich jederzeit zuverlässig resetten.

Daher würde ich, wie von Erik auch vorgeschlagen, einen Treiberneustart nur dann erlauben, wenn die Hardware gerade nicht in Benutzung ist (d.h. Treiber können auch nur rekursiv entladen werden, wenn sie von anderen Treibern genutzt werden). Auf der anderen Seite heißt das, dass du gewisse Änderungen halt nur mit einem Systemneustart machen kannst. Halte die Bootzeit schön klein und das ist nicht so schlimm, wie es aussieht. ;-)

Gruß
Titel: Re:Treiber "Management"
Beitrag von: erik.vikinger am 22. September 2010, 12:12
Hallo,


das automatische Neustarten von Treibern, vor allem von jenen die das System braucht, ist schon ziemlich tricky. Da sollte man sich genau überlegen ob man das als erstes in ein Hobby-OS integriert. Der einzigst sinnvolle Weg ist auch nur möglich wenn die original Treiber-Datei im Speicher vorgehalten wird und zwar nicht nur mit einer guten Prüfsumme sondern mit echten Korrektur-Daten versehen (Reed-Solomon oder was ähnliches), Speicherfehler passieren wirklich!

Das mit dem automatischen übernehmen eines neuen Treibers (z.B. wenn ein Programmierer einen neuen kompiliert hat) ist nicht nur äußerst riskant sondern auch grob fahrlässig! Wenn Dein OS wirklich mal irgend jemand benutzt und durch dieses Sicherheitsleck tatsächlich ein Schaden entsteht könnte man den Programmierer eventuell tatsächlich vor ein deutsches Gericht bringen, gegen "grobe Fahrlässigkeit" hilft auch keine Beteuerung "Jeder darf mein Zeug benutzen aber ich übernehme keine Verantwortung!". Schon aus moralischer Sicht würde ich sagen das ein Programmierer immer etwas Verantwortung für seinen Code trägt. Also ich kann nur wiederholen das man so eine Funktion besser erst gar nicht programmiert. Bei Linux muss der Treiberprogrammierer auch ein "rmmod blubber; modprobe blubber;" ans Ende seines Build-Scriptes (oder sonstwas) packen und wird dafür auch root-Rechte haben müssen. Für einen Programmierer der gut genug ist einen Treiber zu programmieren sollte das auch nicht zu viel verlangt sein und ein normaler User/Admin fühlt sich sicher etwas wohler wenn er sich sicher sein kann das sein OS nur dann einen neuen Treiber akzeptiert wenn er das explizit abgesegnet hat. In meinem OS möchte ich dem Driver-Loader nur gestatten Treiber zu starten die in der Datenbank stehen und deren SHA256-Check-Summe noch stimmt. Zum Ändern der Datenbank wird man auf jeden Fall eine explizite Erlaubnis von root brauchen. Das diese Datenbank verwundbar ist wenn das System nicht läuft (und die Platte in einem anderen Rechner einbaut wird) ist mir klar aber zur Laufzeit einfach einen neuen Treiber automatisch zu akzeptieren geht IMHO nur wenn alles mit starker Kryptographie sehr gut abgesichert ist (und selbst dann könnte sicher nicht jeder Admin ruhig schlafen).

Was an Treibern so gefährlich ist? Ganz klar der uneingeschränkte HW-Zugriff. Selbst wenn ein Treiber nur seine HW kontrollieren kann so kann doch ein Ethernet-Controller-Treiber eine komplette Kopie des physischen RAMs in die weite Welt schicken oder ein HDD-Treiber einen solchen Memory-Dump irgendwo auf die Festplatte legen. Beide können aber auch den physischen Speicher mit neuen Daten überschreiben, insbesondere der Ethernet-Treiber kann da als aktive Hintertür benutzt werden (da könnte man durchaus einen kleinen Server implementieren der es einem externen Angreifer ermöglicht Deinen RAM zu analysieren und zu manipulieren). Das ist IMHO Risiko genug das es sich lohnt wenigstens mal ein klein wenig über die Sicherheit des Systems nachzudenken.


Grüße
Erik
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 22. September 2010, 12:38
Also gut ihr habt mich überzeugt ;) Wenn ein Treiber-Update stattfinden soll, wird für den Anfang ein Neustart notwendig sein.

Was mir noch so im Kopf rumschwirrt. Was macht man wenn man 2 unterschiedliche Treiber/Dateien für das gleiche Gerät hat? Einfach den ersten nehmen oder den neueren?

Zitat von: erik
Das diese Datenbank verwundbar ist wenn das System nicht läuft (und die Platte in einem anderen Rechner einbaut wird) ist mir klar
Sorry, aber an sowas denke ich nicht mal. Wenn es um Sicherheit geht und es möglich ist die Platte auszubauen, an einen anderen PC anzuschließen, die Daten darauf zu manipulieren und die Platte dann wieder zurück zu packen. Wozu dann noch Sicherheit unter deinem OS? Das ein OS zur Laufzeit nicht manipulierbar sein sollte ist klar, aber wenn obiges möglich ist, dann ist das auch egal. Soll heißen wenn es so wichtig ist dass das OS läuft bzw. das die Daten darauf so wichtig sind, dann sollte dieses Szenario überhaupt nicht möglich sein. Ergo wird es einfach ignoriert ;)

Ich mache mir auch keine Illusionen das mein OS irgendwann mal produktiv eingesetzt wird (ich schreibe an einem OS was vorallem und zuerst alte Hardware unterstützt bzw. darauf laufen soll). Ich mache das aus Spaß an der Sache und irgendwo muss man dann auch mal Abstriche machen. Sicherheit ist im Moment sogar ein verdammt großes Problem, da ich davon überhaupt keine Ahnung habe, auch nicht wie man bestimmte Sachen vernünftig macht, aber darüber mach ich mir eigentlich weniger Sorgen.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 22. September 2010, 13:27
Ich empfehle cat /proc/sys/net/ipv4/fuckups (http://mirror.fem-net.de/CCC/26C3/mp4/26c3-3596-de-cat_procsysnetipv4fuckups.mp4), einen Talk (knappe Stunde) vom letzten Chaos Communication Congress. Dort wird beschrieben, wie man durch eine Ansammlung kleiner, vereinzelter, an sich ungefährlicher Bugs in ein Netzwerk eindringen kann.
Warum? Unter anderem werden dort auch zwei Ethernet-Treiber missbraucht, um Payload als neues Paket an den Kernel weiterzureichen.

Der letzte Playstation 3 Hack basiert auf modifizierten USB-Geräten, die im USB-Treiber einen Buffer Overflow verursachen und damit code execution erlauben. Gegen physische Angriffe kann man sich nicht absichern (Festplattenverschlüsselung hilft nicht gegen Keylogger in der Tastatur), deswegen stehen solche Server auch in abgesicherten Rechenzentren und/oder abgeschlossenen Stahlschränken.

Bei deinem zwei-Treiber-ein-Gerät-Fall würde ich unterscheiden, ob du zwei verschiedene Treiber hast oder einen Treiber in verschiedenen Versionen. Im ersteren Fall würde ich entweder den spezielleren oder beide laden - einer kommt nicht an die Ressourcen ran und wird beendet - und im letzteren Fall halt die neuere Version.

Beispiel hierfür wäre "nvidia" gegen "vesa" - ersterer ist, auch wenn älter, sicherlich geeigneter - oder "Chipsatztreiber" gegen "PIO-IDE-Treiber". Das wird aber erst interessant, wenn du von den generischen Treibern wegkommst; bis dahin kannst du einfach die neuere Version starten (aber: manueller Override für den Fall, dass der neue nicht funktioniert!).

Gruß
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 22. September 2010, 16:30
@Svenska

So lange wie man nicht irgendetwas anderes bzw. andersartiges als das DMA "erfindet" was wir momentan haben, kann man sich gegen solche Sachen schwer bis gar nicht schützen, zumal aus 100% Sicherheit nie geben wird.
Programmierfehler wirst du auch in Treibern von vertrauenswürdigen Quellen haben.

Zitat von: svenska
Beispiel hierfür wäre "nvidia" gegen "vesa" - ersterer ist, auch wenn älter, sicherlich geeigneter - oder "Chipsatztreiber" gegen "PIO-IDE-Treiber".
Sehr gutes Bsp.! Meine Frage dazu wäre, wie man, wenn man Treiber anhand ihrer unterstützten Geräte irgendwo einsortiert, solche "allgemeinen" Treiber überhaupt behandelt?

Meine spontane Idee wäre, die Geräteart mit einem Hersteller den es nicht geben kann (sprich ein spezieller Code) dafür zu nutzen und sobal ein Treiber für ein Gerät von genau dem Hersteller vorhanden ist, nimmt man diesen anstatt einen für alle Hersteller.
Frage ist nur, gibt es einen solchen Hersteller-Code, der entweder "illegal" ist oder halt einfach nicht verwendet wird?
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 22. September 2010, 17:17
Zitat von: svenska
Ich empfehle cat /proc/sys/net/ipv4/fuckups, einen Talk (knappe Stunde) vom letzten Chaos Communication Congress. Dort wird beschrieben, wie man durch eine Ansammlung kleiner, vereinzelter, an sich ungefährlicher Bugs in ein Netzwerk eindringen kann.
Warum? Unter anderem werden dort auch zwei Ethernet-Treiber missbraucht, um Payload als neues Paket an den Kernel weiterzureichen.
Ich habe mir das gerade mal angeschaut und von dem was ich verstanden habe (denke ich zumindestens ;) ), kann ich nur sagen, solch Code hat es verdient gecrackt zu werden ;)
Titel: Re:Treiber "Management"
Beitrag von: erik.vikinger am 22. September 2010, 18:36
Hallo,


Zitat von: erik
Das diese Datenbank verwundbar ist wenn das System nicht läuft (und die Platte in einem anderen Rechner einbaut wird) ist mir klar
Sorry, aber an sowas denke ich nicht mal. Wenn es um Sicherheit geht und es möglich ist die Platte auszubauen, an einen anderen PC anzuschließen, die Daten darauf zu manipulieren und die Platte dann wieder zurück zu packen. Wozu dann noch Sicherheit unter deinem OS? Das ein OS zur Laufzeit nicht manipulierbar sein sollte ist klar, aber wenn obiges möglich ist, dann ist das auch egal. Soll heißen wenn es so wichtig ist dass das OS läuft bzw. das die Daten darauf so wichtig sind, dann sollte dieses Szenario überhaupt nicht möglich sein. Ergo wird es einfach ignoriert ;)
Für den physischen Zugriff auf ein System sind aber andere Voraussetzungen zu erfüllen als für den virtuellen Zugriff, ein Einbruch in einen Sicherheits-Server-Raum ist sicher deutlich schwieriger als einen öffentlich erreichbaren Server einfach per IP anzusprechen. Gegen den physischen Zugriff kann ich per SW faktisch nichts tun (also ignoriere ich das auch) aber gegen den virtuellen Zugriff sehe ich mich schon in der Pflicht da wenigstens die offensichtlichen Maßnahmen auch zu ergreifen (das ich kein Hochsicherheits-OS erstellen möchte ist wohl klar aber ganz und gar ignorieren möchte ich dieses Thema auch nicht). Wenn irgendwelche Wartungsarbeiten an Internet-Servern durchgeführt werden werden diese auch vom Netz genommen (und nach einem Treiber/Kernel-Update sicher auch neu gebootet). Wenn der angebotene Service sehr wichtig ist dann nimmt man eben mehrere redundante Server und klemmt immer nur einen ab.


So lange wie man nicht irgendetwas anderes bzw. andersartiges als das DMA "erfindet" was wir momentan haben, kann man sich gegen solche Sachen schwer bis gar nicht schützen, zumal aus 100% Sicherheit nie geben wird.
Das Problem am DMA ist das ein busmasterfähiges Gerät überall ran kann, sogar an die anderen Geräte (ein gehackter Ethernet-Treiber könnte auch die Daten in den Frame-Buffer umleiten). Schön wäre es wenn man zumindest bei externen Zugriffen auf den normalen RAM in Chipsatz ein paar Sperren hätte so das der Kernel wenigstens sich selber (und vielleicht noch Pages die die Applikationen als besonders sensibel markiert haben weil z.B. Passwörter drin liegen) schützen könnte.

Programmierfehler wirst du auch in Treibern von vertrauenswürdigen Quellen haben.
Aber keine gefährlichen Hintertüren, obwohl es da auch schon mehrere Gegenbeispiele gibt aber dagegen kann man sich eben nicht schützen (< 100%).

Meine spontane Idee wäre, die Geräteart mit einem Hersteller den es nicht geben kann (sprich ein spezieller Code) dafür zu nutzen und sobal ein Treiber für ein Gerät von genau dem Hersteller vorhanden ist, nimmt man diesen anstatt einen für alle Hersteller.
Frage ist nur, gibt es einen solchen Hersteller-Code, der entweder "illegal" ist oder halt einfach nicht verwendet wird?
Von dieser Idee würde ich lieber Abstand nehmen. Bei PCI gibt es dafür den Class-Code, Du musst bei Deinen Treibern nur sagen ob die anhand der Class-Codes oder anhand der Vendor/Product-ID zugeordnet werden sollen (die zweiten sind die spezielleren und sollten bevorzugt werden).


Grüße
Erik


Edit:
@Svenska: Danke für den Link
Titel: Re:Treiber "Management"
Beitrag von: kevin am 22. September 2010, 18:45
Das Beispiel lässt sich aber noch schön erweitern, so dass nicht mehr so klar ist, dass der eine Treiber der schlechtere generische und der andere der bessere spezielle ist: vesa/nv/nouveau/nvidia. Einmal generisch; einmal ein älterer freier Treiber; einmal ein neuerer, aber noch experimenteller; und zum Abschluss noch ein proprietärer vom Hersteller.

Da hat man wohl verloren, wenn man das automatisch entscheiden will.
Titel: Re:Treiber "Management"
Beitrag von: erik.vikinger am 22. September 2010, 19:11
Hallo,


und zum Abschluss noch ein proprietärer vom Hersteller.
Ich denke das dürfte bei all unseren OSen grundsätzlich auszuschließen sein. ;)

Da hat man wohl verloren, wenn man das automatisch entscheiden will.
Automatisch sollte man so komplexe Dinge IMHO gar nicht mehr entscheiden. Das Programm das die Datenbank (oder was auch immer) mit den Treibern zusammenstellt sollte prüfen das keine Kollisionen drin sind, also keine Vendor/Product-ID-Kombination doppelt vergeben ist und auch kein Class-Code doppelt vergeben ist. Die Entscheidung des Lade-Mechanismus, welchen Treiber er laden soll, muss immer eineindeutig sein. Im Zweifelsfall muss root vorher entscheiden.


Grüße
Erik
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 22. September 2010, 19:15
Zitat von: erik
Schön wäre es wenn man zumindest bei externen Zugriffen auf den normalen RAM in Chipsatz ein paar Sperren hätte so das der Kernel wenigstens sich selber (und vielleicht noch Pages die die Applikationen als besonders sensibel markiert haben weil z.B. Passwörter drin liegen) schützen könnte.
Ich würde mir ne andere Variante als besser vorstellen. Nämlich ungefähr so wie bei ISA DMA, sprich wie DMA programmiert wird ist bekannt und bei allen Sachen gleich, sprich es ist im Standard drin (vielleicht ein extra Register im PCI CfgSpace). Dies ist natürlich für den gleichzeitigen Zugriff mehrerer Geräte ungünstig, aber das könnte man so lösen, das man halt nen Standard hat wie das geregelt wird (im MMIO Bereich).
Dann wäre es nämlich möglich die ganze DMA Geschichte nur über den Kernel oder einen Server laufen zu lassen und der Treiber an sich hätte gar kein Zugriff mehr darauf. Damit kannst du dein System dann zu annähernd 100% gegen Treiberfehler absichern (annähernd, weil einem von euch bestimmt ein Grund einfällt warum das nicht so ist ;) ).

Zitat von: erik
Von dieser Idee würde ich lieber Abstand nehmen. Bei PCI gibt es dafür den Class-Code, Du musst bei Deinen Treibern nur sagen ob die anhand der Class-Codes oder anhand der Vendor/Product-ID zugeordnet werden sollen (die zweiten sind die spezielleren und sollten bevorzugt werden).
Und genau das ist ja das Problem. Denn wie könnte man das machen?

Ich hatte mir eine Struktur die ungefähr so aussieht vorgestellt:
struct device_t {
 char busName[6]; //in dem Fall "PCI   "
 uint32t classCode;
 uint32t deviceID;
 uint32t vendorID;
}
Damit könnte ich dann eine VendorID und DeviceID von z.B. 0x10000 nehmen. Denn ansich sind die Sachen ja nur 16bit breit und so könnte ich die restlichen 16bit für genau solche Fälle nehmen.

Zitat von: taljeth
Das Beispiel lässt sich aber noch schön erweitern, so dass nicht mehr so klar ist, dass der eine Treiber der schlechtere generische und der andere der bessere spezielle ist: vesa/nv/nouveau/nvidia. Einmal generisch; einmal ein älterer freier Treiber; einmal ein neuerer, aber noch experimenteller; und zum Abschluss noch ein proprietärer vom Hersteller.
Naja, ich sags mal so, bei mir würde installiert/vorhanden heißen, wenn der Treiber in dem Treiberverzeichnis drin ist. Man sollte sich dann eventuell für später irgendetwas einfallen lassen um einen speziellen Treiber auszuwählen.
Ich habe mir als Ziel aber insbesondere gesetzt, das du das Medium wo mein OS drauf ist, nehmen kannst und in einen anderen PC steckst und da funktioniert es dann auch/trotzdem. Sollte auch funktionieren, da die wichtigen Sachen zum Booten ja eh generische Sachen sind (IDE/SATA/USB/SCSI)!?

Zitat von: erik
Die Entscheidung des Lade-Mechanismus, welchen Treiber er laden soll, muss immer eineindeutig sein. Im Zweifelsfall muss root vorher entscheiden.
Das wird bei meinen Zielen (siehe Oben) wohl sehr schwierig umzusetzen sein. Denn wie willst du den Benutzer fragen, wenn es sich z.B. um den Grafiktreiber handelt.
Was ich mir noch vorstellen könnte ist dass man erst mal generische Treiber nimmt (z.B. VBE) und dann wenn das System soweit ist, das Treiber nachgeladen werden können, sucht man nach spezielleren Treibern und nutzt die dann. Beim Bootvorgang sollte eine Geräteübergabe an einen anderen Treiber eigentlich noch möglich sein.
Titel: Re:Treiber "Management"
Beitrag von: erik.vikinger am 23. September 2010, 12:12
Hallo,


Ich würde mir ne andere Variante als besser vorstellen. Nämlich ungefähr so wie bei ISA DMA, sprich wie DMA programmiert wird ist bekannt und bei allen Sachen gleich, sprich es ist im Standard drin (vielleicht ein extra Register im PCI CfgSpace). Dies ist natürlich für den gleichzeitigen Zugriff mehrerer Geräte ungünstig, aber das könnte man so lösen, das man halt nen Standard hat wie das geregelt wird (im MMIO Bereich).
Dann wäre es nämlich möglich die ganze DMA Geschichte nur über den Kernel oder einen Server laufen zu lassen und der Treiber an sich hätte gar kein Zugriff mehr darauf. Damit kannst du dein System dann zu annähernd 100% gegen Treiberfehler absichern (annähernd, weil einem von euch bestimmt ein Grund einfällt warum das nicht so ist ;) ).
Das würde bedeuten das man Flexibilität und Funktionalität gegen Sicherheit eintauscht, ich denke dafür dürfte es nicht viele Unterstützer geben. Der Vorteil der PCI-Geräte ist doch gerade das jedes Gerät genau die Fähigkeiten hat die es benötigt. Wie sollte man mit so einer generischen Lösung z.B. TCP-Offloading für Ethernet-Controller realisieren? Selbst wenn Du jedem PCI-Gerät einen eigenen aber genormten DMA-Manager mitgibst dann muss dieser eben den kleinsten gemeinsamen Nenner darstellen, was quasi alle PCI-Geräte zu arg einschränken würde oder Du musst den perfekten Alleskönner als DMA-Manager spezifizieren der in den meisten PCI-Geräten nur unnötiges Silizium kostet und am Ende doch nicht die speziellen Wünsche des jeweiligen Gerätes zu 100% erfüllen kann. So verlockend diese Idee auch ist ich denke das ist extrem kontraproduktiv (und unrealistisch).

Zitat von: erik
Von dieser Idee würde ich lieber Abstand nehmen. Bei PCI gibt es dafür den Class-Code, Du musst bei Deinen Treibern nur sagen ob die anhand der Class-Codes oder anhand der Vendor/Product-ID zugeordnet werden sollen (die zweiten sind die spezielleren und sollten bevorzugt werden).
Und genau das ist ja das Problem. Denn wie könnte man das machen?
Was genau ist das Problem? Du findest ein PCI-Gerät und holst die Vendor/Product-IDs und den Class-Code und durchsuchst damit erst das Array mit den spezifischen Treibern, anhand Vendor/Product-ID, und danach (falls nichts spezifisches gefunden wurde) das Array mit den generischen Treibern, anhand des Class-Code.

Zitat von: erik
Die Entscheidung des Lade-Mechanismus, welchen Treiber er laden soll, muss immer eineindeutig sein. Im Zweifelsfall muss root vorher entscheiden.
Das wird bei meinen Zielen (siehe Oben) wohl sehr schwierig umzusetzen sein. ....
Trotzdem muss diese Entscheidung immer eineindeutig sein. Dann muss eben die Entscheidung von root mit in die Datenbank mit aufgenommen werden oder man braucht andere klare Regeln. Man könnte z.B. immer sagen das auf unbekannten Systemen (für die root noch keine explizite Entscheidung getroffen hat) immer erst mal generische Treiber bevorzugt werden sollen. Und ansonsten darf es in der Datenbank eben keine Kollisionen geben, das Beispiel von taljeth ist in der Hinsicht IMHO fehlerhaft, es sollte nicht möglich sein mehrere spezifische Treiber für das selbe Gerät (also identische Vendor/Product-IDs) zu installieren. Das gilt IMHO auch für die generischen Treiber, auch hier sollte es nicht möglich das mehrere Treiber für ein und den selben Class-Code zuständig sind.


Grüße
Erik
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 23. September 2010, 13:21
@erik

Andere Idee  :-D

Was wäre wenn man DMA über die MMU (sowas wie ne IOMMU gibt es ja bei AMD schon, ob dass ungefähr das ist was ich meine weis ich aber nicht) laufen lassen würde. Sprich du initialisierst den DMA Kontroller mit dem PageDir (also den Wert von CR3 des Treibers, der sollte sich eigentlich nicht ändern) und dann übergibst du immer die virtuelle anstatt der physischen Adresse? Würde das nicht alle Probleme lösen und trotzdem alles andere wie gewohnt zulassen?

Zitat von: erik
Was genau ist das Problem? Du findest ein PCI-Gerät und holst die Vendor/Product-IDs und den Class-Code und durchsuchst damit erst das Array mit den spezifischen Treibern, anhand Vendor/Product-ID, und danach (falls nichts spezifisches gefunden wurde) das Array mit den generischen Treibern, anhand des Class-Code.
Das Problem ist, wie erstellst du das Array mit den generischen Treibern, wenn man diese nur anhand der IDs bestimmen kann.
Ich wollte eine Struktur für beide Arten von Treibern und wenn es da keinen Wert für die VendorID gibt, der laut PCI Specs nicht zugelassen ist, dann hast du nur spezielle Treiber, erweitere ich aber die VendorID auf 32bit, kann ich Werte haben die nicht zugelassen sind und kann so meine generischen Treiber erkennen.

Zitat von: erik
Das gilt IMHO auch für die generischen Treiber, auch hier sollte es nicht möglich das mehrere Treiber für ein und den selben Class-Code zuständig sind.
Ich weis nicht ob wir jetzt von der selben Sache reden, aber was ist mit einem IDE Treiber für Intel-Chipsätze, einem für SIS-Chipsätze usw. die haben alle den selben Class-Code und werden erst über den Vendor bestimmt.
Selbe für Grafikkarten, die haben alle den selben Class-Code, nur andere VendorIDs.
Selbst unter Windows kann man mehrere Treiber für ein und das selbe Gerät haben, es wird halt immer nur einer genutzt (der dann in der Registry eingetragen ist).
Titel: Re:Treiber "Management"
Beitrag von: erik.vikinger am 23. September 2010, 14:49
Hallo,


Was wäre wenn man DMA über die MMU (sowas wie ne IOMMU gibt es ja bei AMD schon, ob dass ungefähr das ist was ich meine weis ich aber nicht) laufen lassen würde. ....
Diese IOMMU ist wimre für die Virtuallisierung gedacht aber es müsste auch möglich sein die IOMMU für die Sicherheit einzusetzen. Das Problem welches ich sehe ist das man sehr viele dieser IOMMUs bräuchte, für jeden gerade laufenden Vorgang eine. Und das Gerät müsste auch für jeden Vorgang genau wissen welche dieser IOMMUs es benutzen soll, ein SATA/AHCI-Host-Controller kann ja durchaus mehrere Anfragen verschiedener Clients parallel bearbeiten. Ich bin mir nicht sicher ob sich dieses Problem wirklich zuverlässig in Hardware lösen lässt, ich hab da für meine Plattform schon mal drüber nachgedacht und bin auf keine gescheite Lösung gekommen. Alles was mir dazu eingefallen ist sind mehrere Range-Register im Chip-Satz die bestimmen auf welche Speicherbereiche die HW zugreifen darf (positiv Decoding) oder welche Speicherbereiche verboten sind (negativ Decoding). Für ersteres bräuchte man eventuell sehr viele dieser Register weil die Daten ja im physischen RAM wild zerstreut sein können und mit letzterem kann der Kernel eigentlich nur sich selbst etwas beschützen falls er nicht zu zerstreut im physischen RAM liegt (was auf meiner Plattform sicher gegeben ist). Das Problem das so ein Filtermechanismus zusätzliche Latenz (die mit mehr Registern auch größer wird) beim Speicherzugriff der Geräte erzeugt bleibt in jedem Fall erhalten. Man würde also für ein kleines bisschen Sicherheit ein kleines bisschen Performance opfern. Das beste was ein OS tun kann ist, wenn es für die Treiber von virtuell an physisch umrechnet, möglichst genau hinzuschauen ob der Treiber auf die virtuellen Adressen überhaupt zugreifen darf.


Das Problem ist, wie erstellst du das Array mit den generischen Treibern, wenn man diese nur anhand der IDs bestimmen kann.
Du könntest ein enum dazu packen das entscheidet was für ein Treiber das ist. Für die Product/Vendor-IDs sind IMHO 0x0000 und 0xFFFF verboten (eventuell nur wenn Vendor-ID == Product-ID ist) und es gibt auch ungültige Class-Codes, wenn Du das genau wissen möchtest musst Du in die PCI-Spec schauen (wenn Du möchtest kann ich das heute Abend mal machen), aber sauber ist dieser Weg meiner Meinung nach nicht.

Ich weis nicht ob wir jetzt von der selben Sache reden, aber was ist mit einem IDE Treiber für Intel-Chipsätze, einem für SIS-Chipsätze usw. die haben alle den selben Class-Code und werden erst über den Vendor bestimmt.
Selbe für Grafikkarten, die haben alle den selben Class-Code, nur andere VendorIDs.
Hier wäre das enum wieder gut, Du köntest nicht nur einen Typ für generisch (Class-Code) und einen Typ für spezifisch (Vendor/Porduct-ID) haben sondern auch zusätzliche Mischformen wie eben Class-Code + Vendor-ID (ohne Product-ID) so könntest Du alle IDE-Controller/Grafikkarten eines bestimmten Herstellers in eine Gruppe sortieren.

Selbst unter Windows kann man mehrere Treiber für ein und das selbe Gerät haben, es wird halt immer nur einer genutzt (der dann in der Registry eingetragen ist).
Bei Windows ist die Registry die Datenbank und was da nicht drin steht wird auch nicht zu booten benutzt, erst wenn der User Windows anweist einen neuen Treiber zu suchen (bzw. Windows den User frag ob es nach einem neuen suchen soll) kommt auch ein neuer Treiber in die Registry und wird auch erst nach dem nächsten Boot aktiv.


Grüße
Erik
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 23. September 2010, 15:03
Zitat von: erik
Das beste was ein OS tun kann ist, wenn es für die Treiber von virtuell an physisch umrechnet, möglichst genau hinzuschauen ob der Treiber auf die virtuellen Adressen überhaupt zugreifen darf.
Naja, das ist das was ich machen will, löst das eigentlich Problem aber nicht wirklich, denn der Treiber kann noch immer hinschreiben wo er lustig ist.

Zitat von: erik
Für die Product/Vendor-IDs sind IMHO 0x0000 und 0xFFFF verboten (eventuell nur wenn Vendor-ID == Product-ID ist) und es gibt auch ungültige Class-Codes, wenn Du das genau wissen möchtest musst Du in die PCI-Spec schauen (wenn Du möchtest kann ich das heute Abend mal machen), aber sauber ist dieser Weg meiner Meinung nach nicht.
Naja, das ist doch genau sowas was ich gesucht habe, aber da ich eigentlich schon die IDs auf 32bit erweitern wollte (die 6bytes sind dann auch nicht so schlimm) ist das eigentlich auch egal.
Was gefällt dir daran nicht bzw. denke ich mal du siehst da irgendwo ein Problem?

Zitat von: erik
Bei Windows ist die Registry die Datenbank und was da nicht drin steht wird auch nicht zu booten benutzt, erst wenn der User Windows anweist einen neuen Treiber zu suchen (bzw. Windows den User frag ob es nach einem neuen suchen soll) kommt auch ein neuer Treiber in die Registry und wird auch erst nach dem nächsten Boot aktiv.
Das ist genau das was ich auf keinen Fall haben will. Mir hat die Idee immer gefallen, das du dein USB-Stick, mit dem OS darauf, nimmst und an nen anderen PC steckst und schon läuft das OS ohne das es Probleme gibt (das z.B. der Treiber nicht in der Registry steht oder nicht im Bootscript steht oder nicht in den Kernel kompiliert ist).

Zu dem Thema passt doch eigentlich ne LiveCD auf Linux-Basis. Wie wird das dort gemacht? Sind da alle Treiber in irgendeinem Skript eingetragen (denn im Kernel sind die ja nicht mehr, sondern als externe Module)?

Was so auch noch nicht gemacht wurde (außer vielleicht bei Windows, da ist es in den INF-Dateien) das die Treiber nicht nachgucken ob ein Gerät für sie vorhanden ist (das wird bei Linux, möchte ich meinen, noch so gemacht) sondern das der Treiber auch nur geladen wird, wenn ein Gerät für ihn vorhanden ist.
Damit kann man einiges an Zeit einsparen (denke ich doch). Zumindest sollte sich der Bootvorgang so wesentlich beschleunigen lassen.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 24. September 2010, 02:20
Hallo,

im Fall "ich habe einen generischen VESA-Treiber und einen speziellen i915-Treiber...welchen nehm ich?" sollte man immer den speziellen Treiber bevorzugen. Einfacher Grund: Es gibt silicon bugs in Hardware oder schlecht geschriebene Treiber. Dein generischer Treiber nutzt vielleicht (BIOS-/ROM-)Funktionen, die die Hardware "an sich selbst vorbei" programmieren und das führt eventuell später dazu, dass ein Wechsel nicht mehr möglich ist (Beispiel: vesafb/viafb gegen openchrome gegen via_chrome9. Wechsel von einem zum anderen führt zum Totalabsturz.)

Erst, wenn kein spezieller Treiber mehr vorhanden ist, wird der generische Treiber geladen. Als Vendor-/Device-ID sollte 0x0000 freigegeben sein. Die Werte würde ich übrigens im Treiber jeweils als 16bit-Werte speichern - weil es so ohnehin im Standard steht. Warum mehr? Vorteile hast du keine, Nachteile auch nicht. (Zumal du dir, wenn du eigene PCI-IDs erzeugst, möglicherweise mehr Ärger beschaffst als nötig. Und inband signalling ist sowieso ganz schlecht!)

Im Falle, dass mehrere spezielle Treiber für ein Gerät vorhanden sind, sollte der Nutzer gefragt werden, oder man nimmt einfach beide. Wenn der erste erfolgreich arbeitet, sind die Ressourcen für die Hardware belegt und der zweite Treiber funktioniert dann nicht. Warum siehe weiter unten.

Gegen den Fall, dass ein Treiber mittels DMA wahllos im Adressraum rumschreibt, kannst du als OS-Programmierer nichts tun. Sinnvoll wäre hier höchstens, die Treiber so zu gestalten, dass sie dies nicht tun - und das heißt, im Treiber prüfen.

Was die Linux-Live-CDs angeht, so hast du im Kernel einen Teil der Geräte fest eingetragen (Linux ist modularisiert, aber monolithisch), ansonsten wird eine initrd (initiale Ramdisk, neuerdings meist initramfs = ein zu entpackendes cpio-Archiv) vom Bootloader mitgeladen. Diese dient als Root-Dateisystem und enthält eine Menge an für diesen Kernel kompilierten Treibern; es werden davon die geladen, welche im System vorhandene Hardware unterstützen. Es gibt eine Datenbank, die wird mit "depmod" erzeugt und enthält nur die Modulabhängigkeiten zueinander, d.h. "snd-hda-intel" braucht "sndcore" braucht "snd", oder "ne2" braucht "8390", oder "pcnet_cs" braucht "8390", "pcmcia_cs" und "pcmcia" etc.pp. Das wird bei verschachtelten Treibern nötig.

Wobei es da möglicherweise sinnvoll ist, die Treiber grundsätzlich über eine Abstraktion (z.B. der Bussysteme) zu führen - also einer API - oder (einfacher) diese Abhängigkeiten mit in die Module zu packen. "modprobe" verarbeitet jedenfalls diese dependencies, "insmod" nicht. In letzterem Fall musst du die bedingten Treiber vorher selbst laden.

Unter Linux schaut jeder Treiber ohnehin auf die Hardware - es ist nämlich wichtig, ob "ath" auch die entsprechende Chipversion unterstützt. Es gibt (gab?) auch zwei Module für RTL8139: 8139cp (RTL8139 C+) und 8139too (RTL8139 außer C+ und ähnliche). Das wiederum wird nötig, wenn du mehrere Geräte gleicher PCI-IDs hast. Der Windowstreiber besteht dann aus zwei Treibern, die erst den Chipsatz untersuchen.

Treiber werden aber grundsätzlich nur geladen, wenn die entsprechende Hardware auch vorhanden ist - das ist bei Linux so. Ausnahmen gibt es nur, wenn du Treiber für ISA-Geräte hast; diese werden aber nicht mehr grundsätzlich geladen, sondern müssen (mit Parametern) in z.B. /etc/modules aufgeführt werden.

Um den Bootvorgang vollständig unabhängig zu halten, solltest du alle bootkritischen Treiber in deinem Kernel vorliegen haben. Ob das über eine (nachzuladende = anpassbare) initiale Ramdisk läuft oder über ein in die Kernelbinary eingebautes Dateisystem (wie es Award-BIOSse für das BIOS-ROM machen), kannst du entscheiden. Oder du lässt die Module von deinem Multiboot-Bootloader mitladen, allerdings müsstest du dann die Konfiguration jeweils an das System anpassen. Für die LiveCD-Konfiguration lässt du dann halt nur generische Treiber laden bzw. hast eine angepasste Liste vorliegen.

edit:
Zu dem Video: Bedenke, dass das in dem Code nur subtile Bugs waren, die eventuell auch nur auf bestimmten Revisionen funktionieren. Und, dass der relevante Abschnitt in einer/zwei von hunderten Codezeilen steckt - versteckt in Code, der eine Hardware mit/ohne Datenblatt korrekt ansteuern muss. Da passieren Fehler. Wenn du behauptest, du kriegst das besser hin, dann enttäusche ich dich unbesehen.

Gruß,
Sebastian
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 24. September 2010, 09:08
Zitat von: svenska
Die Werte würde ich übrigens im Treiber jeweils als 16bit-Werte speichern - weil es so ohnehin im Standard steht. Warum mehr? Vorteile hast du keine, Nachteile auch nicht. (Zumal du dir, wenn du eigene PCI-IDs erzeugst, möglicherweise mehr Ärger beschaffst als nötig. Und inband signalling ist sowieso ganz schlecht!)
Weil ich meistens alles zumindest auf 4byte aligne. Wenn es aber im PCI Standard Werte gibt die ohne hin nicht zugelassen sind dann kann ich die natürlich nutzen.
Ich würde so ja keine neuen PCI-IDs (wenn man es genau nimmt nur eine ;) ) erzeugen sondern einfach nur einen Wert wie z.B. 0xDEADBEEF als ne Art Konstante damit ich weis das ist ein generischer Treiber.

Zitat von: svenska
Wobei es da möglicherweise sinnvoll ist, die Treiber grundsätzlich über eine Abstraktion (z.B. der Bussysteme) zu führen - also einer API - oder (einfacher) diese Abhängigkeiten mit in die Module zu packen. "modprobe" verarbeitet jedenfalls diese dependencies, "insmod" nicht. In letzterem Fall musst du die bedingten Treiber vorher selbst laden.
Genau für sowas macht sich mein Konzept ganz gut. Ich bin mir gerade zwar nicht sicher das wir vom selben Thema sprechen aber egal.
Ich wollte diese Abstraktion von Bussystemen auf jeden Fall machen (zumindest ISA/PCI/USB) und die Abhängigkeiten (die ich momentan sehe, kann sein das dann doch noch andere hinzu kommen) lösen sich von ganz alleine. Denn wenn kein PCI-Busmanager geladen und gestartet ist, werden die anderen Treiber auch nicht benötigt, da noch gar keine Geräte vorhanden sind.

Zitat von: svenska
Treiber werden aber grundsätzlich nur geladen, wenn die entsprechende Hardware auch vorhanden ist - das ist bei Linux so.
Ok, das wusste ich nicht. Aber wie funktioniert dann das installieren eines neuen Treibers? Muss der Kernel dann neu kompiliert werden oder wird der Treiber in irgendein Bootskript eingetragen und wird mitgeladen auch wenn er vielleicht gar nicht benötigt wird?

Zitat von: svenska
Oder du lässt die Module von deinem Multiboot-Bootloader mitladen, allerdings müsstest du dann die Konfiguration jeweils an das System anpassen.
Naja, ich wollte dann meinen Loader alle wichtigen Treiber (so fern vorhanden) laden lassen (PCI, USB, IDE, SATA, USB-MSD). Ob das dann auch so klappt oder ich das nochmal über den Haufen werfen muss, werd ich dann sehen.

Zitat von: svenska
Zu dem Video: Bedenke, dass das in dem Code nur subtile Bugs waren, die eventuell auch nur auf bestimmten Revisionen funktionieren. Und, dass der relevante Abschnitt in einer/zwei von hunderten Codezeilen steckt - versteckt in Code, der eine Hardware mit/ohne Datenblatt korrekt ansteuern muss. Da passieren Fehler. Wenn du behauptest, du kriegst das besser hin, dann enttäusche ich dich unbesehen.
Ich habe schon wirklich schöne Bugs produziert, vorallem finden sich meine Bugs immer so schwer (weil ich sie immer an der falschen Stelle vermute).
Aber was da manchmal gemacht wurde ist ein "try&fail"-Verfahren. Vorallem fand ich es gut, wenn man einen Patch dann wieder rückgängig macht und der Fehler ist wieder da ;)
Zumal das ja teilweise Code von den Leuten war die die Dokumentation haben müssten (z.B. Intel bei ihrer eigenen Hardware).
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 24. September 2010, 13:56
Hallo,

Zitat von: svenska
Die Werte würde ich übrigens im Treiber jeweils als 16bit-Werte speichern - weil es so ohnehin im Standard steht. Warum mehr?
Weil ich meistens alles zumindest auf 4byte aligne.
Okay, das ist natürlich ein Grund. ;-)

Ich wollte diese Abstraktion von Bussystemen auf jeden Fall machen (zumindest ISA/PCI/USB) und die Abhängigkeiten (die ich momentan sehe, kann sein das dann doch noch andere hinzu kommen) lösen sich von ganz alleine. Denn wenn kein PCI-Busmanager geladen und gestartet ist, werden die anderen Treiber auch nicht benötigt, da noch gar keine Geräte vorhanden sind.
Naja, ich bezog mich bei Abhängigkeiten zwischen Treiberdateien auch darauf, dass du bei ähnlicher Hardware eine gewisse Menge an "common code" hast und den wiederum als eigenen Treiber auslagerst (8390.o gemeinsam für "ne", "ne2", "ne2k-pci", "pcnet_cs", weil alles ne2000 ist). Dann hast du so eine einfache Abhängigkeit nicht mehr.

Spielt aber erstmal nur untergeordnet eine Rolle.

Zitat von: svenska
Treiber werden aber grundsätzlich nur geladen, wenn die entsprechende Hardware auch vorhanden ist - das ist bei Linux so.
Ok, das wusste ich nicht. Aber wie funktioniert dann das installieren eines neuen Treibers? Muss der Kernel dann neu kompiliert werden oder wird der Treiber in irgendein Bootskript eingetragen und wird mitgeladen auch wenn er vielleicht gar nicht benötigt wird?
Warum solltest du neue Treiber installieren? :-)

Du hast in /lib/modules/`uname -r`/* deine Treiberdateien als Kernelmodule (.ko) liegen und der Kernel lädt die halt, wenn er die entsprechende Hardware findet. Diese Module werden beim Neukompilieren des Kernels ebenfalls neu erzeugt, sie sind Kernelspezifisch. (Darum hat der nvidia-Treiber auch einen kleinen Opensource-Anteil: Den Glue-Code zwischen binary blob und Kernel.)

In /etc/modules kannst du Module einfügen, die er immer laden soll und in /etc/modprobe.d/blacklist trägst du Module ein, die du unter keinen Umständen automatisch geladen haben möchtest.

Je nach Distribution wird zusätzlich zu einem Kernel-Update auch die initrd/initramfs neu erzeugt, sodaß diese dann die (evtl nur bootkritischen) Module in zum Kernel passender Version enthält.

Da die meisten Treiber zum Kernel gehören, hast du natürlich weniger Stress mit Treiberupdates. Bei Treibern, die außerhalb des Kernels gewartet werden (nvidia, manche WLAN-Treiber) ist das etwas schwieriger - das läuft dann meistens über die Distributionen, die vorkompilierte passende Module bereitstellen (Debian: "nvidia-glx") oder eine automatische Bauvorrichtung mitbringen (Debian: "dkms"). Man kann Kernelmodule auch außerhalb des Kernel-Sourcetrees bauen, wenn man die passenden Header hat.

Zitat von: svenska
Oder du lässt die Module von deinem Multiboot-Bootloader mitladen, allerdings müsstest du dann die Konfiguration jeweils an das System anpassen.
Naja, ich wollte dann meinen Loader alle wichtigen Treiber (so fern vorhanden) laden lassen (PCI, USB, IDE, SATA, USB-MSD). Ob das dann auch so klappt oder ich das nochmal über den Haufen werfen muss, werd ich dann sehen.
Das sollte funktionieren.

Ich habe schon wirklich schöne Bugs produziert, vorallem finden sich meine Bugs immer so schwer (weil ich sie immer an der falschen Stelle vermute).
Aber was da manchmal gemacht wurde ist ein "try&fail"-Verfahren. Vorallem fand ich es gut, wenn man einen Patch dann wieder rückgängig macht und der Fehler ist wieder da ;)
Zumal das ja teilweise Code von den Leuten war die die Dokumentation haben müssten (z.B. Intel bei ihrer eigenen Hardware).
Das ändert aber nichts daran, dass du dir im Datenblatt anschaust "Mensch, der sollte mit diesem/jenem Feature klarkommen, machen wir das" und nicht mitkriegst, dass vier Jahre vorher jemand anders schon festgestellt hat, dass eben dieses Feature nicht so tut wie im Datenblatt angegeben. Oder dass plötzlich ganz anderes Verhalten auftritt - an völlig fremden Stellen.

Treiberentwicklung ist zu einem Großteil "try&error". Das sehe ich bei nouveau/openchrome, aber auch bei meiner Fritzbox, wo ich dem eth-Entwickler leider ständig sagen muss "geht immernoch nicht". (Das sind 2 Schnittstellen auf einem Chip. Viele Geräte haben einen konfigurierbaren Switch dahinter angeschlossen. Die meisten restlichen nutzen einfach den ersten Anschluss, Fritzboxen nutzen den zweiten. Die automatische Erkennung der Verkabelung ist broken und so richtig weiß keiner, wie man das zuverlässig erkennen kann.) Wichtig ist, dass es erstmal funktioniert und dann fasst es keiner mehr an. Subtile Fehler tauchen dann später auf. Linux 2.6.36 behebt auf Alpha einen 14-Jahre alten Bug, den man erst jetzt gefunden hat. Und da haben viele Leute gesucht.

Und wenn du den universellen VESA-Treiber geschrieben hast, mit Unterstützung von S3 Trio32 (VBE1) bis nVidia mit Refreshsettings (VBE3), dann fällt dir eine Karte in die Hand, die behauptet, sie könne es besser als sie es kann. Und dein Treiber schlägt der Länge nach hin. :-P

Gruß,
Sebastian
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 24. September 2010, 14:23
Zitat von: svenska
Naja, ich bezog mich bei Abhängigkeiten zwischen Treiberdateien auch darauf, dass du bei ähnlicher Hardware eine gewisse Menge an "common code" hast und den wiederum als eigenen Treiber auslagerst (8390.o gemeinsam für "ne", "ne2", "ne2k-pci", "pcnet_cs", weil alles ne2000 ist). Dann hast du so eine einfache Abhängigkeit nicht mehr.
Gut, wie gesagt, ich habe noch nicht wirklich Erfahrung in der Treiber-Programmierung, aber ich würde wahrscheinlich alles dann halt doppelt und dreifach als binary-Code vorliegen haben. Das man den Source mitverwenden kann ist ja was ganz anderes.

Zitat von: svenska
Warum solltest du neue Treiber installieren?
Naja, nicht OpenSource Treiber bzw. finde ich es eher unglücklich das Treiber so sehr zum Kernel gehören, das dieser diese schon zur compile-Zeit kennen muss. Sowas will ich in meinem OS absolut nicht.
Wenn Treiber im UserMode laufen, sollte das auch besser funktionieren, da sie da nicht ganz so viel Schaden anrichten können.

Ich will jedenfalls nicht für jeden Treiber meinen Device-Server neu kompilieren müssen und ich will mir die Option offen halten, das auch andere Treiber programmieren können und das man diese nachträglich "installieren" kann ohne das etwas kompiliert werden muss.

Zitat von: svenska
Das ändert aber nichts daran, dass du dir im Datenblatt anschaust "Mensch, der sollte mit diesem/jenem Feature klarkommen, machen wir das" und nicht mitkriegst, dass vier Jahre vorher jemand anders schon festgestellt hat, dass eben dieses Feature nicht so tut wie im Datenblatt angegeben. Oder dass plötzlich ganz anderes Verhalten auftritt - an völlig fremden Stellen.
Eigentlich darf ich das jetzt nicht sagen (da ich es selbst nicht wirklich mache, gerade bei solchen Sachen nicht), aber sollte man sowas nicht dokumentieren, damit genau sowas nicht passieren kann?

Vorallem merkt man an solchen Bsp wieder mal wie sehr doch die Uni-Welt und die reale Welt auseinander sind ;)

Wäre die Welt da draußen so wie sie dir in der Uni beschrieben wird, dann würden die Leute (wenigstens innerhalb eines Unternehmens) miteinander kommunizieren und der Bug wird entweder behoben oder wird in die Dokumentation aufgenommen.

Zitat von: svenska
Und wenn du den universellen VESA-Treiber geschrieben hast, mit Unterstützung von S3 Trio32 (VBE1) bis nVidia mit Refreshsettings (VBE3), dann fällt dir eine Karte in die Hand, die behauptet, sie könne es besser als sie es kann. Und dein Treiber schlägt der Länge nach hin.
Davon gehe ich jetzt mal bei allen meinen Treibern aus. Ich lerne ja noch, da wird wohl kein Treiber perfekt werden ;)
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 24. September 2010, 15:13
Hallo,

Zitat von: svenska
Warum solltest du neue Treiber installieren?
Naja, nicht OpenSource Treiber bzw. finde ich es eher unglücklich das Treiber so sehr zum Kernel gehören, das dieser diese schon zur compile-Zeit kennen muss. Sowas will ich in meinem OS absolut nicht.
Das bedeutet, dass du eine Binärschnittstelle zur Verfügung stellen musst, mit der deine Treiber mit dem System reden. Linux hat das aus gutem Grund nicht - es soll Herstellern so schwer wie möglich gemacht werden, Closed Source-Treiber zu benutzen.

Selbst Broadcom hat jetzt eingelenkt und es gibt inzwischen freie Treiber von denen. Damit kannst du natürlich nicht rechnen. Die BSDs haben übrigens auch keine feste Treiber-ABI, aber da durch die Lizenz alles freigegeben ist, können die Hersteller alles selbst basteln.

Wenn Treiber im UserMode laufen, sollte das auch besser funktionieren, da sie da nicht ganz so viel Schaden anrichten können.
Falscher Ansatz - sie können unendlich viel Schaden anrichten. Die richtige Frage ist, ob du den Treibern soweit vertraust, dass sie es nicht tun.

Ich will jedenfalls nicht für jeden Treiber meinen Device-Server neu kompilieren müssen und ich will mir die Option offen halten, das auch andere Treiber programmieren können und das man diese nachträglich "installieren" kann ohne das etwas kompiliert werden muss.
Geht unter Linux ja auch, inzwischen auch automatisiert in den Distributionen. Es ist nur schwieriger.

Dazu kommt halt auch, dass manche Schnittstellen als GPLONLY deklariert sind (weil Hersteller sich bekanntermaßen nicht daran halten), und weil es ein großer Monolith ist, in dem Treiber alle möglichen Kernelfunktionen aufrufen können. Ändern diese sich, so muss der Treiber angepasst werden.

Legst du die Treiberschnittstelle fest, dann bist du gezwungen, sie kompatibel zu halten und (wenn sich deine Schnittstelle als unzureichend erweist) musst dann parallel mehrere dieser Schnittstellen anbieten (können). Das ist dann eine Frage der Skalierbarkeit: Bei 10 Treibern ist es egal, bei 10k Treibern essentiell wichtig. Vergleiche die frühen Linux-WLAN-Treiber (mit eigenem Stack, nur unverschlüsselt/WEP) mit den etwas späteren ("SoftMAC" WLAN-Stack, allerdings nicht in den Kernel aufgenommen) und den aktuellen ("mac80211" WLAN-Stack, im Kernel).

mac80211-Treiber können (mit Ausnahmen) alle WEP, WPA, WPA2, Monitor Mode und Host Mode. Der Stack ist so primitiv (und mächtig), dass eventuelle WEP-Hardware nicht genutzt werden kann - allerdings kann dadurch jede Karte WPA2. Die Arbeit wird dem Treiber abgenommen und in der CPU erledigt.

Zitat von: svenska
Das ändert aber nichts daran, dass du dir im Datenblatt anschaust "Mensch, der sollte mit diesem/jenem Feature klarkommen, machen wir das" und nicht mitkriegst, dass vier Jahre vorher jemand anders schon festgestellt hat, dass eben dieses Feature nicht so tut wie im Datenblatt angegeben. Oder dass plötzlich ganz anderes Verhalten auftritt - an völlig fremden Stellen.
Eigentlich darf ich das jetzt nicht sagen (da ich es selbst nicht wirklich mache, gerade bei solchen Sachen nicht), aber sollte man sowas nicht dokumentieren, damit genau sowas nicht passieren kann?
Wenn du es als Hersteller nicht weißt, nicht vorhersehen kannst oder es aufgrund von Fehlern passiert, dann steht es nicht in der Dokumentation. Darum gibt es Errata: "Ups, wir haben einen Fehler gefunden. Guck mal."

Nicht gefundene Fehler stehen da nicht drin. Und Fehler, die grobe Sicherheitslücken sein können oder genug Interna bereitstellen, werden aus politischen Gründen nicht immer dokumentiert. (Eine Fehlerbeschreibung, die gut genug für Workarounds ist, ist meist auch gut genug für Exploits.)

Zitat von: svenska
Und wenn du den universellen VESA-Treiber geschrieben hast, mit Unterstützung von S3 Trio32 (VBE1) bis nVidia mit Refreshsettings (VBE3), dann fällt dir eine Karte in die Hand, die behauptet, sie könne es besser als sie es kann. Und dein Treiber schlägt der Länge nach hin.
Davon gehe ich jetzt mal bei allen meinen Treibern aus. Ich lerne ja noch, da wird wohl kein Treiber perfekt werden ;)
Ich meinte: Dein Treiber sei jetzt perfekt und optimal. Dann stolpert er über nicht-perfekte Hardware.

Das eine (perfekter Treiber) widerspricht dem anderen (perfekte Hardware). Also entsteht eine Mischung aus try&error, whitelists, blacklists und Workarounds.

Damit musst du leben und wenn du dir über sowas beim Design einen Kopf machst, kann es nur leichter werden. ;-)

Gruß
Titel: Re:Treiber "Management"
Beitrag von: FlashBurn am 24. September 2010, 15:49
Zitat von: svenska
Das bedeutet, dass du eine Binärschnittstelle zur Verfügung stellen musst, mit der deine Treiber mit dem System reden. Linux hat das aus gutem Grund nicht - es soll Herstellern so schwer wie möglich gemacht werden, Closed Source-Treiber zu benutzen.
Das ist halt ne Philosophie-Entscheidung.

Zitat von: svenska
Falscher Ansatz - sie können unendlich viel Schaden anrichten. Die richtige Frage ist, ob du den Treibern soweit vertraust, dass sie es nicht tun.
Ich dachte mit DMA wären wir uns einig das man da leider nichts machen :(

Zitat von: svenska
Geht unter Linux ja auch, inzwischen auch automatisiert in den Distributionen. Es ist nur schwieriger.
Falscher Thread, aber egal. Ich behaupte mal genau solche Schwierigkeiten (und das ein Treiberupdate auch meisten nen Kernelupdate bedeutet) verhindern das Linux jemals bei einem Otto-Normal-Verbraucher großartig genutzt wird.

Zitat von: svenska
Legst du die Treiberschnittstelle fest, dann bist du gezwungen, sie kompatibel zu halten und (wenn sich deine Schnittstelle als unzureichend erweist) musst dann parallel mehrere dieser Schnittstellen anbieten (können). Das ist dann eine Frage der Skalierbarkeit: Bei 10 Treibern ist es egal, bei 10k Treibern essentiell wichtig. Vergleiche die frühen Linux-WLAN-Treiber (mit eigenem Stack, nur unverschlüsselt/WEP) mit den etwas späteren ("SoftMAC" WLAN-Stack, allerdings nicht in den Kernel aufgenommen) und den aktuellen ("mac80211" WLAN-Stack, im Kernel).
Ich behaupte mal das ist ne Design-Frage!? Eine vernünftig designte Schnittstelle sollte nicht verändert werden müssen (soviel zur Theorie ;) ).

Zitat von: svenska
mac80211-Treiber können (mit Ausnahmen) alle WEP, WPA, WPA2, Monitor Mode und Host Mode. Der Stack ist so primitiv (und mächtig), dass eventuelle WEP-Hardware nicht genutzt werden kann - allerdings kann dadurch jede Karte WPA2. Die Arbeit wird dem Treiber abgenommen und in der CPU erledigt.
Wenn ich das richtig verstanden habe, dann wird die gesamte Verschlüsselung in Software gemacht? Die Idee gefällt mir.
Wenn man das richtig anstellt, sollte es sogar so funktionieren, das der Treiber eventuell vorhande Hardwarefeatures nutzt und der Rest wird per Software gemacht (ungefähr wie bei OpenGL/DirectX).

Zitat von: svenska
Ich meinte: Dein Treiber sei jetzt perfekt und optimal. Dann stolpert er über nicht-perfekte Hardware.

Das eine (perfekter Treiber) widerspricht dem anderen (perfekte Hardware). Also entsteht eine Mischung aus try&error, whitelists, blacklists und Workarounds.

Damit musst du leben und wenn du dir über sowas beim Design einen Kopf machst, kann es nur leichter werden.
Ich sags mal so, wenn eine CPU irgendeinen Fehler hat (z.B. bestimmte Pentium-Bugs) und die noch nicht bekannt sind. Dann kannst du erstmal gar nichts machen, weil der Kernel nicht läuft.
Ist der Fehler dann bekannt samt nen Work-Around, kannst du diesen in deinen Kernel einbauen.

Genauso würde ich dann bei einem "perfekten" Treiber vorgehen. Hat die Hardware nen Fehler funktioniert der Treiber und damit das System nicht. Denn wenn der Fehler (wie in deinem Bsp.) in einem generischen Treiber liegt und du keinen speziellen hast, läuft dein OS halt auf der Hardware nicht. Erst wenn du nen Work-Around drin hast läuft es dann.
Sehe da jetzt nicht so das Problem. Sowas musste ich schon oft in meinem Bootloader machen, wegen irgendwelchen BIOS-Sachen, die schlecht bis gar nicht dokumentiert sind.
Titel: Re:Treiber "Management"
Beitrag von: Svenska am 24. September 2010, 16:24
Hallo,

Zitat von: svenska
Legst du die Treiberschnittstelle fest, dann bist du gezwungen, sie kompatibel zu halten und (wenn sich deine Schnittstelle als unzureichend erweist) musst dann parallel mehrere dieser Schnittstellen anbieten (können). Das ist dann eine Frage der Skalierbarkeit: Bei 10 Treibern ist es egal, bei 10k Treibern essentiell wichtig.
Ich behaupte mal das ist ne Design-Frage!? Eine vernünftig designte Schnittstelle sollte nicht verändert werden müssen (soviel zur Theorie ;) ).
Erschwerend kommt hinzu, dass sich Hardware verändert. Wieder ein Beispiel: Eine Grafikkarte lässt sich recht einfach als simpler 2D-Framebuffer abstrahieren, eventuell mit ein paar Beschleunigungsfunktionen (BitBlt, Transparenz, YUV-Overlay). Betrachtest du aber eine heutige Grafikkarte, dann findest du CUDA, 3D-Matritzenfunktionen und viel mehr. Daher lässt sich eine 3D-Grafikkarte auch (und recht sinnvoll) als programmierbare Shadereinheit abstrahieren, bei der du den 2D-Anteil als Textur betrachtest. Genau das geschieht derzeit in Linux mittels Gallium3D.

Die jetzigen Ergebnisse sehen gut aus: Software-Rendering ist wesentlich schneller als vorher, die API ist nicht OpenGL-zentrisch, sondern es gibt auch einen nativen Direct3D 10/11 State Tracker, man kann es für Video-Dekodierbeschleunigung und Vektorgrafiken verwenden. Und es geht auf jeder Grafikkarte mit modernen Shadern. Außerdem benutzt keine moderne GUI mehr die beschleunigten Funktionen wie Rechtecke/Musterzeichnen/... und für Schatten ist das alles suboptimal.

Das eine lässt sich auf das andere nicht oder nur schlecht abbilden und daher muss so eine Abstraktion auch mal geändert werden. Plus: Eine perfekte Abstraktion denke ich mir nicht aus und du wahrscheinlich auch nicht. :-P

Zitat von: svenska
mac80211-Treiber können (mit Ausnahmen) alle WEP, WPA, WPA2, Monitor Mode und Host Mode. Der Stack ist so primitiv (und mächtig), dass eventuelle WEP-Hardware nicht genutzt werden kann - allerdings kann dadurch jede Karte WPA2. Die Arbeit wird dem Treiber abgenommen und in der CPU erledigt.
Wenn ich das richtig verstanden habe, dann wird die gesamte Verschlüsselung in Software gemacht? Die Idee gefällt mir.
Grundsätzlich ja. Da die Hersteller gemerkt haben, dass WEP schlecht war und sich jetzt nicht trauen (müssen), eine Verschlüsselung in Hardware zu gießen, wird bei modernen WLAN-Chipsätzen die gesamte Crypto eh im Treiber gemacht.

Wenn man das richtig anstellt, sollte es sogar so funktionieren, das der Treiber eventuell vorhande Hardwarefeatures nutzt und der Rest wird per Software gemacht (ungefähr wie bei OpenGL/DirectX).
Ja. Das setzt aber auch wieder voraus, dass du die Hardware sinnvoll abstrahiert hast, um eben solche Fähigkeiten dann auch wieder feststellen und ausnutzen zu können. Schließlich muss DirectX alle von der Hardware unterstützten Funktionen auch anbieten, um sie als Software-Fallback anbieten zu können.

Ich sags mal so, wenn eine CPU irgendeinen Fehler hat (z.B. bestimmte Pentium-Bugs) und die noch nicht bekannt sind. Dann kannst du erstmal gar nichts machen, weil der Kernel nicht läuft.
Ist der Fehler dann bekannt samt nen Work-Around, kannst du diesen in deinen Kernel einbauen.
Naja, der Kernel wird wahrscheinlich schon laufen. Aber vielleicht wird dein Scheduler unglaublich langsam oder einmal die Woche schmiert ein Prozess ab und keiner weiß warum. Oder (Pentium-Bug) die Winkelfunktionen im Coprozessor sind kaputt. Dein Kernel nutzt nur Ganzzahlarithmetik, deine Anwendung macht aber Floating-Point Cast-Auf-Int Zeigerarithmetik und stürzt ab. Sowas merkt man nicht

Genauso würde ich dann bei einem "perfekten" Treiber vorgehen. Hat die Hardware nen Fehler funktioniert der Treiber und damit das System nicht. Denn wenn der Fehler (wie in deinem Bsp.) in einem generischen Treiber liegt und du keinen speziellen hast, läuft dein OS halt auf der Hardware nicht. Erst wenn du nen Work-Around drin hast läuft es dann.
Der generische Treiber ist aber fehlerfrei (so die Annahme). Und die Probleme sind sehr subtil. Wobei es generische Treiber auch meistens nicht trifft, weil die meist andere (alte, stabile, getestete) APIs benutzen: Aber es trifft zum Beispiel den rtl8187b, der mit deinem Treiber für rtl8187 nicht (oder nur schlecht) funktioniert.[/quote]

Ist auch kein Problem, man sollte nur halt mal drüber nachgedacht haben.

Gruß,
Sebastian