xxchrisxx wrote:
What are the main differences between the two and what are their strong/weak points?
A monolithic kernel has little or no structure. "The structure is that there is no structure." (Andrew Tanenbaum in OSDI.) The code is certainly partitioned into separate source files, but they are all linked into a big glob of a binary, with the exception of modules. A monolithic kernel is a collection of procedures, like a massive C program. The whole kernel consists of its functionality partitioned off into these procedures. Everything is in the kernel - drivers, networking, terminal handling, filesystems, etc. All these are implemented in terms of procedures. Even with modules, the kernel normally keeps a table of function pointers which resolve to procedures in the modules.
A microkernel is a minimal kernel. It contains just enough functionality so that "everything else" can be implemented on top of it. A microkernel typically only includes processes, scheduling, memory management, IPC and perhaps some device drivers. All other functionality, like networking, filesystems, terminal handling and even some drivers are simply servers that run as processes on the microkernel.
The disadvantage to monolithic kernels is that feature creep or "futureitis" can cause massive bloat. Even small changes to the kernel can break the whole thing, because of the intricate interdependencies in the procedures that are all in each others' pants. On the upside, they are arguably simpler to hack together, and they are faster and more efficient than microkernels because drivers and such are all statically linked to the binary. Calling a procedure is faster than using IPC to communicate with a process running on a microkernel.
The disadvantage to microkernels is that they are somewhat slower (see comments above about monolithic efficiency.) They are somewhat more difficult to develop. Where does the minimal functionality end? When having drivers running as processes, what happens to your interrupt latency, do interrupts run too long? You need to write some really slim, lean and mean code in a microkernel to achieve fast robust performance comparable to a monolithic kernel. The advantage of a microkernel is that a change won't break the entire kernel, assuming you are changing the service processes. Also one service process crashing will not necessarily crash the entire system. Also you can plug and chug with different service processes at runtime without recompiling the kernel or service processes. A microkernel is also much easier to maintain than a monolithic kernel. You don't have to get your head around all that source code to make change X. You work in the context of a process running atop the kernel, or you are working in a small, tight microkernel.
There are other advantages and disadvantages, but these are the main ones.
For me, my money is on the microkernel design. All my kernel development will be the microkernel/server design. I don't want my kernel development to crash to a halt at some point in the future where it's just a huge fat pig and seriously broken from feature creep and spaghetti code. This is a serious issue in current Linux kernels - feature creep and "futureitis" I mean. Debugging and making a usable monolithic kernel when it's been in heavy, constant development for a decade is not a trivial task. Further, not a single developer understands the entire system and all possible kernel control paths. It's physically impossible. You're brushing on the limits of what a human being is capable of.
If you're going to write a production consumer OS, make it a microkernel or die an early death from not being able to expand and accommodate all those new features.