Autor Thema: c++ linken problem  (Gelesen 13974 mal)

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« 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
« Letzte Änderung: 14. May 2010, 08:08 von MrPerfekt »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 13. May 2010, 11:14 »
Und was passiert?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #2 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'

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 13. May 2010, 12:36 »
Du musst mit -fno-exceptions -fno-rtti kompilieren.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #4 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

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 13. May 2010, 15:20 »
Den hast du wahrscheinlich vergessen extern "C" zu deklarieren, siehe auch wiki. Ansonsten hast du die Funktion vergessen zu definieren oder linkst die entsprechende Objektdatei nicht hinzu.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 13. May 2010, 17:14 »
Den hast du wahrscheinlich vergessen extern "C" zu deklarieren, siehe auch wiki. 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_
« Letzte Änderung: 13. May 2010, 17:18 von MrPerfekt »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #7 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.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #8 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
« Letzte Änderung: 13. May 2010, 17:22 von MrPerfekt »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #9 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.
« Letzte Änderung: 13. May 2010, 17:23 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #10 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
« Letzte Änderung: 13. May 2010, 17:26 von MrPerfekt »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #11 am: 13. May 2010, 17:27 »
Du kannst dir eventuell auch mal das 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.
« Letzte Änderung: 13. May 2010, 17:30 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #12 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
« Letzte Änderung: 13. May 2010, 17:33 von MrPerfekt »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #13 am: 13. May 2010, 17:33 »
aber wie kann ich den mit grub ersetzten
siehe zB. C++ Kernel mit GRUB bzw. natürlich die OSDev für Einsteiger Serie, 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). 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?
« Letzte Änderung: 13. May 2010, 17:36 von bluecode »
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #14 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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #15 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.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #16 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.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #17 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

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #18 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.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MrPerfekt

  • Beiträge: 26
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 13. May 2010, 17:43 »
danke danke danke
die header zu interpretieren versuche ich dann in meinem loader
danke nocheinmal

mrPerfket
« Letzte Änderung: 14. May 2010, 08:06 von MrPerfekt »

 

Einloggen