Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: rizor am 15. February 2009, 01:45
-
nabend zusammen,
ich habe folgendes Problem:
Ich habe meinen Code ein wenig verändert und meine eigene libc eingebunden.
Nun bekomme ich aber folgenden Fehler:
/home/rizor/Dokumente/Projekte/os-dev/tags/tmp/kernel/krn_msg_display.c.krn_obj: In function `puts_bin_64':
/home/rizor/Dokumente/Projekte/os-dev/trunk/kernel/io/krn_msg_display.c:401: undefined reference to `__udivdi3'
/home/rizor/Dokumente/Projekte/os-dev/trunk/kernel/io/krn_msg_display.c:402: undefined reference to `__umoddi3'
Ich möchte mir der Methode puts_bin_64 wollte ich ein qword in binärer Schreibweise in einen char-array umwandeln.
Der Code der zu diesem Fehler führt, sieht wie folgt aus:
tmp = qword / (1 << i);
qword %= (1 << i);
Woran liegt das?
Habe im Internet gefunden, dass diese Methoden in dne Stdlibs von linux definiert sind.
Kann es sein, dass er die nun nicht mehr findet und ich die schreiben muss?
Danke für eure Hilfe.
Gruß
rizor
-
Diese Funktionen kommen aus der libgcc. Die sollte OS-unabhängig sein, sodass du sie direkt vom Hostsystem nehmen kannst (vorausgesetzt natürlich das hat die selbe Architektur wie die, für die du entwickelst. ;-)). Wo die liegt findest du mit folgendem Befehl:
gcc -print-libgcc-file-name
Unter linux wird die, genau wie die stdlibc, automatisch dazugepackt, wenn du mit gcc linkst, deshalb muss man die da nicht angeben.
-
Also sie liegt da, wo ich sie erwartet habe.
Was ist dann falsch?
Meine Zeile beim Kompilieren sieht wie folgt aus:
-O0 -L $(BUILD_DIR)/usr/local/bin/ -lc -g -fstrength-reduce -fomit-frame-pointer -finline-functions -fno-stack-protector -nostdinc -fno-builtin -march=i386 -I$(BUILD_DIR)/usr/include/ -I$(DEV_DIR_KRN)/include/ -c
Leider sehe ich den Fehler nicht.
Mir sind eben noch zwei andere Warnungen aufgefallen:
/tmp/ccdyFOPs.s: Assembler messages:
/tmp/ccdyFOPs.s:114: Warning: using `%al' instead of `%ax' due to `b' suffix
/tmp/ccdyFOPs.s:134: Warning: using `%al' instead of `%eax' due to `b' suffix
Kann es sein, dass mein GCC fehlerhaft ist?
Ich habe auf die Version 4.3.3 gewechselt.
Vorher war die 4.2.x drauf.
-
Ich würde eher fragwürdigen Inline-Assembler-Code vermuten.
-
Die Datei, die den Assembler-Warning auslöst, sehen so aus:
__asm__ __volatile__ ("inb %1, %0" : "=a" (result) : "dN" (port));
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
Dazu habe ich die Dateiene inb, inw, inl, outb, outw, outl.
Den Code benutze ich aber schon länger.
habe nur die outs und ins für words und longs erweiter.
Der Code sollte doch aber trotzdem funktionieren, oder?
-
Wahrscheinlich haben result und data Datentypen mit der falschen Größe.
-
Den Fehler finde ich leider nicht.
uint_8 inb(uint_16 port){
uint_8 result;
__asm__ __volatile__ ("inb %1, %0" : "=a" (result) : "dN" (port));
return result;
};
uint_16 inw(uint_16 port){
uint_16 result;
__asm__ __volatile__ ("inb %1, %0" : "=a" (result) : "dN" (port));
return result;
};
uint_32 inl(uint_16 port){
uint_32 result;
__asm__ __volatile__ ("inb %1, %0" : "=a" (result) : "dN" (port));
return result;
};
void outb (uint_16 port, uint_8 data){
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
};
void outw(uint_16 port, uint_16 data){
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
};
void outl(uint_16 port, uint_32 data){
__asm__ __volatile__ ("outb %1, %0" : : "dN" (port), "a" (data));
};
Zu dem anderen Problem mit den fehlenden Methoden habe ich auch keine Lösung gefunden.
Woran kann das denn liegen?
Es dürfte an sich doch kein Problem sein, dass auf einem 32-bit System 64-bit-Werte moduliert und geteilt werden, oder?
Wäre mir zumindest neu.
-
Möchtest du für inw/outw und inl/outl möglicherweise auch die Assemblerbefehle durch welche ersetzen, die mit mehr als einem Byte arbeiten - sprich, jeweils die Variante, nach der die C-Funktion benannt ist?
-
:-D
-
hmm....
Ich sollte mit dem Copy-Paste aufhören oder es ordentlich machen.
Dazu kommt noch totale Blindheit.
Aber woran liegt, dass das der linker die Methoden __udivdi3 und __umoddi3 nicht findet?
-
Aber woran liegt, dass das der linker die Methoden __udivdi3 und __umoddi3 nicht findet?
libgcc mitlinken, wurde ja schon von FreakyPenguin gesagt.
-
Ich dachte, dass die immer automatisch mitgelinkt wird.
Wenn ich den Pfad mit -L bei ld und beim gcc mitangebe, dann bekomme ich den Fehler trotzdem noch.
-
Mit -L alleine bringt das wohl nichts. Außerdem gibt man .a's nicht mit -l sondern ohne irgendwas (also so wie Objektdateien) an.
-
Mit -L und dann -l $NAME solte es auch gehen, wenn die Datei lib$NAME.a heißt.
-
Das Problem hat sich gelöst.
Danke für eure Hilfe.
Eine Frage hab ich noch.
Ich muss mein Makefile immer zweimal ausführen.
Beim ersten mal wird gemeldet, dass er die ganzen Methoden aus der libc nicht finden kann.
Beim zweiten mal geht es dann.
Kann es sein, dass die Ausführung auf unterschiedliche Threads aufgeteilt wird?
Ich habe das so geregelt, dass er erst die libc kompiliert und danach dann den Kernel.
Dann müsste es an sich gehen.
-
Parallel macht er nur, wenn du -j benutzt - und das funktioniert dann auch, wenn du die Abhängigkeiten richtig gesetzt hast. Dein Problem klingt eher danach als führtest du irgendetwas in falscher Reihenfolge aus.
-
Stimmt, ich habe aus versehen erst gelinkt....