Page 1 of 1

Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 4:04 am
by z0z0
Hi!

I'm writing a small os for school, and the deadline is pretty close :(.
I've got problems with task switching. My idea is to use the interrupt wrapper of djgpp to do this (the one created by _go32_dpmi_chain_protected_mode_interrupt_wrapper()). I chained on the timer interrupt. The code of the wrapper looks like this:

Code: Select all

push ds
push es
push fs
push gs
pusha
mov ax, _our_selector
mov ds, ax
incl _call_count
cmpl _in_this_handler, $0
jne bypass
movb _in_this_handler, $1 
mov es, ax
mov fs, ax
mov gs, ax
mov ebx, _local_stack
cld
mov ecx, esp
mov dx, ss
mov ss, ax
mov esp, ebx
push edx
push ecx
call _rmih
pop eax
pop ebx
mov ss, bx
movb _in_this_handler, $0
bypass:  popa
nop
pop gs
pop fs
pop es
pop ds
The wrapper calls my interrupt handler with the "call _rmih" instruction. What I tried to do then is to change the stack pointer pushed before the function call to point to the new task's stack. This is done like this:

Code: Select all

_CtxSwitch:
popl %eax
popl %ecx
popl _old_stack
pushl _new_stack
pushl %ecx
pushl %eax
The two push-es before the actual task are because of the eip addresses pushed by function calls.
At first I just tried to switch between two tasks. But the OS seems to run only the one that was the first. And no task switch occurs. I checked the addresses that are loaded (_new_stack) and they are correct.
My question is that could this work, and is it me doing something wrong? Or is this idea totally wrong?

Thanks for your answers.

Re:Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 4:11 am
by DennisCGc
Dumb question, did you unmask the timer interrupt ? And does the pointer of the timer interrupt refer to your code ? ::)

Re:Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 4:27 am
by z0z0
At the bottom of the task's stack there's the address of the code, the code selector and the value of the eflags. And the wrapper ends with an iret, which should load these values as far as i know. And when an interrupt occurs, these values are saved on the stack again right?
Sorry, I'm quite new to assembly.

Re:Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 5:07 am
by DennisCGc
At the bottom of the task's stack there's the address of the code, the code selector and the value of the eflags. And the wrapper ends with an iret, which should load these values as far as i know. And when an interrupt occurs, these values are saved on the stack again right?
If it's from PL3 to PL 0, then yes :)

Re:Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 6:08 am
by Candy
in the eflags that you initially push, is IF enabled?

Re:Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 6:45 am
by z0z0
This is how I push eflags initially:

Code: Select all

  asm("pushfl;popl %0":"=g" (eflags));
  *(--top_of_stack) = eflags;         // EFLAGS
There is no problem with the interrupt, I get the clock ticks all right. I suspect, that I write the new top of stack value to a wrong memory location. Because at the start this location has a value of 0, and then always the value that I pushed previously. Now I try to figure out where I should push the new value.

Re:Using djgpp interrupt wrapper for task switching

Posted: Sun May 09, 2004 9:50 am
by z0z0
Weee, finally I managed to fix task switching. :)
This is the code I use now (if you're interested):

Code: Select all

_VMCtxSwitch:
  movl _tos_new, %esp
  movl _timer_done, %eax
  movb $0, (%eax)
  popal
  nop
  popw %gs
  popw %fs
  popw %es
  popw %ds
  iretl
I skip the return part of the wrapper and use mine.
Anyways, thanks for your time.