pmode die n-te
-
Ein sorry vorweg, ich wette das Thema hängt euch langsam zum Hals raus
-
aber leider hat die Suche mir auch nicht weitergeholfen...
Ich leide beim Versuch einen Code hinzukriegen, der ordentlich in den pmode schaltet, unter den ständig anderen und immer unerklärlicheren Fehlermeldungen von Bochs....Dabei gibt es mir folgende Fehlermeldung aus:
00000485357p[CPU ] >>PANIC<< jump_protected: tss_selector.ti=1 00000485357i[SYS ] Last time is 1076004264 00000485357i[CPU ] protected mode 00000485357i[CPU ] CS.d_b = 16 bit 00000485357i[CPU ] SS.d_b = 16 bit
Nach meinem eher bescheidenem "Verständnis" des pmode dürfte so eine Meldung jedoch niemals zurückgegeben werden, da ich keinerlei Gates und ähnliches anlege, lediglich einfache Deskriptoren.
Durch auskommentieren habe ich herausgefunden, dass sich der Fehler auf den jmp bezieht, der den prefetch - queue leeren soll - was mir jedoch auch nicht großartig weiterhilft, aber vieleicht ja euch?!?
Hier mein Nasmcode:
[BITS 16] ; We need 16-bit intructions for Real mode [ORG 0x7C00] ; The BIOS loads the boot sector into memory location 0x7C00 start: ; Codesegment Basisadresse in gdt_code und gdt_data eintragen xor ebx,ebx mov bx,ds ; BX=segment shl ebx,4 ; BX="linear" address of segment base mov eax,ebx mov [gdt_code + 2],ax ; set base address of 32-bit segments mov [gdt_data + 2],ax shr eax,16 mov [gdt_code + 4],al mov [gdt_data + 4],al mov [gdt_code + 7],ah mov [gdt_data + 7],ah ;gdt_base eintragen xor ebx,ebx mov bx,cs shl ebx,4 mov eax,ebx lea eax,[ebx + gdt] ; EAX=PHYSICAL address of gdt mov [gdt_desc+2],eax mov eax, 0x18 mov [gdt_desc], eax ;Limit setzen cli lgdt [gdt_desc] ; Load the GDT descriptor mov eax, cr0 ; Copy the contents of CR0 into EAX or eax, 1 ; Set bit 0 mov cr0, eax ; Copy the contents of EAX into CR0 db 0x0EA dw pmode dw 0x08 [BITS 32] ; We now need 32-bit instructions pmode: mov eax, 0x10 ; Move a valid data segment into the data segment register mov ds, eax mov ss, eax mov es,eax mov fs, eax ;mov byte [ds:0B8000h], 'P' ; Move the ASCII-code of 'P' into first video memory ;mov byte [ds:0B8001h], 1Bh ; Assign a color code gdt: gdt_null: ; Null Segment times 8 db 0 gdt_code: dw 0xFFFF dw 0 db 0 db 10011010 db 11000000 db 0 gdt_data: dw 0xFFFF dw 0 db 0 db 10010110 db 11000000 db 0 gdt_end: ; Used to calculate the size of the GDT gdt_desc: ; The GDT descriptor dw 0 ; Limit (size) dd 0 ; Address of the GDT times 510-($-$$) db 0 dw 0AA55h
Wird irgendwer aus der Fehlermeldung in dem Zusammenhang schlau?!? Ich verstehe jedenfalls nicht, wie das kommt, das er so ein Deskriptor fürn Tss-gate hält.
-
Hi.
An deinem Code stimmt tatsaechlich was nicht. :p
Ich werde das mal von oben nach unten durchgehen und Optimierungsvorschlaege sowie Fehlerbeschreibungen auflisten:Erstmal kannst du dir die Codezeilen 10 bis 32 komplett schenken.
Die physikalischen Speicheradressen in deinem Bootblock sind immer die selben, also brauchst du sie nicht jedes mal neu berechnen zu lassen.
Da die Basisadressen vom Code und Datensegment eigentlich schon richtig eingetragen sind (0), reicht es, wenn du einfach og. Codezeilen loeschst.
Lediglich die Daten bei "gdt_desc:" muesstest du dann noch aendern.
Also statt 0, gleich die richtige Groesse der GDT (die ist schliesslich auch bekannt) und die Basisadresse eintragen (das waere hier einfach gdt_desc).Mal abgesehen davon, dass dieser Code eh ueberfluessig ist, werde ich ihn trotzdem nochmal durchgehen:
Wieso schiebst du in Zeile 14 ebx nach eax? Diese Codekonstruktion macht IMHO keinen Sinn.
Das gleiche eigentlich auch in Zeile 28.
In Zeile 29 haette es dann auch ein "lea ebx, [ebx + gdt]" oder ein einfaches "add ebx, gdt" getan.In den Zeilen 31/32 liegt dann vermutlich der Fehler, der deinen Code crashen laesst: Du schreibst eax (bekanntlich 32Bit lang) in das nur 16Bit lange "Limit"-Feld von gdtr, und zwar nachdem du dahinter bereits die Basisadresse eingetragen hast. => Die Basisadresse wird auf 0x00000000 zurueckgesetzt.
In den Zeilen 49 bis 52 versuchst du ein 32Bit-Register in 16Bit lange Segmentregister zu stauchen?
Die auskommentierten Zeilen 55/56 wuerden in deinem urspruenglichen Code wohl auch nicht zum Gewuenschten Erebnis fuehren, da dein Datensegment bei der Basisadresse von ds beginnt und nicht bei 0.
Und zum Schluss noch zu den Descriptoren selbst:
Wieso ist dein Datensegment nach unten erweiterbar, wenn es bei 0 anfaengt? Das macht keinen Sinn. Benutze hier besser ein normales Datensegment (Typ 001).So, ich hoffe, dass ich nichts vergessen habe.