Five tiers of OS
© 2023-08-07 Luther Tychonievich
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
other posts
The term operating system means different things to different people.

Last week I decided to update the OS on several computers I manage11 Yes, I manage several. Three at work: a server for student submissions to my class, a desktop in my office, and a laptop I use to present in class; and several at home, as I buy a new one every few years and keep old ones running to make backups, access old files, and test out different systems.. I tried out six different OS-plus systems, which I suppose is more than most of my readers have used, and thought it might be worthwhile explaining a bit more about that.

What is an operating system? You can find many different opinions on this question, but there are a few things to know.

Kernel

The most essential part of what an OS does is present programs with a virtualized version of a computer system. Each application is presented as if it were the only one running on a computer with mostly-unlimited memory. To facilitate safe, shared, device-agnostic coding, all disks, input and output devices, networks, and the like are accessed via sending requests to the operating system rather than by directly sending specific bits down specific wires.

Achieving these features is no mean feat, and operating systems that focus only on these parts are called microkernels. Microkernels have some market share in embedded controllers and other small special-purpose computers; I’ve never used one for something most people would recognize as a computer.

Drivers

The next step beyond the microkernel is the device driver. Every piece of hardware you might want has its own rules about how it works, and because the OS is responsible for allocating which programs can access which devices the code that speaks to each piece of hardware is generally part of the operating system.

As soon as you start down this space, the amount that the OS does grows quite rapidly. For example, on application I use (OBS) can read data from my webcam, but also send its own video data out for other applications to see as if it were a webcam. This means the OS is not just handling the actual devices I have, but also allowing programs to pretend to be devices themselves. And so on.

In principle, most of the drivers could be implemented as normal programs and the OS could simply ship messages between programs; this is the microkernel approach. But all of the OSs you might have heard of (Windows, MacOS, Android, iOS, Linux, FreeBSD, Unix, Irix, Haiku, etc) are monolithic kernels where the drivers run as part of the OS instead.

Distribution

Once we have a kernel and drivers the next thing to consider is how we handle programs and their supporting libraries.

Libraries are portions of programs that many programs share. These are important because there are many programs running at a time on any end-user system; for example, my server is currently running 242 programs, my desktop is running 511. Most of these are services used by other programs, and most of them have many chunks of code in common: code to check if one piece of text is inside another piece of text, code to sort lists of things in alphabetical order, code to draw letters on the screen, and so on. If each program had its own copy of all of that code, I’d need several times more memory and disk space to run and store them all.

Instead, we take common code and put it in shared libraries. We store one copy of each shared library on disk, not one per application, and also store one copy in memory, with the OS telling each program it has its own copy so they don’t have to pay attention to which is which.

Virtually any program you think of as a program or app has dozens of libraries it depends on, most of which depend on other libraries as well, and so on in a big network of dependencies. Different distributions handle different ways of managing these.

The four commercial end-user OSs (Windows, MacOS, Android, and iOS) have a single default distribution model, though all of them also have other unofficial distribution techniques as well. But the most successful OS, Linux, has hundreds of distributions. Some prioritize sharing, limiting what you have access too to make that work; some prioritize freedom, letting you get yourself in a mess if you want; some prioritize isolation, making multiple copies of libraries to avoid accidentally having two applications expect different versions of the same library; and so on. Distributions also differ by the culture of how decisions are made, by the recommended default applications that come with the OS, and by how updates are delivered to both programs and the OS itself.

I currently run three distributions: Manjaro, Mint, and Ubuntu. I’ve used dozens of others in the past.

Display Manager

A big piece of what many people think of as an OS is what it looks like. That is largely the product of two libraries, one on top of the other.

The lower-level library is sometimes called a display manager, display server, or compositor. It provides a set of basic interfaces for allocating regions of the screen to an application, handling window moving and resizing and stacking and hiding, and directing user input events like mouse clicks and key presses to the application the user wants them to reach.

Display managers are big, complicated, and difficult to change. Every OS has changed display manager over time, updating them to better reflect how hardware has progressed and software evolved to keep pace. But such updates are very difficult because they make all pre-update apps stop working well, and getting rid of old code is tricky. For example, you can still find code that uses old direct-mode graphics that was the Microsoft display manager 30 years ago despite them having been through several display managers since then.

Because display managers manage access to screen space and user input, generally only one can run at a time. Because of that, they can be bundled into the OS fairly easily if there is a desire to do so.

Windowing System

Many applications wish to show the same basic user interface elements: windows and buttons and input boxes and pop-ups and file selectors and so on. There’s a lot of code needed to handle this well, and it tends to be bundled up into a single large library called a windowing system.

Because these are just libraries that run on top of a display manager, it possible to have several running at once. Often they are deployed with a main or root windowing system that handles drawing the desktop, task bar, notifications, and so on; but allowing specific applications to use other windowing systems if they wish. For example, MacOS uses Cocoa as it’s main system, but also supports Carbon. I’m typing this in the Geany editor which uses the GTK system regardless of which root windowing system I’m using. The Java programming language comes with two windowing systems of its own (AWT and JavaFX) and spends some effort getting them to run on any OS you might use. And so on.