Martin is OS researcher and co-author of HelenOS since 2005, but also an active user and occasional contributor to GNU/Linux. HelenOS is a portable microkernel and multiserver OS. It runs e.g. on Beagle*, RPi, with ext4 and IPv6 and compositing GUI.
First of all, we should realize that there is no iron curtain between microkernels and monolithic kernels, rather there is a spectrum between the micro- and monolith aspects. For instance, the core memory management is often considered as part of the memory management, but e.g. SCL4 does the memory management (policy) in user space. Also, it’s a multidimensional space with e.g. isolation, componentization and dynamicity.
New kid on the block is OS-V, which is designed specifically for VMs. It builds on the concept that Antii highlighted in his keynote speech: it removes layers of abstraction. It has the API necessary to run POSIX applications, but with a single user, single process, single image, single address space. It is the hypervisor that will take care of the necessary isolation etc.
This multidimensional space exists because different people have different needs. So all these systems can exist peacefully side by side.
Monolithic kernels also learn from microkernels. For instance, they make it possible to move things to userspace: FUSE, libusb, tun devices. The performance penalty can still be handled, e.g. avoiding memory copies. On the other hand, there are also things moving in the other direction, like KMS.
Monolithic kernels could learn from microkernels that the componentisation that you have in the source code is also kept in the running code, i.e. make it clear which component owns which data.
Another thing that monolithic kernels could learn is that bootstrapping is different from the run time. So it is not a good idea to design separate code paths for bootstrap and shutdown, and design the kernel itself as if it is running forever.
Microkernels learn from monolithic kernels to use smart algorithms and data structures. These things are usually first developed in monolithic kernels, so actually microkernels are less innovative which is surprising.
A second thing that microkernels can learn is scalability. Linux scales to 1000s of CPUs, while microkernels struggle with 16 CPUs. Same goes for scaling to embedded systems.
And finally, monolithic kernels are surprisingly portable, while microkernels often target just a single or maybe two architectures. If you design the OS without portability in mind,
Microkernel people sometimes have goals which are just counterproductive.
- Restarting services as a way of dependability. However, just restarting is pretty bad because you don’t have the internal state anymore. In addition, the logical state is usually spread over several services, so restarting risks bringing down other services as well. And also just restarting may just recrash it. So it’s a nice idea but can’t be a dependability goal on its own.
- Micro == small. But that doesn’t mean that the last bit of reduction in code size is still worth it. But code size or binary size has at best a weak correlation between actual bugs.
- Trivial algorithms protect against bugs. This is not true, you can have trivial bugs in trivial code, and you can audit or formally verify complex algorithms.