Autor Thema: Verständnisproblem zu TSS  (Gelesen 2801 mal)

Developer30

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« am: 05. August 2013, 16:15 »
Hallo, ich bins mal wieder  :-D

Ich versuche Software-Multitasking zu implementieren. Auf Ring 0 klappt das auch schon super. Jetzt möchte ich das ganze noch zusätzlich für Ring 3 auf die Beine stellen. Ich orientiere mich dabei an diesem Tutorial.

Zitat von: Tutorial
Was ändert sich für uns mit Ring-3-Tasks? An sich ist es nicht viel. Wie oben schon angemerkt, kommt zum bereits Bekannten nur noch ein Stackwechsel dazu.
Das heißt, es gibt jetzt 2 Stacks pro Task, User- und Kernelstack. Soweit, so gut.

Zitat von: Tutorial
Wenn der Prozessor bei einem Interrupt in Ring 3 ist, also einen Ringwechsel durchführen muss, sichert er esp und ss auf den Stack (wie es in struct cpu_state schon vorgesehen ist). Beim Zurückspringen aus dem Interrupt mittels iret stellt er diese Register auch wieder her.
Auf welchen Stack sichert er esp und ss? Wahrscheinlich ja auf den Kernelstack des alten Tasks.

Zitat von: Tutorial
Nachdem er die Register gesichert hat, lädt der Prozessor den Kernel-Stack (bestehend aus ss und esp). Diese beiden Werte kommen aus dem aktiven Task State Segment (TSS).
Jetzt lädt er also den Kernel Stack des nächsten Tasks aus der TSS. An dieser Stelle frage ich mich, wann tut er das? Beim Betreten oder beim Verlassen der ISR? Oder macht er das garnicht automatisch und ich muss das irgendwo tun?

Bei der Implementierung der TSS steht im Tutorial außerdem folgende Codezeile:
Zitat von: Tutorial
tss[1] = (uint32_t) (new_cpu + 1);
Dazu frage ich mich: Wieso wird der Zeiger um 1 erhöht?

Ich hoffe meine Fragen sind (irgendwo) nachvollziehbar.

lg
Developer30

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 05. August 2013, 16:57 »
Auf welchen Stack sichert er esp und ss? Wahrscheinlich ja auf den Kernelstack des alten Tasks.
Genau, die landen auf dem Kernelstack, der im TSS referenziert ist.

Zitat
Zitat von: Tutorial
Nachdem er die Register gesichert hat, lädt der Prozessor den Kernel-Stack (bestehend aus ss und esp). Diese beiden Werte kommen aus dem aktiven Task State Segment (TSS).
Jetzt lädt er also den Kernel Stack des nächsten Tasks aus der TSS. An dieser Stelle frage ich mich, wann tut er das? Beim Betreten oder beim Verlassen der ISR? Oder macht er das garnicht automatisch und ich muss das irgendwo tun?
Ich glaube, das "nachdem" ist ein bisschen irreführend. Das ist alles Teil der Interruptbehandlung der CPU. Der Kernelstack wird geladen, die Userspace-Registerwerte von ss, esp, cs, eip und eflags darauf gesichert, ggf. auch noch der Error Code, und wenn das alles erledigt ist, springt er erst zu deinem Interrupthandlercode und macht dort weiter.

Zitat
Bei der Implementierung der TSS steht im Tutorial außerdem folgende Codezeile:
Zitat von: Tutorial
tss[1] = (uint32_t) (new_cpu + 1);
Dazu frage ich mich: Wieso wird der Zeiger um 1 erhöht?
Weil dort nach dem nächsten Userspace-Exit der CPU-Zustand wieder hingesichert werden soll. Beim Entry holst du den kompletten Zustand vom Stac, d.h. new_cpu + 1 (C-Pointerarithmetik, das sind sizeof(new_cpu) Bytes!) ist der richtige Stackpointer für den Kernelstack nach dem iret.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Developer30

  • Beiträge: 16
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 05. August 2013, 18:30 »
Danke für deine Antwort  :-)
Das hat mir sehr weitergeholfen die Aufgabe des TSS zu verstehen und mir den Ablauf nochmal im Kopf zu verdeutlichen. Dadurch hab ich es jetzt auch hinbekommen, meinen Scheduler für Ring 3 zu erweitern.
Verständnisproblem gelöst!  8-)

 

Einloggen