Stack Based task Switch Problem
Stack Based task Switch Problem
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...
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...
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Stack Based task Switch Problem
As written here, your function loses the caller stack. i suggest you rather useCode 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
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
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
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!!
thanks!!
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Stack Based task Switch Problem
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
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
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
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Stack Based task Switch Problem
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
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
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:)
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
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
the stack of every task is initialized to
eflags
cs selector
eip
eax
ebx
ecx
edx
ebp
edi
esi
Thanks
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:Stack Based task Switch Problem
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
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
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