Hi,
Have a look at
Multitasking Systems which gives some background and links.
If you want to think about this so you can do it in your own way, basically think about the "execution context" of your (currently single-tasking) kernel. What basically encompasses everything it needs to run as it does? Initially, this may simply include:
- Memory Space.
- General Purpose registers (including (E/R/)IP and the Stack Pointer).
- Segment Registers
- (E)FLAGS
Of course, you have to store more than this for housekeeping, such as process ID's, whether the thread is in a waiting or blocked state etc. Later, your implementation may also include things like SSE state and so on
So basically Multitasking involves saving this process state, selecting the next process to run and loading its process state. Again, there is more complexity when you start thinking of things like Multiprocessing, mutual exclusion, task priorities, lock contention and so on. I don't know that I can explain any more about how it works without getting in to implementation details. As you say, there are plenty of practical examples. Although you don't want to copy/paste code, there is absolutely no harm in reading a few code examples to see how it works before deciding how it fits in with your design.
To get a better idea of the theory, you may also be interested to see how it works on a different architecture, such as the 8 bit RISC AVR
which can be found here.
Cheers,
Adam