Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: ika am 11. October 2009, 01:36
-
hallo leute,
hier ist ein ausschnitt aus dem bootloader den ich verwende (funktioniert alles wunderbar):
(Quelle: http://www.cheebi.de/c-kernel-tutorial.pdf)
cli
mov ax, cs ; Code-Segment holen
mov ds, ax ; Daten-Segment gleichsetzen
xor eax, eax ; ax = 0
mov es, ax ; Extra-Segment auf Null setzen
mov si, GDT ; Quelle : GDT
xor di, di ; Ziel : 0x0000
mov cx, 6 ; 6 DoubleWords kopieren (ganze GDT)
rep movsd
Ich frage mich schon die ganze Zeit warum die GDT an die Adresse 0x0000 im Arbeitsspeicher verschoben wird. Vor allem weil immer dachte der Bereich ist für mich tabu. Kann mich jemand aufklären?
[edit]
Reine Spekulation: wenn man die GDT nach 0x0000 lädt, dann muss man base nicht setzen [ base dd (0) ] dabei ist base doch das offset der GDT ? (bitte kurz abnicken).
[/edit]
-
Ich sehe darin keinen Vorteil, eher ein Problem. Wenn du nach 0x0 kopierst, überschreibst du die IVT. Die brauchst du zwar im Moment nicht mehr, aber sobald du z.B. mal VM86 implementieren willst, wäre es ganz praktisch, wenn sie noch in Ordnung wäre.
Wenn du in bei GDTR: statt 0x0 die korrekte Anfangsadresse der GDT schreibst, sollte das auch ohne das Kopieren funktionieren. Ich vermeide den RM grundsätzlich, deswegen ohne Garantie, aber GDT + 0x7c00 könnte es tun.
-
Danke,
wie gesagt ich habe das Beipiel des Autors genommen, weil es funktioniert. Ich bin dabei mit den code auseinanderzunehmen (wirds überhaupt zusammen geschrieben?), also learning bei doing...
Ich werde mal gleich versuchen, das Offset von GDTS (also dem Anfang der GDT) zur Laufzeit zu setzen. Das wäre eine elegantere lösung wie ich finde.
-
Hm, jo, auch eine Möglichkeit, das zur Laufzeit auszurechnen.
Und bevor du wegen einem schlechten Tut auf die Schnauze fällt: Das Thema A20 scheint er komplett auszuklammern. Das könnte später für lustige Bugs sorgen, die scheinbar überhaupt keinen Sinn ergeben.
-
Danke für den Hinweis...
Erstmal zusammenfassend:
"Problem" gelöst!
Problem:
in dem oben angegebenen Tutorial verschiebt der Autor die GDT (siehe Code) an dem Anfang des Arbeitsspeichers. Dies sollte vermieden werden da dieser Bereich nicht benutzt werden sollte.
Lösung:
cli
;Das Auskommentierte kann man löschen
;mov ax, cs ; Code-Segment holen
;mov ds, ax ; Daten-Segment gleichsetzen
;xor eax, eax ; ax = 0
;mov es, ax ; Extra-Segment auf Null setzen
;mov si, GDT ; Quelle : GDT
;xor di, di ; Ziel : 0x0000
;mov cx, 6 ; 6 DoubleWords kopieren (ganze GDT)
;rep movsd
mov ax,GDT ; <- neu eingefügt
mov [GDTS+2],ax ; <- neu eingefügt
lgdt [GDTS]
Hier wird die Adresse des Anfangs der GDT in GDTS -> base eingetragen. Jetzt kann die GDT geladen werden.
mfg ika
-
Tut das? Müsstest du nicht noch ds draufaddieren? Das Label GDT sollte doch relativ zu deinem RM-Segment (bzw. zu org 0x7c00) sein?
-
ich kann kann dir echt nicht sagen warum das so ist, aber es ist die richtige adresse, habs nochmal debuggt um sicher zu gehen:
mov ax,0x7c09
steht dann in der entsprechenden Zeile, und wenn ich mir danach den regdumps anschaue, dann ist auch der entsprechende wert dring.
-
base DD GDT statt base DD (0x0) sollte auch funktionieren.
-
ja, danke, ist noch einfacher
-
Ups, ds ist ja 0. Dann braucht man da natürlich nicht mehr viel dazuzuzähen. Es war wohl noch zu früh. ;)