The main issue: the kernel needs a stack but can't always allocate memory, e.g. at startup when memory isn't initialized yet, or when the garbage collector is running. Allocating a traditional stack for the kernel is not an issue on the continuation level. However, the kernel and userspace share a codebase. So I guess I have to dynamically determine how to deal with the stack? Seems awkward...
Ok, this might actually work: replace the current userspace function header with `if top_kernelstack < sp < bottom_kernelstack: panic("don't call userspace functions from the kernel!") # this is a cheap check that doesn't read system registers' declare a new function header doing exactly the opposite, then assign each function to the appropriate side of the divide. (Duplicating or adding a kernel->user call gate.)
Once everything works again, replace the usermode stack implementation.
Just figured out another complication: my plan was to allocate a frame for the kernel to use when taking an exception from user mode and put it in the supervisor stack pointer register. This works well! Until there's a kernelmode -> kernelmode exception (e.g. to swap in a page), and you have nowhere to put your registers since the stack pointer is useless.
Mastodon is a server for a federated social network: everyone can run a server if they want to, including me. So this is a Mastodon server for me (Vierkantor) and my friends.