multitasking trouble

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
k0ksz
Posts: 8
Joined: Fri Dec 05, 2008 4:03 am

multitasking trouble

Post 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
tantrikwizard
Member
Member
Posts: 153
Joined: Sun Jan 07, 2007 9:40 am
Contact:

Re: multitasking trouble

Post by tantrikwizard »

It looks like you forgot to push the eflags.
k0ksz
Posts: 8
Joined: Fri Dec 05, 2008 4:03 am

Re: multitasking trouble

Post 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) :)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: multitasking trouble

Post 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:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
k0ksz
Posts: 8
Joined: Fri Dec 05, 2008 4:03 am

Re: multitasking trouble

Post 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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: multitasking trouble

Post by Combuster »

So in bochs' debugger it works (also try entering 'c' to let it run without further interruption), but not in normal bochs?!
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
k0ksz
Posts: 8
Joined: Fri Dec 05, 2008 4:03 am

Re: multitasking trouble

Post 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?
k0ksz
Posts: 8
Joined: Fri Dec 05, 2008 4:03 am

Re: multitasking trouble

Post 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. :)
tantrikwizard
Member
Member
Posts: 153
Joined: Sun Jan 07, 2007 9:40 am
Contact:

Re: multitasking trouble

Post by tantrikwizard »

k0ksz wrote:I'm not really familiar with the bochs debugger...
Get familiar with it. RTFM on breakpoints and stepping through code.
k0ksz
Posts: 8
Joined: Fri Dec 05, 2008 4:03 am

Re: multitasking trouble

Post 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!
Post Reply