Autor Thema: Designfragen zu meinem OS  (Gelesen 3550 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« am: 16. March 2009, 10:18 »
Hallo zusammen,

ich habe mir gerade ein paar Gedanken gemacht, wie ich mein OS designen sollte.
Ich wollte es so machen, dass der Kernel wirklich nur Paging und Scheduling beherrscht.
Der Rest soll als Modul nachgeladen werden.
Ein Teil der Module soll allerdings im Kernel-Space laufen.
Nun frage ich mich, wie ich den Modulen die Methoden zur Speicherverwaltung im Kernel-Space mitteile.
Das könnte ich entweder als Übergabeparameter machen (ist mir allerdings zu unelegant) oder durch shared-libraries.
Leider weiß ich nicht, wie ich diese implementieren soll (noch ohne FS).

Dann wollte ich auch noch Treiber in den Userspace auslagern.
Leider weiß ich noch nicht, wie ich den Treibern Rechte für die Ports geben kann.
Ich habe gesehen, dass das TSS eine IO-Bitmap besitzt.
Wie funktioniert die denn?

Außerdem hatte ich vor, dass der Kernel so gut wie nie gelockt wird.
Es soll nur ein Big-Kernel-Lock geben, wenn ein panic ausgelöst wurde.
Bei der Pageverwaltung habe ich es mir so gedacht, dass diese immer nur für die Prozesse gelockt werden.
Nun frage ich mich, ob da immer noch das TSS des Prozesses reicht, oder ob ich da dann später Probleme beim iret bekomme.

Dann habe ich mich auch noch gefragt, wie ich den Prozessen bestimmte Möglichkeiten zur Kommunikation biete (Display).
Das würde an sich doch am besten gehen, wenn ich einen Puffer im Kernelspace funktionieren, oder?
Am besten  baut man den Puffer als Ringpuffer auf, oder?
Wie groß sollte der denn am besten sein?

Danke für eure Hilfe

cu rizor
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 16. March 2009, 11:38 »
Dann wollte ich auch noch Treiber in den Userspace auslagern.
Leider weiß ich noch nicht, wie ich den Treibern Rechte für die Ports geben kann.
Ich habe gesehen, dass das TSS eine IO-Bitmap besitzt.
Wie funktioniert die denn?
Das ist einfach ein Bitmap, die für jeden Port angibt, ob er benutzt werden darf oder nicht. Gesetztes Bit heißt, daß beim Zugriff ein GPF fliegt, gelöscht, daß direkter Zugriff erlaubt ist (oder andersrum, ich bin mir nie so sicher. ;)) Details im Intel-Manual oder tyndur-Quellcode.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 16. March 2009, 11:48 »
Mein Problem ist jetzt nur, welches Bit steht für welchen Port
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 16. March 2009, 13:09 »
Das kannst du mit diesen Formeln ausrechnen:
port ist die Nummer des IO-Ports
byte ist das Offset des Bytes in der Bitmap
bit ist die Nummer des Bits im Byte

byte = port/8
bit = port mod 8 (in C: port%8)

Dh. in C kannst du so ein Bit setzen (und damit jemanden den Zugriff auf den Port sperren)
port und die Adresse von tss_bitmap musst du natürlich selbst wissen ;)
int port = 42;
char *tss_bitmap = 0xD00FC0DE;

tss_bitmap[port/8] |= 1<<(port%8);

PS: Bitmaps arbeiten meistens so, dass das erste Element das repräsentiert werden soll, mit dem ersten Bit repräsentiert wird.
« Letzte Änderung: 16. March 2009, 13:13 von jgraef »

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 16. March 2009, 13:20 »
Ok. Danke.
Das löst eines meiner Probleme.

Gibt es ein gutes Tutorial, wie ich Multitasking implementieren kann?
Ich weiß leider gar nicht, wie ich damit umgehen soll, außer dass der Kernel und jeder Task eine eigenes TSS braucht.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 17. March 2009, 13:20 »
Eigentlich reicht ein TSS (pro Prozessor, ich nehme mal an du machst noch kein Mehrprozessor-OS).
Vom Grunde geht das so:

1) Auf Timer-IRQ warten
2) Wenn zuvor ein Prozess aktiv war, Register sichern
3) Nächsten Prozess suchen
4) Register und Adressspace laden und in Prozess springen

Man braucht natürlich als erstes mal eine IRQ-Verwaltung und eine Speicherverwaltung.

Beim Speichern und Laden von Registern muss man etwas tricksen, dass ist nämlich ein sehr kritischer Teil. Man muss ja direkt, wenn der Timer-IRQ aufgerufen wurde, die Register sichern (Viele finden sich auf dem Stack).
Am besten schaust du dir das mal bei einem anderen OS an.
Bei meinOS werden bei einem IRQ generell alle Register auf den Stack gepusht und dann ESP selbst. Die dann aufgerufene Funktion hat ESP dann als Parameter und erstellt dann eine Tabelle mit Pointern auf die Register. So können jeder Zeit Register gesichert und geladen werden.

Bei der Speicherverwaltung muss eigentlich nur möglich sein, die Executable zu laden und den Adressspace nachher schnell wechseln zu können. Außerdem musst du drauf achten, dass der Kernel in jedem Adressspace drin sein muss.

(Mit Adressspace meine ich eigentlich ein Pagedir, also ein abgeschotteter Adressraum für einen Prozess)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 17. March 2009, 14:20 »
Das habe ich soweit gemacht.
Also es fehlt nur noch der ELF-Loader.
Was genau hat es dann mit dem TSS auf sich?
Muss ich nach einem Taskswitch auch was ändern?
Das mit der Registersicherung mache ich auch so (pusha und dann der Rest).

Also wenn ich dich richtig verstehe:
1. TSS erstellen und laden
2. Initialien Task laden
3. Nach PIT-IRQ die Register sichern.
4. Neu schedulen
5. Register wiederherstellen (kann ich mir die einfach von dem neuen Stack nehmen?)
6. iret

Bei 6. Habe ich noch eine Frage:
Ich lasse in der Seitenverwaltung Interrupts zu.
Die wird natürlich über Syscalls aufgerufen.
Wenn ich nun einen Prozess bei der Syscall-Behandlung unterbreche, springe ich ja im Prinzip von Kernel-Space in den Kernel-Space.
Wenn der Prozess nun erneut Rechenzeit bekommt, springe ich ja mit iret an seine Position.
Bekomme ich da Probleme, wenn ich dann nach der Syscall-Behandlung erneut iret aufrufe?

[EDIT]
Im Wiki steht, dass jeder Task ein eigenes TSS bekommt.
Wieso machst du dass nicht so?
« Letzte Änderung: 17. March 2009, 14:29 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

 

Einloggen