warum komm ich im Bootsektor nicht in Pmode?
-
Hallo!
Ich will direkt mit meinem Bootsektor in Pmode schalten - ich verwende den selben Code wie ich sonst auch zum schalten verwende, nur muss ich eben die Adressen verändern, sind die irgendwie falsch?start: mov ax, 0x07c0 mov es, ax mov ds, ax cli mov ax, 0x4000 mov ss, ax mov sp, 0xffff sti mov eax, des_null add eax, 0x07c00 mov [global_table+GDTSTRUCT.base], eax xor eax,eax mov ax, 40h mov [global_table+GDTSTRUCT.limit], ax
Danke
Kevin
-
Achja, die Fehlermeldung is laut Bochs
00000541862e[CPU ] load_seg_reg: LDT invalid
00000541862p[CPU ] >>PANIC<< exception(): 3rd (13) exception with no resolution
-
Hi.
IMHO sagt dieses Stueck code ueberhaupt nichts aus - Da koennte ich nur mit wilden Vermutungen um mich werfen.
Poste mal die ganze Datei des Bootstraps.
-
Okay, here it is:
[BITS 16] [ORG 0] jmp start Fehler db 'An Error occured',13,10,0 reset db 'Diskette resetet',13,10,0 del db 'Kernel wurde geladen und wird nun ausgeführt',13,10,0 string db 'Reached the Pmode',13,10,0 struc GDTSTRUCT .limit: resw 1 .base: resd 1 endstruc global_table: istruc GDTSTRUCT at GDTSTRUCT.limit, dw 1 at GDTSTRUCT.base, dd 1 iend des_null dw 0000h dw 0000h db 00h db 00000000b db 00000000b db 0 des_code dw 9FFFh ;Größe 4096 Bytes entspr. 8 Sektoren dw 1 ;die ersten 5 Sektoren belassen und dann in den 6. schreiben db 1 db 10011010b ;Codesegment lesbar / ausführbar db 00000000b db 0 des_vram dw 4000h dw 8000h db 0Bh db 10010010b db 11000000b db 0 des_data dw 2000h dw 1 db 1 db 10010010b ;Datensegment lesbar / ausführbar db 11000000b db 0 message: lodsb or al,al jz done mov ah, 0Eh mov bx, 7 INT 10h jmp message done: retn hang: jmp hang error: mov si, Fehler call message jmp hang hlt ret start: mov ax, 0x07c0 mov es, ax mov ds, ax cli mov ax, 0x4000 mov ss, ax mov sp, 0xffff sti mov eax, des_null add eax, 0x07c00 mov [global_table+GDTSTRUCT.base], eax xor eax,eax mov ax, 40h mov [global_table+GDTSTRUCT.limit], ax ;Adresse des Codesegments in den Deskriptor eintragen mov eax, 0 mov ax, cs shl eax, 04h mov [des_code+2], ax shr eax, 10h mov [des_code+4], al mov [des_code+7], ah ;Adresse des Datensegments in den Deskriptor eintragen mov ax,ds shl eax, 4 mov [des_data+2], ax shr eax,10h mov [des_data+4], al mov [des_data+7], ah lgdt [global_table] cli mov eax,cr0 or eax,1 xor eax,eax mov eax, 0x00000001 mov cr0,eax db 0eah dw pmode dw 8 pmode: mov ax, 24 mov ds,ax mov ax, 16 mov es, ax mov si, string xor di,di mov di,(80*2)*24+(80-17)*2 xor ecx,ecx mov ecx, 17 showtext: mov al, [si] stosb inc si inc di loop showtext loop_end: jmp loop_end times 510-($-$$) db 0 dw 0xAA55
-
Oje... net falsch verstehen, aber das ist ja ein ganz schoenes Durcheinander.
Nagut, soweit ich das gesehen hab, liegts hauptsaechlich daran, dass Du dich mit der Einsprungsaddresse bei dem Jump zum PMode vertan hast...
Einfach 7C00 auf das Offset der Addresse addieren und es muesste laufen.db 0eah dw pmode+0x7C00 ;<== Hier! dw 8
Der 2. grobe Fehler, den ich jetzt noch loswerden muss ist, dass die Groesse der GDT falsch eingetragen wird. Die ist tatsaechlich nur halb so gross! (4 descriptoren macht 4*8=20 und nicht 40)
mov ax,0x0020 mov [global_table+GDTSTRUCT.limit], ax
Ansonsten sind da noch mehrere Unfeinheiten drin...
Sollte Interesse bestehen kann ich mich darueber auch noch mal in aller Ausfuehrlichkeit auslassen
-
Deine erste Bemängelung ist der Fehler, vielen Dank!
Aber wenn du wilslt kannst du sagen was noch so falsch ist
-
Ok, handelt sich groesstenteils um Kleinigkeiten, sollte aber dennoch so in einem halbwegs ernstgemeinten OS-Versuch nicht vorkommen...
sp sollte gerade Werte enthalten.
original: mov sp, 0xffff besser: mov sp,0xfffe
Ist nicht unbedingt falsch, aber es waere guenstiger, die Variablen gleich
mit sinnvollen Werten zu initialisieren, als dann spaeter bekannte
fixe Werte erst zusammenrechnen und in den Speicher schreiben zu lassen...Also - dieses Stueck code hier rausschmeissen:
mov eax, des_null add eax, 0x07c00 mov [global_table+GDTSTRUCT.base], eax xor eax,eax mov ax, 40h mov [global_table+GDTSTRUCT.limit], ax
und dafuer bei den Variablen folgende Werte einsetzen:
global_table: istruc GDTSTRUCT at GDTSTRUCT.limit, dw 0x0020 at GDTSTRUCT.base, dd 0x00007C00+des_null iend
Das gleiche gilt uebrigens fuer den Datensegment descriptor...
Von dem kennst Du die BaseAddr auch schon vor der Laufzeit. (Du weist ds schliesslich selbst zu Beginn des Programms einen fixen Wert zu)Zu dem code oben 2 Anmerkungen:
Es ist nicht sinnvoll, erst eax via xor zu loeschen um in der naechsten Zeile ax mit einem fixen Wert zu fuellen, nur um selbigen dann ueber ax in den Speicher zu schreiben.
fuer sowas haette auch einfachmov word [global_table+GDTSRUCT.limit],0x0020
gelangt.
mov eax,cr0 or eax,1 xor eax,eax mov eax, 0x00000001 mov cr0,eax
Das ist nicht sinnvoll! Ich glaube das hatten wir aber schonmal
xor di,di mov di,(80*2)*24+(80-17)*2 xor ecx,ecx mov ecx, 17
Du musst einen Register vor dem Befuellen mit fixen Werten nicht nochmal extra loeschen. =>xor-Anweisungen weg.
So, ich glaub das war alles :p
[ Dieser Beitrag wurde am 08.05.2003 um 17:40 Uhr von Nobuo T editiert. ]