Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: elfish_rider am 05. April 2005, 17:08
-
Komischerweise funktioniert mein PMode-Jump nicht mehr. Das GDTR wird nämlich nicht richtig geladen. Ich werd nicht schlau aus meinem Code, es liegt sicher an einem lächerlichen Fehler, den irgendwer sofort finden wird:
XOR EAX, EAX ; GDT einrichten, um danach in den PM zu schalten
MOV DS, EAX
MOV ES, EAX
MOV ESI, Desc0
XOR EDI, EDI
MOV ECX, EndOfGDT-Desc0
REP MOVSB
LGDT [GDT]
MOV EAX, CR0
OR EAX, 1
MOV CR0, EAX
JMP 8h:PMStart
BITS 32
PMStart:
MOV AX, 2<<3 ; Selektoren zuweisen
MOV DS, AX
MOV ES, AX
MOV AX, 3<<3
MOV SS, AX
MOV ESP, 0FFFh
MOV EBP, ESP
XOR AL, AL ; Bildschirm löschen
MOV ECX, 320*200 ; (bei Platzproblemen weglassen)
MOV EDI, 0A0000h
REP STOSB
MOV ECX, KERNEL_SIZE*512 ; Kernel von 30000h nach 100000h kopieren
MOV ESI, 30000h
MOV EDI, 100000h
REP MOVSB
JMP 100000h ; Zum Kernel springen, der den Rest initialisiert:
; IDT, IRQs
; --------------------
; Daten
; --------------------
GDT:
DW 10000h ; Limit
DD 0 ; Basisadresse
Desc0: ; Null
DW 0
DW 0
DB 0
DB 0
DB 0
DB 0
Desc1: ; Systemcode 0 - 7F F000h
DW 07FFh
DW 0000h
DB 00h
DB 10011010b
DB 11000000b
DB 00h
Desc2: ; Systemdaten 0 - 7F F000h
DW 07FFh
DW 0000h
DB 00h
DB 10010010b
DB 11000000b
DB 00h
Desc3: ; Temp. Stack
DW 00FFFh ; Grösse 4 KB
DW 8000h ; Basis 8000h
DB 00h
DB 10010010b
DB 01000000b
DB 00h
EndOfGDT:
-
wenn es ein bootsektor ist, muss am anfang org 0x7c00 stehen, weil du DS und ES auf 0 setzt. (denn sonst kopierst du die GDT statt von 0x0000:0x7CXX von 0x0000:0x00XX)
das limit deiner GDTR ist außerdem zu groß. es muss den wert (anzahl_der_selektoren * 8) - 1 haben. (8 =größe eines selektors)
du kopierst deinen kernel an eine adresse mit einer ungeraden mbyte zahl (d.h. bit 20 ist gesetzt). vorher solltest du das A20 setzen, sonst landet dein kernel wenn du ihn nach 0x00100000 kopierst bei 0x00000000 ...
sei außerdem vorsichtig mit den basen in deinen selektoren. ich rate davon ab, basen ungleich 0 zu nehmen, weil das alles sonst sehr kompliziert zu überschauen ist und schwer zu debuggen.
btw: im real mode kannst du außerdem esi und edi (und alle anderen 32bit register) nicht zur adressierung nutzen. gibt afaik irgendne exception ... du musst dich mit den unteren 16 bit begnügen. (du addressierst zwar nicht sondern weist nur werte zu, aber lass dich nicht hinreissen mit 32bit zu adressieren ...)
-
Ich habe nur einen Teil des Bootloaders abgedruckt, ich hätte es vorher sagen sollen.
1. ORG 7C00h habe ich weiter oben
2. Das Limit ist wahrscheinlich falsch, somit wird das GDTR gar nicht geladen (Bochs meckert zwar erst später), aber mit 0FFFFh sollte es gehen
3. A20 ist vorher gesetzt (durch BIOS und Tastatur-Controller)
4. Nur der Stack hat ja ne andere Basis als 0??
5. Habe ich es vorher auch nur mit 16-bit-Befehlen versucht, lag also nicht an dem
AUSSERDEM: Wieso meckert NASM nicht bei DW 10000h??? Das passt gar nicht in ein 16-bit-wert...
-
nasm schneidets einfach ab^^
Es gibt einen Opcode prefix der auch im Realmode adressieren mit 32Bit erlaubt, aber keine ahnung ob oder wie das genau funktioniert, hab es lieber wenn alles rein ist^^