Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Hauke am 07. October 2008, 13:04
-
Ich wollte ein C++ Kernel zum laufen bringen, doch mit dieser Fehlermeldung kann ich nicht richtig deuten, weil ich mich mit dem Linken nicht so auskenne.
Die Fehlermeldung:
ld -T Link.ld -o Kernel.bin
Video.o:Video.cpp:(.text+0x294): undefined reference to `__ZN6CVideo6memcpyEPvPKvj'
Video.o:Video.cpp:(.text+0x2ce): undefined reference to `__ZN6CVideo6memsetEPvij'
Video.o:Video.cpp:(.text+0x309): undefined reference to `__ZN6CVideo6memsetEPvij'
Die Datei Link.ld:
/*Link.ld*/
OUTPUT_FORMAT("binary")
INPUT (kernel32.obj Kernel.o Video.o)
ENTRY(start)
SECTIONS
{
.text 0x10200 :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
__CTOR_LIST__ = .; LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors) LONG(0) __CTOR_END__ = .;
__DTOR_LIST__ = .; LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors) LONG(0) __DTOR_END__ = .;
data = .; _data = .; __data = .;
*(.data)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
Die anderen Dateien sind die aus dem c++ Kernel Tutorial.
-
der linker beschwert sich, dass er
Video::memcpy
Video::memset
nicht finden kann, du sie aber irgend wo benutzen willst.
-
Ja hab den Fehler gefunden, hab vergessen Die Funktionen in die Klasse einzubinden (Klasse::Funktion).
Danke.
Ich wüsste gern noch etwas anderes gibt es eine Möglichkeit, dass eine C/C++ Funktion zwingen kann mit IRET statt RET zurückspringt, dass ganze währe für Interrupts sehr nützlich. Vielleicht gibt es ja eine Möglichkeit.
-
Schreib einen Stub in Assembler, der dann deine C-Funktion aufruft.
-
Ich weis nicht genau, was ‘Stub‘ ist, aber ich schätze du meinst dass:
Int_xy:
call funktion ;funktion ist eine c Funktion
iret
OK, das kann man machen. Darauf bin ich eigentlich auch gekommen, aber ich hab mir gedacht, dass es Vielleich eine andere Möglichkeit dazu gibt, weil für den Compiler das keine große Schwierigkeit sein sollte.
-
Du willst das sowieso haben, du wirst nämlich im allgemeinen für alle Interrupts denselben Handler aufrufen wollen. Jetzt gibt es da aber beispielsweise Exceptions mit Errorcode und welche ohne. Bei denen ohne willst du noch ein push 0 machen, damit dein Stack einheitlich aussieht. Und mit der Zeit kommt da noch mehr Zeug rein. ;)
-
Ich sehe schon, dass es mit C/C++ auch nicht ganz so einfach ist.
Jetzt hab die IDT in c realisiert, jedoch hab ich da noch ein Problem mit globalen Funktionen.
Ich hab eine Test Funktion in asm geschrieben:
global int00
...
int00:
iret
und in der cpp Datei auch deklariere
extern void int00();
und mit (unsigned int) int00
verwende ich das.
Und im Linkscript hab ich auch
ENTRY(int00)
hinzugefügt (ich weis nicht, ob das erforderlich ist)
aber der Linker prangert folgendes an: undefined reference to '__Z5int00v'
Wo muss ich den alles die Funktion hinschreiben
Wie muss ich das den richtig machen.
-
das liegt am C++
wenn du asm funkitonen includen willst, musst du das mit
extern "c" void int00();
machen. ( oder im asm die labels nach C++-Standard benennen :wink: )
Das 'entry(int00)' ist falsch. es würde bedeuten, dass deine
objekt-datei(kernel) mit deiner int00-Funkiton gestartet werden soll.
-
extern "c" void int00();
Geht nicht, er meckert folgendes:
language string '"c"' not recognized
oder im asm die labels nach C++-Standard benennen
wie macht man das?
-
sry.
du musst das c groß schreiben C.
oder im asm die labels nach C++-Standard benennen
wie macht man das?
das hab ich nicht wirklich ernst gemeint, ich bin auch nicht sicher ob es reicht die labels so zu benennen:
__Z5int00v
wie genau sich das zusammen setzt weiß ich nicht, aber es sind unteranderem die parametr die übergeben werden mit eingearbeitet.
-
Es reicht definitiv die Labels so zu benennen wie in der Fehlermeldung des Linkers angegeben. Das ganze nennt sich C++ name mangling und ist Compilerabhängig und eben nicht im C++ Standard spezifiziert. Es ist aber in der bzw. einer der gcc ABI(s) genau beschrieben wie gcc das macht (siehe hier (http://www.codesourcery.com/public/cxx-abi/abi.html#mangling)), aber ich würde dir eher raten einfach den richtigen Labelnamen aus den Linkerfehlermeldungen zu entnehmen, dass geht einfach als sich über das ganze Gedanken zu machen.
-
Ja geht jetzt.
Danke :-)
-
Wie wäre es damit, einfach bei extern "C" zu bleiben anstatt sich aus Fehlermeldungen was zusammenzubauen? Kommt mir irgendwie wesentlich sauberer vor...
-
extern "C" ist nicht in jedem Kontext verwendbar. Es funktioniert (zumindest unter g++) nicht für Memberfunktionen (auch nicht für statische).
-
Die Frage ist, ob man es da braucht oder ob man nicht besser eine Wrapperfunktion schreibt. Assembler ist nunmal nicht objektorientiert.