Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Themen - oern

Seiten: [1]
1
OS-Design / VFS-Konzept
« am: 13. May 2013, 15:54 »
Hallo,

ich entwickle gerade den Treibermanager / ein VFS für mein OS und wollte es hier mal vorstellen. Kritik und Fälle, in denen das Konzept nicht ausreicht, sind erwünscht. :-)

Der Kernel ist ein modularer Monolith, d.h. die Kerneldatei beinhaltet nur den Prozess (mit Threads)-, Speicher-, Interrupt-, Modul- und Treiber/Dateimanager. Die Treiber werden von der Modulverwaltung entweder als Multibootmodul (für Boottreiber) oder aus einer Datei geladen. Dabei verwende ich ELF-Relocatables (wie der Linuxkernel). Wenn ein Modul geladen wird, wird (ebenfalls wie im Linuxkernel) eine Funktion mod_init aufgerufen, in der der Treiber z.B. Caches anlegen und sich beim Treibermanager anmelden kann. Beim Entfernen wird mod_destroy aufgerufen, die u.a. Aktionen aus mod_init rückgängig macht. Abhängigkeitsverwaltung wird es vorerst nicht geben.

Den grundlegenden Teil des VFS bilden die Treiber (Driver). Ein Treiber wird vom System anhand eines menschenlesbaren Namens identifiziert und kann Fähigkeiten (Capabilities) bereitstellen. Als Fähigkeiten sind erst mal geplant: Speichermedium, Dateisystem, Bus, HID (Human Interface Device) und Video (dass das nicht ewig reicht, ist mir klar, z.B. Netzwerk). Dies hat den Vorteil (gegenüber einem System, das nur Typen unterstützt), dass z.B. ein Treiber für die serielle Schnittstelle ja sowohl HID als auch Video-Gerät ist und man so nicht zwei Treiber zu registrieren muss. Ein Treiber stellt außerdem ein einziges Callback bereit, das als Parameter eine IO-Anfrage bekommt (dazu später mehr). Außerdem hat er eine Liste von Geräten, die von diesem Treiber verwaltet werden.

Ein Gerät wird vom System anhand zweier ID-Nummern identifiziert. Diese müssen nicht unbedingt benutzt werden (0 ist default), und ich denke, dass zwei ausreichen. Bei einem ATA-Treiber kann z.B. die erste für die Platte und die zweite für die Partition stehen, bei Grafikkarten eins für die Karte und eins für den Bildschirm usw. Das Gerät hat auch eine Fähigkeiten-Maske, d.h. ein Gerät, das ein Treiber registriert, muss nicht alle Funktionen unterstützen, die der Treiber bereitstellen kann. Es beinhaltet außerdem den Root-Knoten des Dateibaums des Gerätes.

Ein Knoten wird anhand eines menschenlesbaren Namens identifiziert (d.h. Verzeichniseinträge und Knoten werden nicht getrennt betrachtet). Ein Knoten hat Attribute (z.B. Zugriffzeit, ACLs, Größe) und einen Typ (nur Datei, Symlink oder Verzeichnis).

Um eine IO-Operation mit einem Knoten durchzuführen, muss man das oben genannte Callback des Treibers benutzen und eine IO-Anfrage vorbereiten. Die Anfrage enthält den Knoten, auf den sie sich bezieht, die Funktion, in der das Gerät benutzt wird (entspricht den Capabilities, es darf aber nur ein Bit gesetzt sein), den Typ der Anfrage (Lesen, Schreiben, Attribute lesen, Attribute Schreiben, Erstellen, Entfernen, etc.), Daten und die Größe der Daten.

Vollständige Pfade beginnen mit dem Namen des Treibers. Darauf folgen ggf. in Klammern bis zu zwei ID-Nummern (mit Komma getrennt) und ein Doppelpunkt. Danach folgt (ohne führendes '/', da ja sowieso von der Wurzel ausgegangen wird) der Pfad innerhalb des Gerätes, ganz "normal" mit Slashes abgetrennt. Beispiel: ata(0,1):foo/bar.txt oder vga:modeinfo.
An dem ersten Beispiel sieht man auch, dass Dateisysteme nicht über den Dateisystemtreiber, sondern über den Massenspeichertreiber angesprochen werden, der den zu benutzenden Treiber ermittelt (und natürlich zwischenspeichern darf).
Andere Treibertypen sollen vom Usermode nicht direkt über das VFS angesprochen werden, sondern es soll einheitliche Schnittstellen für die jeweiligen Fähigkeiten geben, z.B. hat ein Grafik/Videogerät standardmäßig eine Datei "modeinfo" in seinem Wurzelverzeichnis, aus der die verfügbaren Modi (vermutlich nur maschinenlesbar) ausgelesen werden können, und "control", in die (vermutlich auch nur maschinenlesbar) sozusagen "male ein Rechteck vom Punkt (a;b) zum Punkt (c;d)" geschrieben werden kann.

Noch weiß ich nicht genau, wie ich das Businterface gestalten soll, da damit sowohl z.B. PCI als auch USB verwaltet werden soll, ebenso wie das HID-Interface da man damit auch sowohl Zeigegeräte als auch Tastaturen etc. verwenden können soll.

Falls jemand bis hier gelesen haben sollte (oder auch sonst), vielen Dank, ich freue mich auf Kritik.
Viele Grüße,

oern
2
OS-Design / IRQs im Kernel
« am: 01. May 2013, 14:41 »
Hallo,

ich habe mal wieder einen Kernel begonnen (modularer Monolith). Dabei habe ich mir folgendes Problem überlegt:
Der Kernel nicht unterbrechbar ist, d.h. alle Interrupts sind in der IDT als "Interrupt Gate" eingetragen. Ein Programm ruft eine Kernelfunktion per Syscall auf (danach sind HW-Interrupts deaktiviert). In dieser Kernelfunktion (z.B. Lesen aus einer Datei) muss auf einen Block eines Massenspeichermediums zugegriffen werden, der nicht im Cache ist. Dies soll per DMA geschehen, d.h. der Storage-Controller löst nach Abschluss des Transfers einen IRQ aus. Wie soll der Kernel davon erfahren?
Die Lösung wäre natürlich, zumindest den Syscall und eventuell die IRQs unterbrechbar zu machen, aber das erfordert ja sehr viel Locking (was für SMP aber ja eh notwendig wird). Gibt es einfachere Lösungen oder existiert dieses Problem überhaupt nicht?

oern
3
Lowlevel-Coding / Problem mit Interrupts
« am: 14. February 2012, 18:06 »
Hallo,

ich habe mal wieder angefangen, einen neuen Kernel zu schreiben weil meine alten alle zu kaputt waren.
Jetzt hänge ich bei der IDT / den Interrupts.
Ich habe so ziemlich das gleiche Problem wie manche andere hier auch schon hatten, aber die Fehler die es da waren können es eigentlich nicht sein.
Offenbar wird der Stack, wo die Registerwerte beim Sprung in den Handler drauf sind, kaputt gemacht. Zum Beispiel kommen wenn ich (nach Laden der IDT) die Interrupts einschalte zuerst (laut QEMU-Logs) ein Int 0x21 (wieso der kommt weiß ich nicht, ist doch Tastatur?), danach ein Int 0x20 und dann ein Int 0x0e. Ich habe einen Registerdump auch bei IRQs. Der behauptet aber beim ersten IRQ, dass IRQ 4 (statt 1) und beim zweiten, dass IRQ 3 (statt 0), aufgerufen wurde. Beim zweiten IRQ stimmen auch die Registerwerte vom Stack nicht mehr mit den aus den QEMU-Logs überein (z.B. steht in CS der Wert von EIP, in ESP die EFLAGS etc.). Beim Page Fault ist dann von den Werten her alles in Ordnung. Der Code, der die IDT einrichtet, ist in Assembler geschrieben und schreibt nur die Handleraddressen in die IDT; der Rest (Flags, Segment) steht da schon vorher drinnen, damit so wenig wie möglich zur Laufzeit gemacht wird (mir kommt es unnötig vor, die Flags und das Codesegment zur Laufzeit zu bestimmen, obwohl die schon zur Kompilierzeit feststehen, mache ich bei der GDT genau so).
Außerdem wird der PIC auf die entsprechenden Nummern gemappt. Bootloader ist GRUB und kein eigener.

Alles in allem: Interrupts funktionieren nicht. Wieso nicht? :roll:

Ich könnte noch den Code posten, das mache ich aber erst, falls überhaupt jemand sich das hier durchliest. Ich hoffe, dass die restliche Beschreibung genau genug war, aber sonst sagt ihr das ja.

Grüße,

oern
4
Offtopic / Panikmache wegen DNS-Changer
« am: 11. January 2012, 20:00 »
Hallo,

ich habe gerade mitbekommen, dass angeblich "Tausende deutsche Web-Surfer ab März offline" (t-online.de) sein sollen.
Das ist doch so eigentlich falsch, denn wenn die entsprechenden geänderten DNS-Server offline sind, bedeutet das nur, dass man eben keine Domains mehr benutzen kann. Und Computer, die sich die DNS-Server-IP nicht per DHCP vom Router holen, sind doch sowieso nicht betroffen. Oder ändert der DNS-Changer die DNS-IP direkt in den entsprechenden PCs?
Also als Frage(n): Was ist das Problem daran  bzw. wie funktioniert der DNS-Changer bzw. inwiefern hängt das vom verwendeten OS auf den Client-PCs eines Netzwerks ab?

Grüße,
oern
Seiten: [1]

Einloggen