multitasking trouble
Posted: Tue Dec 09, 2008 1:43 pm
Hi!
I'm just trying to get basic multitasking working but I have some trouble...
First I'm going to post some parts of my sources.
The PIT irq handler code:
The schedule function:
t1 and t2 in the above code are two thread instances created during the initialization of the scheduler.
This is the code I use to initialize the stack of a new thread:
Definitions used in the previous code block:
The threads just have an infinite loop with a kprintf that should print to the screen.
First time the timer IRQ is fired it calls the scheduler just as I planned and thread #2 will be executed. I see a lot of "2" chars printed by the thread on the screen. At the next timer irq the scheduler is called again and thread #2 is selected. But before getting to the thread again I get a general protection fault. The EIP printed in the gpf handler is 0x101C01. As I see in the disassembly version of the kernel 0x101C01 is not a valid address. The only occurrence of the 0x101C01 address in the disasm. output is before a "call kprintf" in this form: "movl $0x101C01, (%esp)".
Do you have any idea what could cause this kind of problem? Do you see any error in my tasking codes?
Thanks,
k0ksz
I'm just trying to get basic multitasking working but I have some trouble...
First I'm going to post some parts of my sources.
The PIT irq handler code:
Code: Select all
.global irq0_handler
irq0_handler:
cli
pushl $0
pushl $0
pusha
push %ds
andl $0xFFFF, (%esp)
push %es
andl $0xFFFF, (%esp)
push %fs
andl $0xFFFF, (%esp)
mov $KERNEL_DS, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
pushl %esp
call schedule
addl $4, %esp
movl %eax, %esp
pop %fs
pop %es
pop %ds
popa
addl $8, %esp
iret
Code: Select all
register_t schedule( registers_t* regs ) {
thread_t* next;
if ( current == t2 ) {
next = t1;
} else {
next = t2;
}
if ( current != NULL ) {
current->context.esp = ( register_t )regs;
}
kprintf( "next thread: %x\n", next );
outb( 0x20, 0x20 );
return next->context.esp;
}
This is the code I use to initialize the stack of a new thread:
Code: Select all
int arch_create_thread( thread_t* thread, void* entry ) {
registers_t* regs;
register_t* stack;
memset( &thread->context, 0, sizeof( cpu_context_t ) );
stack = ( register_t* )( ( uint8_t* )thread->kernel_stack + PAGE_SIZE );
regs = ( registers_t* )( ( uint8_t* )stack - sizeof( registers_t ) );
memset( regs, 0, sizeof( registers_t ) );
regs->fs = KERNEL_DS;
regs->es = KERNEL_DS;
regs->ds = KERNEL_DS;
regs->cs = KERNEL_CS;
regs->ip = ( unsigned long )entry;
regs->flags = 0x203246;
regs->ss = KERNEL_DS;
regs->sp = ( unsigned long )( stack - 1 );
thread->context.esp = ( register_t )regs;
return 0;
}
Code: Select all
typedef unsigned long register_t;
typedef struct regsisters {
unsigned long fs, es, ds;
unsigned long di, si, bp, ksp, bx, dx, cx, ax;
unsigned long int_number, error_code;
unsigned long ip, cs, flags, sp, ss;
} registers_t;
First time the timer IRQ is fired it calls the scheduler just as I planned and thread #2 will be executed. I see a lot of "2" chars printed by the thread on the screen. At the next timer irq the scheduler is called again and thread #2 is selected. But before getting to the thread again I get a general protection fault. The EIP printed in the gpf handler is 0x101C01. As I see in the disassembly version of the kernel 0x101C01 is not a valid address. The only occurrence of the 0x101C01 address in the disasm. output is before a "call kprintf" in this form: "movl $0x101C01, (%esp)".
Do you have any idea what could cause this kind of problem? Do you see any error in my tasking codes?
Thanks,
k0ksz