Why are all major OS's (Windows, macOS, Linux, *BSD) all monolithic kernels? Why aren't there more microkernel operating systems, like for example Redox or Minix?
The NT kernel and XNU (macOS) are considered hybrid kernels. QNX, a microkernel, is absolutely everywhere (i.e., cars).<p>Performance of microkernels is or was a hotly debated topic back in the '90s; microkernels generally had lower performance than their monolithic counterparts. There was a famous argument comparing Linux (monolithic) to MINIX (micro) [0]. Wikipedia has simple explanations for the differences between hybrid, mono, and micro kernels that serve as a decent primer [1] and a visual that I find helpful [2].<p>[0] <a href="https://en.wikipedia.org/wiki/Tanenbaum%E2%80%93Torvalds_debate" rel="nofollow">https://en.wikipedia.org/wiki/Tanenbaum%E2%80%93Torvalds_deb...</a><p>[1] <a href="https://en.wikipedia.org/wiki/Kernel_(operating_system)" rel="nofollow">https://en.wikipedia.org/wiki/Kernel_(operating_system)</a><p>[2] <a href="https://en.wikipedia.org/wiki/Hybrid_kernel#/media/File:OS-structure2.svg" rel="nofollow">https://en.wikipedia.org/wiki/Hybrid_kernel#/media/File:OS-s...</a>
Definitely read up on the Torvalds/Tanenbaum debate as there are lots of moving pieces and interesting theories.<p>My opinion summed up ridiculously concisely is that the reasons are largely accidents of timing (i.e. there was room in the market for new entrants), mixed with trivial-at-the-time but high-impact choices. Had Tanenbaum been permitted by his publisher to give away copies of minix freely, Linux may never have been started at all. Had Tanenbaum chose raw performance over teachability (the kernel was a teaching tool after all), it may have made a difference. (warning: this part is controversial) There's also a lot of question about whether the GPL licensing kept Linux relevant, or if it was largely inconsequential. My opinion is that GPL made a big difference. Had the licensing of Minix been GPL flavored, it probably wouldn't have been used by companies like Intel for the Management Engine, but there might have been enough "forced sharing" to keep it relevant. Impossible to say for sure, but that's my two cents.
Linux wouldn't really exist today if it wasn't for GNU Hurd being a microkernel. It took so damn long for Hurd to become stable that nobody wanted to use it. But people did want to use the GNU tools. So Linus made the Linux kernel a simple monolith, shipped it quickly, integrated patches quickly, and everyone started using it. By the time Hurd was stable, Linux was popular. So microkernels are hard and monoliths are easier, and the first one to the party tends to stick around the longest.
<i>Very</i> oversimplified answer: Microkernels still have a performance hit, end-users care more about performance than stability/security (at least at the ratio/margin in question), therefore we use the faster monolithic kernels for most user-visible systems, with carve outs where the performance hit isn't <i>so</i> bad (hence NT/Darwin really being more hybrid now, and even Linux <i>can</i> do some drivers in userspace). As other comments note, this only applies to places where performance matters; lots of embedded systems do in fact care more about reliability than performance so the outcome is different.
A good starting point for this question would be this famous discussion:<p><a href="https://en.wikipedia.org/wiki/Tanenbaum–Torvalds_debate" rel="nofollow">https://en.wikipedia.org/wiki/Tanenbaum–Torvalds_debate</a><p>Which in a nutshell comes down to Linus's view that producing a system that meets current needs (for example by offering a simple API) and is reasonably performant -- even if it ran on but a single architecture such as the i386 -- was more promising than a design offering "theoretical" benefits (such as portability) but which either didn't deliver the goods today or just wasn't reasonably performant.<p>This is a vast simplification of a much broader set of issues but if one digs into the notes of why subsequent projects (e.g. Windows NT) moved away from microkernel designs, or the roughly analogous microservices debate of the past decade -- one often finds echoes of the same basic considerations.
Linux has more microkernel features than you'd think. You can run all of networking, filesystems, HID and more in user space with BPF/Fuse. What else is left?
New OSes that have come out are pretty much universally microkernels. Fuchsia from Google is on a lot of their devices, and is a microkernel. SeL4 and QNX are microkernels for security and safety critical devices. I believe that Firecracker from AWS is also sort of microkernel-like (but pretends to be Linux). If you are building the device, the kernel, and the software, chances are that you are using a microkernel in 2024.<p>Windows and the Unix OSes just have a lot more market penetration, strong network effects, and a big first-mover advantage. That means that when you are buying your OS or your hardware or your software, you're probably stuck with a monokernel.
Nobody actually wants microkernels. Remember that the microkernel design is just a pessimistic mitigation. It assumes code will be crashy and full of exploits forever, and that it's worth significantly complicating the design as well as sacrificing performance to try and mitigate that. If you're making an OS you could invest resources into micro-kernelling everything and then trying to resolve the many hard problems and bugs that mitigation itself creates, or you could just .... fix the bugs! Kernels aren't infinitely large and the latter is actually much preferable if you can do it.<p>Some kinds of code are inherently in the core failure domain and trying to use restartable processes for them is impossible. For example if the code configuring your PCI controller crashes half way through, well, you need to reboot. You can't just restart the driver because you have no idea what state the hardware is in. A reboot gets you back into a known state, a server restart doesn't. Likewise if your root filesystem server segfaults, you can't restart it because your process start code is going to involve sending RPCs to the filesystem server so it'd just deadlock.<p>Finally, it's a spectrum anyway. Microkernel vs monolithic is not a hard divide and code moves in and out of those kernels as time and hardware changes. The graphics stack on Windows NT started out of kernel, moved into the kernel, then moved back out again. In all OS' the bulk of the code resides in userspace libraries and in servers connected via IPC.
Because microkernel was born in an era when cpu cycles were precious and albeit minimal, the difference in performance would be noticeable. Also, back then there were no security reasons to choose one over another; those were the days of NNTP and unencrypted email, and the web didn't even exist. I can't comment about other OSes, but in the case of Linux, when microkernels became stable enough, Linux had already taken over and was already running from supercomputers down to embedded systems (also 8088 based ancient hardware if one also counts ELKS). As of today, in my opinion, the biggest obstacle are device drivers; that's the biggest battleground that determines the success or failure of an OS. Linux runs pretty much everywhere and where hardware manufacturers stubbornly refuse to document their hardware, there are thousands of developers around the world spending time and money to reverse engineer closed drivers so that Linux can support more hardware. Of course once they're written they can be ported to other OSes, but that requires more time and more people devoted to the job.
In the world of Linux, "micro-kernel-like things" are done when they are beneficial. An example of this is FUSE: filesystems in user space. There is a benefit to being able to run a filesystem in its own address space as a user process, so it is done.<p>Also the model of a Unix kernel with services (daemons) in user space is kind of similar to the microkernel model. The graphical desktop is not in the kernel, the mail server isn't in the kernel, crond isn't in the kernel, the web server isn't in the kernel, the database server isn't in the kernel ... and maybe that's as close as we need to get to the microkernel.<p>Speaking of web servers in user space: at least for serving a static page, it's faster for that to be inside the monolithic kernel, where it can access the protocol stack and filesystem code without crossing a protection boundary.
Over the history of Linux, we have seen experimentation both with moving kernel things into user space (like with FUSE) as well as user things in to the kernel (TUX server, now evidently unmaintained).
Because once something works it is hard to start over from scratch and also hard to do a major refactor. It can be done but few can dedicate the time needed and so you stick with what is even if not ideal.
1. There is value in 'central control' several reasons;<p>- the people required to work on it<p>- in a timely fashion<p>- in a coordinated fashion<p>- the resources required<p>- bugs, updates, maintenance<p>2. The competition for aforementioned talent<p>3. The competition for aforementioned resources<p>4. Profit motive
For one thing, writing things in a microkernel are far more <i>complex</i>. In theory the isolation can mean lower impact of bugs and security issues; but in practice, the complexity means more bugs which are harder to debug. That's why you don't really see microkernels outside of embedded use cases -- the lower functionality requirement makes the complexity manageable.<p>You can write a rocket OS as a "proper" microkernel, but there's no way you could write a full-blown Windows OS as a "proper" microkernel.<p>That said, Windows or Linux can take leaves out of the microkernel playbook and apply them judiciously: KVM's architecture is arguably an example of this, where the core kernel does only the minimum necessary, and everything else is pushed to the user-mode component (QEMU, Firecracker, etc).
According to Qubes OS, they are not realistic today: <a href="https://www.qubes-os.org/faq/#what-about-safe-languages-and-formally-verified-microkernels" rel="nofollow">https://www.qubes-os.org/faq/#what-about-safe-languages-and-...</a>
Is Linux really a monolithic kernel? I mean yeah for most use cases such as desktops and servers it is but there's nothing preventing you from disabling most of its features and drivers and keeping a very minimal core (I'm sure lots of embedded Linux does this) and you can, right now, make it act as a microkernel by putting any component in userspace, mounting filesystems and devices via FUSE and networks via TUN, at its current state.<p>Now the question becomes why these components are built in the kernel and not in userspace? The answer is clear for each individual component. See how the in-tree NTFS driver eventually replaces NTFS-3g. Basically when an in-tree solution exists it just gets preferred over userspace solutions because of performance and reliability etc.