OS Design, Implementation and Structures
How you decide what an OS should be (user vs system goals, policy vs mechanism), the five ways to arrange a kernel from MS-DOS to loadable modules, and the six kinds of system programs that live on top.
What you will be able to do
- State user goals and system goals for an OS and explain why they pull in different directions.
- Separate policy from mechanism in any example and explain why the separation buys flexibility.
- Describe all five OS structures (simple, monolithic, layered, micro-kernel, modular) with an example, advantages and disadvantages each.
- Explain how modules differ from layers and how modular kernels differ from micro-kernels.
- List the six categories of system programs and classify any tool into one of them.
Designing an OS: there is no silver bullet
Before you write a line of the kernel, decide who it is for.
Designing an operating system is one of the biggest software projects there is, and the slides open with a warning: no silver bullet, but some approaches have been successful. The internal structure of different OSs varies widely, and it is shaped by two things: the choice of hardware and the type of OS you are building (a real-time kernel for a pacemaker and a time-sharing server OS make very different choices).
The first job is to define goals and specifications. Who is this OS for? The slides split the answer into two camps that often conflict.
User goals vs system goals
User goals (what the person at the keyboard wants)
- Convenient to use
- Easy to learn
- Reliable
- Safe
- Fast
System goals (what the designers and maintainers want)
- Easy to design, implement and maintain
- Flexible
- Reliable
- Error-free
- Efficient
Policy vs mechanism: what vs how
Build the knob once, decide how far to turn it later.
The most important design principle on these slides is to separate policy from mechanism. A mechanism determines how to do something. A policy decides what will be done. Keep them apart and you can change your mind about the policy without rewriting the mechanism.
Policy vs mechanism, with the slide example and a few more
| Mechanism (how) | Policy (what) |
|---|---|
| A timer that interrupts the CPU after a set interval (ensures CPU protection) | How long the timer is set for a particular user |
| A priority field in each process and a scheduler that picks the highest | Which processes get high priority (interactive first? shortest first?) |
| A page-replacement routine that can evict any page | Which page to evict (least recently used? first in first out?) |
| File permission bits that the kernel checks on every open | Who is allowed to read the payroll file |
Why does this matter so much? Because policies change and mechanisms do not. A university lab might want fair sharing today and priority for research jobs next semester. If the scheduling mechanism is general (a timer plus a ready queue), switching policy is a configuration change. If the policy is baked into the mechanism, you rewrite the kernel. The slides say the separation allows maximum flexibility if policy decisions are to be changed later.
Why an OS needs a structure
Millions of lines of code cannot be one blob.
A system as large and complex as a modern OS must be engineered carefully if it is to work and be modified easily. The common approach is to partition the task into small components rather than build one monolithic system. Each component should be a well-defined portion of the system with carefully defined inputs, outputs and functions. How these components are interconnected and melded into a kernel is what we call the operating system structure.
The five structures on the slides
- 1Simple structure (MS-DOS)
- 2Monolithic structure (original UNIX)
- 3Layered structure
- 4Micro-kernel structure
- 5Modular structure (Solaris, Linux)
Simple and monolithic structures
MS-DOS had no walls. Original UNIX had one big room.
Many operating systems do not have well-defined structures. Such systems are small, simple and limited. The classic example is MS-DOS: it was written to fit in as little memory as possible, so application programs could call BIOS routines directly and write straight to the display. There was no protection because the Intel 8088 it ran on had no dual mode.
Simple structure (MS-DOS)
Advantages
- Simple to develop.
- Superior performance: no layers to pass through.
Disadvantages
- The entire OS breaks if just one user program malfunctions.
- No abstraction or data hiding: all layers can communicate with one another.
- The OS's operations are accessible to all layers, which can result in data tampering and system failure.
The monolithic structure is the next step up. The core of the OS is called the kernel, and in a monolithic design the kernel acts as a manager for everything: file management, memory management, device management and so on. That means a large number of functions at one level, all in one address space. The original UNIX used this structure, split into just two parts: system programs and the kernel.
Monolithic structure (original UNIX)
Advantages
- Simple to design and implement: all operations are managed by the kernel only.
- Relatively fast execution because all services live in the same address space. There is no cost for switching address spaces when one service calls another.
Disadvantages
- If any service fails, the entire system fails: everything shares one address space so the services are connected and affect each other.
- Not flexible to introduce a new service; you rebuild the kernel.
Layered structure
Each layer only talks to the one below it.
In a layered structure the OS is divided into a number of layers (levels). The bottom layer (layer 0) is the hardware; the highest layer (layer N) is the user interface. Each layer is built only on the layers beneath it, and each layer hides the existence of certain data structures, operations and hardware from higher layers. Layer 3 does not know or care how layer 1 works; it just calls layer 2's functions.
Layered structure
Advantage
- Simplicity of construction and debugging. You debug layer 1 on bare hardware. Once it works, you debug layer 2 knowing that any bug must be in layer 2, because layer 1 is already correct.
Disadvantage
- A layer can use only lower-level layers, so careful planning is necessary. Where does the disk driver go relative to the memory manager? The driver needs memory for buffers, but the memory manager may need to swap to disk.
- Each request passes through several layers, which adds overhead (in practice, the slides keep it to the planning point).
Micro-kernel structure
Take everything that is not essential out of the kernel.
The micro-kernel approach removes all non-essential components from the kernel and implements them as system and user-level programs. What is left is a micro (smaller) kernel that provides only minimal process and memory management plus a communication facility. The slide diagram shows this split clearly.
Who lives where in a micro-kernel system
| Mode | Components | How they talk |
|---|---|---|
| User mode | Application programs, file system, device drivers | Send messages to each other through the kernel |
| Kernel mode (the micro-kernel) | Interprocess communication, memory management, CPU scheduling | Passes messages between user-mode services |
| Below | Hardware |
Notice what has moved: the file system and device drivers, which are inside the kernel in a monolithic design, now run as ordinary user-mode processes. When an application wants to read a file, it does not call into the kernel's file code. It sends a message to the file-system server, the micro-kernel delivers it, and the reply comes back the same way.
Micro-kernel structure
Advantages
- Portable between platforms: only the tiny kernel is hardware-specific.
- Each micro-kernel component is isolated, so the system is safe and trustworthy.
- Because micro-kernels are smaller, they can be successfully tested.
- If any component fails, the rest of the OS is unaffected and continues to function normally. A crashed driver is restarted, not a reboot.
Disadvantages
- Increased inter-module communication reduces performance. Every service request is a message through the kernel instead of a direct function call.
- The system is complex to construct.
Modular structure: the best current methodology
A small kernel, plus modules you can load while the system is running.
The slides call this the best current methodology: loadable kernel modules. The kernel provides core services, and other services are implemented dynamically, as the kernel is running. Concretely: CPU scheduling and memory management algorithms are implemented directly in the kernel, while support for different file systems is provided by loadable modules. Plug in a USB stick formatted as exFAT and Linux loads the exFAT module on the spot.
How modules relate to the other two designs
Modules vs layers
- Similar: each subsystem has clearly defined tasks and interfaces.
- Different: any module is free to contact any other module, which eliminates the problem of passing through multiple intermediary layers.
Modules vs micro-kernel
- Similar: the kernel is relatively small.
- Different: the kernel does not have to implement message passing, because modules are loaded into kernel space and call each other directly.
The slide example is the Solaris modular approach: a core kernel surrounded by seven kinds of loadable modules (scheduling classes, file systems, loadable system calls, executable formats, STREAMS modules, miscellaneous, device and bus drivers). Linux uses the same idea with .ko files; lsmod lists the modules currently loaded on your machine.
Common OS structures shown on the slides (what each real system is)
| System | Structure in practice |
|---|---|
| Mac OS X | Hybrid: the Mach micro-kernel plus BSD components in one kernel, with kernel extensions loadable on top. Layered from the Aqua user interface down through Cocoa, Quicktime and BSD. |
| iOS | Same core as Mac OS X (Darwin), layered with Cocoa Touch, Media Services and Core Services above it. Structured layers over a hybrid kernel. |
| Windows | Hybrid: a kernel and executive in kernel mode with user-mode subsystems and environment servers. Started as micro-kernel, moved graphics into the kernel for speed. |
| Linux | Monolithic kernel with loadable modules: scheduling and memory management in the core, drivers and file systems as modules. |
All five structures in one glance
| Structure | Example | Key advantage | Key disadvantage |
|---|---|---|---|
| Simple | MS-DOS | Simple to develop, best performance | One bad user program breaks the whole OS; no data hiding |
| Monolithic | Original UNIX | Fast, same address space | One failing service kills the system; hard to add services |
| Layered | THE, early Multics-style designs | Easy to construct and debug layer by layer | Layers use only lower layers; careful planning needed |
| Micro-kernel | Mach, QNX, MINIX | Portable, isolated, testable, survives component failure | Message passing slows it down; complex to build |
| Modular | Solaris, Linux | Small kernel, direct calls, load services at run time | Kernel-mode modules can still crash the kernel (in practice) |
System programs: the tools around the kernel
Not the kernel, not your application. The stuff in between, like ls, gcc and ssh.
An important aspect of a modern system is its collection of system programs. They provide a convenient environment for program development and execution. Some of them are simply user interfaces to system calls (the rm command is a thin wrapper around the unlink() call); others are considerably more complex (a compiler). Most users' view of the OS is defined by system programs, not by the actual kernel. The slides list six types.
The six categories of system programs
| Category | What they do | Slide examples | Real tools |
|---|---|---|---|
| 1. File manipulation | Manipulate system files | Create, delete, copy, rename, print, dump, list | cp, mv, rm, ls, mkdir, Windows Explorer |
| 2. Status information | Provide data on the current or past status of the system | Date and time, available memory or disk, number of users, detailed performance, logging and debugging information | date, df, free, who, top, Task Manager |
| 3. File modification | Change the data in a file or modify it in another way | Editors for files on disk; special commands to search file contents or perform transformations | vim, nano, grep, sed, Notepad |
| 4. Programming language support | Support features for different languages | Compilers, assemblers, debuggers, interpreters | gcc, as, gdb, python |
| 5. Program loading and execution | Make sure programs can be loaded into memory and executed correctly | Absolute loaders, relocatable loaders, linkage editors, overlay loaders | ld, the ELF loader, Windows PE loader |
| 6. Communication | Create virtual connections among processes, users and computer systems | Send messages to another user's screen, browse web pages, send e-mail, log in remotely, transfer files | ssh, scp, ftp, write, a web browser, an email client |
Before the exam
The lines worth memorising, and the mistakes that lose marks.
Remember this
- 1No silver bullet. OS structure varies with hardware and OS type. First define goals and specifications.
- 2User goals: convenient, easy to learn, reliable, safe, fast. System goals: easy to design/implement/maintain, flexible, reliable, error-free, efficient.
- 3Mechanism = how, policy = what. Timer is a mechanism; how long to set it per user is a policy. Separation gives maximum flexibility when policies change.
- 4OS structure = how components are interconnected and melded into a kernel. Partition into small components with well-defined inputs, outputs, functions.
- 5Five structures: simple (MS-DOS), monolithic (original UNIX), layered, micro-kernel, modular (Solaris, Linux).
- 6Simple: no data hiding; one bad user program breaks everything. Monolithic: everything in one address space, fast, but one failing service kills the system and it is inflexible.
- 7Layered: layer 0 = hardware, layer N = user interface; each layer hides details from higher layers; easy to debug, but a layer can only use lower layers.
- 8Micro-kernel: only IPC, memory management and CPU scheduling in the kernel; file system and drivers in user mode; talk via messages. Portable, isolated, testable, but slower and complex.
- 9Modular: loadable kernel modules; scheduling and memory management in core, file systems as modules; any module calls any module; small kernel without message passing.
- 10Six system program types: file manipulation, status information, file modification, programming language support, program loading and execution, communication.
- 11Loaders: absolute, relocatable, linkage editors, overlay. Language support: compilers, assemblers, debuggers, interpreters.
- 12Some system programs are just user interfaces to system calls; others (compilers) are considerably more complex.
Exam traps
- The timer is not a policy, because it is the mechanism that enforces CPU protection; the policy is how long the timer is set for a given user.
- Monolithic is not the same as simple structure, because monolithic UNIX keeps a kernel boundary between user programs and the OS while MS-DOS lets user programs reach hardware directly.
- A modular kernel is not a micro-kernel, because modules run in kernel space and call each other directly instead of passing messages.
- A layer in a layered OS cannot call a higher layer, because each layer is built only on the layers below it; that constraint is why careful planning is the listed disadvantage.
- The file system is not part of the micro-kernel, because the micro-kernel keeps only IPC, memory management and CPU scheduling; the file system runs as a user-mode program.
- "Fast" is not a system goal on these slides, because it is listed under user goals; the corresponding system goal is "efficient".
- Loaders are not programming language support, because the slides give program loading and execution its own category.
- Renaming a file is not file modification, because it does not change the data inside; it is file manipulation.
Quiz yourself
One question at a time with instant feedback. Your best score is saved.
Which of the following is listed as a user goal for an operating system, rather than a system goal?
Not quite
User goals are convenient, easy to learn, reliable, safe and fast. Easy to design, flexible and error-free are system goals for the people building and maintaining the OS.
Finished reading?
Mark this lecture as done
Take the quiz above first so your score is saved here.