I haven't yet fully finished my Task scheduler, and it's only about 20% done, but so far all I do is let the PIT interrupt the CPU, and then I have my code to switch tasks form there. It's pretty buggy, my code, but at least my program Loader works fine now.
I can't wrap my head around is how it should load the next set of instructions for the CPU to execute (where/how do I store this?)
I believe that you're supposed to write an ASM stub to push the CS:EIP pair (and several other registers) onto the stack. When the task is switched back to after having been switched from, the ASM stub pops the CS:EIP pair back, and continues executing. Remember that CS points to the Code Segment you're currently executing in, and (E)IP is the Instruction Pointer register, which contains the memory address of the current instruction. So in essence, popping the CS:EIP pair back pretty tells the processor where to continue executing from, provided you also restored the correct segments, and whatnot.
You also asked how you could allot a certain number of milli- or nano- seconds to a process: this is done via the Programmable Interval Timer. In order to fully understand that, I recommend looking at
These very comprehensive tutorials. I haven't seen anyone else go into so much detail about every step. And what i love about his work is that he doesn't dump code, but just explains the concept, and gives you the freedom to ignore his code examples and think up your own implementation. His PIT tutorial is highly detailed.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.