Autor Thema: GPF bei neuladen von SS  (Gelesen 4647 mal)

Thunder

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« am: 22. September 2010, 09:44 »
Hallo,

mich quält schon längere Zeit ein Problem, das mit dem Wechsel nach Ring 3 zu tun hat.
Ich initialisiere den TSS-Deskriptor in der GDT und den Speicherbereich in dem die Daten des TSS liegen. Das funktioniert.
void init_tss(void){
    DWORD pt=(DWORD) &tss; // tss ist die Struktur die ich global definiert habe
    void *ept=tss_entry; // hat die Adresse des TSS-Eintrags in der GDT
    *((BYTE*) ept+5) = (pt << 16) & 0xFF;
    *((BYTE*) ept+6) = (pt << 24) & 0xFF;
    *((WORD*) ept+2) = pt & 0xFFFF;
    tss.esp0=(DWORD) task_stack+STACKSIZE;
    tss.ss0=0x10;
    tss.ds=0x23;
    tss.ss=tss.ds; tss.es=tss.ds; tss.fs=tss.ds; tss.gs=tss.ds;
    tss.iopb=0;
    tss.eax=0; tss.ebx=0; tss.ecx=0; tss.edx=0; tss.esi=0; tss.edi=0;
    tss.ebp=0x300000;
    tss.esp=tss.ebp;
   
    set_tss();
}

inline void set_tss(void){
    asm volatile(    "mov $0x28, %ax\n"
                    "ltr %ax\n");
}

//aus der GDT:
    dw 0x68
    dw 0x0
    db 0x0,0xE9
    db 0x0,0x0
Der TSS-Deskriptor in der GDT ist an Position 6, wenn man bei 1 zu zählen beginnt und den Nulldeskriptor mitzählt.

Dann beginne ich mit dem Ringwechsel. Der Code dafür sieht so aus:
    asm volatile(    "mov $0x23, %ax\n"
                    "mov %ax,%ds\n"
                    "mov %ax,%es\n"
                    "mov %ax,%fs\n"
                    "mov %ax,%gs\n"
                    "mov %ax,%ss\n"
                    "ljmp $0x1B, $.152\n"
                    ".152:\n"
                    );

Doch bei der Zeile "mov %ax,%ss" bekomme ich einen General Protection Fault. Redscreen sagt:
Zitat
EXCEPTION 13     ERRORCODE 32
EAX 2097187     EBX 1073180
ECX 23     EDX 1208320
EIP 1050545     CS 8
ESP 1073140    SS 1052995
DS 35     ES 35
FS 35     GS 35

Die Einträge in meine GDT sind in folgender Reihenfolge:
 - Nulldeskriptor
 - Kernel-Code
 - Kernel-Daten
 - User-Code
 - User-Daten
 - TSS

Hoffe ihr könnt mir helfen.

mfg Thunder

PS: ich habe auch schon Mal selber in der Intel-Doku nachgeschaut, aber dort steht, dass Fehler mit dem SS nur passieren, wenn ich ein Codesegment hineinlade, was ich nicht tue.

Programm Noob

  • Gast
Gespeichert
« Antwort #1 am: 22. September 2010, 10:05 »
Mit deinem ASM Code wechselst du normalerweise nicht nach ring3. Ring 3 sollte dein mulitasking machen.

Am besten gibst du uns mal einen Link zum SVN/GIT Repo oder zu ner gepackten datei mit deinem ganzem Code.Dann kann man bedser gucken worans liegt.

Programm Noob

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 22. September 2010, 10:45 »
Du kannst per jmp keinen Ringwechsel durchführen, wenn ich das grad richtig sehe. Du kannst zwar in ein anderes Codesegment springen, es muss aber die gleiche Privilegstufe haben.

Aber soweit kommt der Code ja gar nicht. Das Problem ist, dass du ein Ring-3-ss laden willst, obwohl dein cs im Moment Ring 0 ist. Das heißt, du hast RPL != CPL und das gibt einen #GP. (Kannst du beispielsweise bei der Beschreibung von mov im Intel-Manual nachlesen, aber sicher auch irgendwo in Teil 3)

Für einen Ringwechsel nimmst du am besten iret, wie das auch in allen Tutorials beschrieben sein dürfte. Damit kannst du in ein Codesegment einer anderen Privilegstufe springen, und cs und ss werden gleichzeitig neugeladen, so dass sie immer konsistent sind.

@Noob: Meinst du wirklich, du könntest helfen, wenn du den Code hättest, wenn du es so nicht siehst?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Thunder

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 22. September 2010, 11:35 »
Danke taljeth, ich schaue mir das mit iret nochmal an - ich verwende nämlich (im Moment) nur Singletasking und dachte, dass ich es dafür nicht brauche.

mfg Thunder

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 22. September 2010, 11:51 »
Ohne Interrupts kommt auch ein Singletaskingsystem nicht aus, insofern brauchst du diesen Code sowieso. Das einzige, was du dir sparen kannst, ist der Scheduler, weil du keine Tasks wechselst (außer beim Starten und Beenden eines Programms natürlich).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen