Page 1 of 1

Stack Based task Switch Problem

Posted: Fri Sep 06, 2002 12:09 pm
by Slasher
Hello,i'm back after a long time of coding with a new problem! ???
I'm using stack based task switching for my kernel but can't seem to get it to work. :-[
this is the problem:
When i create a new task,i create its stack frame as follows

create_frame:
mov eax,[running_stack] ;get stack address
mov esp,[eax] ;put stack address in esp
pushfd ;push eflags
push word CODE_SEL ;push code selector for task
push dword [task_address] ;push task address
mov [running_stack],dword esp ;store new stack addr
ret
i want to use iretd to switch tasks

i'm testing the task switching function right now by calling it manually once.it works under BOCH but crashes
on a real pc.this is the function

task_switch:

mov eax,[running_stack]
mov esp,[eax]
iretd

the problems i noticed with this are
1.the timer interrupt handler doesn't work,but if i change the iretd to retd the timer interrupt handler runs fine.(under BOCH)
2. ALL Fails on REAL PC,it just crashes!!!
Help Please...

Re:Stack Based task Switch Problem

Posted: Fri Sep 06, 2002 12:58 pm
by Pype.Clicker
Code Slasher wrote:

Code: Select all

create_frame:
mov eax,[running_stack] ;get stack address
mov esp,[eax]                  ;put stack address in esp
pushfd                              ;push eflags
push word CODE_SEL      ;push code selector for task
push dword [task_address] ;push task address
mov [running_stack],dword esp ;store new stack addr
ret
As written here, your function loses the caller stack. i suggest you rather use

Code: Select all

create_frame:
    push ebp
    mov ebp,esp
    mov eax,[running_stack] 
     ...  ; please don't touch ebp here !!
    mov [running_stack],esp
    mov esp, ebp
    pop ebp
    ret
another thing that seems darky to my senses is that you get your esp pointer from **running_stack and then stores it into *running_stack ... did i miss something ??

Note that you're not forced to use esp to create your frame:

Code: Select all

create_frame:
mov eax,[running_stack] ;get stack address
mov [eax],STARTUP_FLAGS
mov [eax-4],CODE_SEL      ;push code selector for task
mov edx,[task_address] ;push task address
mov [eax-8],edx
sub eax,12
mov [running_stack],eax ;store new stack addr
ret

Re:Stack Based task Switch Problem

Posted: Fri Sep 06, 2002 1:04 pm
by Slasher
Thanks for the post and advice!! will look into them. Can you please suggest why the task switching works on BOCH but freezes on a real PC.
thanks!!

Re:Stack Based task Switch Problem

Posted: Fri Sep 06, 2002 1:09 pm
by Pype.Clicker
dunno ... my own OS works on real hardware and behaves weirdly in BOCHS ;) ... maybe you should have locked IRQs while you were setting up another stack. i really advice you to use [eax] rather than push/pops ...

Re:Stack Based task Switch Problem

Posted: Fri Sep 06, 2002 1:18 pm
by Slasher
So the idea is fine and my iretd is the right choice? cause i created the task frames just the same way it would be when an interrupt occurs, so that subsequent iretd in switch_task would return to the interrurted address?
my ideas for stack switch is
on timer interrupt:
store esp into the current task's stack pointer
get esp for new task from new task's stack pointer
pop all stored general registers(one at a time not popad)
then issue iretd(this should switch to the task)

that my algorithm, i have the feeling i'm missing ( assuming) somethings. please can anyone verify this algorithm with theirs. am i missing vital steps?

thanks

Re:Stack Based task Switch Problem

Posted: Sun Sep 08, 2002 2:15 pm
by Pype.Clicker
hmm, i didn't see a "push all registers" corresponding to "pop all registers", but i guess its present in your head anyway ;)

A trick i give you from Clicker dev. is that you should better unlock the 8259 (out 20,20) before your code could issue a stack switch so that switching to a task that is resumed (i.e. that has been suspended by sem_wait() rather than by a timer interrupt) will not keep the IRQ locked :-)

Re:Stack Based task Switch Problem

Posted: Sun Sep 08, 2002 2:55 pm
by Slasher
Yes,i acknowledge the IRQ before the iret
ie mov al,0x20
mov 0x20,al
iretd
The task switching works(once) on BOCH but doesn't on a real PC.
I have a feeling its a problem with the way i initialize each process stack frame upon creation. So i'll go home and change it.(above in previous posts). i just thought of something today, and correct me if i'm wrong!
this is it:
the real pc decrements esp before it places the value of a push instruction on the stack ie
PUSH value
is executed by the pc as
sub esp,xx (xx is either 1(byte stack),2(short int stack) or 4(long int stack)
mov esp,value
so the code above should be
...
....
mov [eax - 4],SYSTEM_FLAG
mov [eax - 8],CODE_SEL
mov [eax - 12],code_offset
.....
.....
right?confirm please!!!
Thanks for the all the advice:)

Re:Stack Based task Switch Problem

Posted: Mon Sep 09, 2002 1:09 pm
by Slasher
Hi, I've gotten task switching to work under BOCH, but on a real PC it causes a GENERAL PROTECTION FAULT (EXCEPTION 13) on the first task switch!!! :( Anyone with any ideas what could be wrong?
the stack of every task is initialized to

eflags
cs selector
eip
eax
ebx
ecx
edx
ebp
edi
esi


Thanks

Re:Stack Based task Switch Problem

Posted: Tue Sep 10, 2002 1:40 am
by Pype.Clicker
i think you'll need a GPF handler to show where the exception occurs and what is the error code the CPU pushed on the stack ... can't help without this info ...

Re:Stack Based task Switch Problem

Posted: Thu Sep 12, 2002 5:47 am
by Slasher
Hi,
I kept looking over the code and came up with nothing. So I decided to look at the stack allocation. I initially started allocating system and user stack pointers from the 2mb mark. System Stack starts at 2mb, and user stacks start 1024k below it.
I then changesd the address to 4mb ie system stack starts at 4mb and user stacks start 1024k below it, and immediately my Task Switching was working Flawlessly!!! ;D
I'm still wondering why it wouldn' t work with stacks starting at 2mb, cause i know that my kernel isn't even 10kb large,the tasks i'm using to test the task switching is in the kernel(cpl 0) and i hadn't written any system info to addresses in that range! But i'll investigate it with a better GPF handler as you sugessted.
Any idea why this change in Starting ESP pointer from 2mb to 4mb solved the task switching problem?
Thanks for all your help