“LINUX is obsolete.” LINUX is a monolithic style system. This is a giant step back into the 1970s. That is like taking an existing, working C program and rewriting it in BASIC. To me, writing a monolithic system in 1991 is a truly poor idea.
— The Tanenbaum-Torvalds Debates (1991)
Andrew Tanenbaum, a professor and author of a book on operating systems had developed a Unix-like open-source operating system called MINIX as a teaching tool. It would directly influence Linus Torvalds to develop Linux a few years later.
However, there was one philosophical difference: MINIX was a microkernel architecture, and Linux was a monolithic kernel architecture.
Their exchanged messages on Usenet would later be called the “Tanenbaum-Torvalds debates.” While sometimes veering off topic and into “flame war” territory, they touched on issues still relevant today in system design.
In them, Tanenbaum makes three predictions:
Microkernels are the future
x86 will eventually lose to RISC
Everyone will run a free GNU OS
Breaking each down, what happened, why it happened, and the important lessons.
Microkernels are the future. What is the difference between a microkernel and a monolithic kernel? A microkernel only exposed a small kernel mode API — basic interprocess communication, virtual memory, and scheduling. A monolithic kernel has a much larger kernel — file system, device drivers, VFS, and more.
Why microkernels? Smaller APIs mean better portability. Separation of concerns, in theory, gives benefits to better architecture — more accessible to test, smaller blast radius for bugs, and more.
Why monolithic kernels? Performance (in a microkernel, many parts have to run in slower userspace). And ease of development. Separation of concerns vs. separation of address spaces.
What actually happened: microkernels (in a narrow definition) became highly complicated very quickly. Building everything in user space using basic IPC primitives made development slow and error-prone. There was somewhat of a false dichotomy between micro and monolithic kernels — the Linux kernel ended up being sort of a hybrid approach. Linus is ironically one of the biggest supporters of doing as much as possible in userspace. A large amount of functionality is exposed via hot-swappable kernel modules.
Lessons learned:
Unikernels are probably the closest thing to microkernels today. They are specialized, single-address-space machine images constructed by using library operating systems. It solves the problem in microkernels of having to develop critical features in userspace (there is no kernel/userspace distinction in microkernels). It also has a small API surface.
Performance + ease of development trumped separation of concerns (at least in kernel development)
We solved the security concerns of a larger kernel surface by just running hypervisors and abstracting away the hardware.
Semantics don’t always matter (running code does)
Part 2: “x86 will eventually lose to RISC” tomorrow.
I just did some reading about eBPF (ebpf.io). Where this is going to be sit in the micro vs monolith kernel?