Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: ZettaME am 01. August 2004, 21:22
-
Hallo Allerseits,
ich beziehe mich auf das Tutorial von TeeJay (Protected Mode Tutorial). Nun denn - ich habe versucht den dort beigestellten Download-Code (kernel16.asm) dahingehen zu verändern, dass am Schluß eine einfache Zeichenausgabe über den Videospeicher erfolgt.
nach der Marke PMODE2:
habe ich dann folgendes eingefügt:
MOV BYTE [0xB8000], 'z'
MOV BYTE [0xB8001], 0x07
habe sonst nichts am Code verändert! Es erfolgt jedoch nicht die gewünschte Ausgabe am Bildschirm.
In einer anderen Variante hab ich vor dem letzten FAR JUMP, dann dies eingefügt und die Ausgabe am Bildschirm erfolgte nach dem Bootvorgang:
;(Auszug aus dem modifizierten Code (Original TeeJay))
.
.
.
MOV BYTE [0xB8000], 'z'
MOV BYTE [0xB8001], 0x07
jmp 0x8:0x10000 + PMODE2 ;Sprung in das "neue" Codesegment
PMODE2:
.
.
.
Hat jemand einen Tip oder eine Lösung, wie es im 1. Fall funktionieren kann?
Vielen Dank!
Gruß
ZettaME
-
Du musst an 0xA8000 schreiben, da der Codedeskriptor nach dem jump am phy. Offset 0x10000 beginnt. Also 0xB8000 - 0x10000 = 0xA8000
-
Das ist leider so nicht richtig. Nach der Marke PMODE2 ist der Anfang des Codesegment wieder auf 0. GEnau das selbe gilt für das Datensegment das in dem Falle eigentlich das verantwortliche wäre.
Versuche mal eine Lösung mit stos:
mov edi,0xB8000 ;Adresse das Videospeicher im Textmodus
mov ah,'Z' ;der buchstabe
mov al,0x07 ;Farbe
;Die Segmente stehen schon richtig also da nix ändern
stosw ;nun wird ax zur Addresse an edi verschoben und edi um 2 erhöht also bereit für das nächste Zeichen...
-
OH ja ich sehe jetzt erst, dass das eine neue Version vom kernel16 ist
-
@Roshl
hab das mal ausprobiert, funktioniert aber nicht! Hier mal der komplette Code:
;###############################################
[BITS 16] ;16 Bit Code erstellen
jmp start ;GDT überspringen
NULL_Desc:
dd 0
dd 0
CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 10011010b ;Zugriffsberechtigungen
db 11001111b ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3
DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0 ;Adresse der GDT (wird später eingetragen)
start:
cli ;Interrupts ausschalten
mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen
shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)
mov [CODE_Desc+2], ax ;Lineare Adresse des Codesegmentes als
mov [DATA_Desc+2], ax ;Startadresse des Code- und Datendeskriptors
shr eax, 16 ;eintragen
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al
mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc
mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen
lgdt [gdt] ;GDT laden
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
[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 ;Selektor für das Datensegment erstellen
shl eax, 3
mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, 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:
MOV EDI, 0xB8000
MOV AH, 'z'
MOV AL, 0x07
STOSW
jmp End ;Zum Ende Springen
;times 512-($-$$) db 0; ;Da der Linker sich nicht mit ungeraden
;Dateigrößen verträgt, wird diese Datei auf 512
;gepaddet.
End:
;#################################################
Hier die variante die funktioniert:
;#################################################
[BITS 16] ;16 Bit Code erstellen
jmp start ;GDT überspringen
NULL_Desc:
dd 0
dd 0
CODE_Desc:
dw 0xFFFF ;Segmentgröße Byte 0/1
dw 0 ;Segmentbasisadresse Byte 0/1
db 0 ;Segmentbasisadresse Byte 2
db 10011010b ;Zugriffsberechtigungen
db 11001111b ;Zusatz + Segmentgröße Bits 16 - 19
db 0 ;Segmentbasisadresse Byte 3
DATA_Desc:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt:
Limit dw 0 ;Größe der GDT (wird später eingetragen)
Base dd 0 ;Adresse der GDT (wird später eingetragen)
start:
cli ;Interrupts ausschalten
mov eax, cs ;EAX auf derzeitiges Codesegment setzen
mov ds, ax ;DS auf Codesegment setzen
shl eax, 4 ;EAX mit 16 multiplizieren (Lineare Adresse
;des Codesegments errechnen)
mov [CODE_Desc+2], ax ;Lineare Adresse des Codesegmentes als
mov [DATA_Desc+2], ax ;Startadresse des Code- und Datendeskriptors
shr eax, 16 ;eintragen
mov [CODE_Desc+4], al
mov [DATA_Desc+4], al
mov eax, cs ;Startadresse der GDT errechnen
shl eax, 4
add eax, NULL_Desc
mov [Base], eax ;Startadresse der GDT eintragen
mov [Limit], WORD gdt - NULL_Desc -1 ;Größe der GDT errechnen und eintragen
lgdt [gdt] ;GDT laden
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
[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 ;Selektor für das Datensegment erstellen
shl eax, 3
mov ds, ax ;Daten- Stack- und Extrasegment mit
mov ss, ax ;Datensegmentdeskriptor laden
mov es, 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
MOV EDI, 0xB8000
MOV AH, 'Z'
MOV AL, 0x07
STOSW
jmp 0x8:0x10000 + PMODE2 ;Sprung in das "neue" Codesegment
PMODE2:
jmp End ;Zum Ende Springen
;times 512-($-$$) db 0; ;Da der Linker sich nicht mit ungeraden
;Dateigrößen verträgt, wird diese Datei auf 512
;gepaddet.
End:
;##################################################
Es sollte aber ersteres tun...
Viele Dank für Eure Unterstützung :o)
ZettaME
-
Nachtrag,
wenn ich im 1. Fall 0xA8000 als Videospeicheradresse angebe, passiert ebenfalls nichts...
-
Habe es gelöst,
mein bootloader hat den Kernel an eine falsche Startadresse geladen.
MfG
ZettaME