That's very nice. It's approaching the QNX level of microkernel.
One unusual feature of QNX is that the kernel doesn't parse strings anywhere. There's a "resource manager", but that's a process. Programs register with the resource manager for a piece of the pathname namespace ("/dev", "/fs", etc.) and then get open requests sent to them when a pathname starts with their part of the namespace. Parsing creates a large attack surface, and getting it out of the kernel is a win.
QNX tries to avoid variable-length objects in the kernel. Messages are variable length and copied by the kernel, but from one user space to another, not queued in kernel space. Most of the ways a kernel can run out of memory are avoided in QNX. If the kernel is out of resources, some system calls return errors, but the kernel doesn't crash.
If you're doing a kernel in Rust, it's helpful to think that way. Rust doesn't handle out-of-memory conditions well.
Do you happen to know languages that do handle out of memory conditions well? That seems like an interesting topic. If I understand how it's done in C, I wouldn't call that "well", but it does provide the mechanisms for doing it (which is more than can be said for all languages). Language level features (or coding styles in C that could be implemented at a language level elsewhere) that provide for increased and intuitive control would be interesting.
Ada is one of the few languages that takes out-of-memory conditions seriously. The exception Storage_Error is raised.
Java, C# and Microsoft's common runtime have out-of-memory exceptions, but I'm not sure how reliable they are in a limited-memory environment. They're more like "GC isn't helping much" exceptions.
One unusual feature of QNX is that the kernel doesn't parse strings anywhere. There's a "resource manager", but that's a process. Programs register with the resource manager for a piece of the pathname namespace ("/dev", "/fs", etc.) and then get open requests sent to them when a pathname starts with their part of the namespace. Parsing creates a large attack surface, and getting it out of the kernel is a win.
QNX tries to avoid variable-length objects in the kernel. Messages are variable length and copied by the kernel, but from one user space to another, not queued in kernel space. Most of the ways a kernel can run out of memory are avoided in QNX. If the kernel is out of resources, some system calls return errors, but the kernel doesn't crash.
If you're doing a kernel in Rust, it's helpful to think that way. Rust doesn't handle out-of-memory conditions well.