Autor Thema: [solved] Teil 4: console.c/console.h - woher?  (Gelesen 18086 mal)

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« am: 02. December 2009, 12:45 »
Ich habe auch eine Frage zu dem Tutorial: http://lowlevel.brainsware.org/wiki/index.php/Teil_4_-_Hello_World#printf. In diesem Teil wird von einer console.h gesprochen.
Der Code darüber
typedef __builtin_va_list       va_list;
#define va_start(ap, X)         __builtin_va_start(ap, X)
#define va_arg(ap, type)        __builtin_va_arg(ap, type)
#define va_end(ap)              __builtin_va_end(ap)
funktioniert als console.h bei mir nicht.
Da habe Ich mir gedacht, dass der GCC Compiler die Datei aus dem System nimmt. Also habe ich auf meinem Linux System danach gesucht, aber mehr als eine console.h gefunden und alle durchprobiert. In einigen ist ein direkter Fehler in der .h-Datei und passiert der Fehler bei kprintf("Hello World!\n");
GCC gibt mir als Fehler: init.c:5: error: implicit declaration of function ‘kprintf’ Kann mit jemand helfen, warum bei mir die console.h nicht funktioniert?
« Letzte Änderung: 25. March 2010, 11:08 von spaceemotion »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. December 2009, 13:32 »
Hi und willkommen an Board,

wie hast du es denn geschafft in das Forum im Archiv zu kommen? Eigentlich sind diese Foren nicht öffentlich zugänglich. Ich hab dein Thema mal verschoben.

Zur Frage: console.c und console.h musst du selbst erstellen. Im Tutorial wird davon ausgegangen, dass du zumindest eine einfache Ausgabefunktion, die dort kprintf genannt wird, selbst schreiben kannst.

In console.h, müsstest du die Funktionsdeklaration (Prototyp) schreiben, und in console.c die Funktionsdefinition (Implementierung). Der Prototyp könnte in etwa so aussehen, wenn du erstmal mit einer einfachen Funktion anfangen willst:
void kprintf(const char *string);
« Letzte Änderung: 02. December 2009, 13:43 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #2 am: 03. December 2009, 11:34 »
Hallo,
und danke für die schnelle Antwort.
Ich habe
void kprintf(const char *string);
ausprobiert und bekomme von GCC nun undefined reference to `kprintf' als Fehler. Diesen Fehler hatten zwar andere http://www.keil.com/support/docs/2729.htm auch schon mal. Aber bei denen war der Fehler wo anders. Wie kann man diesen Fehler den los werden?
Ich glaube, dass der Fehler daran liegt, dass nicht definiert wurde, wohin und wie er etwas ausgeben soll. Wie kann man dem Kernel das sagen?


mfG. Spaceemotion

Cool-Andy

  • Gast
Gespeichert
« Antwort #3 am: 03. December 2009, 12:00 »
Hast du die Funktion richtig implentiert?
Vielleicht könntest du mal deinen Code für "kprintf" posten.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 03. December 2009, 12:02 »
Ich habe die Vermutung, dass er noch gar kein kprintf geschrieben hat. Das wäre dann erstmal der nächste Schritt.

undefined reference heißt, dass eine Funktion oder Variable benutzt werden soll, die es gar nicht gibt (oder die zumindest nicht in den Dateien enthalten ist, die gelinkt werden).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #5 am: 03. December 2009, 12:12 »
Hier mein Code für kprintf:
init.c
#include "console.h"
 
void init(void)
{
    kprintf("Hello World!\n");
}

console.h
void kprintf(const char *string);

Cool-Andy

  • Gast
Gespeichert
« Antwort #6 am: 03. December 2009, 12:37 »
taljeth hat Recht!

Du musst die Funktion "kprintf" erst noch schreiben. So was ist wenn man sein eigenes OS schreibt nicht automatisch da!

Schau dir das hier mal an: http://lowlevel.brainsware.org/wiki/index.php/Ausgabe_5#Die_Programmiersprache_C
Da steht auch ein Code für Bildschirmausgaben!

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #7 am: 03. December 2009, 12:54 »
Wir haben so etwas in der Art aus dem Tutorial:
void init(void)
{
    const char hw[] = "Hello World!";
    int i;
    char* video = (char*) 0xb8000;
 
    for (i = 0; i < sizeof(hw); i++) {
        // Zeichen i in den Videospeicher kopieren
        video[i * 2] = hw[i];
 
        // 0x07 = Hellgrau auf Schwarz
        video[i * 2 + 1] = 0x07;
    }
}
Diese Reihe ist gibt einen Text aus. Nur habe ich versucht das so umzuschreiben, dass er ein ENTER mit ausgibt.
const char hw[] = "Hello World!\nI'm a computer";Das Enter stellt er nur falsch da. Aus dem ENTER wird ein kleiner runder Kreis. Ich kann euch das Bild später einmal hochladen, weil ich in diesem Netzwerk kein FTP habe.
In dem Tutorial stand auch, dass man den Bildschirm aufräumen könnte. Ich wüsste auch gerne wie das geht.

Cool-Andy

  • Gast
Gespeichert
« Antwort #8 am: 03. December 2009, 13:13 »
Wenn du ein OS schreibst musst du (fast) alles selber machen! Auch Zeilenumbrüche!
Zum Bildschirm löschen: Ja, das geht.

ABER: Es gibt da ein sehr gutes Tutorial: http://lowlevel.brainsware.org/wiki/index.php/Ausgabe_1.
Ich glaube es wäre besser, das erstmal durchzulesen (am Besten alle Ausgaben!).  :-D

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 03. December 2009, 15:30 »
Finger weg vom Magazin, da sind teilweise sehr fragwürdige Ansätze drin.

spaceemotion, bist du dir sicher, dass du den Code zur Textausgabe verstanden nicht nur einfach kopiert hast? Du schreibst das Zeichen 10 ('\n') in den Buchstaben nach dem "Hello World". Wenn du was in einer neuen Zeile haben willst, musst du stattdessen dafür sorgen, dass der nächste Text an einer anderen Stelle im Videospeicher ausgegeben wird.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Cool-Andy

  • Gast
Gespeichert
« Antwort #10 am: 03. December 2009, 15:40 »
Zitat
Finger weg vom Magazin, da sind teilweise sehr fragwürdige Ansätze drin.

Warum schreibt ihr dann nicht so eine schöne rote Zeile, wie so oft drüber?  :x
Wenn ich jetzt das erste Mal auf die Wiki stoßen würde, und das Magazin finden würde, würde ich es sofort einstudieren!

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 03. December 2009, 19:58 »
Ist das Magazin nicht sowieso schon mit gelben und roten Hinweisen gepflastert?

Okay, "Finger weg" war vielleicht etwas übertrieben, aber es sollte nicht die erste Quelle für einen Einsteiger sein. Es erläutert Dinge ziemlich zusammenhangslos und macht so ziemlich alles in Assembler. Im Ergebnis führt das nur dazu, dass Code kopiert wird ohne dass er wirklich verstanden ist - und am Ende stranden diejenigen dann wieder hier, damit wir es fixen.

Als Tutorialreihe zum Mitmachen ist OS-Dev für Einsteiger zu bevorzugen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Cool-Andy

  • Gast
Gespeichert
« Antwort #12 am: 03. December 2009, 20:01 »
Ich würde einen roten Hinweis mit "Nicht für Anfänger geeignet" oder so ganz oben hinsetzen.
Andere Frage: Wird das Magazin eigentlich noch weiter geschrieben?

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #13 am: 04. December 2009, 17:31 »
spaceemotion, bist du dir sicher, dass du den Code zur Textausgabe verstanden nicht nur einfach kopiert hast?
Ja habe ich, 
Du schreibst das Zeichen 10 ('\n') in den Buchstaben nach dem "Hello World". Wenn du was in einer neuen Zeile haben willst, musst du stattdessen dafür sorgen, dass der nächste Text an einer anderen Stelle im Videospeicher ausgegeben wird.
An welche denn? 0xb8000 ist die Startadresse, aber wo ist die nächste Zeile?
Zum Bildschirm löschen: Ja, das geht.
Und wie?

Tobiking

  • Beiträge: 24
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 04. December 2009, 17:49 »
Eine Zeile ist 80 Zeichen lang, also fängt die zweite Zeile bei Speicheradresse + 80 Zeichen an. Bei den folgenden Zeilen ist das genauso, der Grafikkartenspeicher geht direkt von anfang bis Ende durch.

Bildschirm löschen ist einfach den ganzen Bildschirm mit Leerzeichen "vollschreiben".

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #15 am: 05. December 2009, 11:27 »
Und wie mache ich dann daraus einen einzigen Befehl?

DerHartmut

  • Beiträge: 236
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #16 am: 05. December 2009, 12:37 »
Also das Denken sei da schon dir überlassen ;-)
$_="krJhruaesrltre c a cnp,ohet";$_.=$1,print$2while s/(..)(.)//;
Nutze die Macht, nutze Perl ;-)

Cool-Andy

  • Gast
Gespeichert
« Antwort #17 am: 05. December 2009, 12:56 »
In dem du eine Funktion schreibst!  :-o

spaceemotion

  • Beiträge: 49
    • Profil anzeigen
    • SpaceEmotion
Gespeichert
« Antwort #18 am: 05. December 2009, 16:41 »
Ich habe jetzt eine .h geschrieben:
init.c
#include "console.h"


void init(void)
{

clearscreen();
kprintf("Hello World,\nI'm LionOS");

}
console.h
#ifndef INCLUDE_console_H

#define INCLUDE_console_H


void kprintf(const char hw)
{

char* video = (char*) 0xb8000;

int i;

int timesofnewline = 0;

// C-Strings haben ein Nullbyte als Abschluss

for (i = 0; i<sizeof(hw); i++) {

if (hw[i] == '\n')

{

timesofnewline++;

}

else

{

// Zeichen i in den Videospeicher kopieren

video[i * 2 + timesofnewline * 80] = hw[i];

 
        // 0x07 = Hellgrau auf Schwarz

        video[i * 2 + 1 + timesofnewline*80] = 0x07;
}

    }

}



void clearscreen()
{

char* video = (char*) 0xb8000;

const char empty[] = "   ";

    int i;

//char* video = (char*) 0xb8000;

 
// C-Strings haben ein Nullbyte als Abschluss

for (i = 0; i==800; i++) {


        // Zeichen i in den Videospeicher kopieren

        video[i * 2] = empty[1];

 
        // 0x07 = Hellgrau auf Schwarz

        video[i * 2 + 1] = 0x07;

    }


}
#endif

Und LD meckert, dass in der (von GCC generierten) init.o ein Fehler sei.

Cool-Andy

  • Gast
Gespeichert
« Antwort #19 am: 05. December 2009, 16:54 »
Hm,
ich würde ne extra Datei (z.B. "console.c") anlegen, dort die ganzen Funktionen reinschreiben und in console.h dann nur:
#ifndef _console_H_
#define _console_H_

void kprintf(const char hw);
void clearscreen();

#endif
In console.c muss dann noch #include "console.h" rein und (hoffentlich) fertig.
Probier es mal aus, ich hoffe ich konnte dir helfen.  :-D

 

Einloggen