Dieses Problem wäre auch gelöst. Es hatte nichts mit den Segmentregistern zu tun, diese dürften richtig gesetzt sein, sondern vielmehr mit einem Stückchen Assemblercode, das an der falschen Stelle stand. Aber geholfen hat das nichts. Jetzt bekomme ich wieder Pagefaults :S Zum einen bekomme ich beim Eintritt in den Ring 3 einen Page Fault, wenn der Kernel nicht zum Schreiben gemappt ist. Das ist das geringere Übel, ich muss eben noch herausfinden, welche Kernelbereiche für Ring 3 Tasks zum Schreiben gemappt sein müssen. Durch ein wenig Experimentieren müsste ich die Lösung finden. Das größere Übel besteht darin, dass es bei der Rückkehr in den Ring 0 crasht. Irgendwie werden die Kernelsegmente bzw. der Kernelstack nicht geladen.
Vielleicht wäre der Code des Interrupthandlers relevant:
extern "C" CPU_State *InterruptCallback(CPU_State *cpu)
{
Task *task = NULL;
if(cpu->intr <= 0x1f)
{
if(cpu->intr == 8 || cpu->intr == 18)
{
[...] Fehler behandeln
}
}
else if(cpu->intr >= 0x20 && cpu->intr <= 0x2f)
{
if(cpu->intr == 0x20 && TaskMgr.GetSchedulingState())
{
task = TaskMgr.Schedule(cpu);
gdt.TSSSetCPU(uint32_t(task->CPU + 1)); // void GDT::TSSSetCPU(uint32_t cpu) {tss[1] = cpu;}
}
if(cpu->intr >= 0x28)
outportb(0xa0, 0x20); // EOI an Slave-PIC
outportb(0x20, 0x20); // EOI an Master-PIC
}
else if(cpu->intr >= 255)
{
[...] Fehler behandeln
}
cpu = idt.callback(cpu);
if(task)
{
cpu = task->CPU;
if(task->MContext)
{
M.ActivateContext(task->MContext);
asm volatile ( // User-Datensegmente laden
"mov $0x23, %ax;"
"mov %ax, %ds;"
"mov %ax, %es;"
);
}
else
M.ActivateKernelContext(); // Kernel-Datensegmente wurden schon in Assemblerteil, der diese Routine aufruft, geladen
}
return cpu;
}
Ich bin so langsam wirklich am Verzweifeln -.-