Autor Thema: QEmu greift auf falschen Speicher zu  (Gelesen 11711 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« am: 22. February 2010, 08:51 »
Hallo zusammen,

ich habe ein Problem mit QEmu.
Wenn der Emulator startet, stürzt er mitfolgendem Status ab:
qemu: fatal: Trying to execute code outside RAM or ROM at 0x000a0000

EAX=00004500 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00009fe0
EIP=0000fdfb EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =9000 00090000 0000ffff 00009300
CS =9020 00090200 0000ffff 00009b0f
SS =9000 00090000 0000ffff 00009300
DS =9000 00090000 ffffffff 00cf9300
FS =9000 00090000 0000ffff 00009300
GS =9000 00090000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT=     000c9a50 00000017
IDT=     00000000 000003ff
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00004500 CCD=00004546 CCO=ADDB   
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Aborted

Ich vermute mal, dass es am Linker-Script liegt, da es vorher funktioniert hat.
Hier ist auch mal mein Linker-Script.
LD meldet allerdings keine Fehler oder Warnungen.
ENTRY(boot) /* the entry-method for the kernel */
OUTPUT_FORMAT(elf32-i386) /* the linked code is x86-code */

ALIGNMENT = 0x1000; /* the alignment for the linker-parts */
LINK_ADDRESS = 0x100000; /* the link-address of the kernel */

SECTIONS
{
. = LINK_ADDRESS; /* load the kernel at LINK_ADDRESS */

/* elemental symbols for correct mapping */
__kernel_start = .; /* the method for the loaded entry */
__ro_data_start = .; /* the start of the read-only-data */

/* code-section from the c-code*/
.text : AT(ADDR(.text))
{
__text_start = .; /* the start of the text-section */
__mb_start = .;
*(.multiboot)
__mb_end = .;
*(.text)
__text_end = .; /* the end of the text-section */
}


/* read-only data */
.rodata : AT(ADDR(.rodata))
{
__ro_start = .; /* the start of the read-only-section */
*(.rodata)
__ro_end = .; /* the end of the read-only-section */
}

/* symbols for other kernel-modules */
.symbols : AT(ADDR(.symbols))
{
__symbols_start = .; /* the start of the symbols-section */
*(.symbols)
__symbols_end = .; /* the end of the symbols-section */
}


. = ALIGN(ALIGNMENT); /* align the code at the alignment-address */
__ro_data_end = .; /* the end of the read-only-data*/
__rw_data_start = .; /* the start of read-write-data */


/* initialized data */
.data : AT(ADDR(.data))
{
__data_start = .; /* the start of the data-section */
*(.data)
__data_end = .; /* the end of the data-section */
}

/* uninitialized data */
.bss : AT(ADDR(.bss))
{
__bss_start = .; /* the start of the bss-section */
*(.bss)
__bss_end = .; /* the end of the bss-section */
}

. = ALIGN(ALIGNMENT); /* expand the kernel to a new ALIGNED address */

__rw_data_end = .; /* the end of read-write-data */
__kernel_end = .; /* the method for the loaded end*/
}

Woran kann es denn liegen?

Gruß,
rizor
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #1 am: 22. February 2010, 09:09 »
Bei mir tritt ein ganz ähnlicher Fehler auf, wenn nicht genau der gleiche Fehler auf...
Ich habe allerdings noch nicht herausgefunden, wie ich diesen beheben kann. Alles, was ich bisher herausgefunden habe ist, dass der Fehler nicht auftritt, wenn ich den Aufruf der C Funktion "KernelInit" aus dem GRUB Assemblerstub entfernt habe...

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 22. February 2010, 09:11 »
Wie entferne ich die Funktion denn aus dem ASM-Stub?

[EDIT]
Mir fällt gerade ein, dass ich kein Grub verwende.
Ich benutze den -kernel-Parameter von Grub.
Der lädt direkt das Elf-File
« Letzte Änderung: 22. February 2010, 09:17 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #3 am: 22. February 2010, 09:16 »
Es ging mir darum. Sobald ich vom Assemblerstub aus C/C++ Code ausführe, tritt bei mir genau der gleiche Fehler auf. Wenn ich ihn behoben habe, schreiben ich, wie ich das gemacht habe...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 22. February 2010, 09:43 »
Wie sieht denn der Entrycode (also boot) aus?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 22. February 2010, 10:23 »
Meine StartUp-Methode sieht so aus:
.section multiboot
#ifdef CONFIG_MULTIBOOT
#define MB_MAGIC 0x1badb002
#define MB_FLAGS 0x0
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)

.align 4
.int MB_MAGIC //mbh_magic every time
.int MB_FLAGS //mbh_flags every time
.int MB_CHECKSUM //mbh_checksum every time
.int 0x0 //mbh_header_addr mbh_flags[16]
.int 0x0 //mbh_load_addr mbh_flags[16]
.int 0x0 //mbh_load_end_addr mbh_flags[16]
.int 0x0 //mbh_bss_end_addr mbh_flags[16]
.int 0x0 //mbh_entry_addr mbh_flags[16]
.int 0x0 //mbh_mode_type mbh_flags[2]
.int 0x0 //mbh_mode_width mbh_flags[2]
.int 0x0 //mbh_mode_height mbh_flags[2]
.int 0x0 //mbh_mode_width mbh_flags[2]
#endif /* CONFIG_MULTIBOOT */

.section .text

#ifdef CONFIG_MULTIBOOT
.extern mbm_init
#endif /* CONFIG_MULTIBOOT */
.extern init

.global boot
boot:
cli
mov $krn_esp , %esp
#cover the stack-backtrace
push 0
push 0
mov %esp , %ebp
#ifdef CONFIG_MULTIBOOT
push %ebx
push %eax
call mbm_init
push %eax
#endif /* CONFIG_MULTIBOOT */
call init
cli
hlt

.section .bss
.space 8192
krn_esp:
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #6 am: 22. February 2010, 10:28 »
Funktioniert das ganze denn wenn du als erstes ein
cli
hlt
ausführst? Macht mbm_init oder init irgendwas interessantes? Das cli;hlt kannst du auch so lange weiter im Code nach unten verschieben, bis es eben nicht mehr tut und dir dann überlegen warum das dann nichtmehr tut :wink:
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

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 22. February 2010, 10:30 »
Das werde ich nachher mal ausprobieren.
Das mbm_init wertet einfach den Multiboot-Header aus.
init startet dann die physikalische und virtuelle Speicherverwaltung.
Außerdem wird das char-Array des Aufrufs ausgewertet und danach startet dann der eigentliche Kernel
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #8 am: 22. February 2010, 10:32 »
Das sind aber schon eine ganze Menge an Sachen die schieflaufen können. Da solltest du erstmal wie oben beschrieben (oder mit den Debuggingfeatures aus deinem Emulator) herausfinden, wo genau es schiefläuft.
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #9 am: 22. February 2010, 11:25 »
Da der Thread nun schon mal offen ist, frage ich einfach.  :roll:
 
Und zwar nutze ich momentan qemu 0.12.2 unter windows um meinen Kernel per "qemu -kernel kernel.zwerg" laufen zu lassen. Der Fehler, der auftritt ist dem von rizor sehr ähnlich: http://nopaste.info/b310717e31.html
 
Nun habe ich daran eine Weile herumprobiert und es schien, dass der Fehler auftritt, sobald C/C++ Code aufgerufen wird. Also habe ich die Aufrufe komplett aus dem Stub entfernt (auskommentiert). Nun tritt dieser Fehler immer noch auf... Kann es sein, dass dann in meinem Linkerscript/Assemblerstub ein Fehler ist?
Linkerscript: http://nopaste.info/8d64928881.html
Assemblerstub: http://nopaste.info/dfcca884b0.html

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #10 am: 22. February 2010, 11:42 »
Am Linkerskript fällt mir auf, dass du zum einen .dtors in .data hast zum anderen aber discarden willst. Ansonsten kannst du mal mit objdump überprüfen, ob die physischen/virtuellen Adressen der Sektionen stimmen. Wenn nicht, dann würde es bei jedem absoluten Jump/Call kaputtgehen.
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #11 am: 22. February 2010, 12:07 »
Der Dump ist hier: http://nopaste.info/40559b2d95.html
 
Was mir auffällt ist, dass die Startadresse 0x0010000c ist. Sollte das nicht eigentlich die Adresse von "loader" sein, sprich 0x00100098?
Ansonsten kann ich hier nicht wirklich erkennen, dass etwas falsch ist...

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #12 am: 22. February 2010, 12:13 »
Joa, die Startadresse sieht nach Humbug aus... warnt der ld beim Linken? Ich kann mich erinnern, dass bei mir mal was in Richtung "no entry symbol found, default to <irgendwas>" gesagt hatte, als er das Symbol des Entry-Points nicht gefunden hat. Macht aber irgendwie auch keinen Sinn, dass Symbol ist ja da...

edit: Kannst du eventuell auch mal disassemblieren?
« Letzte Änderung: 22. February 2010, 12:15 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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #13 am: 22. February 2010, 12:56 »
Es funktioniert nun etwas weiter.  :roll: Es lag daran, dass ich falsch herum gelinkt habe, sprich erst init.o (C/C++ Code) und dann startup.o (Assemblerstub).
 
Die Fehlermeldung sieht nun genau so aus, wie die im Eröffnungspost. Alles was ich gemacht habe war folgendes:
* eine Klasse eingebaut
* ein globales Objekt angelegt
Und genau da kommt der Absturz von qemu... Die Funktion "ConstructorsInit" will den Konstruktor der globalen Variable aufrufen und zerhaut dabei irgendwas ...  :-o
Mal schauen, ob ich herausfinden kann, was...

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #14 am: 22. February 2010, 13:08 »
Wenn du mir den Sourcecode und ein Floppyimage zukommen lässt, könnte ich es mir mal anschauen.
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #15 am: 22. February 2010, 13:24 »
Den Sourcecode kann ich gerne hochladen, allerdings habe ich kein Diskettenimage, da ich den Kernel via "qemu -kernel ..." ausführe.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #16 am: 22. February 2010, 13:33 »
Oder so. :-)
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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #17 am: 22. February 2010, 13:47 »
Und da ist er: http://wp1127936.wp167.webpack.hosteurope.de/zeug/os.zip
 
Ich hab den ganzen anderen Mist entfernt (leere Ordner und so) :roll:
Sollte der Code funktionieren, dann macht der Crosscompiler irgend etwas kaputt...
 
EDIT:
Am Kernel muss noch einiges gemacht werden. Allen voran muss erst einmal das Konfigurationsscript fertig geschrieben werden. Nur wollte ich einfach mal etwas herumprobieren.
« Letzte Änderung: 22. February 2010, 13:57 von ChristianF »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #18 am: 22. February 2010, 14:46 »
Das Kernelimage hat keine Multibootheader (mit mbchk überprüft) und qemu (0.11.0 und 0.12.2) stört das scheinbar nicht... oder aber mbchk macht Mist

edit: mbchk hat wohl recht: Bei mir landet die Multibootheader an Offset 0x2004 in der Datei.
« Letzte Änderung: 22. February 2010, 15:12 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

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #19 am: 22. February 2010, 15:30 »
humm...
eigentlich sollte der Multibootheader an Offset 0 liegen, weswegen ich ja extra hierfür die Sektion "multiboot" in das Linkerscript eingebaut habe. Allerdings habe ich hier in der cygwin umgebung auch kein "mbchk" um das zu testen:
/* first of all the multiboot structure */ 
.multiboot : AT(ADDR(.multiboot) - KERNEL_VMA_TO_LMA)
{
  *(.multiboot)
}

Ich habe auch nochmal probiert, bin aber zu keinem Ergebnis mehr gekommen, nur dass irgendwas kaputt geht, wenn ich auch nur eine globale Variable einbaue...
« Letzte Änderung: 22. February 2010, 15:33 von ChristianF »

 

Einloggen