Operating Systems: Features and Functions
Essential to modern computers are operating systems (OS). While the choice of an operating system may or may not say much about an individual, it does say a great deal about how their computer is going to operate. This is because an operating system controls the basic functions of a computer, such as program execution, memory management, disk access, and running of and interaction between various devices (printers, disk drives, scanners, digital cameras, modems, video cards, sound cards, etc.). An operating system serves as some kind of "buffer" between application software and the hardware of the computer that they are running on.
However, the question of 'What an operating system is?' is complicated by many different visions of what an operating system should be. This is so mainly because the various operating systems and architectures that are available today take different approaches in answering the question. Today, operating systems range from small real-time kernels, mostly installed on embedded devices, to protected-mode multi-user systems. Some operating systems are minimalist, covering only the most basic functions, whereas others are highly intricate and even dictate the user interface. Here I attempt to give a generic definition of what an operating system is.
An operating system is a collection of software that provides services for computer programs. In other terms, an operating system is a composition of a kernel and utility programs; the kernel controls the allocation of hardware resources while the utility programs enhance the usefulness of the computer. One simply cannot grasp what an operating system really is without having some fundamental understanding of what a kernel is. So in the following section, the kernel (which is the heart of an operating system) will be discussed, after which the features and functions of operating systems will also be analyzed—the primary objective of this writing.
The operating system kernel
An operating system kernel is a computer program that serves as an intermediary layer between the hardware and application programs. A kernel makes it possible for software to interact with the underlying hardware of the operating system. Such software (mostly application software) achieve this by issuing service requests to the kernel. (These requests are called system calls.) When a service request is received, the kernel translates it into instructions for the CPU or other electronic components of the computer to execute.
The way operating system kernels handle requests, however, differ from one another. Consider the following analogy: an application program wants to have a cup of coffee so it makes a request to the kernel. What should the kernel do at this point? Should it delegate the coffee making activity to somebody else (microkernels) or should it make it by itself (monolithic kernels)? Delegating the activity can be advantageous, in that, the kernel would then have less things to worry about. However, that comes at the cost of performance: finding who to delegate, calling the person, etc. But how about a mixed approach? Say, let the kernel do some core stuff by itself and delegate other things to other people (hybrid kernels).
In a microkernel operating system design, the kernel itself does not contain any functions—all tasks are delegated to separate programs called servers. These servers provide services for the operating system, leaving the kernel to contain only what it needs to operate: a mechanism of mapping requests to servers and executing them. This greatly reduces the size of the kernel, and also increases its stability since any fault in any of the servers does not really affect the kernel itself. Nevertheless, the critical overall performance of microkernels are lower than that of their monolithic counterparts because of their (mostly) large number of request-to-server mappings. Popular examples of microkernel operating systems are GNU Hurd, MINIX, and QNX.
A monolithic kernel is a system program that contains all the code required to perform every kernel related task. It contains all the core operating system functions and device drivers. Since all the various functions live in the same memory area, it is possible for one function to modify the behavior of another function. Worse yet, data corruption resulting from the operation of one function can cause the whole system to crash. However, with these negative side effects come some great gains: the dynamic module loading ability of some monolithic kernels minimizes the operating system's memory footprint while running faster than microkernels in most practical cases. Examples of monolithic operating systems are DOS, BSD, Linux, and OpenVMS.
The architecture of hybrid kernels is similar to that of microkernels, except not every request is delegated to a server, but some code are loaded into kernel space as in monolithic kernels. The performance overhead incurred by microkernels when running some services (such as the filesystem) in user space is eliminated by moving the code for such services into kernel space. This technique allows the kernel to enjoy the best of both worlds: modularity and performance. However, there is a compromise: unlike monolithic kernels, hybrid kernels cannot dynamically load additional modules to extend the capabilities of the kernel. Examples of hybrid kernel operating systems are Microsoft Windows, Mac OS X, and the discontinued BeOS.
Features of an operating system
When talking about features of an operating system, often they get mixed up with its functions. I define an operating system's feature as a prominent attribute of the operating system; in other words, its major components. In fact, features that operating systems offer vary greatly from each other that it is difficult to tell which ones qualify to be listed and which ones don't. In this section, I will discuss only those that are widely known and accepted. It is noteworthy that, regarding monolithic operating systems, the features mentioned below may appear to be that of the kernel but not the operating system itself. True; but that argument becomes completely false when one looks at the subject from the angle of a microkernel operating system.
On modern microprocessors, there are at least two modes of operation: kernel mode and user mode. If an application running in user mode tries to perform a privileged operation (such as directly accessing the hardware), the CPU will most likely throw an exception. So, then, how does an application read input from the keyboard or write to the screen? It does so by sending a request to the kernel. Of course, this slows down the operation, but ensures that application programs do not execute code that could damage or compromise the system. These requests that application programs send to the kernel are called system calls. A system call can thus be simply defined as a request by a computer program to the operating system's kernel.
When a system call is invoked, control is transferred to the kernel which, in turn, determines whether the calling application should be granted the requested service. If granted, the kernel executes the necessary instructions, causes a switch into user mode, and returns control back to the calling program. Most operating systems however provide an intermediary interface that sits between applications and the system calls layer, in a form of a library or an Application Programming Interface (API). Such an intermediary interface makes it possible for programs written in high level languages to invoke system calls. Moreover, it is easier and more portable to use a library or an API than to code the system call in assembly language instructions.
A computer system is usually made up of several devices such as disk drives, keyboards, mice, video adapters, sound cards, etc. When a user attaches such devices to their computer, they expect the operating system to identify the device and make use of it. Indeed, the operating system may know what the device is but not how to communicate with it. The latter problem is solved by means of a driver. A device driver is a computer program that controls a particular device attached to a computer. It provides an interface through which the operating system can transparently make calls to the device. In fact, device drivers have built-in functions that are meant to be called by the operating system or other privileged programs.
Devices are generally slower compared with the CPU. This means that whereas the CPU could be doing other stuff, it many times waits for a busy but slow device to finish whatever job it is doing. This bad behavior, however, is mitigated by the use of hardware interrupts. Interrupts cause control to be transferred to a routine designed to process the interrupt. For example, when a key is pressed on a computer keyboard, a hardware interrupt is generated, which invokes the keyboard device driver. After the driver has finished processing the event, control is returned back to the interrupted program. However, only a few peripherals support interrupts which means that drivers have to poll the hardware, i.e. ask whether there is an event to process.
Every computer file is stored in a linear space on a storage device of finite capacity. Each file has its address on storage, which is determined by the number of byte offsets from the beginning of the storage medium. But then, there is the need for a structure that tells where one piece of data begins and a where it ends—a file system. File systems keep track of unused space on the disk as well as additional information about each file such as the name, size, owner, creation date, access control, encryption, etc. What is more, file systems manage the directory structure and the mapping of file names to file control blocks. A file system can thus be defined as a structured data representation and a set of metadata that describe stored data.
A storage medium is made up of several cells which are 1 byte in size. These cells are grouped together into sectors of fixed length (e.g. 1024 bytes) which is the minimum addressable unit of the physical storage. A group of sectors make a block, which, in turn, when grouped make up a partition. Each byte is addressed by using a pair of sector and in-sector offset. For example, byte 3000 on a file system of sectors of size 1024 bytes will be referenced at sector 3 offset 952, i.e. [sector]+[sector]+[952 bytes], noting that each sector is of size 1024 bytes. Despite this scheme, on many file systems, the in-sector offset is ignored, causing files to occupy whole sectors. So a file of size of say, 1 byte, will occupy 1024 bytes of storage, for example.
Here is another feature of an operating system: its user interface. An operating system's user interface determines how the user interacts with the computer. The two most common forms of a user interface are the Command Line Interface (CLI) and the Graphical User Interface (GUI). A CLI provide a prompt at which commands can be given line-by-line. This kind of interface is usually implemented with a program called a command line shell, which accepts commands as text input and converts them to the appropriate operating system functions. CLIs can be quite powerful for experienced users, but if one does not know the system well enough, they can become quite lost. Examples of CLIs are the UNIX shells and the Windows Command Prompt.
In contrast, a GUI provides a visual environment where a device (such as a mouse) is used to navigate the system and perform tasks. Unlike CLIs where performing a task can become slow and error-prone (such as when very long commands are to be entered), GUIs present the user with widgets that trigger some of the operating system's commands, reducing complexity and the need to memorize command names and their parameters. For many users, a GUI present a more accessible user interface; however, the choice of a user interface is simply a matter of personal preference. Examples of GUIs are those implemented in Microsoft Windows, Apple's Mac OS X, and GNOME/KDE for the X Windows system on Unix-like operating systems.
Functions of an operating system
This section is currently being rewritten. In the meantime, here are the functions that will be discussed when the work is completed. (You may want to focus your current research activities on these areas.)
- Process management
- Code execution
- Context switching
- Memory management
- Virtual memory
- Device management
- Disk access
- Interrupt handling