Ok, ich komme mal wieder nicht weiter^^
Ich habe in meinen Kernel Multitasking integriert, was nach einigen Hürden auch gut geklappt hat.
Seitdem ich aber in den Ring3 umgestiegen bin, startet QEMU einfach die ganze Zeit neu.  
 Das sind die Quellcodes:
#include "includes.h"
#define GDT_FLAG_DATASEGM	0x02
#define GDT_FLAG_CODESEGM	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_GRAN		0x800
#define GDT_FLAG_32_BIT		0x400
#define GDT_ENTRIES			0x5
static uint64_t gdt[GDT_ENTRIES];
void init_gdt()  
{ 
  gdt_set_entry(0, 0, 0, 0);
  gdt_set_entry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
  gdt_set_entry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
  gdt_set_entry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
  gdt_set_entry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEGM | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
  gdt_set_entry(5, (uint32_t)tss, sizeof(tss), GDT_FLAG_TSS | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
  
  load_gdt();
  kprintf(P_GDT_LOADED);
}
 
void gdt_set_entry(int i, unsigned int base, unsigned int limit, int flags)
{
  gdt[i] = limit & 0xffffLL;
  gdt[i] |= (base & 0xffffffLL) << 16;
  gdt[i] |= (flags & 0xffLL) << 40; 
  gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
  gdt[i] |= ((flags >> 8) & 0xffLL) << 52;
  gdt[i] |= ((base >> 24) &  0xffLL) << 56;
}
void load_gdt()
{
  struct {
    uint16_t limit;
    void * pointer;
  } __attribute__((packed)) gdtp = {
    .limit = GDT_ENTRIES * 8 - 1,
    .pointer = gdt,
  };
  asm volatile("lgdt %0" : : "m" (gdtp));
  asm volatile("ltr %%ax" : : "a" (5 << 3));
  
  asm volatile("mov $0x10, %ax;"
			"mov %ax, %ds;"
			"mov %ax, %es;"
		     "mov %ax, %ss;"
		     "ljmp $0x8, $.1;"
		     ".1:");
}
static uint8_t stack_a[4096];
static uint8_t stack_b[4096];
static uint8_t user_stack_a[4096];
static uint8_t user_stack_b[4096];
static int current_task = -1;
static int num_tasks = 2;
static struct cpu_state* task_states[2];
void init_taskmanager()
{
  task_states[0] = init_task(stack_a, user_stack_a, task_a);
  task_states[1] = init_task(stack_b, user_stack_b, task_b);
  kprintf("Der Taskmanager wurde initialisiert\n");
}
struct cpu_state * init_task(uint8_t* stack, uint8_t* userstack, void* entry)
{
  struct cpu_state task_cpu_state = {
    .eax = 0,
    .ebx = 0,
    .ecx = 0, 
    .edx = 0,
    .esi = 0,
    .edi = 0,
    .ebp = 0,
    .esp = (uint32_t)userstack + 4096,
    .eip = (uint32_t)entry,
    .cs = 0x18 | 0x03,
    .ss = 0x20 | 0x03,
    .eflags = 0x202,
  }; 
   
  struct cpu_state* state = (void*) (stack + 4096 - sizeof(task_cpu_state));
  *state = task_cpu_state;
  kprintf("%x\n", state->eip);
  return state;
} 
struct cpu_state * schedule(struct cpu_state * cpu)
{
  if(current_task >= 0) {
    task_states[current_task] = cpu;intr_common_handler:
    //CPU-Stand sichern  
    push %ebp
    push %edi
    push %esi
    push %edx
    push %ecx
    push %ebx
    push %eax
    mov $0x10, %ax
    mov %ax, %ds
    mov %ax, %es
    push %esp
    call handle_interrupts
    mov %eax, %esp
    mov $0x23, %ax
    mov %ax, %ds
    mov %ax, %es
    pop %eax
    pop %ebx
    pop %ecx
    pop %edx
    pop %esi
    pop %edi
    pop %ebp
    add $8, %esp
    iret#include "includes.h"  
struct cpu_state * handle_interrupts(struct cpu_state * cpu)
{
  struct cpu_state * new_cpu = cpu; 
  
  if(cpu->intr <= 0x1f) {
    clear();
    changeColor(0x1f);
    kprintf("\n Das Betriebssystem hat ein Problem festgestellt und muss beendet werden.\n\n");
    
    kprintf(" Interrupt:%v %d (Exception)\n", 15, (int)cpu->intr);
    kprintf(" Fehlercode:%v %x\n\n", 15, cpu->error);
       
    kprintf(" CPU zum Zeitpunkt des Interrupts:\n\n"); 
    
    kprintf("\teax:%v %x%vebx:%v%x\n", 10, cpu->eax, 25, 32, cpu->ebx);
    kprintf("\tecx:%v %x%vedx:%v%x\n", 10, cpu->ecx, 25, 32, cpu->edx); 
    kprintf("\tesi:%v %x%vedi:%v%x\n", 10, cpu->esi, 25, 32, cpu->edi);
    kprintf("\tebp:%v %x%veip:%v%x\n", 10, cpu->ebp, 25, 32, cpu->eip); 
    kprintf("\tesp:%v %x\n", 10, cpu->esp);
    kprintf("\tcs:%v %x%vss:%v%x\n", 10, cpu->cs, 25, 32, cpu->ss);
    kprintf("\tFlags:%v %x\n", 10, cpu->eflags); 
    kprintf("\n Taste druecken um einen CPU-Reset auszufuehren...\n Mach dir keine Hoffnungen, ich komme wieder. :madcat:");
    outb(0x64, 0xFE);
    
    while(1) asm volatile("cli; hlt");
    
  } else { 
    if(cpu->intr >= 0x20 && cpu->intr <= 0x2f) {
	 if(cpu->intr >= 0x28) {
	   outb(0xa0, 0x20); 
	 } else {
	   outb(0x20, 0x20);
	 }
	 if(cpu->intr == 0x20) {
	   new_cpu = schedule(cpu);
	   tss[1] = (uint32_t)(new_cpu+1);
	 }
	 if(cpu->intr == 0x21) kb_irq_handler(cpu->intr);
    }
  }
  
  return new_cpu;
}Falls ihr noch irgendwelche QEMU Logs braucht, lasst es mich hören.  
