Autor Thema: Usermode Multitasking  (Gelesen 14021 mal)

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« am: 26. April 2012, 21:18 »
Ich habe vor ein paar Tagen ein bisschen weiter mit meinen Kernel gemacht und schon habe ich das nächste Problem.
Es geht um Multitasking im Usermode.
Interrupts und Multitasking mit Thread\Prozess-Strukturen haben bereits funktioniert, doch im Ring 3 hängt sich QEmu kommentarlos auf und Bochs rebootet.

Erstmal habe ich schon ein paar Verständnisprobleme:
  • Wozu brauche ich diesen UserStack? Es existiert ja bereits ein Threadeigener Stack, also wozu nocheiner?
  • Weshalb wird dieses TSS gebraucht? Die UserStack-Adresse übergebe ich ja bereits im CPU-State

Nun zum konkreten Problem und Code:
Ich vermute, dass die Emulatoren beim GDT abstürzen.
Daher dieser Code: ("gdt.c")
#include "gdt.h"
#include <stdint.h>
#include "console.h"
#include "tss.h"

#define GDT_FLAG_DATASEG 0x02
#define GDT_FLAG_CODESEG 0x0a
#define GDT_FLAG_TSS     0x09

#define GDT_FLAG_SEGMENT 0x10
#define GDT_FLAG_RING0   0x00
#define GDT_FLAG_RING3   0x60
#define GDT_FLAG_PRESENT 0x80

#define GDT_FLAG_4K      0x800
#define GDT_FLAG_32_BIT  0x400

#define GDT_ENTRIECOUNT 5
static uint64_t Gdt_Gdt[GDT_ENTRIECOUNT];

static inline void Gdt_SetEntry(int i, unsigned int Base, unsigned int Limit, int Flags)
{
    Gdt_Gdt[i] = Limit & 0xffffLL;
    Gdt_Gdt[i] |= (Base & 0xffffffLL) << 16;
    Gdt_Gdt[i] |= (Flags & 0xffLL) << 40;
    Gdt_Gdt[i] |= ((Limit >> 16) & 0xfLL) << 48;
    Gdt_Gdt[i] |= ((Flags >> 8 )& 0xffLL) << 52;
    Gdt_Gdt[i] |= ((Base >> 24) & 0xffLL) << 56;
}

void Gdt_Init()
{
    Console_WriteLine("Lade GDT");
    struct
    {
        uint16_t Limit;
        void* Ptr;
    } __attribute__((packed)) GdtP = {.Limit = GDT_ENTRIECOUNT * 8 - 1, .Ptr = Gdt_Gdt, };

    // GDT-Eintraege aufbauen
 
    Gdt_SetEntry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K | GDT_FLAG_PRESENT);
    Gdt_SetEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K | GDT_FLAG_PRESENT);
    Gdt_SetEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
    Gdt_SetEntry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
    Gdt_SetEntry(5, (uint32_t)(&Tss_Tss), sizeof(Tss), GDT_FLAG_TSS | GDT_FLAG_PRESENT | GDT_FLAG_RING3);

    // GDT neu laden
    asm volatile("lgdt %0" : : "m" (GdtP));
   
    // Segmentregister neu laden, damit die neuen GDT-Eintraege auch wirklich
    // benutzt werden
    asm volatile(
        "mov $0x10, %ax;"
        "mov %ax, %ds;"
        "mov %ax, %es;"
        "mov %ax, %ss;"
        "ljmp $0x8, $.1;"
        ".1:"
    );
   
    // Taskregister neu laden
    asm volatile("ltr %%ax" : : "a" (5 << 3));
   
    Console_WriteLine("GDT bereit");
}
und der Code von "tss.h":
#ifndef TSS
#define TSS

#include <stdint.h>
#include <stddef.h>
typedef struct TssStruct
{
    uint32_t prevtasklink;
    uint32_t esp0;
    uint32_t ss0;
    uint32_t esp1;
    uint32_t ss1;
    uint32_t esp2;
    uint32_t ss2;
    uint32_t cr3;
   
    uint32_t eip;
    uint32_t eflags;
    uint32_t eax;
    uint32_t ecx;
    uint32_t edx;
    uint32_t ebx;
    uint32_t esp;
    uint32_t ebp;
   
    uint32_t esi;
    uint32_t edi;
    uint32_t es;
    uint32_t cs;
    uint32_t ss;
    uint32_t ds;
    uint32_t fs;
    uint32_t gs;
   
    uint32_t ldt;
    uint32_t iomapbaseaddress;
   
} __attribute__((packed)) Tss;
extern Tss Tss_Tss;
#endif
In "tss.c" setze ich eigentlich bis auf "ss0" bloß alles auf Null. "ss0" wird auf 16 gesetzt.

Nochwas anderes was ich mich seit einiger Zeit frage:
Kann man eigentlich davon ausgehen dass der Gcc das "Gdt_SetEntry" komplett so inlined und optimiert, dass es wie eine einfache Zuweißung einer LL-Konstante im Assemblercode dasteht?

Ich hoffe ihr könnt mir, wie schon bei meinen ersten Problem, sehr kompetent weiterhelfen.  :-D

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 26. April 2012, 22:51 »
Wozu brauche ich diesen UserStack? Es existiert ja bereits ein Threadeigener Stack, also wozu nocheiner?
Für Userland und Kernel brauchst du unterschiedliche Stacks, weil ansonsten Usercode den Kernelstack kaputtmachen könnte. Entweder irgendwelche Kerneldaten überschreiben, die auf dem Stack liegen, oder auch gern einfach esp irgendwo in die Botanik setzen. Wenn man also denselben Stack für beides benutzen könnte, hätte man ein Sicherheitsproblem. Damit das nicht passiert, ist der Protected Mode so gebaut, dass bei jedem Ringwechsel auch immer gleich ein Stackwechsel dabei ist.

Ein eigener Userspace-Stack für jeden Thread muss also unbedingt sein. Wo man eventuell noch Sachen zusammenlegen kann, ist bei den Kernelthreads. Theoretisch reicht da einer pro CPU, allerdings kann man dann den Prozessorzustand nicht mehr einfach bequem auf den Stack pushen und dort liegen lassen, bis man wieder zu diesem Task zurückkommt, weil der Stack ja vom nächsten Task weiterbenutzt werden würde. Stattdessen müsste man den Registerzustand z.B. direkt in der struct task speichern.

Zitat
Weshalb wird dieses TSS gebraucht? Die UserStack-Adresse übergebe ich ja bereits im CPU-State
Das TSS wird benutzt, wenn vom Userspace in den Kernel zurückgewechselt wird, z.B. durch einen IRQ oder eine Exception. Die Kernelstack-Adresse kann der Userspace erstens nicht geben, weil er gar nicht weiß, wann ein IRQ kommt, und zweitens wäre das ja wieder ein Sicherheitsproblem.

Zitat
Nun zum konkreten Problem und Code:
Ich vermute, dass die Emulatoren beim GDT abstürzen.
Warum vermutest du nur? Du kannst z.B. mit einer Endlosschleife genau eingrenzen, wo es passiert.

Zitat
Kann man eigentlich davon ausgehen dass der Gcc das "Gdt_SetEntry" komplett so inlined und optimiert, dass es wie eine einfache Zuweißung einer LL-Konstante im Assemblercode dasteht?
Mit einer hohen Optimierungsstufe und konstanten Parametern würde es mich nicht wundern, wenn er das tatsächlich hinbekommt. Allerdings spielt das überhaupt keine Rolle, der Code braucht nämlich nur ein paar Takte und läuft eh nur genau einmal während der gesamten Laufzeit des Kernels...
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 27. April 2012, 14:37 »
1:
Also es gibt doch einen Kernelstack und jeweils zwei Stacks für jeden Thread. Einen "normalen" und einen UserStack.
Nochmal Code dazu:
Thread Thread_New(uint8_t* Stack, uint32_t StackSize, uint8_t* UserStack, uint32_t UserStackSize, ThreadEntry Entry)
{
    CpuState NewCpuState =
    {
        .eax = 0,
        .ebx = 0,
        .ecx = 0,
        .edx = 0,
        .esi = 0,
        .edi = 0,
        .ebp = 0,
       
        .esp = ((uint32_t)UserStack) + UserStackSize,
        .eip = (uint32_t)Entry,
 
        // Ring-0-Segmentregister
        .cs  = 0x18 | 3,
        .ss  = 0x20 | 3,
 
        // IRQs einschalten (IF = 1)
        .eflags = 0x202,
    };

    // Den angelegten CPU-Zustand auf den Stack des Tasks kopieren, damit es am
    // Ende so aussieht als waere der Task durch einen Interrupt unterbrochen
    // worden. So kann man dem Interrupthandler den neuen Task unterschieben
    // und er stellt einfach den neuen Prozessorzustand "wieder her".
    CpuState* NewCpuStateStack = (void*) (Stack + StackSize - sizeof(NewCpuState));
    *NewCpuStateStack = NewCpuState;
    Thread NewTread = { .CpuState = NewCpuStateStack, .Stack = Stack, .StackSize = StackSize, .UserStack = UserStack, .UserStackSize = UserStackSize};
    return NewTread;
}

2:
Hmm ok.
Momentan setzte ich wie im Tutorial "esp0" immer auf den UserStack des Threades:
  Tss_Tss.esp0 = (uint32_t)(NewThread->UserStack); [color=050565]//"NewThread" stammt vom Scheduler[/color]
Ist das evt. auch falsch?

3:
Ich vermute, da ich mir zu 99,p9% sicher bin.
Aber ja ich bin mir jetzt ganz sicher.
Der Fehler tritt genau hier auf:
  [color=050565]// Taskregister neu laden[/color]
  asm volatile("ltr %%ax" : : "a" (5 << 3));


4:
Ich kompiliere immer mit "-o3".  :-)
     

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 30. April 2012, 12:01 »
Weiß wirklich KEINER weiter?  :-P


kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 30. April 2012, 12:54 »
Also es gibt doch einen Kernelstack und jeweils zwei Stacks für jeden Thread. Einen "normalen" und einen UserStack.
Diese "normalen" Stacks sind alles Kernelstacks. Du brauchst immer wenn der Kernel läuft einen Kernelstack, und immer  wenn Userspace-Code läuft einen Userspace-Stack. Wenn du das Modell aus dem Tutorial nimmst, dann läuft der Kernel immer mit dem Stack des momentan aktiven Tasks. Der eine Kernelstack, den du ganz am Anfang aufsetzt bevor es irgendwelche Tasks gibt, wird nicht mehr weiterbenutzt, nachdem der erste Taskwechsel passiert ist (außer natürlich du machst das bewusst und weist ihn z.B. dem Idle-Task zu).

Zitat
Momentan setzte ich wie im Tutorial "esp0" immer auf den UserStack des Threades:
  Tss_Tss.esp0 = (uint32_t)(NewThread->UserStack); [color=050565]//"NewThread" stammt vom Scheduler[/color]
Ist das evt. auch falsch?
esp0 ist wie der Name sagt für Ring 0, also den Kernel. Du brauchst hier also einen Kernelstack und keinen Userstack.

Zitat
Ich vermute, da ich mir zu 99,p9% sicher bin.
Aber ja ich bin mir jetzt ganz sicher.
Der Fehler tritt genau hier auf:
  [color=050565]// Taskregister neu laden[/color]
  asm volatile("ltr %%ax" : : "a" (5 << 3));
Also nicht beim Aufsetzen der GDT, sondern beim Laden des TSS ins Taskregister. Der nächste Schritt wäre zu schauen, welche Exception denn da überhaupt auftritt. Bei qemu kannst du den Parameter -d int benutzen und dann in der Logdatei /tmp/qemu.log nachschauen. Andere Emulatoren kennen oft ähnliche Funktionen.

Auf den ersten Blick sehe ich die zwei Möglichkeiten #GP (v=0d) und #TS (v=0a). Das erstere wäre, wenn die GDT irgendwelche Probleme macht (z.B. Limit zu klein gesetzt, oder der GDT-Eintrag ist Müll), das letztere, wenn auf das TSS zwar zugegriffen werden kann, aber der Inhalt nichts taugt. Wobei, wenn ich's mir recht überlege, ltr den TSS-Inhalt gar nicht anschaut. Der Fehlercode kann auch hilfreich sein.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 30. April 2012, 17:45 »
1:
Also reicht ein Kernelstack für alle Tasks?
Der Task befindet sich ja nur im Interrupt im Kernelmodus und beim verlassen sieht der Stack wie zuvor aus.

2:
"esp0" muss ich dann wohl auf diesen einen Kernelstack setzten.

3:
Funktioniert bei mir leider nicht.
Es kommt "/tmp/qemu.log not found".
Ich habe schon überall "tmp"-Ordner erzeugt doch das "tmp"-Verzeichnis bleibt weiterhin ungefunden.
Ganz nebenbei sind die Verzeichnistrennstriche verkehrtherum. Evt. ein Bug in der Windowsversion?

Und schonmal vielen Dank, dass du dich der Sache jetzt nochmal angenommen hast.  :wink:

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 30. April 2012, 18:09 »
Hallo,

Windows hat Laufwerksbuchstaben, die in dem Pfad von Qemu irgendwie fehlen, weil das ein Linux-Pfad ist. ;-) Starte Qemu mit "-D qemu.log", dann sollte die Datei im aktuellen Ordner erzeugt werden.

Ein Kernelstack für alle Tasks reicht nur dann aus, wenn du garantieren kannst, dass immer nur ein Kernelmodus gleichzeitig aktiv ist und du den entsprechenden Codeabschnitt vollständig durchlaufen hast, ehe du wo auch immer hin zurückkehrst.

Anders ausgedrückt: Du willst pro CPU (Kern) einen Kernelstack haben, da zwei CPUs gleichzeitig zwei Interrupts verarbeiten können.

Gruß,
Svenska

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 30. April 2012, 20:18 »
Ok, ich denke die Sache mit den Stacks ist jetzt wirklich klar.
Ich werde jetzt vorerst nur einen nutzen.
Mehrere Kerne anzusteuern oder sogar Hyperthreading zu nutzen stell ich ich mir horrormässig schwierig vor und bleibt daher erstmal weg.

Bloß das mit "-D qemu.log" funktioniert bedauerlicherweiße noch nicht. Je nach Parameterreihenfolge kommt entweder "invalid option" oder wieder "/tmp/qemu.log not found".  :x
Ist vielleicht meine QEmu-Version zu alt? (0.9.0)
Die Windowsversionen wurden ja angeblich in der letzten Steinzeit kompiliert.  :|

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 30. April 2012, 21:47 »
Mehrere Kerne anzusteuern oder sogar Hyperthreading zu nutzen stell ich ich mir horrormässig schwierig vor und bleibt daher erstmal weg.
Wenn du ein paarmal geschickt gegentrittst, fangen sie an, deinen Code auszuführen. Schwierig ist nur, dafür zu sorgen, dass sie nicht irgendwelche Datenstrukturen gleichzeitig nutzen. ;-)
Denke nur dran, dass du es vielleicht irgendwann mal wollen könntest und dann den ganzen Code neuschreiben müssen ist unschön.

Ist vielleicht meine QEmu-Version zu alt? (0.9.0)
Die Windowsversionen wurden ja angeblich in der letzten Steinzeit kompiliert.  :|
Besorge dir eine neuere. Die gibts im Netz (z.B. hier, aber auch nicht sicherer als irgendeine japanische Version).

Gruß,
Svenska

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 30. April 2012, 23:03 »
Zitat
Besorge dir eine neuere. Die gibts im Netz (z.B. hier, aber auch nicht sicherer als irgendeine japanische Version).
Hab ich mir runtergeladen und in meinen QEmu-Ordner gepackt.
Doch was jetzt? In dem Ordner ist nicht eine "qemu.exe" sondern eine ganze Reihe.
Wenn ich "qemu-system-i386.exe" oder "qemu-system-x86_64.exe" aufrufe, tut sich ziemlich viel - nämlich gar nichts!
Egal was ich per Kommandozeile(Also auch bei "qemu-system-i386.exe th349cx9!") übergebe: Es kommt nichtmal eine Fehlermeldung.  :x

Das einzige was manchmal passiert ist, dass die "qemu.log" erstellt wird.
Aber auch die ist nur leer.

EDIT:
Ich habe eben eine "Teillösung" auf der Seite gefunden.
Wenn man "-L "%cd%\pc-bios"" mitangibt, kommt immerhin ein Scharzes Fenster.
Von dort an tut sich aber wieder nichtsmehr.  :-(
« Letzte Änderung: 30. April 2012, 23:16 von OS_3000 »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 04. May 2012, 22:32 »
Qemu sollte unter Windows die Datei qemu.log im aktuellen Verzeichnis erzeugen, wenn man nicht "-D irgendwas" angibt. Diese Option hab ich auch bisher nicht gekannt/benötigt. -d int sollte reichen.

Probier auch mal SET SDL_STDIO_REDIRECT=0 in der Kommandozeilenumgebung auszuführen, bevor du qemu startest. Je nachdem wie es kompiliert wurde, kann es dann auch was auf der Konsole ausgeben.
« Letzte Änderung: 04. May 2012, 22:37 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 04. May 2012, 23:44 »
Danke, hat aber leider beides nichts gebracht.
qemu.log wird sogar sogar erstellt, ist aber genauso leer wie die Ausgabe in CMD.

Auch nach 1 Minute sieht es noch aus wie im Bild im Anhang.
Es tut sich einfach nichts.  :-(

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 05. May 2012, 00:11 »
Das ist seltsam. Du könntest noch versuchen, ob du wenigstens in den Monitor von qemu kommst, indem du Strg-Alt-2 drückst, und dort dann "c" eingibst, um die Ausführung zu starten. Zurück zu deinem OS kommst du mit Strg-Alt-1. Aber vermutlich wird das nichts bringen, weil du ja qemu gar nicht gesagt hast, dass er pausieren soll (Parameter -S). Das sollte man nämlich eigentlich am "[stopped]" in der Titelleiste erkennen. Mehr fällt mir leider auch nicht mehr ein
Dieser Text wird unter jedem Beitrag angezeigt.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 05. May 2012, 14:40 »
Der Monitor geht.
C bringt aber leider nichts.

Ich habe eben noch versucht einen anderen BIOS einzustellen, doch leider erfolglos.

EDIT:
Oh, plötzlich gehts!  :-D
Hat anscheinend an den Parameter "-M isapc" gelegen.

Naja jetzt aber die "qemu.log":
SMM: enter
EAX=00000001 EBX=00be0cb0 ECX=00000000 EDX=00000cfc
ESI=000f27cd EDI=0003802d EBP=00be0ad0 ESP=00006f3c
EIP=000f3766 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fcd80 00000037
IDT=     000fdb70 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=000f27a0 CCD=00000001 CCO=LOGICB 
EFER=0000000000000000

SMM: after RSM
EAX=00000001 EBX=00be0cb0 ECX=00000000 EDX=00000cfc
ESI=000f27cd EDI=0003802d EBP=00be0ad0 ESP=00006f3c
EIP=000f3766 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fcd80 00000037
IDT=     000fdb70 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000000 CCO=EFLAGS 
EFER=0000000000000000
« Letzte Änderung: 05. May 2012, 14:45 von OS_3000 »

Svenska

  • Beiträge: 1 792
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 05. May 2012, 15:30 »
Ja, "-M isapc" ist broken. Ich habe auch mal einen (Debian-)Bugreport deswegen geöffnet, den aber niemand interessiert. ;-) Für die 32-Bit-Entwicklung solltest du vielleicht qemu-system-i386.exe benutzen. Das "-soundhw all" kannst du weglassen, solange du dich nicht mit Audio befassen möchtest und ein Parameter "-L pc-bios" sollte ausreichen, wenn du dich im Qemu-Ordner befindest.

Gruß,
Svenska

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 05. May 2012, 16:07 »
Zitat
Für die 32-Bit-Entwicklung solltest du vielleicht qemu-system-i386.exe
Dann stehen aber nur i386 Funktionen zur Verfügung?
Ich möchte den i686(Pentium 3) vorraussetzen, da er als erstes SSE unterstützt und da mein ältester Computer einen Pentium 3 beinhaltet.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 05. May 2012, 16:46 »
Der Unterschied zwischen i386 und x86_64 ist 32-Bit vs. 64-Bit. Das heißt nicht, dass i386 tatsächlich ein 386er ist, sondern der kann auch schon SSE3 oder so. Es ist trotzdem kein Problem, wenn du die x86_64-Version nimmst.

Was ich aus dem qemu.log rauslese ist, dass dein OS entweder nichts macht (insbesondere keine werden keine Exceptions ausgelöst), oder es wird überhaupt nicht ausgeführt.
« Letzte Änderung: 05. May 2012, 16:57 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 05. May 2012, 17:37 »
Sorry, war wahrscheinlich noch eine Versuchsversion.
Habs mal neukompiliert.
Jetzt rebootet er wie Bochs mit folgender Ausgabe:
SMM: enter
EAX=00000001 EBX=00be0cb0 ECX=00000000 EDX=00000cfc
ESI=000f27cd EDI=0003802d EBP=00be0ad0 ESP=00006f3c
EIP=000f3766 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fcd80 00000037
IDT=     000fdb70 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=000f27a0 CCD=00000001 CCO=LOGICB 
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=00be0cb0 ECX=00000000 EDX=00000cfc
ESI=000f27cd EDI=0003802d EBP=00be0ad0 ESP=00006f3c
EIP=000f3766 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fcd80 00000037
IDT=     000fdb70 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000000 CCO=EFLAGS 
EFER=0000000000000000
check_exception old: 0xffffffff new 0xd
     0: v=0d e=0028 i=0 cpl=0 IP=0008:00000000001051a5 pc=00000000001051a5 SP=0010:00000000003fff60 EAX=0000000000000028
EAX=00000028 EBX=0000e910 ECX=00108768 EDX=00000010
ESI=00054767 EDI=0005476c EBP=003fff88 ESP=003fff60
EIP=001051a5 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00108740 00000027
IDT=     00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=000000e9 CCO=LOGICB 
EFER=0000000000000000
check_exception old: 0xd new 0xd
     1: v=08 e=0000 i=0 cpl=0 IP=0008:00000000001051a5 pc=00000000001051a5 SP=0010:00000000003fff60 EAX=0000000000000028
EAX=00000028 EBX=0000e910 ECX=00108768 EDX=00000010
ESI=00054767 EDI=0005476c EBP=003fff88 ESP=003fff60
EIP=001051a5 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00108740 00000027
IDT=     00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=000000e9 CCO=LOGICB 
EFER=0000000000000000
check_exception old: 0x8 new 0xd
SMM: enter
EAX=00000001 EBX=00be0cb0 ECX=00000000 EDX=00000cfc
ESI=000f27cd EDI=0003802d EBP=00be0ad0 ESP=00006f3c
EIP=000f3766 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fcd80 00000037
IDT=     000fdb70 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=000f27a0 CCD=00000001 CCO=LOGICB 
EFER=0000000000000000
SMM: after RSM
EAX=00000001 EBX=00be0cb0 ECX=00000000 EDX=00000cfc
ESI=000f27cd EDI=0003802d EBP=00be0ad0 ESP=00006f3c
EIP=000f3766 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000fcd80 00000037
IDT=     000fdb70 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000000 CCO=EFLAGS 
EFER=0000000000000000

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 05. May 2012, 17:43 »
Die IDT ist nicht eingerichtet. Das musst du beheben, bevor du irgendwas in Richtung User Mode machst.
Dieser Text wird unter jedem Beitrag angezeigt.

OS_3000

  • Beiträge: 53
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 05. May 2012, 19:23 »
Aber nur da er bei der Gdt abstützt.
Du meintest ja, es würde #GP oder #TS auftreten.
Ich werde aber aus der Ausgabe in der Log nicht so recht schlau.

 

Einloggen