Autor Thema: PMode-JMP  (Gelesen 2645 mal)

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« 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:

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 05. April 2005, 19:55 »
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 ...)
Dieser Text wird unter jedem Beitrag angezeigt.

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. April 2005, 10:41 »
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...

Roshl

  • Beiträge: 1 128
    • Profil anzeigen
    • http://www.lowlevel.net.tc
Gespeichert
« Antwort #3 am: 06. April 2005, 16:51 »
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^^
[schild=1]Wieder ein wertvoller(?) Beitrag von Roshl[/schild]

 

Einloggen