Autor Thema: Problem mit textausgabe  (Gelesen 3217 mal)

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« am: 06. October 2009, 19:17 »
Hi Leute,
ich bin am verzweifeln. Seit Tagen oder Wochen versuche ich die Textausgabe in meinem Kernel zum laufen zu bekommen. Aber es will einfach nicht. Das einzige was funktioniert ist die Funktion Cls(); Wenn cih Set_Cursor nicht auskommentiere, meldet der Kompiler folgendes
kernel_c.o: In function `main':
Kernel.c:(.text+0x48): undefined reference to `Set_Cursor'
Ich verstehe nicht warum. Und dann noch das mit der Textausgabe. Das auskommentierte in Kernel.c funktioniert. Wenn ich aber den gleichen Code nehme, und ihn in eine andre Funktion packe (sei es Cls()) funktioniert er auf einmal nicht mehr. Ich bin schon seit Wochen am herumprobieren, aber ich finde die Lösung nicht. Hie mein Code:
Kernel.c
#include "OS.h"

// Main function (this is called in Kernel.asm)
int main()
{
   //char *video = (char*)0xB8000;
  char *hello = VERSION;


  // Clear the screen
  Cls();

  kprintf(hello, 1, 1);
  // String ausgeben
  /*while (*hello) {
    *video = *hello;
    video++;
    *video = 0x07;
    video++;
    hello++;
  }*/

  Set_Cursor(11, 0);

  while (1);

  return 0;
}

OS.h
#ifndef OS_H_INCLUDED
#define OS_H_INCLUDED

#include "Graphic.h"

// Version of the Kernel
#define VERSION "28.09.2009"

// Util.c
extern void OutPort(unsigned int iPort, unsigned char chData);
extern unsigned char InPort(unsigned int iPort);

// Graphic.c
extern void Cls();
extern void Set_Cursor(const int iX, const int iY);
extern void kprintf(char* chBuffer, const unsigned int iXPos, const unsigned int iYPos);


#endif // OS_H_INCLUDED

Graphic.c
#include "OS.h"

// Vars
int iXPos, iYPos; // Position of the cursor
char* VGAMem = (char*) 0xB8000; // Pointer to the videoram
unsigned int iAttrib = 0x0F; // Attributes for the text

// Functions

// Clear the screen
void Cls()
{
    // Clear the screen
    int i = 0;
    while(i < (80 * 2 * 25))
    {
        VGAMem = 0x20;
        i++;
        VGAMem = 0x07;
        i++;
    }

}

// Print text on the screen
void kprintf(char* chBuffer, const unsigned int iXPos, const unsigned int iYPos)
{
    VGAMem = (char*) 0xB8000;
    while(*chBuffer)
    {

        *VGAMem = *chBuffer;
        VGAMem++;
        *VGAMem = 0x07;
        VGAMem++;
        chBuffer++;
    }
}

// Set text attributes
void Set_Attribute()
{

}

// Set the cursor
void Set_Cursor(const int iX, const int iY)
{
    unsigned short Position = (iX * 80) + iY;

    OutPort(0x3D4, 0x0E);
    OutPort(0x3D5, (unsigned char)((Position>>8)&0xFF));
    OutPort(0x3D4, 0x0F);
    OutPort(0x3D5, (unsigned char)(Position&0xFF));
}

Util.c
#include "OS.h"

// Write something to an I/O port
void OutPort(unsigned int iPort, unsigned char chData)
{
    asm volatile ("outb %%al,%%dx"::"d" (iPort), "a" (chData));
}

// Read something from an I/O port
unsigned char InPort(unsigned int iPort)
{
    // Vars
    unsigned char chData;

    // Read from the port
    asm volatile ("inb %w1,%b0"    : "=a"(chData)    : "d"(iPort));

    return chData;
}

CreateKernel.sh
nasm -f elf -o kernel_asm.o Kernel.asm
gcc -m32 -ffreestanding -o util_c.o -c Util.c -Wall -Werror -nostdinc
gcc -m32 -ffreestanding -o graphic_c.o -c Graphic.c -Wall -Werror -nostdinc
gcc -m32 -ffreestanding -o graphic_h.o -c Graphic.h -Wall -Werror -nostdinc
gcc -m32 -ffreestanding -o os_h.o -c OS.h -Wall -Werror -nostdinc
gcc -m32 -ffreestanding -o kernel_c.o -c Kernel.c -Wall -Werror -nostdinc
ld -T LinkerSkript.ld -o Kernel.bin kernel_asm.o kernel_c.o Graphic_c.o Util_c.o

Ich hoffe, mir kann einer helfen. Vielen dank schon mal im Voraus.

ika

  • Beiträge: 27
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. October 2009, 21:30 »
Hallo,
also zumindestens bei der Textausgabe kann ich dir weiterhelfen:
void printf(char *text);
int main()
{
printf("Mega hammer geil, die Textausgabe funzt :)");
for(;;);
}
void printf(char *text)
{
char *ptr;
for ( ptr = (char *)0xb8000; *text != 0; text++ )
{
*(ptr++) = *text;
*(ptr++) = 0xe;
}
}
das hier funktioniert bei mir. Probier mal aus.

[edit]
// Print text on the screen
void kprintf(char* chBuffer, const unsigned int iXPos, const unsigned int iYPos)
{
    VGAMem = (char*) 0xB8000;
    while(*chBuffer)
    {

        *VGAMem = *chBuffer;
        VGAMem++;
        *VGAMem = 0x07;
        VGAMem++;
        chBuffer++;
    }
}
(auch wenn es wohl nichts mitt dem problem zutun hat)
was ich mich noch frage, wozu die beiden letzteren parameter da sind. oder soll mit denen später die Funktion SetCorsorPosition aufgerufen werden?
« Letzte Änderung: 06. October 2009, 21:54 von ika »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. October 2009, 22:42 »
Hi,

ich weiß nicht, ob ich deine Frage bezüglich dieser Fehlermeldung richtig verstehe:
Zitat
kernel_c.o: In function `main':
Kernel.c:(.text+0x48): undefined reference to `Set_Cursor'
Ist dir nicht klar, wieso es nicht funktioniert, wenn du (in main) eine Funktion (Set_Cursor) aufrufst, die du genau in dem Moment davor gelöscht hast?

Zum eigentlich Problem: Wie sieht das Linker-Skript aus? Wie lässt du den Kernel laden? Wenn der Kernel nicht dahin geladen wurde, wo er hingelinkt wurde, können durchaus die von dir beschriebenen Probleme (dass es einmal funktioniert und einmal nicht) auftreten.

Was mir noch auffällt:
Zitat
gcc -m32 -ffreestanding -o graphic_h.o -c Graphic.h -Wall -Werror -nostdinc
gcc -m32 -ffreestanding -o os_h.o -c OS.h -Wall -Werror -nostdinc
Das ist mal ziemlich sinnlos. .h-Dateien kompiliert man nicht. Du linkst sie ja auch nicht mal mit, weil du im Aufruf von ld diese Dateien ja gar nicht erwähnst.
Dieser Text wird unter jedem Beitrag angezeigt.

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 07. October 2009, 19:57 »
Ich verstehe nicht ganz, was du mit gelöscht meinst.
Linkerskript:
ENTRY (loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)

SECTIONS
{
  . = 0x00100000;
   
  .text :
  {
    *(.text)
  }
   
  .rodata :
  {
    *(.rodata)
  }

  .data :
  {
    *(.data)
  }

  .bss :
  {
    _sbss = .;
    *(COMMON)
    *(.bss)
    _ebss = .;
  }
}

Wegen den Header Dateien. Hast recht, war dumm von mir.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 07. October 2009, 20:27 »
Ups hab mich verlesen. Habe das "nicht" bei "nicht auskommentiert" überlesen. Dann ist der Punkt hinfällig ...

Welchen Compiler benutzt du?
Unter Windows? Mit fällt nämlich auf, dass du mal die Dateinamen groß und mal klein schreibst.
Wie lädst du den Kernel? Mit GRUB?
« Letzte Änderung: 07. October 2009, 20:30 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 08. October 2009, 14:40 »
gcc, Linux und Grub

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 08. October 2009, 14:47 »
Hi,

dann kann es durchaus sein, dass die Schreibweise der Dateinamen dafür verantwortlich ist:

Mit diesem Befehl hast du eine Datei namens graphic_c.o (mit kleinem g) erstellt:
gcc -m32 -ffreestanding -o graphic_c.o -c Graphic.c -Wall -Werror -nostdinc

Hier sagst du dem Linker aber er soll die Datei Graphic_c.o (mit großem G) nehmen:
ld -T LinkerSkript.ld -o Kernel.bin kernel_asm.o kernel_c.o Graphic_c.o Util_c.o

Wenn du jetzt zufällig (zum Beispiel von früheren Versuchen) noch eine Graphic_c.o herumliegen hast, nimmt er immer diese Datei statt der neuerstellten graphic_c.o. In der alten Graphic_c.o könnte es sein, dass es noch kein Set_Cursor gibt, aber ein Cls, und das wäre dann die Erklärung für das Verhalten.

Also am besten schaust du mal in das Verzeichnis mit den Objekt-Dateien und überprüfst, ob dort Graphic_c.o und graphic_c.o rumliegen. Unabhängig davon kannst dich auf eine Schreibweise einigen.
Dieser Text wird unter jedem Beitrag angezeigt.

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 08. October 2009, 19:38 »
Das war wirklich der Fehler....
Ist das peinlich :oops: .......
Danke!

 

Einloggen