Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: MrPerfekt am 13. May 2010, 10:55

Titel: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 10:55
hallo
Könnt ihr mir sagen was ich beim Linken falsch mache
ich habe eine Methode BootPoint und möchte diese als einstiebspunkt in mein Programm vestlegen

damit linke ich:
ld -static -melf_i386 -e BootPoint -o $bin/$entrypoint $bin/*.o &&
objcopy -R .note -R .comment -S -O binary $bin/$entrypoint $bin/entrypoint.bin || exit 1
Titel: Re: c++ linken problem
Beitrag von: kevin am 13. May 2010, 11:14
Und was passiert?
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 12:31
asoo entschuldige das habe ich fergessen
usr/bin/ld.bfd.real: warning: cannot find entry symbol BootPoint; defaulting to 0000000008048074
/home/andreas/Desktop/BlackWindow/bin/kernel.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
/home/andreas/Desktop/BlackWindow/bin/loader.o:(.eh_frame+0x12): undefined reference to `__gxx_personality_v0'
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 12:36
Du musst mit -fno-exceptions -fno-rtti kompilieren.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 15:07
der tipp mit dem kompilieren hat geholfen
aber den startpunkt findet er trotzdem noch nicht
hättet ihr da auch noch eine idee

/usr/bin/ld.bfd.real: warning: cannot find entry symbol BootPoint; defaulting to 0000000008048094
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 15:20
Den hast du wahrscheinlich vergessen extern "C" zu deklarieren, siehe auch wiki (http://www.lowlevel.eu/wiki/C%2B%2B#C.2B.2B_Funktionen_aus_C.2FAssembler_nutzen). Ansonsten hast du die Funktion vergessen zu definieren oder linkst die entsprechende Objektdatei nicht hinzu.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:14
Den hast du wahrscheinlich vergessen extern "C" zu deklarieren, siehe auch wiki (http://www.lowlevel.eu/wiki/C%2B%2B#C.2B.2B_Funktionen_aus_C.2FAssembler_nutzen). Ansonsten hast du die Funktion vergessen zu definieren oder linkst die entsprechende Objektdatei nicht hinzu.
Genau dass war mein fehler danke
aber es funktioniert noch nicht ganz
Hier nochmal eine zusammenfassung:
- Mein Bootloader Ladet ein paar sektoren in den Arbeitsspeicher
- Mein Bootloader Schaltet in den 32bit protected mode
- Mein Bootloader springt an das erste byte meines geladenen programmes
== Bis hier funktioniert alles danach nichts mehr
- das programm sollte 2 zeichen schreiben
- das programm ruft eine methode aus einem 2.ten programm auf
- diese methode hängt sich in einer endlosschleife auf

Ich compilliere mit
g++ -fno-exceptions -fno-rtti -Wall -m32 -Iinclude $i -c -o $olinke mit
ld -static -melf_i386 -e BootPoint -o $bin/$entrypoint -Ttext 0x8000 $bin/*.ound füge so mein programm an meinen bootloader
cat $bin/$boot.bin $bin/$entrypoint.bin > $bin/out.bin

Mein haupt cpp programm:
#include "loader.h"
#include "kernel.h"
void BootPoint()
{
int x = 1, y = 0;
char*videoPosition;
videoPosition = (char*)(0xB8000 + (y * 80 + x)*2);
*videoPosition = '=';
*((char*)(0xB8000)) = '=';
KernelMain();
}
und die dazugehörige .h datei
#ifndef _loader_h_
#define _loader_h_

extern "C" void BootPoint();
#endif // ifndef _loader_h_
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 17:18
Die obligatorische Frage: Warum meinst du einen eigenen Bootloader schreiben zu wollen/müssen? In 99% der Fälle willst du einfach GRUB nehmen. Es gibt mehrere Tutorials wie man das macht im Wiki, sogar eins mit C++.

Ansonsten müsste man den konkreten Sourcecode sehen oder die genauen Fehlermeldungen in einem Emulator mit Debugausgaben (z.B. bochs wenn man die Debugausgaben für "CPU0" hochschraubt, was man irgendwo im Konsolenmenü kann [zumindest die Linux-User]).

edit: Ich wette dein Bootloader versteht das ELF-Dateiformat nicht.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:19
der bootloader funktioniert
ich habe bereits ein programm laden können welches nicht gelinkt worden ist

mein bootloader unterstützt noch kein dateiformat
das ist der grund warum ich meinen eigenen verwende
ok nicht nur das
mich interessiert es wie alles funktioniert
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 17:22
der bootloader funktioniert
Natürlich :roll:
Was meinst du wie viele das hier schon versucht haben glaubhaft zu versichern? Irgendwann glaubt man einfach nicht mehr an den "ich kopier mir was zusammen und das funktioniert ganz bestimmt in allen Lebenslagen ohne das ich irgendwas vom Bootloader verstanden haben muss und das ganze in 512Byte"-Bootloader.

edit: So wie das aussieht baut ld aber da eine ELF-Datei, oder? Kannst du ja per objdump nachprüfen. Wenn du kein Dateiformat im Bootloader implementiert hast, tut das natürlich nicht.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:24
ok ich habe vielleich so begonnen
aber was herausgekommen ist wirst du nigenst im internet finden
(auser die professorische gdt)
(idt habe ich noch nicht implementiert)
da ich alles selbst geschrieben habe

edit: So wie das aussieht baut ld aber da eine ELF-Datei, oder? Kannst du ja per objdump nachprüfen. Wenn du kein Dateiformat im Bootloader implementiert hast, tut das natürlich nicht. moment
noch einmal langsam
was meinst du
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 17:27
Du kannst dir eventuell auch mal das (http://www.lowlevel.eu/wiki/GRUB#Warum_GRUB.3F) durchlesen. Da stehen abgesehen von der obligatorischen Werbung für GRUB meinerseits auch ein paar Sachen drin die man über seinen Bootloader wissen sollte.

Ich meine, dass ld der ausgegebenen Datei ein bestimmtes Dateiformat verpasst, in dem Fall ist es ELF (Executable and Linkable Format, das Standarddateiformat für ausführbare Programme unter Unix). Das dient dazu, dass derjenige der die Datei lädt weiß, an welche Adresse es zu laden ist bzw. falls er es an eine andere Adresse laden will herausfindet welche Adressen (zB von Jumps/Calls, Zugriffen auf das Datensegment, etc...) er abändern muss. Außerdem wird die ausführbare Datei in Sektionen (Code, Daten) unterteilt, damit das Betriebssystem beispielsweise den Codebereich readonly und executable machen kann und den Datenbereich readwrite und non-executable.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:30
ok dann kurz einen bootloader:
[ORG 07C00h] ;ab hier Startet das Programm
[bits 16]

jmp 0000h:start


start:
        ; Update the segment registers
mov ax, cs
        mov ds, ax
        mov es, ax

call print

;================================================================
;Lade das weitere Programm in den Arbeitsspeicher
;================================================================
reset:                      ; Reset the floppy drive
mov ax, 0           ;
mov dl, 0           ; Drive=0 (=A)
int 13h             ;
jc reset            ; ERROR => reset again


read:
mov ax, 0x0050 ; ES:BX = 0050:0000
mov es, ax ;
mov bx, 0x0000 ;

mov ah, 2 ; Load disk data to ES:BX
mov al, 5 ; Load 5 sectors
mov ch, 0 ; Cylinder=0
mov cl, 1 ; Sector=1
mov dh, 0 ; Head=0
mov dl, 0 ; Drive=0
int 13h ; Read!

jc read ; ERROR => Try again

;================================================================
;Das weitere Programm wurde in den Arbeitsspeicher geladen
;Schalte in den Protected Mode
;================================================================
[BITS 16]
cli ; Interrupts ausschalten
lgdt [gdtr] ; GDT Pointer laden

mov eax,cr0 ; In PMode wechseln, indem das niedrigste
or al,1 ; Steuerungsbit von cr0 geändert wird
mov cr0,eax ; muss über Umweg über ein anderes Register gemacht werden

jmp codesel:PMode ; FarJump zu einer 32-Bit PMode Funktion

[BITS 32]
PMode:
mov ax,datasel ; Segmentregister laden
mov ds,ax
mov ss,ax
mov esp,0x90000 ; Stack aufsetzen

mov eax, 1 ; Zeile
mov ebx, 0 ; Spalte
call print32

jmp 0x0500+512
;================================================================
;Das Programm ist nun im Protected Modus
;GDT
;================================================================
gdtr: ; Desktiptortabelle
dw gdt_end-gdt-1 ; Limit
dd gdt ; Basisadresse
gdt:
dd 0,0 ; Null-Deskriptor
codesel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x9A ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
datasel equ $-gdt
dw 0xFFFF ; Segmentgrösse 0..15
dw 0x0000 ; Segmentadresse 0..15
db 0x00 ; Segmentadresse 16..23
db 0x92 ; Zugriffsberechtigung und Typ
db 0xCF ; Zusatzinformationen und Segmentgrösse 16...19
db 0x00 ; Segmentadresse 24..31
gdt_end:
;================================================================
;GDT ende
;================================================================

;================================================================
; int2string (schreibt eax in den string)
; eax = number
;================================================================
[bits 16]
int2string:
PUSHA
LEA edi,[string]
MOV esi, edi
;MOV eax, 479
MOV ecx, 0x000A
startLoop:

MOV byte [edi], '0'
XOR edx,edx
DIV ecx

ADD [edi],edx
;MOV byte [edi], ebx
;ADD [edi],ebx

INC edi
CMP eax,0
JNE startLoop
MOV byte [edi],0
DEC edi
; vertausche die Richtung
switchLoop:
MOV ah, [esi]
MOV al, [edi]

MOV [esi], al
MOV [edi], ah

DEC edi
INC esi
CMP edi,esi
JA switchLoop

POPA
RET
;================================================================
; end int2string
;================================================================

;================================================================
; Print 16
;================================================================
string DB "Lade Black Window 0.0.0.0.0.0.0.6.0",0
print:
PUSHA
LEA bx,[string]
startOutLoop:
CMP byte [bx],0
JE ende
MOV ah,0eh
MOV al,[bx]
INT 10h
INC bx
JMP startOutLoop
ende:

MOV bh, 0
MOV ah, 03h
INT 10h
MOV ah, 02h
MOV dl, 0
INC dh
INT 10h
POPA
RET
;================================================================
; end Print
;================================================================

;================================================================
; Print 32
; eax = Line
; ebx = Position
;================================================================
[bits 32]
string32 DB "32 Bit Protected Modus geladen                ",0
print32:
pusha
mov edx,0x50
mul edx
add eax,ebx
mov edx,0x2
mul edx
add eax,0xb8000
lea edx,[string32]

.paintloop:
mov cl,[edx]
mov byte [eax],cl
inc edx
add eax,0x2
cmp byte [edx],0
jne .paintloop

popa
ret
[bits 16]
;================================================================
; end Print
;================================================================



;================================================================
;Schreibe die Bootloaderidentifikation
;================================================================
times 440-($-$$) db 0
dq 0x00000000 ;Optional Disk Signatur
dw 0x0000 ;Usually Nulls
  ;Table of primary partitions
times 510-($-$$) db 0
bootloaderIdentifikation dw 0x0AA55
;================================================================
;ende Schreibe die Bootloaderidentifikation
;================================================================


aber wie kann ich den mit grub ersetzten
da müsste ich mir immerwieder einen grub auf mein img laden
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 17:33
aber wie kann ich den mit grub ersetzten
siehe zB. C++ Kernel mit GRUB (http://www.lowlevel.eu/wiki/C%2B%2B-Kernel_mit_GRUB) bzw. natürlich die OSDev für Einsteiger Serie (http://www.lowlevel.eu/wiki/Kategorie:OS-Dev_f%C3%BCr_Einsteiger), die C benutzt, aber dafür einiges mehr zu bieten hat.

Zitat
da müsste ich mir immerwieder einen grub auf mein img laden
Korrekt, aber das ist unter Linux normal kein Problem (siehe zB hier (http://www.lowlevel.eu/wiki/GRUB#Siehe_auch)). Im Zweifelsfall bleibt immer der Ausweg ein vorgefertigtes Image (zB das von tyndur) herzunehmen und alles andere runterzuschmeißen.

edit: Was genau erwartest du von uns bezüglich des Quellcodes deines Bootloaders?
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:35
aber jetzt einmal angenommen mein bootloader funktioniert
(hat er ja bei programmen die nicht gelinkt werden gemacht)
dann müsst ja irgentwo noch ein fehler sein
Titel: Re: c++ linken problem
Beitrag von: kevin am 13. May 2010, 17:36
Ja, du gibst ihm eine Datei im falschen Dateiformat. Wenn er den ELF-Header als Code ausführen will, kommt eben Mist raus.
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 17:37
Wie gesagt, dein Kernel hat ein Dateiformat, dass der Bootloader nicht versteht. Du kannst jetzt entweder den Kernel so Linken, dass er eine "flache Binary" ist (d.h. spezielles Dateiformat) oder deinem Bootloader das verwendete Dateiformat beibringen.

edit: Ich sollte vielleicht noch sagen, dass ersteres keine tolle Lösung ist.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:38
asoo
jetzt verstehe ich
jetzt wird mir einiges klar
aber wie kann ich so linken das eine reine binare datei datei übrich bleibt
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 17:41
--oformat=binary zur Kommandozeile hinzufügen sollte das tun. Dann sollte allerdings dein Bootloader wissen an welche Adresse der Kernel gelinkt wurde, d.h. dann auch an welche Adresse er den Kernel zu laden hat.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 17:43
danke danke danke
die header zu interpretieren versuche ich dann in meinem loader
danke nocheinmal

mrPerfket
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 18:49
ok irgentwie doch noch nicht
ich bekomme danach eine datei raus mit der ich nichts anfangen kann
weder mit objcopy noch direct als bin datei
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 18:59
Das objcopy macht auch keinen Sinn mehr auf eine "flache Binärdatei", insofern kannst du das sowieso weglassen. Ansonsten weiß ich nicht, was du damit gerne "anfangen" würdest. Wenn du das mal genauer spezifizieren könntest und dann auch noch sagst was dann passiert bzw. wieso es nicht geht, dann könnte man dir vielleicht helfen.

edit: Das Problem ist wahrscheinlich (wie ich oben schon erwähnt hatte), dass du ld nicht sagst, an welche Adresse der Code gelinkt wird. An genau diese Adresse muss der Bootloader dann auch den Code laden (sonst funktionieren absolute Jumps/Calls, Datenzugriffe, etc... nicht, was hoffensichtlich einsichtig sein sollte).

edit2: Was ganz wesentliches vergessen: Dein Bootloader weiß nicht an welcher Adresse innerhalb der Datei sich der Einsprungspunkt (also zB main) befindet. Das ist auch einer der Gründe warum man ungern auf ein Dateiformat verzichtet (wie bereits oben erwähnt). Aber mit irgendeiner weiteren Frickellösung kriegt man auch das hin.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 13. May 2010, 20:53
sorry wenn ich nocheinmal störe
irgentwie kann ich mit dem file dass dabei rauskommt nichts anfangen
Titel: Re: c++ linken problem
Beitrag von: kevin am 13. May 2010, 20:59
Vielleicht solltest du dann doch erstmal den einfachen Weg nehmen und GRUB benutzen.

Sich absichtlich für den schwereren Weg zu entscheiden, weil man eine Herausforderung sucht, ist schön und gut, aber dann darf man nicht erwarten, dass andere einem die Arbeit abnehmen. Wenn du dir einen anständigen Bootloader zutraust, solltest du auch deine Binaries halbwegs im Griff haben.
Titel: Re: c++ linken problem
Beitrag von: bluecode am 13. May 2010, 22:50
irgentwie kann ich mit dem file dass dabei rauskommt nichts anfangen
Wenn du Hilfe willst, dann solltest du sehr viel genauer erklären wo du ein Problem hast. Nichtmal meine Kristallkugel hilft mir da gerade weiter. :-D
Titel: Re: c++ linken problem
Beitrag von: Svenska am 14. May 2010, 03:55
Und, ohne dir zu Nahe treten zu wollen, ein bisschen Rechtschreibung (oder zumindest eine automatische Rechtschreibprüfung, Firefox hat sowas eingebaut) macht Posts grundsätzlich besser lesbar.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 14. May 2010, 08:08
könnt ihr mir fl noch sagen warum ich mit dieser datei nichts anfangen kann
bzw wie ich es schaffe das der startpunkt mein 1. befehl ist

hab schon allemöglichen optionen ausprobiert und fiel gegoogelt
Titel: Re: c++ linken problem
Beitrag von: bluecode am 14. May 2010, 08:46
bzw wie ich es schaffe das der startpunkt mein 1. befehl ist
Indem du diejenige Funktion in eine eigene Sektion packst (siehe gcc-Dokumentation zu __attribute__((section("blub"))) (http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Function-Attributes.html#Function-Attributes)). Dann brauchst du noch ein Linkerskript (siehe OSDev für Einsteiger bzw. das C++ mit GRUB Tutorial für Ideen). In diesem Linkerskript sollte dann die Sektion "blub" zu Beginn stehen, damit der Code deiner "Startfunktion" eben ganz am Anfang steht.
Aber wie bereits oben gesagt ohne richtiges Dateiformat kommen nur Frickellösungen raus, die dir irgendwann später wieder um die Ohren fliegen raus.

Zitat
könnt ihr mir fl noch sagen warum ich mit dieser datei nichts anfangen kann
Ich sage es nochmals in hoffentlich ausreichender Deutlichkeit: Das ist keine (ausreichende) Problembeschreibung. Damit kann hier niemand etwas anfangen. Das ist genauso wie zu sagen meine Kaffeemaschine funktioniert nicht ohne dem Techniker zu sagen welche Marke oder Modell es denn wäre, was denn eigentlich nicht funktioniert und natürlich ohne die Kaffeemaschine überhaupt zur Reparatur mitzubringen.
Titel: Re: c++ linken problem
Beitrag von: MrPerfekt am 16. May 2010, 11:19
sorry sorry
Ich hatte in Letzter Zeit viel stress.
Aber jetzt um einiges mehr Zeit.
Ich nehme nun einmal den guten ratschlag an und probiere das elf32 format in meinen Bootloader zu integrieren.
Ich melde mich ob es funktioniert hat.
Danke forerst einmal.