Page 1 of 1
Help with software multitasking
Posted: Sun Jun 17, 2007 7:43 am
by Jabus
I'm sorry if this is in the wrong forum. I wasn't sure where to post it.
I'm currently trying to put software multitasking in my kernel. However I need to just check whether what I am doing is right. this is what I currently do:
When a process has run for a certain amount of time I copy all the information in the TSS e.g. esp0,ss0 etc. into a location into a TSS structure and copy the information from the TSS structure of the next process into the TSS. finally I use iret. However when I do that I get a general protection fault. Is there anything else I should do? If you want I will post the code.
Posted: Sun Jun 17, 2007 9:57 am
by AJ
No - that's not software multitasking, it's a slightly unusual version of hardware switching. For software MT, do the following:
* Push all segment registers and general purpose registers (use PUSHA?).
* If you are switching address spaces, save CR3 somewhere.
* Save your current ring 0 ESP somewhere.
Now for the incoming task:
* Load the new ESP from wherever you saved it to.
* Restore CR3 (if applicable).
* Pop all general purpose (POPA?) and segment registers.
* Put the value of ESP0 in to the TSS - this has to be the value of the base of your ring 0 stack, as it will be used when this task is un-scheduled.
* iret
The last iret assumes that your ring 0 stack contains a valid CS, EIP and EFLAGS. If you are entering a ring 3 task, you will also require a valid ring 3 ESP and SS on the ring 0 stack.
So, the only value you need to change in the TSS is ESP0.
HTH
Adam
Posted: Mon Jun 18, 2007 9:10 am
by JAAman
* If you are switching address spaces, save CR3 somewhere.
you shouldnt need to do this, as CR3 isnt something that normally changes, it doesnt need to be saved on task-switch (you should already have a saved copy of the CR3, saving on each task-switch is unnecessary and doesnt produce any benefit assuming that CR3 doesnt change while the task is running -- if it changes while the task is not running, this will not correct that)
also, depending on your design, you may not have to change ESP0 in your TSS either (i dont -- it depends on how you isolate your kernel stack between threads)
Posted: Mon Jun 18, 2007 12:21 pm
by AJ
JAAman wrote:
also, depending on your design, you may not have to change ESP0 in your TSS either (i dont -- it depends on how you isolate your kernel stack between threads)
I'm interested in that - how do you do it - map the ring 0 stack base to a different page in each memory space? Personally, I currently change ESP0 on each switch.
Oh - and the CR3 saving thing came from some experimenting I was doing with my kernel today, where the kernel changed memory spaces for a particular function. Of course, when the kernel got scheduled out, its previous PD was loaded and the function I was trying to achieve messed up. I therefore needed to save the current CR3 in order for everything to work smoothly...guess I need to work on my task-space memory management
Cheers,
Adam
Posted: Mon Jun 18, 2007 2:31 pm
by Aali
i have a single-threaded kernel that runs multiple user-level threads
that way, i dont need more than one kernel stack
(it sort-of rules out efficient SMP though, since the kernel must complete whatever it is doing before it can service another user thread)
oh, and it would be a very bad idea to do this in a monolithic kernel, obviously (if you have to wait for anything inside the kernel the whole system will grind to a halt)
i dont know if that is what he was talking about, though
Posted: Tue Jun 19, 2007 6:42 am
by JAAman
well, in a task switch, you dont need to change esp0, because each process will have its own page mappings, but in most systems threads dont change the page mapping, but in my system all task switches change at least some page mappings -- including thread switches -- which (among other things) changes the page mappings of the kernel stack -- which means every thread will have the same kernel stack location (but mapped to a different physical location of course)
Posted: Tue Jun 19, 2007 7:18 am
by AJ
OK - thanks for that explanation.
I've just re-visited my code and it looks like I'm reloading ESP0 every time *even though* my ring 0 stacks have the same virtual addresses...