Page 1 of 1

multitasking trouble

Posted: Tue Dec 09, 2008 1:43 pm
by k0ksz
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:

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
The schedule function:

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;
}
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:

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;
}
Definitions used in the previous code block:

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;
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

Re: multitasking trouble

Posted: Tue Dec 09, 2008 6:22 pm
by tantrikwizard
It looks like you forgot to push the eflags.

Re: multitasking trouble

Posted: Wed Dec 10, 2008 12:26 am
by k0ksz
tantrikwizard wrote:It looks like you forgot to push the eflags.
Eflags is pushed to the stack by the CPU when it enters to the interrupt handler. (in my theory) :)

Re: multitasking trouble

Posted: Wed Dec 10, 2008 5:09 am
by Combuster
I would load this into bochs debugger to locate the exact location where the error occurs.
But since it isn't my OS you'll have to do that yourself :wink:

Re: multitasking trouble

Posted: Wed Dec 10, 2008 5:16 am
by k0ksz
Combuster wrote:I would load this into bochs debugger to locate the exact location where the error occurs.
But since it isn't my OS you'll have to do that yourself :wink:
I tried to debug it with bochs running the code step-by-step, but during this the fault didn't come up.

Re: multitasking trouble

Posted: Wed Dec 10, 2008 5:26 am
by Combuster
So in bochs' debugger it works (also try entering 'c' to let it run without further interruption), but not in normal bochs?!

Re: multitasking trouble

Posted: Wed Dec 10, 2008 5:28 am
by k0ksz
I'm not really familiar with the bochs debugger as I'm not used it too much but one question: do interrupts get fired during the step-by-step executing?

Re: multitasking trouble

Posted: Wed Dec 10, 2008 5:42 am
by k0ksz
I think the problem is that in schedule() I don't set current to the thread I'm going to execute. In this case after the first preemption is done on this thread the current ESP value is not saved and when the scheduler tried to execute it again it will use the original ESP value. :)

Re: multitasking trouble

Posted: Wed Dec 10, 2008 9:38 am
by tantrikwizard
k0ksz wrote:I'm not really familiar with the bochs debugger...
Get familiar with it. RTFM on breakpoints and stepping through code.

Re: multitasking trouble

Posted: Wed Dec 10, 2008 10:32 am
by k0ksz
tantrikwizard wrote:
k0ksz wrote:I'm not really familiar with the bochs debugger...
Get familiar with it. RTFM on breakpoints and stepping through code.

Thanks for your great answer... I think you should RTFM the Intel manuals about eflags and interrupts ;) r0fl ...

Please lock this thread!