Normally I always use Qemu, because I'm used to it, and because when I start Bochs on Ubuntu I get vga image directive malformed, and I don't know how to work with Bochs, on Ubuntu. But now something strange happend with qemu:
I was working on multithreading, after a while I got it to work but, when the list of threads reached its end and switched back to the main thread, I got a General Protection Fault, first I checked my code, but I couldn't see something that could have caused it, so I started Bochs,(after a reboot into Windows, because I can't get it to work in Ubuntu :c ), but strangely everything ran perfect...
So, could it be a bug in Qemu, or did I do something wrong? Is there a way to fix it, because I prefer Qemu over Bochs.
Also, what could I do to get Bochs working on Ubuntu?(Now I get "Panic: vgarom directive malformed"(or something similar).
If you wish to try it for yourself:
http://www.megaupload.com/?d=JD2KW0CT
Or I you wish to examine my threading code:
Code: Select all
unsigned int current_thid = 0;
thread_t *current_thread;
thread_t *ready_queue;
void init_threading (void)
{
dissable();
current_thread = ready_queue = (thread_t*)kmalloc(sizeof (thread_t));
current_thread->regs.eip = 0;
current_thread->regs.edi = 0;
current_thread->regs.esi = 0;
current_thread->regs.ebx = 0;
current_thread->regs.edx = 0;
current_thread->regs.ecx = 0;
current_thread->thid = current_thid;
current_thread->name = "Main";
current_thread->next = 0;
enable();
}
void switch_thread( registers_t *regs )
{
current_thread->regs.edi = regs->edi;
current_thread->regs.esi = regs->esi;
current_thread->regs.eax = regs->eax;
current_thread->regs.ebx = regs->ebx;
current_thread->regs.ecx = regs->ecx;
current_thread->regs.edx = regs->edx;
current_thread->regs.ebp = regs->ebp;
current_thread->regs.esp = regs->esp;
current_thread->regs.eip = regs->eip;
current_thread = current_thread->next;
if(!current_thread) current_thread = ready_queue;
regs->edi = current_thread->regs.edi;
regs->esi = current_thread->regs.esi;
//regs->ebp = current_thread->regs.ebp;
//regs->esp = current_thread->regs.esp;
regs->eax = current_thread->regs.eax;
regs->ebx = current_thread->regs.ebx;
regs->ecx = current_thread->regs.ecx;
regs->edx = current_thread->regs.edx;
regs->eip = current_thread->regs.eip;
}
int install_thread(tf_t eip, char *name /*, u32int *stack*/ )
{
dissable();
current_thid++;
thread_t *new_thread = (thread_t*)kmalloc(sizeof(thread_t));
new_thread->regs.eip = eip;
new_thread->name = name;
new_thread->thid = current_thid;
new_thread->next = 0;
/*u32int esp; asm volatile("mov %%esp, %0" : "=r"(esp));
u32int ebp; asm volatile("mov %%ebp, %0" : "=r"(ebp));
new_thread->regs.esp = esp;
new_thread->regs.ebp = ebp;*/
thread_t *tmp = (thread_t*)ready_queue;
while(tmp->next)
{
tmp = tmp->next;
}
tmp->next = new_thread;
enable();
return current_thid;
}
void timer_handler(registers_t regs)
{
// Send reset signal to master. (As well as slave, if necessary).
outb(0x20, 0x20);
ticks++;
switch_thread( ®s );
}
Code: Select all
[GLOBAL irq0]
irq0:
cli
push byte 0
push byte 32
jmp irq_pit
[EXTERN timer_handler]
irq_pit:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call timer_handler
pop ebx ; reload the original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP