Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Another Stupid Coder am 30. July 2004, 09:28
-
Hallo, ihr.
Nachdem ich mich eine Zeit lang nur mit Theorie und Assembyl beschäftigt habe grub ich gestern einen "meiner" (das meiste ist "übernommen"...aber verstehen tue ich es schon) alten C-Kernel wieder aus plötzlich sagte er mir ld
kernel.o(.data+0x0): multiple definition of `VideoMem'
video.o(.data+0x0): first defined here
kernel.o(.bss+0x0): multiple definition of `VideoPos'
video.o(.bss+0x0): first defined here
Was doch darauf schließen lässt das er die Datei "video.h" (wo VideoMem und VideoPos definiert sind) 2 mal includiert oder? Tja, hier kommt der Sourcecode:
video.h :
#ifndef HELIOS_VIDEO_H
#define HELIOS_VIDEO_H
// Format : COLOR_BACK_FORE
#define COLOR_BLACK 0xF0
#define COLOR_BLUE 0xF1
#define COLOR_GREEN 0xF2
#define COLOR_TUERKIS 0xF3
#define COLOR_RED 0xF4
#define COLOR_MAGENTA 0xF5
#define COLOR_BROWN 0xF6
#define COLOR_LIGHTGRAY 0xF7
#define COLOR_DARKGRAY 0xF8
#define COLOR_LIGHTBLUE 0xF9
#define COLOR_LIGHTGREEN 0xFA
#define COLOR_LIGHTTUERKIS 0xFB
#define COLOR_LIGHTRED 0xFC
#define COLOR_LIGHTMAGENTA 0xFD
#define COLOR_YELLOW 0xFE
#define COLOR_WHITE 0xFF
// Variables
char *VideoMem = (char *) 0xb8000;
unsigned int VideoPos = 0;
void ClearScreen(char Color);
unsigned int PrintMsg(char *Msg, char Color);
#endif
video.c :
#include <video.h>
void ClearScreen(char Color)
{
VideoPos = 0;
while(VideoPos < (80 * 25 * 2))
{
VideoMem[VideoPos] = ' ';
VideoPos++;
VideoMem[VideoPos] = Color;
VideoPos++;
};
VideoPos = 0;
};
unsigned int PrintMsg(char *Msg, char Color)
{
while(*Msg)
{
if(*Msg == '\n')
{
VideoPos = (((VideoPos / 160) + 1) * 160) + (VideoPos % 160);
}
else
{
VideoMem[VideoPos] = *Msg;
*Msg++;
VideoPos++;
VideoMem[VideoPos] = Color;
VideoPos;
};
};
return(1);
};
kernel.c :
#include <video.h>
k_main()
{
ClearScreen(COLOR_BLACK);
PrintMsg("Hello, World!", COLOR_BLUE);
};
das Makefile (es sind nur ein paar schnell reingetippte Befehle) :
all:
gcc -ffreestanding video/video.c -c -I./video/
gcc -ffreestanding kernel.c -c -I./video/
nasm k_init.asm -f aout
ld -T Link.ld k_init.o video.o kernel.o -o kernel
nasm boot.asm -o boot.bin
cat boot.bin kernel > kernel.img
rm boot.bin
rm kernel
rm kernel.o
rm k_init.o
Ich hoffe jemand kann mir helfen, Danke jedenfalls schon im vorraus.
-
Du inludierst sie ja auch 2mal;) einmal in der kernel.c einmal in der video.c
Das du das ifndef verwendest heisst ja nicht das er die ganze datei nicht includet, beim ersten mal wird der inhalt übernommen, beim zweiten mal übergeht er alles aber wie das helio... schon definiert ist, includiert wird sie trotzdem nur werden keien zusätzlichen daten compiliert. Ich hoffe das war soweit sinnvoll ud verständlich was ich sagte^^
-
Ja, schon aber das sollte doch eigentlich keinen Fehler hervor rufen oder? Denn compilliert wirds doch nur einmal...also was kann ich da machen?
-
Nimm einfach mal das include in der kernel.c raus du weisst ja schliesslich was du wo definierst oder? mehrfachdefis bringen meist probleme
Aber das eigentliche problem leigt glaube ich darin dass du kernel und video getrennt compilierst, mache einfach beides zusammen, also include die video an den anfang der kernel, dein makefile müssteste auch dann ändern also nur noch einmal das gcc am anfang dann beim ld auch nur noch eine objektdatei.
du baust es ja nicht zum kern wo es ja hinsoll sondern machst ne seperate datei draus, also du kompilierst es wirklich 2 mal, seh ich auch jetzt erst. einmal komlierst es in kernel dann ins video dann erst linkt er das ganze.(man kling ich heute wirr...) jedenfalls mach ein ein include der video in den kernel änder das makefile und alles solte behoben sein
-
Wird das nicht 2 mal compiliert? Der kompiliert die Dateien doch unabhängig voneinander, so das beim 2. mal (Das kompilieren des Kernels) HELIOS_VIDEO_H noch garnicht definiert ist. Dann ist es 2 mal (jeweils einmal in deb Beiden Dateien) vorhanden und das gibt einen Fehler. Mit es meine ich die Variblen. Am besten du packst die mit in die Video.c und in die Header bindest du sie dann mit extern ein.
-
Genau das selbe wollte ich damit auch ausdrücken^^
-
Ja, sorry, habe geschrieben, während du es reingestellt hast und deswegen ist es jetzt doppelt. (Aber die Lösungen sind doch bisschen anders, oder?)
-
im endeffekt ist es egal obs in die video oder in die kernel includiert wird, sonst isses doch das selbe
-
Wie ich dich verstanden habe, willst du die beiden .c zusammenfassen oder zusammenfassend kompilieren (mit gcc). Nach meinem Vorschlag sollen die aber einzelt kompiliert werden und dann gelinkt (Makefile bleibt gleich). Oder habe ich dich da falsch verstanden?
-
Ne schon richtig, ich merk grad so wie dus machst isses doch irgendwie das selbe wie er es macht oder? Er kompilierts auch einzeln und linkt es dann.
-
Ja, aber ich habe die Variblen in einer .c, die dann !ein! Objekt wird und nicht in den Headern, die mehrfach eingebunden werden können.
-
Danke, für eure Tipps! Ich nehme mal an das es so klappt, aber ich werde es gleich testen gehen.
-
hi
Ein tipp:
reserviere nie in einem Header Speicher.
definier die Variablen in video.c und setze vor die Variablen in video.h ein extern, damit sagst du dem Compiler, das es die Variable gibt (und was für eine Typ die hat) aber sie wird halt eben nicht definiert (=Speicherplatz reservieren).
mfg gurru
-
@gurru: Davon rede ich doch die ganze Zeit. (OK, ich rede nicht, sondern ich schreibe)
-
Ja, mitlerweile hab's sogar ich kapiert, danke :) (wirklich nicht bös' gemeint!)
War mir auch vorher schon klar, nur habe ich den Fehler meinerseits nicht wirklich wahrgenommen.
-
hi
@ch15
Sorry, habs übersehen
mfg gurru