Microkernel
From Free net encyclopedia
←Older revision | Newer revision→
A microkernel is a minimal form of computer operating system kernel providing a set of primitives, or system calls, to implement basic operating system services such as address space management, thread management, and inter-process communication. All other services, those normally provided by the kernel such as networking, are implemented in user-space programs referred to as servers.
Contents |
Background
One innovation of the Unix operating system is the use of a large number of small programs that can be strung together to complete a task with a pipe rather than a single large program. The result is more flexibility and improved development, as each program is small and dedicated to a single role and easier to understand and debug. Under Unix, the "operating system" consists of many of these utilities along with the master control program, the kernel. The kernel provided access to the hardware, scheduled the execution of programs, as well as controlled all hardware to avoid conflicts if two programs attempt to simultaneously access the same resource or device. In order to mediate such access, the kernel was given special rights on the system and led to the division between user-space and kernel-space.
Kernel bloat
Early operating system kernels were rather small, partly because computer memories were small. As the capability of computers grew, the number of devices the kernel had to control also grew. Early versions of UNIX had kernels of quite modest size, even though those kernels contained device drivers and file system managers. Berkeley UNIX (BSD) began the era of the "big kernel". When address spaces increased from 16 to 32 bits, kernel design was no longer cramped by the hardware architecture, and kernels began to grow. This growth trend continued for several decades, resulting in UNIX, Linux, and Microsoft Windows kernels with millions of lines of privileged code.
To date, attempts to reverse this trend have not been highly successful. This is not a technical problem. Nevertheless, the market for existing operating systems is so entrenched that little work continues on microkernel design.
Inter-process communication
Microkernels tried to reverse the growing size of kernels and return to a system in which most tasks would be completed by smaller utilities. The key problem under Unix had been trying to model the entire world as files, which some designers felt no longer seemed to apply. Instead the microkernels took a step back and considered pipes as a specific example of a much more general concept: inter-process communications, or IPC. IPC could be used to emulate Unix-style pipes, but it could also be used for practically any other task, passing data at high speeds between programs.
With IPC the operating system can once again be built up of a number of small programs. Networking can be removed from the kernel and placed in a separate user-space program, which is then called by other programs on the system. All hardware support is handled in this fashion, with programs for networking, file systems, graphics, etc.
Microkernel servers
Servers are programs like any others, allowing the operating system to be modified simply by starting and stopping programs. For a small machine without networking support, for instance, the networking server simply isn't started. Under a traditional system this would require the kernel to be recompiled, something well beyond the capabilities of the average end-user. In theory the system is also more stable, because a failing server simply stops a single program, rather than causing the kernel itself to crash.
However, part of the system state is lost with the failing server, and it is generally difficult to continue execution of applications, or even of other servers with a fresh copy. For example, if a server responsible for TCP/IP connections is restarted, applications could be told the connection was "lost" and reconnect, going through the new instance of the server. However, other system objects, like files, do not have these convenient semantics, are supposed to be reliable, not become unavailable randomly and keep all the information written to them previously. So, database techniques like transactions, replication and checkpointing need to be used between servers in order to preserve essential state across single server restarts.
The system then functions as if it has a full Unix kernel; the fact that the networking support was being "handed off" is invisible. Instead of a single six million-line kernel, there are a series of smaller programs instead. Additionally, users can choose capabilities as needed and run only those programs, tailoring the system to their needs. The same sort of changes to a traditional kernel, also known as a monolithic kernel or monokernel, are very difficult due to the high level of interconnectedness between parts of the system.
The role of the kernel in such a system is limited. In addition to providing basic task management (starting and stopping other programs), it provides the IPC system and security. When booting, the kernel starts up a series of servers to handle the hardware on the system, granting those servers additional rights as needed. New programs, those being started by the user, use the IPC system to access hardware, calling the kernel to pass along messages after being checked for rights and validity. To handle these tasks, ports introduce filesystem-like endpoints into the IPC system, complete with rights for other programs to use them. For instance, a network server would hold the write permissions to the networking hardware, and keep a number of ports open for reading to allow other programs to call it. Other programs could not take over the networking hardware without the kernel specifically granting this access, and only after the networking server agreed to give up those rights.
The "collection of servers" model offers many advantages over traditional operating systems. With the majority of code in well-separated programs, development on such a system becomes considerably easier. Developing new networking stacks on a traditional monolithic kernel required the entire kernel to be recompiled and rebooted, hard-crashing the machine if there was a bug. With a microkernel there is less chance that an updated networking system would do anything other than inconvenience the user and require that one program to be relaunched. It also offeres considerably more security and stability for the same reasons. Additionally the kernel itself becomes smaller — later versions of Mach were only 44,000 lines of code.
Essential components of a microkernel
The minimum set of services required in a microkernel seems to be address space management, thread management, inter-process communication, and timer management. Everything else can be done in a user program, although in a minimal microkernel, some user programs may require special privileges to access I/O hardware. A few operating systems approach this ideal, notably QNX and IBM's VM.
Most microkernel systems don't go quite that far. Most put at least some device drivers in the kernel. LynxOS is an example. Most also include a file system in the kernel.
A key component of a microkernel is a good inter-process communication system. Since many services will be performed by user programs, good means for communications between user programs are essential, far more so than in monolithic kernels. The design of the inter-process communication system makes or breaks a microkernel. To be effective, the inter-process communication system must not only have low overhead, it must interact well with CPU scheduling.
Start up, or booting, of a microkernel can be difficult. The kernel alone may not contain enough services to start up the machine. Thus, either additional code for startup, such as key device drivers, must be placed in the kernel, or means must be provided to load an appropriate set of service programs during the boot process.
Some microkernels are designed for high security applications. EROS and KeyKOS are examples. Part of secure system design is to minimize the amount of trusted code; hence, the need for a microkernel. Work in this direction, with the notable exception of systems for IBM mainframes such as KeyKOS and IBM's VM, has not resulted in widely deployed systems.
Performance
Microkernels need a highly efficient way for one process to call another, in a way similar to a subroutine call or a kernel call. The traditional performance problems with microkernels revolve around the costs of such calls. Microkernels must do extra work to copy data between servers and application programs, and the necessary interprocess communication between processes results in extra context switch operations. The components of that cost are thus copying cost and context switch cost.
Attempts have been made to reduce or eliminate copying costs by using the memory management unit, or MMU, to transfer the ownership of memory pages between processes. Mach uses this approach. This approach adds complexity but reduces the overhead for large data transfers. It is unclear whether the additional complexity is worth the trouble. QNX manages without it, incurring some extra copying costs.
Systems which page programs out to disk create additional problems for interprocess communication. Unless both the source and destination areas are currently in memory, copying must be delayed, or staged through kernel-managed memory. Copying through kernel memory adds an extra copy cost and requires extra memory. Delaying copying for paging delays complicates the interprocess communication system. QNX ducks this problem entirely by not supporting paging, which is an appropriate solution for a hard real-time system like QNX.
Reducing context switch cost requires careful design of the interaction between interprocess communication and CPU scheduling. Historically, UNIX interprocess communication has been based on the UNIX pipe mechanism and the Berkeley socket mechanism used for networking. Neither of these mechanisms has the performance needed for a usable microkernel. Both are unidirectional I/O-type operations, rather than the subroutine-like call-and-return operations needed for efficient user to server interaction. QNX has high-performance call-and-return primitives. Mach has very general primitives which tend to be used in a unidirectional manner, resulting in scheduling delays.
The question of where to put device drivers owes more to history than design intent. In the mainframe world, where I/O channels have memory management hardware to control device access to memory, drivers need not be entirely trusted. The Michigan Terminal System (MTS), in 1967, had user-space drivers, the first operating system to be architected in that way.
Minicomputers and microcomputers have not, with a few exceptions, interposed a memory management unit between devices and memory. (Exceptions include the Apollo/Domain workstations of the early 1980s.) Since device drivers thus had the ability to overwrite any area of memory, they were clearly trusted programs, and logically part of the kernel. This led to the traditional driver-in-the-kernel style of UNIX, Linux, and Windows.
As peripheral manufacturers introduced new models, driver proliferation became a headache, with thousands of drivers, each able to crash the kernel, available from hundreds of sources. This unsatisfactory situation is today's mainstream technology.
With the advent of multiple-device network-like buses such as USB and FireWire, more operating systems are separating the driver for the bus interface device and the drivers for the peripheral devices. The latter are good candidates for moving outside the kernel. So a basic feature of microkernels is becoming part of monolithic kernels.
Examples
Examples of microkernels and operating systems based on microkernels:
- AmigaOS
- Amoeba
- Brainix
- Chorus microkernel
- Coyotos
- EROS
- K42
- LSE/OS (a nanokernel)
- KeyKOS (a nanokernel)
- The L4 microkernel family, used in TUD:OS, GNU Hurd.
- Mach, used in original GNU Hurd, NEXTSTEP, OPENSTEP, and XNU (used in Mac OS X)
- MERT
- Minix
- MorphOS
- Phoenix-RTOS
- QNX
- RadiOS
- Spring operating system
- Symbian OS
- VSTa
See also
- Kernel (computer science)
- Monolithic kernel
- Hybrid kernel
- Exokernel, a research kernel architecture with a more minimalist approach to kernel technology.