Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - nukthem

Seiten: [1]
1
Lowlevel-Coding / Problem mit der IDT
« am: 02. March 2006, 18:54 »
Hallo!

Ja du hast wahrscheinlich im IDT Deskriptor einen Fehler gemacht. Ich kann im ausführbaren Code keinen erkennen.
Das dritte WORD beim IDT Deskriptor muss folgendes Format haben:

|P|DPL|0|Typ|0|0|0|DWord-Count|

P (Present) muss 1 sein, wenn der Interrupthandler nicht ausgelagert ist
DPL (Privilegierungsstufe) sollte 00 sein
Typ sollte 1110 für ein Interrupt-Gate sein
DWord-Count brauchst du wahrscheinlich nicht und sollte deshalb 00000 sein

Um es nochmal auf den Punkt zu bringen sollte die dritte Zeile nach "idt_DIV_ERROR:" so aussehen:
dw 1000111000000000b
Nun solltest du problemlos deine Exception bekommen ^^

Außerdem solltest du nach dem Label "PMODE:" als erstes das Datensegment aktualisieren und dann erst Code Segmentstartadresse auf 0 setzen:
mov ax, 8
mov ds, ax
mov WORD [gdt_CODE_Desc+2], 0
...
...

Denn damit verhinderst du, dass die Nullen ganzwoanders in den Speicher geschrieben werden, weil in ds ja noch das Realmode Segment steht und nicht der Deskriptor für den P-Mode.

PS: Du solltest auf keinen Fall Code- und Datensegment über den kompletten virtuellen Adreßraum von 4 GB!!!! gehen lassen. Denn erstens hast du wahrscheinlich gar keine 4GB zur verfügung und zweitens sollte das Codesegment auch wirklich nur den Code enthalten den man ausführen will. Sonst kann es durch Programmfehler auch passieren, dass nichtausführbarer Code ausgeführt wird, wodurch der Prozessor abstürzt.
2
Lowlevel-Coding / Virtual-8086-Mode
« am: 01. March 2006, 01:31 »
Vielen Dank für die Antwort.
Es waren die Segmente. Ich hatte sie nicht auf Realmode eingestellt.
 :oops:

Doch nun eröffnet sich für mich gleich die nächste Frage.
Um die Interrupts im Virtual86 Task zu handeln, habe ich IOPL auf 0 eingestellt, damit bei int, pushf, popf, iret, cli, sti eine General Protection Exception ausgelöst wird.
Dann schaue ich nach, welcher der genannten Befehle die Exception ausgelöst hat und emuliere diesen.
Z.B. bei "int 10h" speichere ich die Rüchsprungadresse auf dem V86-Stack und hole mir in der Realmode Interruptvektortabelle die Adresse vom Interrupt-Handler.
Um diesen dann auszuführen sieht Intel vor dies durch ein iret zu bewerkstelligen.
Leider funktioniert das bei mir nur in BOCHS. Auf dem echten PC und bei MS Virtual PC löst der iret Befehl für den Rücksprung zum V86 Interrupt-Handler wiederum eine General Protection Exception aus.

Ich poste mal einen Teil meines (teilweise) kommentierten Exceptionhandlers für General Protection Exception:
(CONST_FIRSTMB_SEGMENT beinhaltet einen Selektor, der als pseudo Datensegment auf das erste Megabyte des Arbeitsspeichers zeigt; Physikalische Adresse 0x0 bis 0x100000)

pop ecx ; Error Code
pop ecx ; eip
pop ebx ; cs
push ebx
push ecx

mov ax, CONST_FIRSTMB_SEGMENT
mov es, ax
shl ebx, 4
add ebx, ecx
mov edi, ebx
mov bx, [es:edi]

mov ax, bx
and ax, 00ffh
cmp ax, 00cdh
jne NEAR no_v86_int
shr bx, 8
shl bx, 2
mov di, bx
mov ax, [es:edi] ; ax = offset
mov bx, [es:edi+2] ; bx = segment
mov bp, ax

pop eax ; ip
pop ecx ; cs
pop edx ; FLAG
pop edi ; sp
pop esi ; ss

push bp ; save offset of int handler
push bx ; save segment of int handler
push eax
push ecx
push edx

mov bx, si
mov ax, di
shl bx, 4
add bx, ax
xor edi, edi
mov di, bx
mov ax, CONST_FIRSTMB_SEGMENT
mov es, ax ; es:edi pointer to stack of v86 task
sub edi, 2
pop eax
mov [es:edi], ax ; push FLAG on v86 stack
mov ecx, eax
sub edi, 2
pop eax
mov [es:edi], ax ; push cs on v86 stack
sub edi, 2
pop eax
mov [es:edi], ax ; push ip on v86 stack
shl esi, 4
sub edi, esi ; edi = new sp
shr esi, 4

pop bx ; segment of int handler
pop ax ; offset of int handler

push esi ; ss
push edi ; sp
push ecx ; FLAG
and ebx, 0000ffffh
push ebx
and eax, 0000ffffh
push eax

iret


Mir ist ein Rätsel warum BOCHS den iret Befehl ohne erneute Exception ausführt aber das in der Realität nicht so ist. Aber das mit BOCHS ist ja sowieso eine eigene Geschichte.  :roll:
Das VM-Bit im gepushten (E)FLAG ist auf jeden Fall gesetzt, sodas auch gewähleistet ist, dass wieder in den V86-Mode umgeschaltet wird.
3
Lowlevel-Coding / Virtual-8086-Mode
« am: 26. February 2006, 13:09 »
Hallo!
Ich habe es bereits erfolgreich hinbekommen "normale" Task-Switches via TSS und Jump auf das Task-Gate durchzuführen.
Ich möchte aber zeitweise 8086 Code ausführen, weshalb ich den Virtual-8086-Modus brauche. Intel sagt, man schaltet in den Virual-8086-Mode, indem man das VM-Bit im EFLAG-Image des TSS für den neuen Task setzt. Dies habe ich wie folgt gemacht:

pushfd
pop eax
or eax, 00020000h
mov [es:36], eax ; bei es:36 befindet sich das EFLAG-Image

Wenn ich nun weiter unten in meinem Code den Task-Switch durchführe, bekomme ich eine "General Protection Exception".
Setze ich das VM-Bit im EFLAG-Image nicht, wird der Task ordnungsgemäß geswitcht und es kommt keine Exception.
Kann mir bitte jemand sagen, was ich falsch mache bzw. wie ich richtig in den Virtual-8086-Mode schalte?

PS: Ich bin mir 100%-ig sicher, dass die "General Protection Exception" beim Task-Switch kommt, und nicht schon irgendwo davor.
Seiten: [1]

Einloggen