Autor Thema: iret problem (triple fault)  (Gelesen 1849 mal)

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« am: 23. August 2008, 15:05 »
Hi
Momentan beschäftige ich mich mit multitasking, und möchte ertsmal testweise ein einzigen prozess starten. Dazu legen ich eine neue PD an, und mappe den speicher so, wie ich ihn brauche.
Alles liegt an der adresse, wo es hingehört.
Dann lade ich die neue PD und möchte in den code des prozesses springen. Da ich später taskwechsel per iret machen muss (damit mir keine flags verloren gehen) wollte ich auch für diesen test iret verwenden...
Leider endet das in einem triple fault :(

Testweise habe ich es dann mal mit ret versucht, und das funktioniert...
Warum funktioniert iret nicht?

aufbau mit ret
; *PD wechseln, und stack initialisieren*

mov eax, 0x00000002 ; Die flags
push eax
popf
mov eax, 0x00003000 ; Hier liegt der code
push eax
ret ; und prozess starten, Funktioniert

Der aufbau zum testen des stackinhaltes (in diesem fall des eflags-wertes)
; *PD wechseln, und stack initialisieren*

   pop eax ;eip    (0x00003000) > OK
   pop eax ;cs     (0x00000008) > OK
   pop eax ;eflags (0x00000002) > OK
   jmp fncprint
  hlt
;iret

Und so mach ichs mit iret
; *PD wechseln, und stack initialisieren*

iret

Wie man sieht, sind die werte auf dem stack korrect, und wenn ich manuell die flags ändere, und dann in den code springe funktionierts auch, nur mit iret gets nicht :(

qemu: fatal: triple fault
EAX=e0000011 EBX=00010ff4 ECX=00c02007 EDX=000003f8
ESI=009fff8f EDI=00a0d800 EBP=009fffa8 ESP=00010ff4
EIP=00a06948 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00012101 0000001f
IDT=     00a0f0d4 0000018f
CR0=e0000011 CR2=00012109 CR3=00c02007 CR4=00000010
CCS=00000010 CCD=e0000011 CCO=LOGICL 

Wo liegt das problem?

ps.: Ich habe interrupts deaktiviert. Aber wenn ich sie aktiviere, ändert sich nichts.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 23. August 2008, 16:24 »
Lass dir bei qemu mal (mit -d int) die Interrupts/Exceptions ins Log schreiben und schau dir an, welche da zuerst fliegt. Das gleiche kannst du natürlich auch in bochs machen...
Ich sehe übrigens nicht wo du das Page-Directory wechselst. Das steht zwar im Kommentar aber ist im Code nicht vorhanden...
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

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #2 am: 23. August 2008, 16:58 »
Ich schätze mal, das es erst ab hier interessant wird...
check_exception old: ffffffff new e
    17: v=0e e=0000 i=0 cpl=0 IP=0008:00a06949 pc=00a06949 SP=0010:00010ff4 CR2=00012109
EAX=e0000011 EBX=00010ff4 ECX=00c02007 EDX=000003f8
ESI=009fff8f EDI=00a0d800 EBP=009fffa8 ESP=00010ff4
EIP=00a06949 EFL=00000202 [-------] CPL=0 II=1 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00012101 0000001f
IDT=     00a0f0d4 0000018f
CR0=e0000011 CR2=00012109 CR3=00c02007 CR4=00000010
CCS=00000010 CCD=e0000011 CCO=LOGICL
check_exception old: e new e
    18: v=08 e=0000 i=0 cpl=0 IP=0008:00a06949 pc=00a06949 SP=0010:00010ff4 EAX=e0000011
EAX=e0000011 EBX=00010ff4 ECX=00c02007 EDX=000003f8
ESI=009fff8f EDI=00a0d800 EBP=009fffa8 ESP=00010ff4
EIP=00a06949 EFL=00000202 [-------] CPL=0 II=1 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00012101 0000001f
IDT=     00a0f0d4 0000018f
CR0=e0000011 CR2=00012109 CR3=00c02007 CR4=00000010
CCS=00000010 CCD=e0000011 CCO=LOGICL
check_exception old: 8 new e
qemu: fatal: triple fault
EAX=e0000011 EBX=00010ff4 ECX=00c02007 EDX=000003f8
ESI=009fff8f EDI=00a0d800 EBP=009fffa8 ESP=00010ff4
EIP=00a06949 EFL=00000202 [-------] CPL=0 II=1 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300
CS =0008 00000000 ffffffff 00cf9a00
SS =0010 00000000 ffffffff 00cf9300
DS =0010 00000000 ffffffff 00cf9300
FS =0010 00000000 ffffffff 00cf9300
GS =0010 00000000 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0000 00000000 0000ffff 00008000
GDT=     00012101 0000001f
IDT=     00a0f0d4 0000018f
CR0=e0000011 CR2=00012109 CR3=00c02007 CR4=00000010
CCS=00000010 CCD=e0000011 CCO=LOGICL
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=9000000000000000 4000 FPR7=8000000000000000 4000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000

und hier der anfang des codes... Wobei hier eigentlich alles stimmt... zumindest passen die werte in cr0 und cr3
_ZN12multitasking9StartTaskEPN11processlist7processE:



cli

    mov eax, dword [esp+4]      ;### proc
    mov ebx, dword [eax+4*2]    ;### proc.esp
    mov ecx, dword [eax+4*13]   ;### proc.PageDirectory

;Paging deaktivieren
    mov  eax, cr0
    and  eax, 0x7FFFFFFF
    mov  cr0, eax

;neue virtueller speicher
    mov eax, ecx ;hier ist das PD drinne
    mov cr3, eax

;paging aktivieren
    mov  eax, cr0
    or   eax, 0x80000000
    mov  cr0, eax

    mov esp, ebx    ; esp setzen
                    ; so siehts jetzt auf dem stack aus: eflags/cs/eip/ (oben nach unten)

;... jetzt kommt der ret, bzw iret - teil

Was ich oben noch vergessen zu sangen habe: cs des prozesses ist gleich dem cs des kernels.
Der prozess läuft mit kernelrechten...
« Letzte Änderung: 23. August 2008, 17:12 von RedEagle »

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 23. August 2008, 18:38 »
Hi,

Wenn du das iret testweise ausführts, tust du das auch während eines Interrupts?

Außerdem solltest du eigentlich funktionierende Exceptionhandler haben.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #4 am: 23. August 2008, 19:26 »
Du kriegst einen Pagefault wegen fehlender Page beim Zugriff auf den 1ten Deskriptor, da CR2=00012109 beim Pagefault und die GDT bei 12101 liegt.
btw. beim Wechseln von Cr3 brauchst du nicht das Paging deaktivieren.
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

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #5 am: 23. August 2008, 20:55 »
[..]
Wenn du das iret testweise ausführts, tust du das auch während eines Interrupts? [..]
Ja

[..] Außerdem solltest du eigentlich funktionierende Exceptionhandler haben.
Habe ich, versagt nur in diesem fall, weil s.u.

@bluecode: Stimmt, die GDT habe ich vergessen zu mappen. Und dass ich paging nicht deaktivieren muss war mir auch neu.

Vielen dank für die Hilfe.

 

Einloggen