The primary goal of an operating system is to allow a programmer to make use of the hardware in a fast and secure manner. However, it took many iterations to get to this definition. Brinch Hansens describes seven phases of the operating system which helped us get to where we are today.
I Open Shop
II Batch Processing
IV Time Sharing
V Concurrent Programming
VI Personal Computing
VII Distributed Systems
The first operating system was almost like a computer at a modern day library. Nobody owns it, and if you wanted to use it, you may need to book some time out with a librarian. You may have an hour to use the computer, but you’ll spend at least 10 - 15 minutes getting set up: downloading applications you need, loading files, logging in to websites. It may not seem like much but the overhead definitely adds up. Operating systems in the 1950s were very similar, you would have to book some time out with a human operator and they would schedule a slot for you to run your job. It would take you a while to set up your program, but once you had, you were free to run it for the remainder of your slot.
The next phase of operating systems came with the realization that a human wasn’t needed to schedule these jobs, it could be done with software! Users would load their program onto a tape and the computer would have to process the jobs on a first come first serve basis because it was efficient to go forward with tape but extremely slow to go backwards. Even if you have a 10 minute job scheduled to run, if it is behind another user’s 5 hour job, you will have to wait 5 hours for your job to begin running.
As computer hardware support began to improve, the idea of a hardware interrupt came about. This enabled multiprogramming - allowing an operating system to execute multiple programs at once. Additionally, memory hardware began to support random-access which enabled new scheduling policies outside of first-come first-serve. Atlas was the first operating system in this era and it introduced demand-paging (paging memory in and out of RAM to disk) and supervisor calls (the early version of system calls) both of which are still used today. Scientists began to see problems like starvation with certain process scheduling policies which gave birth to the next phase of operating system innovation.
Timesharing meant what it sounds like - users would be able to share time on a computer simultaneously. To each user, it would seem like they had the whole computer to itself. John McCarthy had pioneered this idea and helped build a small example of it. Multics, although not used much outside of MIT, had built a larger scale version of this timesharing idea and also implemented the first hierarchical file system. This would allow for private files and folders which catalyzed the idea of timesharing and multi-user systems. Then finally came Unix which is still the basis of many operating systems used today.
Concurrency became a big problem as more and more people were using multiprogrammed operating systems. Multiprogramming also made it much more difficult for people to reason about programs without significant thought. To make operating system concepts easier to grasp, scientists began developing abstractions for how things worked and the idea of semaphores. Both things helped reduce the amount of crashes in an operating system and enabled more scientists and engineers to contribute to improving and building an operating system.
The increase in availability for engineers to contribute to operating systems and the reduction in crashes vastly improved the usability of computers. This coupled with reductions in hardware costs made it much more feasible for consumers to own computers. GUIs began to gain more popularity and single-user operating systems gained more investment specifically from a company called Xerox. Xerox had built Xerox Star which was an operating system designed to mimic things found in an office: files, trash, calculators, etc… Xerox Star would soon inspire the birth of Macintosh.
Distributed systems gave users the ability to turn 5 computers into one interface. Instead of the inter-process communication mechanisms used in prior operating systems, they could use remote procedure calls which would communicate to other machines over a local area network. However, this was non-trivial to implement since remote procedure calls, specifically transferring data over network, were more often subject to hardware failures. This meant that remote procedure calls to a different machine could fail and there had to be mechanisms to account for that. RPCs made it possible for users to access data from their local machine that didn’t necessarily exist on their local machine.
There you have it, that’s an introduction to the history of operating systems. I think it is important to understand this before diving into modern day operating systems since it gives some context behind why certain design decisions were made. If you have any questions, don’t hesitate to reach me at firstname.lastname@example.org or DM me on Twitter @asystemshacker.