Autor Thema: Multiboot Information Structure  (Gelesen 16626 mal)

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« am: 26. November 2012, 21:34 »
Irgendwie ist bei mir das Multiboot Information Structure leer. Ich kriege zwar eine Adresse übergeben, aber alles enthält nur 0x0.

So sieht meine Struktur dafür aus:

struct multiboot_info {
  uint32_t flags;
  uint32_t mem_lower;
  uint32_t mem_upper;
  uint32_t bootdevice;
  uint32_t cmdline;
  uint32_t mods_count;
  uint32_t mods_addr;
 
  uint32_t syms_num;
  uint32_t syms_size;
  uint32_t syms_addr;
  uint32_t syms_shndx;
 
  uint32_t mmap_length;
  uint32_t mmap_addr;
  uint32_t drives_length;
  uint32_t drives_addr;
  uint32_t config_table;
  uint32_t boot_loader_name;
  uint32_t apm_table;
  uint32_t vbe_control_info;
  uint32_t vbe_mode_info;
  uint16_t vbe_mode;
  uint16_t vbe_interface_seg;
  uint16_t vbe_intferface_off;
  uint16_t vbe_interface_len;
}__attribute((packed));

Und so soll das zum Test ausgegeben werden:

void init(struct multiboot_info * mb_info)
{
  ...
  kprintf("%x\n", mb_info->mmap_addr);
  ...
}

Nur funktioniert das eben nicht.  :?

Es scheint so, als würde eine Adresse von einer leeren Struktur übergeben werden.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 26. November 2012, 22:08 »
Vermutlich geht was bei der Parameterübergabe an init schief. Kannst du den Code zeigen der init aufruft? Am besten auch das was vorher kommt. Sollte ja nicht viel sein, oder?
Dieser Text wird unter jedem Beitrag angezeigt.

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 26. November 2012, 22:11 »
Vermutlich geht was bei der Parameterübergabe an init schief. Kannst du den Code zeigen der init aufruft? Am besten auch das was vorher kommt. Sollte ja nicht viel sein, oder?

.section multiboot
 
#define MB_MAGIC 0x1badb002
#define MB_FLAGS 0x0
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)
 
// Der Multiboot-Header
.align 4
.int    MB_MAGIC
.int    MB_FLAGS
.int    MB_CHECKSUM

.section .text

.extern init //init.c
 
.global _start
_start:
    mov $kernel_stack, %esp
    push %ebx
    call init

Das ist eigentlich so ziemlich das selbe wie im Wiki.
« Letzte Änderung: 26. November 2012, 22:13 von jo2105 »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 26. November 2012, 22:25 »
Ja, der Code sieht unverdächtig aus.

Ich kann da auch nur ins Blaue raten. Vielleicht ist kernel_stack (bzw. das bss-Segment) kaputt. Vielleicht ist kprintf kaputt. Vielleicht auch was ganz anderes.Was machst du alles in init vor dem kprintf? Möglicherweise ist der Kernel gar nicht Multiboot-kompatibel. Nutzt du das Linker-Skript aus dem Wiki?
« Letzte Änderung: 26. November 2012, 22:27 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 26. November 2012, 22:41 »
Also kprintf funktioniert soweit.
vor dem kprintf leere ich nur den Bildschirm, was damit auch nichts zu tun hat.
Wie kann man denn sehen ob kernel_stack kaputt ist?
Gleiches gilt für die Multiboot-Kompabilität, hier kann ich aber sagen, dass ich den Kernel immer mit qemu -kernel starte, was so weit ich weiß Multiboot vorraussetzt.
Das Linker-Script müsste eigentlich auch mit dem Tutorial übereinstimmen.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 26. November 2012, 22:45 »
Wie kann man denn sehen ob kernel_stack kaputt ist?
Mit einem Debugger. Aber was oder wie man das macht, kann ich aus der Ferne nicht beschreiben. Du kannst dir allerdings mal den Wert von mb_info ausgeben lassen.

Gleiches gilt für die Multiboot-Kompabilität, hier kann ich aber sagen, dass ich den Kernel immer mit qemu -kernel starte, was so weit ich weiß Multiboot vorraussetzt.
Mit dem Parameter kann man auch andere Kernel starten, wenn die irgendeinem der Linux-Bootprotokolle entsprechen. Ich weiß nicht, ob man wirklich einen Kernel unabsichtlich damit kompatibel machen kann. Aber wenn das Linkerskript in Ordnung ist, sollte das nicht passieren.
Dieser Text wird unter jedem Beitrag angezeigt.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 26. November 2012, 22:56 »
Wenn du dem Bootloader nicht sagst das du die mem_map gerne hättest gibt er die dir auch nicht.

Du must das flag bit 1(also 0x2) setzen : MB_FLAGS
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 26. November 2012, 23:02 »
Haha, wenigstens einer hier, der aufpasst und nicht wild rumspekuliert  8-)
Dieser Text wird unter jedem Beitrag angezeigt.

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 26. November 2012, 23:04 »
Wenn du dem Bootloader nicht sagst das du die mem_map gerne hättest gibt er die dir auch nicht.

Du must das flag bit 1(also 0x2) setzen : MB_FLAGS

Das macht bei mir leider keinen Unterschied. (Zumindest wenn ich das so richtig verstanden habe):

#define MB_MAGIC 0x1badb002
#define MB_FLAGS 0x2
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 26. November 2012, 23:07 »
Dann geht das spekulieren weiter. Lass dir mal die übergebene Multiboot-Magic (eax) ausgeben, bzw. prüf den Wert, ob er korrekt ist.
Dieser Text wird unter jedem Beitrag angezeigt.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 26. November 2012, 23:39 »
Ja, das mit den Flags hast du richtig verstanden.

Ich fange dann jetzt auch mal an zu Spekulieren:
- Paging, und GDT hast du noch nicht angefasst?
- Du löschst den Bildschirm mit 0x00, statt mit grauen Leerzeichen (0x20 0x07) ?, evtl. läuft da was schief und du überschreibst die struktur
- dann sind MB_Magic(eax), MB_Info(ebx), mb_info->flags interresant
- Interrupts sind aus ?
- sind wirklich alle Felder 0, oder hast du nur stichprobenartig überprüft?
- du könntest mal eine cmdline angeben: qeum -kernel foo -append "cmdline"
  und gucken ob die korrekt übergeben wird.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 27. November 2012, 00:23 »
Hallo,

wenn du "qemu -kernel" benutzt, dann hat nach dem Start des Kernel EBX (und damit der Zeiger auf die Multiboot-Informationsstruktur) den Wert 0x9500. Die Memory Map liegt bei 0x9000 und endet bei 0x9078. Prüf mal, ob du diese Werte bestätigen kannst.

Schau mal nach, ob du bei 0x9000 die Memory Map trotzdem findest, evtl. überschreibst du dein mb_info. Möglicherweise ist auch das Linkerscript seltsam, aber vorstellen kann ich mir das nicht...

Gruß,
Svenska

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 27. November 2012, 15:16 »
Ich geh dann mal alle Ideen durch.

Dann geht das spekulieren weiter. Lass dir mal die übergebene Multiboot-Magic (eax) ausgeben, bzw. prüf den Wert, ob er korrekt ist.

Der ist korrekt.

Ja, das mit den Flags hast du richtig verstanden.

Ich fange dann jetzt auch mal an zu Spekulieren:
- Paging, und GDT hast du noch nicht angefasst?
- Du löschst den Bildschirm mit 0x00, statt mit grauen Leerzeichen (0x20 0x07) ?, evtl. läuft da was schief und du überschreibst die struktur
- dann sind MB_Magic(eax), MB_Info(ebx), mb_info->flags interresant
- Interrupts sind aus ?
- sind wirklich alle Felder 0, oder hast du nur stichprobenartig überprüft?
- du könntest mal eine cmdline angeben: qeum -kernel foo -append "cmdline"
  und gucken ob die korrekt übergeben wird.

-Paging habe ich noch nicht, aber GDT schon. (aber zu dem Zeitpunkt sind sie noch nicht initialisiert
-Ich lösche den Bildschirm zwar mit 0x0, aber ich habe schon ausprobiert, die clear Funktion rauszunehmen.
-MB_Magic ist ganz normal 0x1BADB002, MB_Info hat die Adresse 0x9500, mb_info->flags ist wie gesagt 0x0
-Interrupts sind zu dem Zeitpunkt aus.
-Ich habe ein Großteil der Felder überprüft.
-Was passiert denn durch die cmdline?

Hallo,

wenn du "qemu -kernel" benutzt, dann hat nach dem Start des Kernel EBX (und damit der Zeiger auf die Multiboot-Informationsstruktur) den Wert 0x9500. Die Memory Map liegt bei 0x9000 und endet bei 0x9078. Prüf mal, ob du diese Werte bestätigen kannst.

Schau mal nach, ob du bei 0x9000 die Memory Map trotzdem findest, evtl. überschreibst du dein mb_info. Möglicherweise ist auch das Linkerscript seltsam, aber vorstellen kann ich mir das nicht...

Gruß,
Svenska

Ich kriege die richtige Adresse (0x9500) übergeben, allerdings ist dort eben alles leer, deswegen kann ich auch nicht die Adresse der Memory Map beziehen. 0x9000 scheint aber auch leer zu sein.

BTW: 5000 Beitrag in diesem Forum   :-)

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 28. November 2012, 14:06 »
Hat keiner ne Idee, was da noch falsch sein könnte.  :?

Ich werde gleich mal ausprobieren, den Kernel als GRUB-Image zu starten.

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 28. November 2012, 18:43 »
Ich glaube, das einzige, was gegen weiteres Rumspekulieren hilft, ist der Code selbst. Muss ja nicht vollständig sein, hauptsache es kompiliert, bootet und zeigt den Fehler.

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 28. November 2012, 19:20 »
-Was passiert denn durch die cmdline?
Nichts, es ist nur ein weiteres Feld in der mb_info, das erstens nicht null sein sollte, und dessen wert du überprüfen kannst. (ein pointer auf den string, den du als cmdline übergeben hast)

Ich bin mit meinem Rumspekulieren hier jetzt auch schon am Ende. Für weiteres wäre wie Svenska schon sagt, ein Binarry oder Compilierender Code(mit Makefile, linkskript etc.) nützlich.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 28. November 2012, 19:54 »
Ich habe das Ganze mal hochgeladen. Lasst euch nicht von dem pmm verwirren, der wird noch gar nicht aufgerufen, es geht dabei erstmal nur um den ersten Aufruf in der init.c.  :-)

http://www.file-upload.net/download-68651/kernel.tar.gz.html

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 28. November 2012, 20:04 »
Irgendwie ist der Link falsch: Hier ist der richtige:

http://www.file-upload.net/download-6866209/kernel.tar.gz.html

 :-)

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 28. November 2012, 20:13 »
Was für eine Qemu-Version nutzt du?

Bei mir (QEMU emulator version 1.0.1) gibt es 0x4f für die Flags aus. (Und ich habe nur #include <stdio.h> auskommentiert damit es über Haupt Compiler, weil ich da keine 32-Bit Version von habe).
« Letzte Änderung: 28. November 2012, 20:18 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

jo2105

  • Beiträge: 58
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 28. November 2012, 20:36 »
Was für eine Qemu-Version nutzt du?

Bei mir (QEMU emulator version 1.0.1) gibt es 0x4f für die Flags aus. (Und ich habe nur #include <stdio.h> auskommentiert damit es über Haupt Compiler, weil ich da keine 32-Bit Version von habe).

Das hört sich auf jedenfall sehr gut an. Ich habe einfach qemu in den Packetmanager eingegeben und runtergeladen. Hast du zufälligerweise einen Link zur der 1.0.1?  Ich finde da nur die Sourcecodes. (oder muss man die erst komplett kompilieren?)

 

Einloggen