Hi leutz,
ich hab ein Problem:
ich hab den Bootloader von Tee Jay benutzt, der der kernel.bin von der Diskette starten soll. Der Bootloader funktioniert. Aber alles weitere nicht mehr: Er zeigt keinen String an...
Liegt das eventuell am linken der Dateien?
Hier mal die linker Datei:
OUTPUT_FORMAT("binary")
INPUT(kernel32.obj ckernel.obj)
ENTRY(start)
SECTIONS
{
.text 0x10200 : {
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(1);
}
.data : {
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(1);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(1);
}
end = .; _end = .; __end = .;
}
Ich versteh nicht, warum hier 0x10200 angegeben wird?
Im Bootloader von Tee Jay wird der Kernel an eine andere Adresse geladen:
ExecuteKernel:
mov ax, 0x1000
push ax ;Segmentadresse an welcher der Kernel ist auf den Stack pushen
mov ax, 0
push ax ;Offsetadresse des Kernels (0) auf den Stack pushen
retf ;Einen FAR-Rücksprung zum Kernel machen
Ich hab hier noch alle restlichen Dateien genauso von tee Jay übernommen, aber es funktioniert nicht:
1. Kernel, er schaltet in den Protected-Mode:
[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:
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:
2. Kernel, springt zum C-Kernel:
[Bits 32]
extern _main
global start
global _EnableA20Gate
start:
call _main
STOP:
jmp STOP
3. Kernel, C-Kernel:
int main()
{
char *Text = "Welcome to Protected Mode";
char *VideoMem = (char*)0xB8000;
while(*Text)
{
*VideoMem = *Text;
*VideoMem++;
*VideoMem = 7;
*VideoMem++;
*Text++;
}
return(0);
}
Warum zeigt er mir den String nicht an?
MfG,
Cheebi