Move the scheduler into kernel space.

Previously, on a context switch, the next context would be the scheduler
which would run in user-mode rather than kernel mode. Then the scheudler
would perform a syscall to load the new thread.

Considering that the scheduler is now so compact (and can be more
compact) this can be removed.

I've also tidied up the context saving and restoring so that only the
target code knows about it.