Before we can define an operating system we need to refine our abstract thinking about computers. In particular, a computer is
a collection of devices that can be manipulated by a program to produce a specified calculation.
This definition is pretty broad and requires a supporting definition for the word device. A device, then, isa machine capable of storing and/or transforming information according to a fixed set of rules.
Now we seem to be getting somewhere. We know that computers are made up of machines, that these machines manipulate information according to rules, and that the rules are finite. While we are at it, let's nail down a definition for program which is
a list of instructions to a computer that direct it to perform a desired calculation. and we can stop there with the semantic acrobatics.
Under this admittedly abstract set of definitions, an operating system is
software that implements an abstract machine using the constituent devices within a computer.
At first, it might seem like this definition is too broad or general. In particular, it doesn't explain what an operating system does nor does it seem to differentiate "operating systems" from "non operating systems" very well. However, these are features of the definition rather than bugs.
Herein lies the problem that the authors of the textbook could not solve. The definition of an operating system is, in fact, quite general. There are many operating systems and many software systems that, in fact, act as operating systems regardless of how they are characterized. It is for this reason that the field is important and difficult -- operating systems are general making understanding and building them a challenge.
This definition may also seem a little controversial given all of the attention "the industry" pays to concerns like security which are not explicitly part of the OS definition. The goal of this class is to help connect modern OS concepts like security, performance, extensibility, and portability to the basic notion of an operating system.
The primary reason that operating systems were invented was to manage complexity.
Computers are complicated machines. They are built from less complicated machines, which, in turn, are built from less complicated machines, etc. down to a "bottom" level of complexity (e.g. the transistor or gate level) where physics and physical chemistry take over. That is, there is a basic unit of machine called a "gate" that performs a basic function (like flipping a switch) composed of physical processes and not other machines.
Knowing that computers are ultimately made up of "gates," however, is not quite enough to understand the complexity question. The other piece of the complexity puzzle has to do with a common engineering approach to dealing with complex systems called, colloquially, "divide and conquer."
When faced with the problem of building complicated things, engineers often decompose the complicated functionality into simpler separate functionalities and rules for combining those functionalities. This method of design organizes the architecture as a hierarchy in which components below a certain level are logically separate and the rules at each level define a small number of ways they can interact.
Hierarchical or "modular" design is much older than computer science and is, perhaps, the most successful human technique for understanding and building things in the real world. Thus it should come as little surprise that computers were designed and built this way from the beginning.
Thus computers are composed of layers of abstractions down to some fundamental level beyond which nature provides the concrete. What does this have to do with operating systems?
Software, however, is relatively cheap with respect to its ability to implement abstraction. Computer manufacturers had been aware of this situation for some time, but it wasn't until Edsger Dijkstra began to look at the problem of using software to extend the hardware abstractions that OS became a "true" field of study. Dijkstra proposed rules for defining software hierarchies that were designed to project successively simpler abstractions "upward" at each level with the top level, ultimately, being the "user." There are other methods of design that have been proposed for operating systems over the years (a few of them successful) but today operating systems are largely designed and built (roughly) according to the abstraction-layering architecture originally due to Dijkstra.
Today, we've given up on the prospect of proving an OS correct. Instead, we use the OS to implement an abstract machine that is simpler than the hardware and "secure." Additionally, the notion of "divide and conquer" inherent in an operating system makes it possible for the OS to multiplex the same set of hardware devices among multiple potentially competing usages. In this case, we also expect the operating system to implement "fairness" where this latter term refers to a global priority scheme and not to the notion that each usage gets the same share of the multiplex.
There are three primary functions that a modern operating system performs:
The answer is actually somewhat complicated (which is probably why the book does not boldly stake a claim to a definition of operating system in the first place -- the chickens).
One of the unheralded original contributions that is unique to computer science is that CS uses abstraction to make things easier. Compare this use of abstraction to that of Mathematics in which it is used to make things more general, at the possible expense of potentially considerable effort.
In a computing context, the way that hardware devices work is often driven more by economic concerns than convenience ones. The expert economic opinions fluctuate, but device interfaces are usually designed to be economical and fast rather than easy-to-use. For example, the hardware interface to a disk controller is designed so that the disk controller can be made cheaply, and so that the disk controller will be fast, but not so much so that you will be able to program it easily. Indeed today, disk controller and disk drive manufacturers rely on the notion that there will be an OS "above" their products to make them usable and, thus, they concentrate on making them cheap, reliable, and fast.
For example, the Linux read()/write()/open()/close() interface is an example of these higher-level abstractions. They ultimately culminate in complicated disk operations that are implemented using the disk hardware interface.
Why does this have anything to do with operating systems? The answer is that if you want to implement higher-level abstractions while ensuring fairness and security you need to implement all or part of them in the OS. Thus the operating system plays a role in making programs easier to write.
"Why isn't the operating system implemented as a library?"
This question, at which you might scoff initially, is actually a reasonable one to ask. In fact, some real time systems actually work this way and there have been wacky scientific computing systems that have considered this organization. For the rest of us, however, the hardware must support a user mode and a supervisor mode, primarily to ensure that the operating system (and not a user program) is ultimately in charge of shared resources.
The hardware must support some way for different devices to cause OS code to run on their behalf. Most devices have small on-board processors, but the bulk of the work that they need to have done must be done by the machine itself. For device-specific code to be executed, most machine support one or more interrupt vectors that permit each device to signal that its own driver needs to be executed.
Modern hardware also typically supports some form of memory protection that allows the OS to isolate user programs from each other. Base/Limit registers and virtual memory mapping support are two different ways that the hardware can maintain secure and fair access to memory. We'll discuss this particular issue at much greater length in this class.