Using djgpp interrupt wrapper for task switching

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
z0z0

Using djgpp interrupt wrapper for task switching

Post 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.
DennisCGc

Re:Using djgpp interrupt wrapper for task switching

Post by DennisCGc »

Dumb question, did you unmask the timer interrupt ? And does the pointer of the timer interrupt refer to your code ? ::)
z0z0

Re:Using djgpp interrupt wrapper for task switching

Post 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.
DennisCGc

Re:Using djgpp interrupt wrapper for task switching

Post 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 :)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Using djgpp interrupt wrapper for task switching

Post by Candy »

in the eflags that you initially push, is IF enabled?
z0z0

Re:Using djgpp interrupt wrapper for task switching

Post 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.
z0z0

Re:Using djgpp interrupt wrapper for task switching

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