Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: hackgod am 16. May 2005, 13:09
-
Ich bins mal wieder. Folgendes: Wie im Betreff erwähnt hab ich nix an
meiner kernel16.asm geändert. Auf einmal funzte dann alles nich mehr.
Nun hab ich durch einsetzen von hlt rausgefunden, an welcher stelle er
hängt:
db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8
Nun hab ich echt kein plan mehr. Wieso funzt das auf einmal nich mehr?
label is vorhanden, 0x8 is der Code-Deskriptor, also müsste es eigentlich
klappen oder?
Hier die Meldung von Bochs:00001961338e[CPU ] load_seg_reg: GDT: ES: index(0200) > limit(000017)
00001961338e[CPU ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
Brauch echt eure hilfe, finde den Fehler einfach nich. :cry: :cry:
mfg
hackgod
-
Vl liegt's ja am Deskriptor...wäre meine Vermutung...
-
nur habe ich an den deskriptoren nichts geändert. vorher haben sie gefunzt...
-
Na ja, ein Limit von 0x17 bytes ist nicht grad viel oder?
Vielleicht passt ja auch deine GDTR nicht mehr, ich denke die wirst du wohl vom Assembler/Linker berechnen lassen, vielleicht hast du durch andere Ãnderungen (Startaddresse, andere Programmteile die hinzugekommen sind und von daher Addressen beim Linken durcheinanderbringen könnten) einen Bug ausgelöst.
EDIT: Also beim Far Jump zum Code stürzt der ab, oder danach? Weil Bochs sich ja über ES beschwert und nicht CS, benutzt die Instruktion die danach folgt ES?
-
nach dem FAR JUMP denke ich, weil ich den hlt hinter den jump gesetzt hab
und er dann die ganze zeit rebootet.
Hier der Teil zu dem er springen soll:[BITS 32] ;32 Bit Code erstellen
PMODE:
mov WORD [CODE_DESC+2], 0 ;Code Segmentstartaddresse auf 0 setzen
mov WORD [DATA_DESC+2], 0 ;Daten Segmentstartadresse auf 0 setzen
mov BYTE [CODE_DESC+4], 0 ;Code Segmentstartaddresse auf 0 setzen
mov BYTE [DATA_DESC+4], 0 ;Daten Segmentstartadresse auf 0 setzen
mov eax, 2
shl eax, 3
mov ds, ax ;Daten- Stack- und Extrasegment mit
mov es, ax ;Datensegmentdeskriptor laden
mov ss, ax
mov eax, 0 ;FS und GS mit Null-Deskriptor laden
mov fs, ax
mov gs, ax
mov esp, 0x1FFFFF ;Stack auf unterhalb der 2 MB Grenze setzen
jmp 0x8:0x10000 + PMODE2 ;Sprung in das "neue" Codesegment
PMODE2:
jmp END ;Zum Ende Springen
Wie kann ich denn die GDTR vom Assembler/Linker berechnen lassen?
Wird doch mein ich durch den Befehl lgdt geladen. Oder meinste die GDT?
Kann es sein wenn ich in meiner kernel32.asm globale Variablen festlege
(wegen ISRs) dass er da durcheinanderkommt?
-
Ja, stimmt, GDTR ist etwas falsch, ich meine den Deskriptor zum Laden der GDT, den du an LGDT übergibts.
-
hier der code für die gdt:
[BITS 16]
jmp start
NULL_DESC:
dd 0
dd 0
CODE_DESC:
dw 0xFFFF
dw 0
db 0
db 0x9A
db 0xCF
db 0
DATA_DESC:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt:
Limit dw 0
Base dd 0
start:
call EnableA20Gate
bt eax, 1
jz PMODE_start
PMODE_start:
cli
mov eax, cs
mov ds, ax
shl eax, 4 ;EAX beinhaltet immer noch den Wert von CS (siehe letzten Codeabschnitt)
mov [CODE_DESC+2], ax ;Den ersten Teil der Linearen Adresse eintragen
mov [DATA_DESC+2], ax
shr eax, 16
mov [CODE_DESC+4], al ;Den zweiten Teil der Linearen Adresse eintragen
mov [DATA_DESC+4], al
mov eax, cs
shl eax, 4
add eax, NULL_DESC
mov [Base], eax
mov [Limit], WORD gdt - NULL_DESC - 1
lgdt [gdt]
mov eax, cr0 ;In den Protected Mode schalten,
or eax, 1 ;indem Bit 0 des CR0 Registers auf 1
mov cr0, eax ;gesetzt wird
db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8
Vielleicht sollte ich erwähnen, dass er die GDT lädt und in den PM schaltet
(hab ich durch setzen von hlt's rausgefunden). Aber dann hakt er beim
FAR JUMP.
-
db 0xea ;FAR-JUMP zum Codesegment
dw PMODE
dw 0x8
probier doch mal ein dd PMODE, du springst doch schließlich in ein 32 bit Segment, da muss natürlich auch der Offset 32 bit sein ;-)
-
hmm, jetzt is er schonmal wieder im PM :?
aber funzt immer noch nich richtig.
Jetzt meint bochs folgendes:00000715547p[CPU ] >>PANIC<< jump_protected: cs == 0
00000715547i[SYS ] Last time is 1116255275
00000715547i[CPU ] protected mode
Weiss jemand wo es eine Erklärung der Bochs-Fehlermeldungen gibt?
Ausserdem wär eine Erklärung von db,dw und dd nich schlecht :lol:
-
mit db,dw und dd kannst du den assembler(-compiler) umgehen und direkt daten bzw. code in deine ausführbare Datei reinschmeißen; der zweite Buchstabe steht dabei nur für die Länge des Datenworts:
b = byte / 8bit
w = word / 16bit
d = doubleword / 32bit
in deinem Fall gibst du damit direkt den Opcode für deinen Sprungbefehl an, welcher da wäre 0xea. Dieser verlangt dann noch, je nach Modus der CPU, zuerst ein Offset (neue Addresse im Segment) und danach den Selector in deiner GDT oder LDT (halt das neue Segment).
-
Gut, dann wär das mit db, dw, dd geklärt. Nur versteh ich immer noch nich
was die Meldung von Bochs bedeuten soll. Wieso sagt Bochs das CS == 0 ist?
Ich müsste ja eigentlich ohne Probleme in das neue Codesegment
springen, oder nicht?