I read once that one advantage of a microkernel architecture is that you can stop/start essential services like networking and filesystems, without needing to restart the whole system. But considering that Linux kernel nowadays (was it always the case?) offers the option to use modules to achieve the same effect, what are the (remaining) advantages of a microkernel?
- Microkernels allow non-fundamental features (such as drivers for hardware that is not connected or not in use) to be loaded and unloaded at will. This is mostly achievable on Linux, through modules.
- Microkernels are more robust: if a non-kernel component crashes, it won't take the whole system with it. A buggy filesystem or device driver can crash a Linux system. Linux doesn't have any way to mitigate these problems other than coding practices and testing.
- Microkernels have a smaller trusted computing base. So even a malicious device driver or filesystem cannot take control of the whole system (for example a driver of dubious origin for your latest USB gadget wouldn't be able to read your hard disk).
- A consequence of the previous point is that ordinary users can load their own components that would be kernel components in a monolithic kernel.
Unix GUIs are provided via X window, which is userland code (except for (part of) the video device driver). Many modern unices allow ordinary users to load filesystem drivers through FUSE. Some of the Linux network packet filtering can be done in userland. However, device drivers, schedulers, memory managers, and most networking protocols are still kernel-only.
A classic (if dated) read about Linux and microkernels is the Tanenbaum–Torvalds debate. Twenty years later, one could say that Linux is very very slowly moving towards a microkernel structure (loadable modules appeared early on, FUSE is more recent), but there is still a long way to go.
Another thing that has changed is the increased relevance of virtualization on desktop and high-end embedded computers: for some purposes, the relevant distinction is not between the kernel and userland but between the hypervisor and the guest OSes.
A microkernel limits the time the system is in kernel mode, as opposed to userspace, to the absolute minimum possible.
If a crash happens in kernel mode, the entire kernel goes down, and that means the entire system goes down. If a crash happens in user mode, just that process goes down. Linux is robust in this regard, but it's still possible for any kernel subsystem to write over the memory of any other kernel subsystem, either purposefully or accidentally.
The microkernel concept puts a lot of stuff that is traditionally kernel mode, such as networking and device drivers, in userspace. Since the microkernel isn't really responsible for a lot, that also means it can be simpler and more reliable. Think of the way the IP protocol, by being simple and stupid, really leads to robust networks by pushing complexity to the edges and leaving the core lean and mean.
You should read the other side of the issue:
Just take a look at x86 architecture -- monolithic kernel only uses rings 0 and 3. A waste, really. But than again it can be faster, because of less context switching.
Monolithic kernel is much older than microkernel. It’s used in Unix while the idea of microkernel appeared at the end of the 1980's.
Examples of OSes having the monolithic kernels are UNIX, LINUX while the OSes having microkernel are QNX, L4, HURD and initially Mach (not MacOS X) which was later converted into hybrid kernel. Even MINIX is not a pure microkernel because its device drivers are compiled as part of the kernel.
Monolithic kernels are faster than microkernels. The first Mach microkernel is 50% slower than monolithic kernels. Later versions like L4 are only 2% or 4% slower than the monolithic kernel.
Monolithic kernels are generally bulky while pure microkernel has to be small in size, even fit into the processor's first level cache (first generation microkernel).
In monolithic kernels, device drivers reside in the kernel space while in the microkernel device drivers reside in the user space.
Since device drivers reside in the kernel space, it makes monolithic kernel less secure than microkernel (Failure in the driver may lead to crash). Microkernels are more secure than monolithic kernels, hence they're used in many military devices.
Monolithic kernels use signals and sockets to ensure IPC while microkernel approach uses message queues. The 1st gen of microkernel poorly implemented IPC so they were slow on context switches.
Adding new features to a monolithic system means recompiling the whole kernel while you can add new feature or patches without recompiling
Windows NT (the underlying kernel to current Windows systems) started out as a quite vanilla microkernel design. Due to performance problems, more and more of the "userland" code migrated into the "micokernel"... today it's microkernel structure is vestigial.
The case is that linux kernel is a hybrid of monolithic and microkernel. In a pure monolithic implementation there are no modules loading at runtime.
microkernel cannot be seriously compared as they describe different aspects of kernel design (structure vs. size).
A typical monolithic kernel was the SunOS-4.x kernel and Linux is still similar, as you manually configure the content of the basic kernel.
The Solaris kernel (starting with 2.1 on 1992) cannot be called monolithic anymore as all drivers are loaded automatically on demand and only a tiny part is loaded during the initial boot.
SunOS-4.x and Solaris (SunOS-5.x) and Linux are all single context implementations. Their entire code runs in a single MMU context.
Mac OS X is based on Mach and runs as a multi context implementation with several processes separated by MMU contexts. In this concept, drivers are in separate processes and separate MMU contexts.
Many people call Mac OS X a "microkernel system", but it may be that the basic kernel is not smaller than the basic kernel from Solaris.
So it seems that it would be better to talk about
single context kernels vs.
multi context kernels.