Discussion on:
Message 43 of 386
Understanding OSes: Kernel Modularity
This is part two of the Understanding OSes series. Part one was Understanding OSes: Booting . Familiarity with the subject matter of part one is recommended before reading part two. Find collected links for this series at the Table of Contents .
At the center of every modern operating system is the kernel. The
kernel is, in essence, the parent program of all other programs that
make up the totality of your OS and computing environment as a whole.
The kernel, however, is not all one piece of homogenous process, at
least in theory, and the degree to which it is separable into distinct
parts is called "modularity". What modularity means changes from one
kernel design to another: in the Linux kernel, a module might the
device driver for your wireless networking card, while in the Hurd
kernel, a module might be even more fundamental, such as the operating
system's interrupt request handling functionality. In the course of
this article, I'll address kernel modularity by describing the
modularity characteristics of several major types of kernel design:
highly modular microkernel, two-part microkernel, monolithic kernel,
and megalithic kernel. I'll do this primarily by examples, though in
some cases my examples will explain the types by contrast as much as by
demonstration of the type.
The most modular OS design philosophy going in theoretical OS design
circles utilizes what is known as a "microkernel" with sort of a cloud
of modular parts floating around it, ready to be attached to and
detached from the microkernel itself to provide functionality if, and
only when, they are needed. This is meant to provide increased
security, because no more kernel is present than is needed to be in
operation at any time, thus reducing the amount of possibly compromised
code. This is meant to provide increased stability, because the
complexity of the current running system is reduced when no more than
exactly what is needed is actually running. This is meant to provide
increased performance, as there is less kernel to be loaded into memory
and to demand the attention of the processor than if everything is
loaded all the time. All of this is how a microkernel is supposed to
make your life better, in theory. As we all should know, however, in
theory there is no difference between theory and practice, and in
practice there is a difference. Make a note of that principle of theory
and practice: I use it a lot.
Unless and until microkernel development makes sudden leaps forward
in perfection of its principles of implementation, we're going to tend
to find many of the intended effects of microkernel design being
reversed. They perform like dogs because interfaces between the modular
chunks of the kernel (the microkernel and its cloud of extensions)
require communication: by analogy, compare being able to pass thoughts
around in your brain with being able to discuss those thoughts with
another human being. Their stability is good, as far as the microkernel
itself is concerned, for exactly the reasons it's theorized it should
be good, but the stability for the whole system is reduced by virtue of
the fact that increased complexity of communication across software
interfaces creates more opportunity for errors and failures to occur,
possibly causing big chunks of the system to fail if something goes
wrong. As far as anyone is aware (or so I'm given to understand),
security operates pretty much as advertised, though there are those who
are skeptical of the claim of increased security as well. I suppose, in
the end, that if the "perfect" microkernel OS were written, it would be
more stable, secure, and quick on the uptake than everything else
going, but if the "perfect" monolithic kernel were written as well, it
too would be perfectly secure, stable, and fast, so one begins to
wonder where the escalation of hypotheticals might end.
There is exactly one commonly available true microkernel OS in
current development, so far as I'm aware. That OS is GNU/Hurd. It's
still not, as of this writing, in ready-for-release form, but it's
operational. From what I understand, it's slow as molasses in
comparison with GNU/Linux system performance, but operational. I'll be
keeping an eye on its development to see where it's going.
There is also a commonly available pseudo-microkernel in current
development that might surprise you. That kernel is called Darwin, and
it's the heart of MacOS X. It is a very nearly "true" microkernel, but
that of course is shot down the tubes as far as microkernel theory is
concerned by the way Apple makes use of the Darwin kernel for the basis
of MacOS X. You see, MacOS X is built as a layered-on monolithic
kernel, with Darwin simply acting as the core of it. Ultimately, MacOS
X seems to be designed as a bilithic kernel, if I'll be allowed the
neologism, which operates pretty much indistinguishably from the way a
monolithic kernel operates.
The next step in our odyssey from microkernel to megalithic kernel
is the modular monolithic kernel. This is a somewhat effective attempt
to wed some of the better facets of microkernel and monolithic kernel
design into one single kernel design standard. The current canonical
example of this is the Linux kernel. The way the Linux kernel works is
largely indistinguishable from the way a normal monolithic kernel
works, as viewed from outside, and thus it enjoys the performance
benefits of a mostly unified operating system. Essentially, a true
monolithic kernel makes everything that is strictly part of the
necessary OS of a computer system part of the kernel, which does not
include the user interface. This is normally only possible by knowing
before you compile your kernel exactly what hardware you'll be using,
and designing the kernel to suit that hardware, then compiling it.
There are ways around this, and I don't pretend to really know anything
about them excepting the way Linux does things, so I won't comment
except on the Linux modular monolithic kernel design.
Within the Linux
kernel, there is a set of module support interfaces that allow for
kernel modules to be loaded and unloaded as needed. Linux notably uses
kernel modules for device drivers, among other purposes. Because of the
tight integration of modules with the kernel, there is minimal
performance loss in the communication between modules and kernel,
though when you compile your kernel you need to "deactivate" support
for modules you know you won't use if you want greater performance
benefits possible through absence of those modules. For those who are
familiar with Linux distributions, this is (at least theoretically) a
performance benefit of using Linux From Scratch, Debian From Scratch,
Gentoo, or really any custom-compiled kernel, assuming you are willing
(and knowledgeable enough) to configure the kernel to suit. All else
being equal, then, the combination of features of modularity and
monolithic kernel design contributes greatly to the performance of
Linux, and helps to explain how a Pentium II 366MHz Thinkpad running
Linux that I own consistently outperforms an Athlon XP 1600+ desktop
system running Windows XP Pro that I also own.
This brings us to the red-headed stepchild of kernel modularity,
Windows. There have, over the years, been aspects of Windows kernel
design that make arguments possible claiming that it is a microkernel
system, a monolithic kernel system, a bilithic kernel system, or a
megalithic kernel system (the last being a system that includes even
such normally application-level software as the user interface in the
kernel itself). Ultimately, I suppose the way to describe the somewhat
schizophrenic history of the Windows kernel is as a modular megalithic
kernel. From top to bottom, the OS itself is made up of separate, but
indivisible, parts. For instance, the user interface of Windows XP is
indeed a separate set of code from the rest of the kernel (and is,
itself, several separate programs interoperating intimately), including
the legendary OS-integrated Explorer rendering engine used to make much
of the user interface possible, but the OS itself literally will not
start and operate properly without all major modular parts of the
entire vertically integrated stack of parts running. If the UI goes
down, the entire operating system is essentially inoperable unless and
until the UI starts working again.
Technically speaking, of course, the
higher-level OS components are not part of the kernel, but there is
such an indistinct dividing line between parts of the operating system
that sometimes it can be a little hard to tell where the kernel ends
and everything else begins. Despite initiatives at Microsoft over the
years intended to implement good design principles in kernel design,
they have largely been sabotaged by the necessities of interfacing the
kernel with the rest of the operating system. The part of the OS that
is officially identified as the kernel by Microsoft, its central parent
process, is actually not a bad design, at all, in theory. In practice,
it is the axle on which the Windows wheel turns, and a stable axle
won't smooth the ride without some rubber between the wheel and the
pavement. The reasons for the evolution of the Windows system
architecture are manifold, and will be the subject of a later addition
to the Understanding OSes series.
Posted by apotheon
Updated - 3rd Aug 2005

































