As a user, you normally interact with the operating system through a set of commands. For example, the DOS operating system contains commands such as COPY and RENAME for copying files and changing the names of files, respectively.
The commands are accepted and executed by a part of the operating system called the command processor or command line interpreter. Graphical user interfaces allow you to enter commands by pointing and clicking at objects that appear on the screen.
But that really doesn’t address the various ways that operating systems make your computer work easier and more efficiently. Their specific capacities are what make them help your computer operate as a user-friendly device. Let’s look specifically at what an operating system does.
Every program running on a computer whether it is a background service or an application is called a process. As long as von Neumann architecture is used to build a computer, only one process per CPU can be run at one time.
Older computer operating systems such as MS-DOS did not try to bypass this limit with the exception of interrupt processing and only one process could be run under them. Mainframe operating systems have had multi-tasking capabilities since the early 1960’s. Modern operating systems enable concurrent execution of many processes at once via multi-tasking even with one CPU.
Process management is an operating system’s way of dealing with running multiple processes at once. Since most computers contain one processor with one core, multi-tasking is done by simply switching processes quickly. Depending on the operating system, as more processes run, either each time slice will become smaller or there will be a longer delay before each process given a chance to run.
Process management involves computing and distributing CPU time as well as other resources. Most operating systems allow a process to be assigned a priority which affects its allocation of CPU time. Interactive operating systems also employ some level of feedback in which the task with which the user is working receives higher priority.
Interrupt driven processes will normally run at a very high priority. In many systems, there is a background process such as the System Idle Process in Windows which will run when no other process is waiting for the CPU.
It's tempting to think of a process as an application, but that gives an incomplete picture of how processes relate to the operating system and hardware. The application you see (word processor, spreadsheet or game) is, indeed, a process, but that application may cause several other processes to begin, for tasks like communications with other devices or other computers.
There are also numerous processes that run without giving you direct evidence that they ever exist. For example, Windows XP and UNIX can have dozens of background processes running to handle the network, memory management, disk management, virus checking and so on.
A process, then, is software that performs some action and can be controlled -- by a user, by other applications or by the operating system.
It is processes, rather than applications, that the operating system controls and schedules for execution by the CPU. In a single-tasking system, the schedule is straightforward. The operating system allows the application to begin running, suspending the execution only long enough to deal with interrupts and user input.
Interrupts are special signals sent by hardware or software to the CPU. It's as if some part of the computer suddenly raised its hand to ask for the CPU's attention in a lively meeting. Sometimes the operating system will schedule the priority of processes so that interrupts are masked -- that is, the operating system will ignore the interrupts from some sources so that a particular job can be finished as quickly as possible.
There are some interrupts such as those from error conditions or problems with memory that are so important that they can't be ignored. These non-maskable interrupts (NMIs) must be dealt with immediately, regardless of the other tasks at hand.
While interrupts add some complication to the execution of processes in a single-tasking system, the job of the operating system becomes much more complicated in a multi-tasking system. Now, the operating system must arrange the execution of applications so that you believe that there are several things happening at once.
This is complicated because the CPU can only do one thing at a time. In order to give the appearance of lots of things happening at the same time, the operating system has to switch between different processes thousands of times a second. Here's how it happens:
All of the information needed to keep track of a process when switching is kept in a data package called a process control block. The process control block typically contains:
Each process has a status associated with it. Many processes consume no CPU time until they get some sort of input. For example, a process might be waiting on a keystroke from the user. While it is waiting for the keystroke, it uses no CPU time. While it is waiting, it is “suspended”.
When the keystroke arrives, the OS changes its status. When the status of the process changes, from pending to active, for example, or from suspended to running, the information in the process control block must be used like the data in any other program to direct execution of the task-switching portion of the operating system.
This process swapping happens without direct user interference, and each process gets enough CPU cycles to accomplish its task in a reasonable amount of time. Trouble can come, though, if the user tries to have too many processes functioning at the same time. The operating system itself requires some CPU cycles to perform the saving and swapping of all the registers, queues and stacks of the application processes.
If enough processes are started, and if the operating system hasn't been carefully designed, the system can begin to use the vast majority of its available CPU cycles to swap between processes rather than run processes. When this happens, it's called thrashing, and it usually requires some sort of direct user intervention to stop processes and bring order back to the system.
One way that operating-system designers reduce the chance of thrashing is by reducing the need for new processes to perform various tasks. Some operating systems allow for a “process lite” called a thread that can deal with all the CPU-intensive work of a normal process, but generally does not deal with the various types of I/O and does not establish structures requiring the extensive process control block of a regular process. A process may start many threads or other processes, but a thread cannot start a process.
So far, all the scheduling we've discussed has concerned a single CPU. In a system with two or more CPUs, the operating system must divide the workload among the CPUs, trying to balance the demands of the required processes with the available cycles on the different CPUs.
Asymmetric operating systems use one CPU for their own needs and divide application processes among the remaining CPUs. Symmetric operating systems divide themselves among the various CPUs, balancing demand versus CPU availability even when the operating system itself is all that's running.
Even if the operating system is the only software with execution needs, the CPU is not the only resource to be scheduled. Memory management is the next crucial step in making sure that all processes run smoothly.
The way computers are built, the memory is arranged in a hierarchal way. It starts with the fastest registers, the CPU cache, random access memory, and disk storage. An operating system’s memory manager coordinates the use of these various memory types by tracking which one is available, which one should be allocated or de-allocated and how to move data between them.
This function is referred to as virtual memory management and increases the amount of memory available for each process by making the disk storage seem like main memory. There is a speed penalty associated with using disks or other slower storage as memory. If running processes requires significantly more RAM than is available, the system may start “thrashing” or slowing down.
This can happen either because one process requires a large amount of RAM or because two or more processes compete for a larger amount of memory than is available. This then leads to constant transfer of each process’s data to slower storage.
Another important part of memory management is managing virtual addresses. If multiple processes are in the memory at the same time, they must be stopped from interfering with each other’s memory unless there is an explicit request to utilize shared memory. This is achieved by having separate address spaces.
Each process sees the whole virtual address space, typically from address 0 up to the maximum size of virtual memory as uniquely assigned to it. The operating system maintains a page tables that matches virtual addresses to physical addresses. These memory allocations are tracked so that when a process ends, all memory used by that process can be made available for other processes.
The operating system can also write inactive memory pages to secondary storage. This process is called “paging” or “swapping”. The terminology varies between operating system.
It is also typical for operating systems to employ otherwise unused physical memory as a page cache. The page cache contains requests data from a slower device and can be retained in memory to improve performance. The OS can also pre-load the in-memory cache with data that may be requested by the user in the near future.
The first task of memory management requires the operating system to set up memory boundaries for types of software and for individual applications.
As an example, let's look at an imaginary small system with 1 megabyte (1,000 kilobytes) of RAM. During the boot process, the operating system of our imaginary computer is designed to go to the top of available memory and then "back up" far enough to meet the needs of the operating system itself.
Let's say that the operating system needs 300 kilobytes to run. Now, the operating system goes to the bottom of the pool of RAM and starts building up with the various driver software required to control the hardware subsystems of the computer. In our imaginary computer, the drivers take up 200 kilobytes. So after getting the operating system completely loaded, there are 500 kilobytes remaining for application processes.
When applications begin to be loaded into memory, they are loaded in block sizes determined by the operating system. If the block size is 2 kilobytes, then every process that is loaded will be given a chunk of memory that is a multiple of 2 kilobytes in size. Applications will be loaded in these fixed block sizes, with the blocks starting and ending on boundaries established by words of 4 or 8 bytes.
These blocks and boundaries help to ensure that applications won't be loaded on top of one another's space by a poorly calculated bit or two. With that ensured, the larger question is what to do when the 500-kilobyte application space is filled.
In most computers, it's possible to add memory beyond the original capacity. For example, you might expand RAM from 1 to 2 megabytes. This works fine, but tends to be relatively expensive. It also ignores a fundamental fact of computing -- most of the information that an application stores in memory is not being used at any given moment.
A processor can only access memory one location at a time, so the vast majority of RAM is unused at any moment. Since disk space is cheap compared to RAM, then moving information in RAM to hard disk can greatly expand RAM space at no cost. This technique is called virtual memory management.
Disk storage is only one of the memory types that must be managed by the operating system, and is the slowest. Ranked in order of speed, the types of memory in a computer system are:
The operating system must balance the needs of the various processes with the availability of the different types of memory, moving data in blocks (called pages) between available memory as the schedule of processes dictates.
All operating systems include support for a variety of file systems. Modern file systems are made up of directories. While the idea is similar in concept across all general purpose file systems, some differences in implementation exist.
Two examples of this are the character that is used to separate directories and case sensitivity. By default, Microsoft Windows separates its path components with a backslash and its file names are not case sensitive.
However, UNIX and Linux derived operating systems along with Mac OS use the forward slash and their file names are generally case sensitive. Some versions of Mac OS (those prior to OS X) use a color for a path separator.
File systems are either journaled or non-journaled. A journaled file system is a safer alternative in the event of a system crash. If a system comes to an abrupt stop in a crash scenario, the non-journaled system will need to be examined by the system check utilities. On the other hand, a journaled file systems recovery is automatic.
The file systems vary between operating systems, but common to all these is support for file systems typically found on removable media like CDs, DVDs, and floppy disks. They also provide for the rewriting of CDs and DVDs as storage mediums.
Another aspect of an operating system has to do with the networking capabilities contained in each. The network links separate computers together from different locations.
Most current operating systems are capable of using the TCP/IP networking protocols. That means that one system can appear on a network of the other and share resources such as files, printers, and scanners using either wired or wireless connections.
Security is important in any computer system. The operating system provides a level of security that can protect your computer and the data on it. System security is based on two principles:
Requesters of information are further divided into two categories:
In addition to the allow/disallow model of security, a system with a high level of security will also offer auditing options. These would allow tracking of requests for access to resources as in “who has been reading this file?”
Operating system security has long been a concern of programmers because of highly sensitive data held on some computers. This is both of a commercial and a military nature.
The US Government Department of Defense created their own criteria of standards that sets basic requirement for assessing the effectiveness of OS security. This became of vital importance to operating system makers because this system was used to classify and select system being considered for the processing, storage ad retrieval of sensitive or classified information.
Internal security can be thought of as a way to protect the computer’s resources from the programs concurrently running on the system. Most operating systems set programs running natively on the computer’s processor. That brings on the problem of how to stop these programs from doing the same task and having the same privileges as the operating system which is just a program too.
Processors used for general purpose operating systems are automatically blocked from using certain hardware instructions such as those to read or write from external devices like disks. Instead, they have to ask the privileged program, or operating system kernel) to read to write. The operating system, therefore, gets the chance to check the program’s identity and allow or refused the request.
An alternative strategy available in systems that don’t meet pre-set requirements is the operating will not run user programs as native code. Instead, they either emulate a processor or provide a host for a “p-Code” based system such as Java.
Internal security is especially important with multi-user systems as it allows each user of the system to have private files that the other users cannot tamper with or read. Internal security is also vital if auditing is to be of any use since a program can potentially bypass the operating system without bypass auditing.
Typically, an operating system offers various services to other network computers and users. These services are usually provided through ports or numbered access points beyond the operating systems network address. These services include offerings such as file sharing, print services, e-mail, web sites, and file transfer protocols (FTP).
At the front line of security are hardware devices known as firewalls. At the operating system level, there are a number of software firewalls available. Most modern operating systems include a software firewall which is enabled by default.
A software firewall can be configured to allow or deny network traffic to or from a service or application running on the operating system. Therefore, one can install and be running an insecure service such as Telnet or FTP and not have to be threatened by a security breach because the firewall would deny all traffic trying to connect to the service on that port.
Today, most modern operating systems contain Graphical User Interfaces (GUIs). A few of the older ones tightly integrated the GUI to the kernel - one of the central components of the operating system. More modern operating systems are modular separating the graphics subsystem from the kernel.
A GUI is basically the pictures you see on the screen that help you navigate your computer. They include the icons and the menus. Many operating systems allow the user to install or create any user interface they desire.
Graphical user interfaces tend to change and evolve over time. For example, Windows has modified its user interface almost every time a new version of Windows is released. The Mac OS GUI changed dramatically with the introduction of Mac OS X in 2001.
A device driver is a specific type of computer software developed to allow interaction with hardware devices. Typically, this constitutes an interface for communicating with the device through the specific computer bus or communications subsystem that the hardware is connected to.
Device drivers provide commands to and/or receiving data from the device and on the other end, the requisite interfaces to the operating system and software applications.
You cannot have a CD-ROM drive, for example, without a device driver for that specific piece of equipment. You have drivers for a printer, scanner, and even your mouse.
It is a specialized hardware-dependent program which is also operating system specific that enables another program - typically an operating system or applications software package or computer program running under the operating system kernel.
This allows the system to interact transparently with the hardware device and usually provides the requisite interrupt handling necessary for any time-dependent hardware interfacing needs.
The key design goal of device drivers is abstraction. Every model of hardware is different. Newer models also are released by manufacturers that provide more reliable or better performance and these newer models are often controlled differently.
Computers and their operating systems cannot be expected to know how to control every device both now and in the future. To solve this problem, operating systems essentially dictate how every type of device should be controlled. The function of the device driver is then to translate these OS mandated function calls into device specific calls.
In theory, a new device which is controlled in a new manner should function correctly is a suitable driver is available. This new driver will insure that the device appears to operate as usual from the operating system’s point of view for any person.
Some operating systems come with pre-installed drivers or a variety of common drivers to choose from. When you buy a new piece of hardware such as a joy stick, they will often come with a disk that contains the device driver that you can install. Other drivers or updated drivers are available online at the manufacturer’s website.
Just as drivers provide a way for applications to make use of hardware subsystems without having to know every detail of the hardware's operation, application program interfaces (APIs) let application programmers use functions of the computer and operating system without having to directly keep track of all the details in the CPU's operation. Let's look at the example of creating a hard disk file for holding data to see why this can be important.
A programmer writing an application to record data from a scientific instrument might want to allow the scientist to specify the name of the file created. The operating system might provide an API function named MakeFile for creating files. When writing the program, the programmer would insert a line that looks like this:
MakeFile [1, %Name, 2]
In this example, the instruction tells the operating system to create a file that will allow random access to its data (signified by the 1 -- the other option might be 0 for a serial file), will have a name typed in by the user (%Name) and will be a size that varies depending on how much data is stored in the file (signified by the 2 -- other options might be zero for a fixed size, and 1 for a file that grows as data is added but does not shrink when data is removed). Now, let's look at what the operating system does to turn the instruction into action.
The operating system sends a query to the disk drive to get the location of the first available free storage location.
With that information, the operating system creates an entry in the file system showing the beginning and ending locations of the file, the name of the file, the file type, whether the file has been archived, which users have permission to look at or modify the file, and the date and time of the file's creation.
The operating system writes information at the beginning of the file that identifies the file, sets up the type of access possible and includes other information that ties the file to the application. In all of this information, the queries to the disk drive and addresses of the beginning and ending point of the file are in formats heavily dependent on the manufacturer and model of the disk drive.
Because the programmer has written the program to use the API for disk storage, the programmer doesn't have to keep up with the instruction codes, data types and response codes for every possible hard disk and tape drive. The operating system - connected to drivers for the various hardware subsystems - deals with the changing details of the hardware -- the programmer must simply write code for the API and trust the operating system to do the rest.
APIs have become one of the most hotly contested areas of the computer industry in recent years. Companies realize that programmers using their API will ultimately translate this into the ability to control and profit from a particular part of the industry. This is one of the reasons that so many companies have been willing to provide applications like readers or viewers to the public at no charge.
They know consumers will request that programs take advantage of the free readers, and application companies will be ready to pay royalties to allow their software to provide the functions requested by the consumers.
As we’ve stated before, there are operating systems in all sorts of products - not just computers. Cell phones, DVD recorders, and TiVo players also have operating systems, however, those OSs are not readily noticeable to the consumer and they do not have any control over them.
This might be a good time to review some of the computer operating systems that are on the market today.