Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: Cheebi am 01. January 2006, 17:30

Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: Cheebi am 01. January 2006, 17:30
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
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: syxce am 02. January 2006, 12:31
TeeJay's Tuorial funktioniert nicht, du bist nicht der erste den es hier erwischt.
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: Cheebi am 02. January 2006, 12:49
Ja und wie komm ich nun dahin, wo ich hin will? Und zwar, dass der C-Kernel mir den String auf den Bildschirm packt??? Du hast es doch auch schon geschafft...!?

Cheebi
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: syxce am 02. January 2006, 14:12
Ja das habe ich, jedoch mit viel arbeit und zeit verbunden, ich habe dir bereits einen Link gschickt wo viele Tutorials findest.
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: Cheebi am 02. January 2006, 17:02
Hi,

kann mir nicht einfach bitte mal jemand den einen funktionierenden Code schicken, inclusive der Linker-Datei für ld, oder zu mindest der Befehlszeile?
Wär echt total nett, wenn ich wenigstens einen Tip bekäme, woran das Haupt-Problem liegt, denn in den Protected-Mode muss ich doch schalten, das kann ich von Tee Jay doch übernehmenm, oder? Und dann kann es doch nicht allzu aufwändig sein, den C-Kernel zu starten. Der liegt an einer bestimmten Adresse, nur wie komm ich dahin?

MfG
Cheebi
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: syxce am 03. January 2006, 00:41
Ich weiss nicht wieviel von TeeJays Code funktioniert, ich würde das lieber lassen.
Du kommst dort hin in dem einen "jmp 0x...." zur Adresse machst an der dein C Kernel liegt.
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: elfish_rider am 03. January 2006, 12:20
Wie wärs mit

void main()
{
   char Text[] = "Welcome to Protected Mode";  
   char *VideoMem = (char*)0xB8000;  

   for(i = 0; Text[i] != 0; i++)
   {
      VideoMem[i] = Text[i];
      VideoMem[++i] = 7;
   }
}


?

EDIT: Ob der Assembler-Code stimmt, weiss ich auch nicht. Ist er schon so weit gekommen?
Titel: C-Kernel zeigt nichts an!? Linker-Datei falsch?
Beitrag von: nooooooooos am 03. January 2006, 12:21
Bei mir hat TJs PM jump nicht gefunzt, darauf probierte ichs mit dem Codeschnipsel in der Ausgabe7 von Stefan2005.

Gruss
Nooooooos