Autor Thema: GP bei Taskwechsel  (Gelesen 3054 mal)

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« am: 02. November 2014, 21:53 »
Hallo liebe community,
ich habe mal wieder ein komisches Problem. Ich hab mein Taskswitching implementiert. Nachdem dies für den Kernelmode functioniert hat hab ich jetzt das cs-Register so verändert, dass er theoretisch in den Usermode wechseln sollte, was er aber nicht tut. Stattdessen gibt es #GP und als Errorcode wird der Segmentregisterindex des cs-Registers, der geladen werden sollte, angegeben.
Im Anhang ist ein Bildschirmfoto des Fehlers.
Der Stackbacktrace, den ihr auf dem Foto seht, sind die Werte auf dem Stack, wie sie vor der Exception waren und der instruction pointer zeigt auf den iretq Befehl, der dann die Werte vom Stack gepoppt hätte. Ich weiss nich was falsch ist mit dem Codesegmentindex.

Hier ein kleiner Ausschnitt aus dem Log von Bochs:
CPU0:
rax: 00000000_00000000 rcx: 00000000_00000000
rdx: 00000000_00000000 rbx: 00000000_00000000
rsp: ffffff7f_ffffffd8 rbp: 00000000_00000000
rsi: 00000000_00000000 rdi: 00000000_00000000
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: 00000000_00108ec7
eflags 0x00000086: id vip vif ac vm rf nt IOPL=0 of df if tf SF zf af PF cf
[CPU0 RD]: LIN 0xffffff7fffffffe8 PHY 0x000000233fe8 (len=8, pl=0): 0x00000000 0x00000202
[CPU0 RD]: LIN 0xffffff7fffffffe0 PHY 0x000000233fe0 (len=8, pl=0): 0x00000000 0x00000018
[CPU0 RD]: LIN 0xffffff7fffffffd8 PHY 0x000000233fd8 (len=8, pl=0): 0x00000080 0x0000004F
[CPU0 RD]: LIN 0x000000000021a138 PHY 0x00000021a138 (len=8, pl=0): 0x00AFFA00 0x0000FFFF
[CPU0 RD]: LIN 0x000000000021a230 PHY 0x00000021a230 (len=8, pl=0): 0x00108E00 0x00088DC3
[CPU0 RD]: LIN 0x000000000021a238 PHY 0x00000021a238 (len=8, pl=0): 0x00000000 0x00000000
[CPU0 RD]: LIN 0x000000000021a128 PHY 0x00000021a128 (len=8, pl=0): 0x00AF9B00 0x0000FFFF
[CPU0 RD]: PHY 0x000000232ff0 (len=8): 0x00000000 0x0023402F ; PML4E
[CPU0 RD]: PHY 0x000000234ff8 (len=8): 0x00000000 0x0023502F ; PDPTE
[CPU0 RD]: PHY 0x000000235ff8 (len=8): 0x00000000 0x0023602F ; PDE
[CPU0 RD]: PHY 0x000000236ff8 (len=8): 0x00000000 0x0023302F ; PTE
[CPU0 WR]: PHY 0x000000236ff8 (len=8): 0x00000000 0x0023306F ; PTE
[CPU0 WR]: LIN 0xffffff7fffffffc8 PHY 0x000000233fc8 (len=8, pl=0): 0x00000000 0x00000010
[CPU0 WR]: LIN 0xffffff7fffffffc0 PHY 0x000000233fc0 (len=8, pl=0): 0xFFFFFF7F 0xFFFFFFD8
[CPU0 WR]: LIN 0xffffff7fffffffb8 PHY 0x000000233fb8 (len=8, pl=0): 0x00000000 0x00010086
[CPU0 WR]: LIN 0xffffff7fffffffb0 PHY 0x000000233fb0 (len=8, pl=0): 0x00000000 0x00000008
[CPU0 WR]: LIN 0xffffff7fffffffa8 PHY 0x000000233fa8 (len=8, pl=0): 0x00000000 0x00108EC7
[CPU0 WR]: LIN 0xffffff7fffffffa0 PHY 0x000000233fa0 (len=8, pl=0): 0x00000000 0x00000018

Wie man sieht wird eine Exception ausgelöst, sobald die CPU den GDT-Eintrag für CS gelesen hat.
Wieso gibt es diesen Fehler? Ich hoffe ihr könnt mir helfen.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. November 2014, 22:42 »
Du musst den CPL (Current Privilege Level) 3 anfordern, wenn du in den User Mode willst. Das heißt du musst CS mit 0x18 + 3 = 0x1B laden.

Wenn Wert 4 und 5 in deinem Stacktrace im Screenshot die Werte für ESP und SS für Ring 3 sind, sehen die außerdem verkehrt aus. ESP liegt auf dem aktuellen Stack (vgl. RSP), das heißt, dass du den Kernel Stack überschreiben würdest. Für SS muss außerdem ebenfalls ein Selektor mit DPL und CPL = 3 angegeben werden, da CPL von SS und CS übereinstimmen müssen.
Dieser Text wird unter jedem Beitrag angezeigt.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 02. November 2014, 22:43 »
Ich bin mir nicht ganz sicher, ob ich aus deiner Log zuverlässig  das rauslesen kann, was mich interessiert (nämlich den Wert von cs und deine GDT).

Falls du aber wirklich 0x18 als Selektor benutzt, was dein Error Code ist, von dem du behauptest, dass er mit dem gewünschten cs übereinstimmt, dann ist das kein Ring-3-Selektor und du meinst vermutlich eher 0x1b.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #3 am: 02. November 2014, 23:09 »
Du musst den CPL (Current Privilege Level) 3 anfordern, wenn du in den User Mode willst. Das heißt du musst CS mit 0x18 + 3 = 0x1B laden.
Danke jetzt geht es. Hab ich wohl im Manual mal gelesen gehabt und dann vergessen.

Wenn Wert 4 und 5 in deinem Stacktrace im Screenshot die Werte für ESP und SS für Ring 3 sind, sehen die außerdem verkehrt aus. ESP liegt auf dem aktuellen Stack (vgl. RSP), das heißt, dass du den Kernel Stack überschreiben würdest. Für SS muss außerdem ebenfalls ein Selektor mit DPL und CPL = 3 angegeben werden, da CPL von SS und CS übereinstimmen müssen.
Die Werte sind schon richtig, den sie liegen schon auf dem Userstack. Beim Erstellen eines Prozesses lade ich diese Werte in dessen Stack. Und beim Taskswitch muss ich dann einfach den Stack Pointer neu setzen.
Oh da fehlt mir dann wohl noch ein Segment. Muss ich den die anderen Segmentregister auch mit CPL=3 laden?

Danke für eure schellen Antworten.

Edit: Das mit dem SS-Register hab ich auch nirgends gefunden. Im Manual steht nur, dass das DPL-Feld im Eintrag für Datensegmente ignoriert wird.
« Letzte Änderung: 03. November 2014, 00:00 von OsDevNewbie »
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 03. November 2014, 20:34 »
Ich bin mir auch nicht mehr ganz sicher, wie das im Long Mode funktioniert. Gedanklich war ich mit meinen Antworten noch bei 32-Bit. Ich finde das mit RPL=3 auch gerade nicht.

Dass der DPL und RPL von SS mit dem CPL übereinstimmen muss, steht in Kapitel 5.7 von Volume 3. Aber ich glaube auch da greifen 64-Bit-Sonderregeln. Da müsste sich mal jemand äußern, der das nicht schon wieder alles vergessen hat.
Dieser Text wird unter jedem Beitrag angezeigt.

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #5 am: 04. November 2014, 18:02 »
Also als ich das cs Register dann mit dem richtigen Wert geladen habe kam die #GP fault trotzdem noch. Und zwar wegen dem ss Register. Ich glaube man muss es doch mit dem richtigen Wert laden. Jetzt funktioniert es jedenfalls.
Danke für eure Antworten.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

 

Einloggen