software task switching in only ring 0

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
daxhuiberts
Posts: 3
Joined: Fri Jan 25, 2008 4:56 am
Location: Amsterdam
Contact:

software task switching in only ring 0

Post by daxhuiberts »

Hello,

It's been a long time ago since I was last active with os development. Got as far as setting up paging and extremely basic malloc and getting the PIT to run. The next step is to get familiar with task switching.

All my code runs in ring 0 in a single address space and I was wondering if it is possible to do software task switching with only this environment, or do I need a ring 0 and a ring 3 and a TSS to get minimal software task switching working?

Because as far as I can tell, when I'm in ring 0 and a interrupt happens, the interrupt handler runs in the same stack as the code before the interrupt and changing the the currently in use stack for task switching is very impractical if not impossible.

Any thoughts on this one?
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

You only need the TSS when changing from ring 3->0, so no, if you just use ring 0, you do not need a TSS. You just switch stack halfway through the int handler, which means setting up the stack of a new task before it runs for the first time.

Cheers,
Adam
daxhuiberts
Posts: 3
Joined: Fri Jan 25, 2008 4:56 am
Location: Amsterdam
Contact:

Post by daxhuiberts »

Yes, of course. But I do have to make sure I'm not dependent on some local interrupt handler data on the current stack while I switch to a different task's stack, right?
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:

Post by Combuster »

True.

You can have your scheduler function return the pointer to the next stack to be used, and then change it at the end of the function, when you don't need the locals anymore. That saves you from having to worry about what happens within the scheduling code with a bit of assembly.

Code: Select all

push registers
mov eax, esp
push eax
call scheduler
mov esp, eax
pop registers
iret
"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 ]
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

The easiest way is to have an asm stub. Before passing control to your task scheduler, save the value of ESP. The scheduler then returns the desired new ESP back to the end of the ASM stub which loads the stack pointer and does an IRET.

As your scheduler is 'stack neutral', you should find that everything aligns nicely. If you do end up adding ring 3 support, just ensure you write the correct stack value to the TSS at ESP0.

Have a look at the ASM snippet > here < for an example about half way down the page (ignore the rest of the tutorial, which isn't that well written IMHO!).

Cheers,
Adam
daxhuiberts
Posts: 3
Joined: Fri Jan 25, 2008 4:56 am
Location: Amsterdam
Contact:

Post by daxhuiberts »

Thank you both for the info,

I eventually came to the same sollution. Receiving the esp in eax
of the desired task by the scheduler and loading that in esp and doing an iret.
For the time being, this sure is a good enough sollution, till I decide to start working with ring 3 support.

Dax (The one with the 'real' DaxOS) :-D
Post Reply