Nicht behebbarer Prozessorfehler beim Wechsel in P-Mode
-
Hallo und Guten Abend..
Das umschalten in den PMode und das beschreiben des Videospeichers klappt schon ganz gut...
mein letztes Problem ist das zurückschalten in den RMode.
Herr Meßmer und Herr Tischer schreiben daß das Löschen des Bit 0 von CR0 dafür reicht. Ich habe dazu auch am Anfang CS gesichert und nach dem löschen von CR0 wieder geladen. Außer einem blinkenden Courser erhalte ich aber keine Reaktion mehr vom System. (Aber auch keinen Prozessorfehler :-))Wie komme ich "sauber" zurück?
Mein Programmcode ist im ersten Posting.Nicky
-
mov eax, cr0 ; Umschalten zum Real Mode xor eax, eax ; Bit 0 löschen mov cr0, eax ;
Warum speicherst du cr0 im Register eax, das du dann ohnehin leerst?
-
Die erste Zeile könnte ich weglassen.. stimmt..
Hab noch kein Programm geschrieben das größer als 4Kb ist.. an einer Zeile mehr stör ich mich erstmal nicht so
Gruß, Nicky
-
Mit oder ohne Zeile heißt das allerdings, dass cr0 id. 0 ist. Wenn du nur das erste Bit löschen willst:
mov eax, cr0 xor eax, 1 mov cr0, eax
Edit: Oder noch schneller mit
mov eax, cr0 dec al mov cr0, eax
unter der Annahme, dass es vorher 1 war.
-
Ich hab mich damit nochnicht rum geärgert.
Würde aber als LeadIn zumindest ein Pusha spendieren.
Ev. noch das SS extra speichern.
Entsprechend als LeaOut SS zurück und Popa
-
Ich habe mir das Listing nun mal etwas näher angeschaut.
Dort wird ja gar nicht der NMI deaktiviert.Routine zum Wechseln vom RM in den 16 Bit-Unrealmode(MASM-Syntax):
START: cli ; Software-Interrupts ausschalten in al, 70h ; Über CMOS-Baustein auch or al, 80h ; die NMIS abschalten out 70h, al call ESEG ; Segmente erweitern auf 32 Bit in al, 70h ; NMIs wieder einschalten and al, 7Fh out 70h, al sti ; Software-Interrupts einschalten ;---------------------------------------------------------------------------- ; GDT für den Protected Mode ;---------------------------------------------------------------------------- org START + ((($-START)/64)*64)+64 ; Code-Ausrichtung ;---------------------------------------------------------------------------- GDTZEIGER DW ? ; Länge der GDT DW ? ; Adresse low -Word:SEGMENTE DW ? ; Adresse high-Word:SEGMENTE DW 0 ; reserviert SEGMENTE DW 0 ; Bits: 0-15 Seg.länge(Bit0-15) DW 0 ; Bits: 0-15 Basis-Adresse Deskriptor-Table DB 0 ; Bits:16-23 Basis-Adresse Deskriptor-Table DB 0 ; Bits: 0- 7 Zugriffsrechte DB 0 ; Bits: 0- 3 Seg.länge(Bit16-19)/Bit7:1=4KByte/0=1Byte DB 0 ; Bits:24-31 Basis-Adresse Deskriptor-Table ;-------------------------------------------- Selektor Segmente DW 0FFFFh ; Segmentlänge Bits: 0-15 DW 0 ; Adresse low Bits: 0-15 08h Code (CS) DB 0 ; Adresse high Bits:16-23 DB 9Ah ; Zugriffsrechte DB 0 ; Seg.Länge Bits:16-19 im Bit0-3 /Bit7:1=4KByte/0=1Byte DB 0 ; Seg.Adresse Bits:24-31 ;--------------------------------------------------- Selektor Segmente DW 0FFFFh ; Segmentlänge Bits: 0-15 DW 0 ; Adresse low Bits: 0-15 10h (SS) DB 0 ; Adresse high Bits:16-23 DB 92h ; Zugriffsrechte DB 0 ; Seg.Länge Bits:16-19 im Bit0-3 /Bit7:1=4KByte/0=1Byte DB 0 ; Seg.Adresse Bits:24-31 ;--------------------------------------------------- Selektor Segmente DW 0FFFFh ; Segmentlänge Bits: 0-15 DW 0 ; Seg.Adresse Bits: 0-15 18h (DS,ES,FS,GS) DB 0 ; Seg.Adresse Bits:16-23 DB 92h ; Zugriffsrechte DB 0FFh ; Seg.Länge Bits:16-19 im Bit0-3//Bit7:1=4KByte/0=1Byte DB 0FFh ; Seg.Adresse Bits:24-31 ;--------------------------------------------------- SEGMENTE_END label WORD Gdt_Groesse equ (OFFSET SEGMENTE_END - SEGMENTE -1) ;---------------------------------------------------------------------------- ; Setzt für das DS,ES,FS,GS-Register eine neue Segmentlänge von 00FFFFFFh. ; Dazu wird in den Protected Mode umgeschaltet. ;---------------------------------------------------------------------------- org START + ((($-START)/32)*32)+32 ; Code-Ausrichtung ;---------------------------------------------------------------------------- ESEG: xor eax, eax mov ax, cs mov ds, ax shl eax, 4 ; EAX ist nun physikalische mov ebx, eax ; Segmentstartadresse mov WORD PTR[SEGMENTE+0Ah], ax ; in den Deskriptoren mov WORD PTR[SEGMENTE+12h], ax ; für CS ror eax, 10h ; und SS in der mov BYTE PTR[SEGMENTE+0Ch], al ; GDT abspeichern mov BYTE PTR[SEGMENTE+14h], al xor eax, eax ; EAX auf null mov ax, OFFSET SEGMENTE ; 16-Bit-Offset add ebx, eax ; GDT-Adresse im mov WORD PTR[GDTZEIGER], Gdt_Groesse ; GDT-Deskriptor mov DWORD PTR[GDTZEIGER+2], ebx pushf ; Flags retten lgdt FWORD PTR[GDTZEIGER] ; GDT laden mov dx, ss ; SS retten mov eax, cr0 ; Steuerwort 0 nach EAX or al, 1 ; Protected Mode ein mov cr0, eax ; im Steuerwort ; Prefetch-Puffer löschen DB 0EAh ; die folgenden Zeilen DW (OFFSET PMODE) ; erzeugen: DW 8 ; JMP FAR CS:PMODE ;------------------------------------------------ org START + ((($-START)/32)*32)+32 ; Code-Ausrichtung ;------------------------------------------------ PMODE: mov ax, 10h ; SS-Selektor auf 64 mov ss, ax ; KByte begrenzen mov ax, 18h mov ds, ax ; DS,ES,FS,GS-Selektoren ; mov es, ax ; mov fs, ax ; mov gs, ax mov eax, cr0 ; Steuerwort 0 nach EAX and eax, not 1 ; Protected Mode aus mov cr0, eax ; im Steuerwort ; Prefetch-Puffer löschen DB 0EAh ; Die folgenden Zeilen er- DW (OFFSET RMODE) ; zeugen das Kommando AKTSEG DW (SEG RMODE) ; JMP FAR CS:RMODE ;------------------------------------------------ org START + ((($-START)/32)*32)+32 ; Code-Ausrichtung ;------------------------------------------------ RMODE: mov ss, dx ; SS zurueck popf ; Flags holen ;---------------------------------------------------------------------------- ; Schaltet das 21. Adreßbit des Prozessors ein. ;---------------------------------------------------------------------------- BIT_FREI: call W_8042 jnz BACK mov al, 0D1h out 64h, al call W_8042 jnz BACK mov al, 0DFh out 60h, al ;----------------------------------------------------------- ; Wartet darauf, bis der 8042 bereit ist. ;------------------------------------------------------------ W_8042: xor cx, cx STATUS: in al, 64h and al, 2 loopnz STATUS BACK: ret
-
Das mit dem NMI hab ich auch nicht.
Bringt aber anscheinend kein Problem.
Ich hatte da bisher keine Sorgen wegen.Ausserdem gebe ich zu bedenken das NMI ja Nicht Maskierbarer Interrupt heist.
-
Hallo zusammen,
ich habe den Fehler gefunden.
Hier der alte Code:
cli lgdt [gdtr] ;Laden der GDT via GDTR mov eax, cr0 ;Springe zum P-Mode or eax, 1 ; setze Bit 0 auf 1 mov cr0, eax ; jmp 0x8:pmode pmode: mov ax, 0x10 mov ds, ax ; GDT'S zuordnen mov ss, ax mov es, ax mov fs, ax mov gs, ax mov eax, cr0 ; Umschalten zum Real Mode xor eax, eax ; Bit 0 löschen mov cr0, eax ; jmp rmode rmode: mov ax, word [segm] mov cs, ax mov ds, ax sti
und hier mein neuer
push ds cli lgdt [gdtr] ;Laden der GDT via GDTR mov eax, cr0 ;Springe zum P-Mode or eax, 1 ; setze Bit 0 auf 1 mov cr0, eax ; jmp 0x8:pmode pmode: mov ax, 18h ; GDT'S zuordnen mov es, ax mov fs, ax mov gs, ax xor eax, eax xor eax, eax mov eax, cr0 ; Umschalten zum Real Mode and al, 11111110b ; Bit 0 löschen mov cr0, eax ; jmp rmode rmode: pop ds sti
Im Grunde brauche ich ja nur die Segmentregister ES, FS und GS auf 32Bit zu erweitern. DS und CS bleiben unverändert.
So funktioniert es jetzt bei mir.Ich probier dann mal weiter.
Gruß und Danke
Nicky
-
gargyle schrieb:
Das mit dem NMI hab ich auch nicht.
Bringt aber anscheinend kein Problem.
Ich hatte da bisher keine Sorgen wegen.Aha. Ist wohl auch nur wenn ein Speicherfehler auftritt?
Ausserdem gebe ich zu bedenken das NMI ja Nicht Maskierbarer Interrupt heist.
Nicht Maskierbar bedeutet aber nur, dass der NMI sich weder über den PIC1(PORT 20h-003Fh), oder PIC2(Port 00A0h-00AFh) selektiv maskieren läßt, noch durch die cli/sti-Befelhle beeinflusst wird, die sonst alle maskierbaren Interrupts generell sperren/freigeben, aber nicht den NMI.
- Generelle Interrupt-Maskierung betrifft alle maskierbaren Interrupts
- Selektive Interrupt-Maskierung betrifft nur den gewählten Interrupt
- Maskenbits (je Interrupt) werden üblicherweise zu Maskenregistern zusammengefasst
- Neben der Interrupt-Maskierung werden üblicherweise auch Interrupt-Prioritäten verwaltet (konfigurierbar)Bitfields for PIC output control word OCW1: Bit(s) Description (Table P0014) 7 disable IRQ7 (parallel printer interrupt) 6 disable IRQ6 (diskette interrupt) 5 disable IRQ5 (fixed disk interrupt) 4 disable IRQ4 (serial port 1 interrupt) 3 disable IRQ3 (serial port 2 interrupt) 2 disable IRQ2 (video interrupt) 1 disable IRQ1 (keyboard, mouse, RTC interrupt) 0 disable IRQ0 (timer interrupt) SeeAlso: #P0015,#P0016,#P0418 Bitfields for PIC2 output control word OCW1: Bit(s) Description (Table P0418) 7 disable IRQ15 (reserved) 6 disable IRQ14 (fixed disk interrupt) 5 disable IRQ13 (coprocessor exception interrupt) 4 disable IRQ12 (mouse interrupt) 3 disable IRQ11 (reserved) 2 disable IRQ10 (reserved) 1 disable IRQ9 (redirect cascade) 0 disable IRQ8 (real-time clock interrupt) SeeAlso: #P0014
0070 -W CMOS RAM index register port (ISA, EISA) bit 7 = 1 NMI disabled from reaching CPU = 0 NMI enabled Note: any write to PORT 0070h should be followed by an action to PORT 0071h or the RTC wil be left in an unknown state.
Bei mir ist auch noch nie ein unbekannter Zustand im RTC vorgekommen.
Für diesen Fall wäre es dann wohl besser einen Zugriff auf Port 71h zu machen:cli ; Software-Interrupts ausschalten in al, 70h ; Über CMOS-Baustein auch or al, 80h ; die NMIS abschalten out 70h, al [b]in al, 71h[/b] call ESEG ; Segmente erweitern auf 32 Bit in al, 70h ; NMIs wieder einschalten and al, 7Fh out 70h, al [b]in al, 71h[/b] sti ; Software-Interrupts einschalten
Dirk
-
supernicky schrieb:
Hallo zusammen,
ich habe den Fehler gefunden.
Prima.
Im Grunde brauche ich ja nur die Segmentregister ES, FS und GS auf 32Bit zu erweitern. DS und CS bleiben unverändert.
So funktioniert es jetzt bei mir.Ich probier dann mal weiter.
Gruß und Danke
Nicky
Ich erweitere meistens nur DS, weil dann seltener Segment-Override Prefixe benötigt werden.
(Ausnahme: Wenn (E)BP oder (E)SP als Adressregister verwendet wird, dann wird ggf. ein Segment-Override Prefix mit DS nötig, wenn darüber adressiert werden soll.
Das läßt sich aber oft vermeiden, wenn man diese beiden Offsetregister nicht zum Adressieren verwendet, wenn man über DS adressieren möchte.)Um über FS und GS zu adressieren braucht man aber immer ein Segment-Override Prefix.
Wenn DS erweitert wurde, dann kann DS auch weiterhin auf unseren Datenbereich zeigen und alle linearen Adressen lassen sich relativ dazu berechnen und darauf anpassen.
Dirk