Autor Thema: Nach dem Booten des Kernels passiert nichts....  (Gelesen 6053 mal)

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« am: 28. February 2006, 09:02 »
Hallo,
nachdem Grub meinen C kernel gebootet hat, passiert nicht, also der Monitor bleibt so, wie er war  :roll:
Hier mal meine Dateien:
kernel.c:

#include "./headers/multiboot.h"
#include "./headers/stdio.h"

int main()
{
ClearScreen();

char *Text = "Welcome to Protected Mode";
char *VideoMem = (char*)0xB8000;

while(*Text)
{
*VideoMem = *Text;
*VideoMem++;
*VideoMem = 7;
*VideoMem++;
*Text++;
}

return(0);
}


headers/multiboot.h:

int main(void);

const unsigned MultibootHeader[12] =
{
0x1BADB002, // der magische Wert
0x00000000, // die Flags
0xE4524FFE, // die Checksumme
(unsigned) MultibootHeader, // Offset des Headers
(unsigned) main, // Offset von main() als Beginn des Code Segments
0x00000000, // Data Segment, da scheißen wir drauf
0x00000000, // BSS Segment, wer braucht`n sowas?
(unsigned) main, // nochmal main(), diesmal als Entry Point
0x00000000, // Grafik? Nein, danke!
0x00000050, // 80 Spalten
0x00000019, // 25 Zeilen
0x00000000 // 0 BPP, wir sind im Text-Modus
};



headers/stdio.h:

#define COLS 80
#define ROWS 25

void ClearScreen(void);


void ClearScreen(void)
{
char *VideoMem = (char*)0xB8000;

int i;

for(i = 0; i == 2000; i++)
{
*VideoMem = ' ';
*VideoMem++;
*VideoMem = ' ';
*VideoMem++;
}
}



Weiß jemand, was ich falsch mache?



Viele Grüße,
   Johannes

C#ris

  • Beiträge: 47
    • Profil anzeigen
    • http://www.xerxys.org
Gespeichert
« Antwort #1 am: 28. February 2006, 09:52 »

char *Text = "Welcome to Protected Mode";
char *VideoMem = (char*)0xB8000;

while(*Text)
{
*VideoMem = *Text;
*VideoMem++;
*VideoMem = 7;
*VideoMem++;
*Text++;
}



Also deine "print"-Funktion kommt mir etwas komisch vor...

*VideoMem++

damit willst du den Pointer incrementieren. Warum dann der Dereferenzierungsoperator? (das gleiche bei *Text++)
Weiß zwar grad nicht welcher zuerst ausgewertet wird, aber komisch ist es schon oder nicht? Analog das gleiche in ClearScreen.

Gruß,
C#ris

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 28. February 2006, 10:04 »
Hier ist es aber auch so gemacht:
http://www.jay-code.de/scripts/htmlgenerator.php?page=ckernel&directory=tutorials  :roll:

Ich mag keine Pointer....


Viele Grüße,
   Johannes

C#ris

  • Beiträge: 47
    • Profil anzeigen
    • http://www.xerxys.org
Gespeichert
« Antwort #3 am: 28. February 2006, 11:03 »
Tja, dann müssen wir den Autor dieser Seite fragen... :roll:

Was passiert denn, wenn du die '*' an den entsprechenden Stellen weglässt?

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 28. February 2006, 11:17 »
Dann kommen Fehler beim Kompilieren:

In file included from kernel.c:2:
./headers/stdio.h: In function ‘ClearScreen’:
./headers/stdio.h:15: warning: assignment makes pointer from integer without a cast
./headers/stdio.h:17: warning: assignment makes pointer from integer without a cast
kernel.c: In function ‘main’:
kernel.c:13: warning: assignment makes pointer from integer without a cast
kernel.c:15: warning: assignment makes pointer from integer without a cast


Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 28. February 2006, 12:17 »
hi,

da waren ein paar falschen * bei ;)

es muss so:
     *VideoMem = *Text; // hier schreiben/lesen wir im speicher => * bleibt
      VideoMem++; // hier aendern wir den pointer => kein *
      *VideoMem = 7;
      VideoMem++;
      Text++;


und so heissen:
     *VideoMem = ' '; // hier schreiben wir was in den speicher => * bleibt
      VideoMem++; // hier aendern wir den pointer => kein *
      *VideoMem = ' ';
      VideoMem++;

natuerlich sind die regeln nicht so einfach, wie in den kommentaren. irgendwann wirds komplizierter und deswegen solltest du dich dann auch tiefer mit c auseinander setzen.

in diesen faellen duerften die ueberfluessigen * allerdings keinen fehler verursacht haben. die entfernten * haben dafuer gesorgt, dass die entsprechende speicherstelle ausgelesen wird. da das ergebnis allerdings nirgends gespeichert wurde (ist ja kein = in den zeilen), ist dieses lesen ins leere gegangen (evtl. hat der compiler das auch erkannt und intern auch die ueberfluessigen * entfernt.)
Dieser Text wird unter jedem Beitrag angezeigt.

C#ris

  • Beiträge: 47
    • Profil anzeigen
    • http://www.xerxys.org
Gespeichert
« Antwort #6 am: 28. February 2006, 12:23 »
Zitat von: PorkChicken

in diesen faellen duerften die ueberfluessigen * allerdings keinen fehler verursacht haben. die entfernten * haben dafuer gesorgt, dass die entsprechende speicherstelle ausgelesen wird. da das ergebnis allerdings nirgends gespeichert wurde (ist ja kein = in den zeilen), ist dieses lesen ins leere gegangen (evtl. hat der compiler das auch erkannt und intern auch die ueberfluessigen * entfernt.)


Richtig, die zuvielen * haben keine Auswirkungen gehabt, da * und ++ gleichwertig sind, jedoch von rechts ausgewertet werden. Ob mit oder ohne * spielte also wirklich keine Rolle...

Gruß,
C#ris

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 28. February 2006, 12:36 »
Ich habs nun umgeändert, aber es geht immernoch nicht :(
Nun werd ich mir erstmal das pointer kapitel in meinem C Buch durchlesen *g*

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 01. March 2006, 10:22 »
Hallo,
so, ich hab nun etwas weiter gearbeitet...
So sieht meine printf Funktion aus:

char *cursor = (char*)0xB8000;
int col = 1;
int row = 1;


void printf(char *text, int color)
{
while(*text)
{
*cursor = *text;
cursor++;
*cursor = color;
cursor++;
text++;
}
}


Doch leider gibt sie nichts aus....

Ich hab mir den Quellcode nun schon tausendmal angeschaut, aber ich finde den Fehler nicht  :roll:
Wisst ihr, was ich mal wieder falsch mache?

C#ris

  • Beiträge: 47
    • Profil anzeigen
    • http://www.xerxys.org
Gespeichert
« Antwort #9 am: 01. March 2006, 14:50 »
Also, ich hab diese Funktion im Debugger mal durchlaufen lassen (cursor hab ich mal mit malloc allokiert) und mal die Werte angeschaut. Die Funktion selbst funktioniert so wie sie soll!

Das Problem denk ich ist das manuelle Umbiegen des Pointer cursor auf 0xB8000. Ich weiß nicht so genau wie dein Kernel aussieht, aber das ganze funktioniert ja nur, wenn 0xB8000 eine physikalische Adresse ist. Sollte der Kernel im ELF-Format kompiliert sein, dann würde die Adresse 0xB8000 natürlich relativ zum Codesegment des Kernels liegen. Oder lieg ich da falsch;)? In diesem Fall passiert einfach nix, weil die Funktion ihre Daten einfach irgendwo in die Gegend schreibt...

Gruß,
C#ris

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 01. March 2006, 15:19 »
Ups....
Ja, mein Kernel ist im ELF-Format kompiliert..
Und wie mach ich das nun, dass *cursor auf die physikalische Adresse Zeigt?

JG

  • Beiträge: 189
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 08. March 2006, 14:04 »
*hochschieb*

 

Einloggen