Autor Thema: ltr-Befehl, TSS, was soll die blöde General-Protection-Fault? [solved]  (Gelesen 7790 mal)

Cheebi

  • Beiträge: 91
    • Profil anzeigen
    • Cheebis Webseite
Gespeichert
ohjee... warum bekomm' ich denn eine General-Protection-Fault-Exception, wenn ich folgenden Code ausführe?

  __asm__ volatile ("ltrw %%ax"::"a"(0x18));
  cli();
  for(;;);

Descriptor 3 der GDT ist der TSSDescriptor und hat folgende Werte:

Word1: 0x00000068
Word2: 0x05808900

Das heißt also:

Größe    = 104 Byte
Base     = 0x5000000
Busy     = false
DPL      = 0
Present  = true
Granular = true

Vom TSS selbst sind nur die beiden Einträge ss0 und esp0 mit Werten besetzt. Alle anderen Einträge tragen den Wert 0.

Warum komme ich also nie zu den Befehlen nach ltrw?

Gruß Cheebi
« Letzte Änderung: 03. August 2007, 18:20 von Cheebi »
0100 1001 0100 1100 0100 0001 0010 0000 0011 1010 0010 1101 0010 1010
http://www.cheebi.de

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 31. July 2007, 16:32 »
Meine ASM-Referenz sagt mir das es für diesen GP-Error folgende glünde geben kann:

  • CPL ist größer 0
  • Selector zeigt auf eine stelle außerhalb der GDT
  • Selector zeigt nicht auf ein TSS
  • Selector zeigt auf activen task

Wenn ich das richtig verstanden habe löst das Ding nen TastSwitch aus, oder?
Dann soltest du auch die Selectoren und EIP im TSS überprüfen.

[edit]
 :oops: man solte schon zu ende lesen  :oops:

wenn CS null ist gibt das natürlich auch nen GP
« Letzte Änderung: 31. July 2007, 16:34 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #2 am: 31. July 2007, 16:34 »
Mein TSS Deskriptor sieht folgendermaßen aus:
dw 0x0068
dw 0x0000
db 0x00
db 0x89
db 0x40
db 0x00

Auf jeden Fall solltest du Granularity auf 0/false setzen.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 31. July 2007, 16:35 »
@MNemo: Nein, das Ding löst keinen Taskswitch aus. Es lädt nur einen Selektor in das Taskstateregister.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Cheebi

  • Beiträge: 91
    • Profil anzeigen
    • Cheebis Webseite
Gespeichert
« Antwort #4 am: 31. July 2007, 16:45 »
@bluecode:

ich hatte folgende Quelle:
http://en.skelix.org/skelixos/tutorial06.php

nach der ist das Granular-Bit zu setzen... Aber auch ohne es zu setzen, tritt bei mir ne GP auf.

dw 0x0068
dw 0x0000
db 0x00
db 0x89
db 0x40
db 0x00
Warum hast du ein reservierte Bit true gesetzt? (Das 7. Bit des 7. Bytes hast du true gesetzt [db 0x40])

gruß Cheebi
0100 1001 0100 1100 0100 0001 0010 0000 0011 1010 0010 1101 0010 1010
http://www.cheebi.de

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 31. July 2007, 17:01 »
@MNemo: Nein, das Ding löst keinen Taskswitch aus. Es lädt nur einen Selektor in das Taskstateregister.
So stand das ach in der ASM - Referenz, konnt mir nur bis eben nix drunter vorstellen.

Dann sollte der Inhalt des TSS ach nicht von Bedeutung sein. Aber das Granularity bit soltest du wirklich aus machen(ich denke nicht das dein tss 104 * 4kb groß ist) und das D-Bit solte dafür vielecht an du hast ja auch im TSS-Type den 368 ausgewählt.

[edit]
bluecode hat das D-Bit auf eins gesetzt nicht ein reservirtes bit.
« Letzte Änderung: 31. July 2007, 17:03 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #6 am: 31. July 2007, 18:47 »
Hm stimmt. Laut den Intel Manuals (6.6.2 TSS Descriptor) ist das Bit reserviert/0... und bei mir funktionierts auch wenn das Bit gelöscht ist. Laut Intel manual können bei ltr folgende Sachen einen GPF auslösen:
Zitat von: Intel Manuals
#GP(0)        If the current privilege level is not 0.
              If a memory operand effective address is outside the CS, DS,
              ES, FS, or GS segment limit.
              If the source operand contains a NULL segment selector.
              If the DS, ES, FS, or GS register is used to access memory and it
              contains a NULL segment selector.
#GP(selector) If the source selector points to a segment that is not a TSS or to
              one for a task that is already busy.
              If the selector points to LDT or is beyond the GDT limit.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 01. August 2007, 14:05 »
Hm stimmt. Laut den Intel Manuals (6.6.2 TSS Descriptor) ist das Bit reserviert/0...

Ok. fh-zwickau.de ist dann wohl nicht ganz so zuverlässig. (Ist ja auch nicht der einzigste Fehler)
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #8 am: 01. August 2007, 14:07 »
Ahso, daher hab ich also den Mist. :-D  :mrgreen:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Cheebi

  • Beiträge: 91
    • Profil anzeigen
    • Cheebis Webseite
Gespeichert
sooo... Problem gelöst:

Ich habe vergessen, die GDT neu zu laden, nachdem ich einen neuen Descriptor (TSSDesc) angelegt habe. (also das Feld GDT.size musste mit Hilfe von lgdt [GDT] aktualisiert werden).

Ich habe aber immer noch eine Frage:

Ist es sinnvoll, die GDT von Anfang an mit Nulldescriptoren zu füllen und dementsprechend das Feld GDT.size gleich so zu setzen:
GDT.base = 0x0;
GDT.size = (sizeof(SDESCRIPTOR) * MAX_DESCS) - 1;
load_GDT(GDT);

Oder sollte man bei jedem neu angelegten Descriptor die GDT mit neuen Werten laden?

Gruß Cheebi
0100 1001 0100 1100 0100 0001 0010 0000 0011 1010 0010 1101 0010 1010
http://www.cheebi.de

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #10 am: 03. August 2007, 17:16 »
Ich seh eigentlich keinen Grund warum man die GDT überhaupt zur Laufzeit erweitern muss (wenn man mal SMP außen vor lässt). Aber ansonsten würd ich die Bereiche einfach 0 setzen und das GDTR nicht aktualisieren. Kann ja im Prinzip nichts passieren, da das present-bit auf 0 gesetzt ist.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

 

Einloggen