To start things off, let's discuss monolithic kernels.
A monolithic kernel is the traditional kernel of the days of ole. All the drivers and system services exist in one big binary blob, sharing code and data.
Now, the pros and cons of this are:
- Pros: Code runs much faster. Most, if not all, system services run in kernel mode, so there is no need to perform costly context switches between user mode and kernel mode. Only two context switches are needed for most syscalls, one from user to kernel on invocation of the syscall, and another context switch from kernel mode back to user mode on syscall return.
- Cons: Bugs in the kernel have a high chance of bringing the entire system down. Also, some kernels must be recompiled to add or remove drivers.
Microkernels, on the other hand, only have a very small portion of their code that runs in kernel mode, that is, has unfettered access to the full system hardware. For the most part, the portion that runs in kernel mode is a mere message marshalling system. All other system services, such as the filesystem, network stack, tty driver, etc., all run as user mode daemons known as "servers".
The pros and cons of this approach is this:
- Pros: If a bug crops up in a system service, and crashes that service, it is very unlikely that the system will crash with it. Usually, the system will merely restart the service. Depending on the system, there might be slight side effects from the service crash. For example, if the network stack crashes, applications might find all of a sudden that their socket handles are all now invalid. Sometimes, this can be made transparent to the applications, e.g. if the filesystem driver crashes, the libc could transparently detect this and reopen all file handles that were made invalid in the crash. Also, adding new drivers and system services to the system is as simple as starting the respective servers for them.
- Cons: Your system runs terribly slower than a monolithic kernel. A write() syscall to a tty, for example, will go to the filesystem driver first (as /dev/tty is filesystem), and then the file system driver would then call upon the teletype driver, and so on and so forth. It may take hundreds, if not thousands of messages to complete one traditional syscall, each message requiring two context switches each, one to kernel mode and one back, and each context switch may take thousands of CPU cycles to complete.
In short, each type of kernel has it's advantages and drawbacks. I am not trying to say that one is better than the other, or anything like that, but each one has it's merits, and I leave it up to the reader to determine which is better for any given situation.