First Operating System -- Part Two

Posted 30 Dec 2023

From simple automation to monitoring machine resources, the incubation of the operating system.


A Quick Recap

In the early days, mounting tapes, inserting decks of punched cards, and gathering printouts was done by the people who had designed and built the machines. They’d also train others, who became the machine’s operators. This left the engineers free to devise the calculations needed for the desired results. Because no one really wanted to spend 15 minutes setting up gear so they could get 5 minutes of actual computing done.

In the commercial world, you also had human machine operators. You’d take your payroll program down to the computer room, and hand it over to the operators. These are the people who had to do all the donkey work. Mount the tapes, configure the connections, load up the punch card deck (often several 2-foot trays of punched cards), and fire off the job. If there was an error, they had to determine if it was a machine error (e.g., tape wasn’t loaded correctly), or a logic error (your program had a bug), then gather up all your submitted materials, and all the error output, and get it back to you.

Good system adiminstrators are lazy. Anything that’s dull and repetitive is a good candidate for automation. And that was true for those early computer operators as well. I haven’t found any documentation of machine-room operations, which would describe this sort of donkey work in detail. But there are some recollections that have been written down, such as the quote from part one. At this point, I’m speculating a bit, but the features of the first forays into automating these machine room operations tell us the “what”, if not the “why”.


Card Readers vs. Tape Drives

One problem faced by the designers of ENIAC (and EDSAC) was that these new vacuum tube machines were much, much faster than their relay-based predecessors. One way they gained more speed was to use punched cards in many tasks. So, punched cards became a standard feature of succeeding computers.

But magnetic tape was even faster, and could store information much more densely, so these started to be used. Then, as now, computer engineers were on a hunt for ever more speed.

As mentioned in the recap (and the end of the previous installment), computers were still used for one program (or calculation, really) at a time. As computers became more widely used, there was a need for specialists who would actually touch the machine, excluding the engineers seeking answers from it. And they spent their days doing boring repetitive tasks, as mentioned in the recap.

Computer rooms started to change. While the computer itself was still expensive (and had to run 24/7), operators could get more done in less time by connecting more devices (we’d call them “peripherals” today), often redundant. You’d have multiple tape drives, each having some program or data of interest on it, like the COBOL compiler or the payroll database. Much cheaper (especially in labor) to buy more tape drives. These would all be connected to the computer at once, and programs would load from them as needed. Remember, there was no operating system, so each program would have to know where each tape drive was connected, and the exact instructions needed to read or write on it.

Similarly, they added more punched card writers, and sometimes an actual printer, since those were the only ways to get your results back off the machine.


Spooling

Someone had an idea – build a machine that can take data from the computer and hold on to it long enough for the (slow) output devices to get it onto paper or cards or mag tape. We’d call this “buffering”. They called it “spooling”. (Much later, someone invented a backronym for it which was descriptive “Simultaneous Peripheral Operation On-Line. But the term came first. Likely from the way mag tapes work.)

One of the ways this was made to work well was to restrict the computer’s input and output devices to magnetic tape. They were the fastest devices, and kept the machine producing results instead of waiting for something to read in or write out. This was called “tape-to-tape” processing.

So now you’d take your punched cards, and use a separate machine to read the cards and write the data out to tape. So this could be done without the computer being involved at all. When your program was done, the operator would take the output tape over to another machine, which basically reversed that process.


Programs Become Jobs

It became obvious that a lazier way to run the machine room was to take in all the programs submitted, and put them all on the same tape. This way, when one program ended, the next one could be read in, while the operator was reading a magazine. In practice, there was a need to separate the programs, so the computer didn’t load them all in at once. So “job cards” were invented. Each deck of punched cards would start with some standard cards, and mark the end of the program with more standard cards.

The end result is that the operator would create a tape from all these jobs, then mount that on the computer, and tell it to start reading from the tape. (Exactly how, I don’t know. Remember, there was no operating system or boot-loader yet.) The machine would read instructions from the standard cards, read the user’s cards up to the end-program card, and then execute what was now in memory.

This was an advance, but with some new tasks that operators had to automate as well. As mentioned before, computer time was expensive, so each minute had to be accounted for and charged to a specific person or department. With the old manual system, all that information would be specified when the program was handed in. But now that cards were spooled onto tapes, that information would be entered on some of the “job cards”, and at the end of the program, the run time and account number would be recorded.

Similar systems were used for data; taking it off punched cards, moving it to tape, marking each block of data at the start and end, and putting all of that onto another tape that was mounted.

All of this took cooperation. Programs had to know which tapes were mounted on what devices. Each program had to know how to command the tapes for reading and writing. If the operators changed where a particular tape was mounted, your program had to change. FORTRAN had the concept of a “Logical Unit Number” (LUN), but those had to be set up at the start of the program. So you only had to change the LUN cards, but not the rest of the program.


The Big Idea

So now we have a computer room with multiple devices connected to the machine. We have “satellite” machines to handle the X-to-tape and tape-to-X conversions without using that expensive computer time for it. And we’ve created an all-tape system to keep the machine running as fast as it can.

We also have a problem: all the programmers have to keep track of where things are, and all programs have to know how to run all the hardware. It would be like having to include the device driver code in-line in all your programs. Every time you write a character to disk, you’d have to include all the code to spin up the disk, position the head, load the data into the register, then execute the write sequence, which must be precisely timed. This system was better (faster, cheaper) than the manual way, but it could be improved.

As usual, with a bit of experience developing and using these techniques, operators started thinking about the rough edges and how to smooth them down. And multiple different approaches were tried in different places, with different machines and cultures.

All of them had the Big Idea: give the machine a standard set of operations which controlled all this reading and writing, without having to put that code in every program.

It didn’t look like an operating system, but this was the kernel (forgive the pun) from which they grew.


MIT’s Director Tapes

In 1951, MIT was contracted to build a computer for the U.S. Navy. The intent was to have it drive a set of aircraft instruments, to be used to train aviators. They wanted it to have a realistic aerodynamics model, so the simulation was higher fidelity than previous systems. This was called the Whirlwind I

This machine had some new ideas (real-time output being just one), but at some point, they introduced the idea of “Director” tapes:

A procedure has been developed to eliminate most of the need for manual intervention in “reading in” the tapes for different problems during a computing period. The procedure makes use of a specially prepared “director” tape which communicates with the computer through a separate input reader. The various problem tapes, together with suitable post-mortem- request tapes, are spliced together in the proper sequence. The complete run is then effected under the control of the director tape by a single push on the read-in button. 1

Note that the “tapes” being referred to here were not magnetic tapes, but paper tapes. These were strips of paper with an index hole down the center (engaged by a sprocket on the reader), and used a 5-bit encoding from side to side. These were first “read” using metal pins that would ride on the paper, and wherever a hole was punched, they’d complete a contact to input one 5-bit character per sprocket advance. This was essentially the same system Herman Hollerith came up with when he invented the punched card. Later, an optical version of this was built, which was faster and didn’t have the maintenance requirements of the electrical version.

To historians, these director tapes are the first step along the path to an Operating System.


IBM 701/704

The General Motors Research group purchased an IBM 701 and had it installed in April of 1954. This was used for design calculations for various engines. It had all the drawbacks mentioned previously, with a 15-minute time-slot actually only allowing about 5 minutes of actual computing time.

A group of 701 users, who met through the IBM users group “SHARE”, had ideas about how to streamline this system. They exchanged those ideas, and agreed to work together to build a “monitor” which would occupy the bottom of memory, and coordinate the actions needed to load and run user programs. One group was from General Motors, and the other from North American Aviation.

(Note that “monitor” has nothing to do with a video output device. And I’m not sure when that name was applied to these nascent programs; much of this history was never written down, or written down much later. These sorts of programs were also known as “supervisors”. I’m not convinced that these programs “monitored” anything, since they only ran between user programs, and had to be explicitly loaded by those programs.)

The target machine was the IBM 704 (an incremental improvement over the 701). When the machine was started, it would load this monitor from a dedicated tape drive. Once running, it would read the jobs in, prepare them for execution (usually assembler code that had to be translated to the binary version), link them to the standard library routines needed (each “chunk” of the job – the main program and each library routine – would be stored in memory and the start of each chunk poked into the main program), and then start the program. At the end of the program, the monitor would be called (by reading from the start of that dedicated tape drive, reloading the monitor), and it would execute the clean-up steps, writing out the accounting info, etc. Then it would read the next job from the input tape and repeat the process.

There were some trade-offs here, but the users were getting more done in less time, so everyone was happy. One of the trade-offs was to configure the machine in a way that was made the “standard”. If a programmer wanted a non-standard configuration, they were told to come in in the wee hours of the night, and run the machine via the manual method previously described. This was an incentive for programmers to use the standard configuration.

Another trade-off was that programmers had to avoid touching certain parts of memory, because that’s where the monitor stored its data. If they didn’t, or their program went awry, the monitor would be damaged and the machine would crash. Not to mention, the programmer had nothing to show for this, but was still charged for the time spent. This was a reason for programmers to spend more time at their desk, checking their code, before wasting computer time worth more than their daily pay.

It’s worth noting that crashes were not an unusual part of the computer operator’s day in the mid-1950’s. Various sources list the “mean time before failing” as 3.5 hours, 8 hours, or 30 minutes. Imagine your desktop computer crashing 3 times a day. (Us old guys don’t have to imagine – Microsoft Windows had the same problem…)

This is generally considered the first real operating system.

A more detailed explanation of this system, by one of the people who built it, is here.


More Monitors

Note that the GM-NAA system was more about standardizing the machine room configuration and programming rules. The key idea is that one of the programs is “special” because it automates all the tape handling and program running, then gets reloaded at the end of each job. But in no sense was it always in memory, like modern operating systems are. It had some data in the first 300 words of memory, but any program could overwrite that data, causing the monitor to malfunction.

As this system (and similar efforts by others) gained acceptance, it was clear there were some improvements that could be made. This is a recurring theme on this blog; most “inventions” are really just incremental improvements to the existing way of doing things. It’s only when enoug improvements are made – over time, by different groups of people – that you see something which is unlike the past.

As computer hardware got more capable, and memory became cheaper, it was possible to skip the “system tape” and load the monitor into memory so it was always running. This was still a cooperative system, handing off to the user program and expecting them to call back in to them when finished.

(Note that “subroutine” had a very different meaning in the mid-50’s. None of those computers had a “return” instruction, or even a “call subroutine” instruction. This is a topic I will return to, as the question of which computer was the first to have this feature is why I started researching this topic.)

Once the monitor was resident, it could provide more features for programs. One neat idea was to put all the code for reading and writing to devices into the monitor. This allowed the programmers to not think about those details. And a nice side-effect was that this encourage programmers to use the monitor routines instead of having to deal with loading them in from tape, or declaring them in the job cards and waiting for the loader to get everything set up and the jump addresses modified.

As more progress was made, it became obvious that the monitor needed protection. By the early 1960’s, computer hardware included the means to protect regions of memory. And these monitors would use those features to ensure its own area remained unchanged.

Newer and faster computers pushed peripheral makers to add buffering to their devices. That enabled the computer to set up an I/O task, transfer the data (to the buffer), then start the task. The computer was then free to go about its other work, and would either check in with the peripheral periodically (“poll” it), or wait for a hardware signal from it, to know when that I/O task was complete. Then, in the interests of more speed, designers and builders started working on “overlapped I/O”, so the computer could juggle many such devices at once.

As computers switched from vacuum tubes to transistors, and long-term storage evolved away from mercury delay lines, and tapes became spinning disks, the monitor changed to take advantage of these improvements.

Interestingly, when computers were still reading from tape and writing to tape, the monitor started naming these tapes. The input tape (with all the jobs on it) was “SYSIN”, and the output tape was “SYSOUT”. The monitor itself, living on a dedicated tape drive, was “SYSRES”. And I’ve seen references to these as “files”. There’s probably another whole research project on how the idea of “files” predates disk drives, and that the earliest forms of the “file system” involved tapes with an “index” or “catalog” at the beginning, allowing easy access to everything on the tape, without having to read (and process) everything from beginning to end.


Wrapping Up

The story of improvements, from relay calculators to digital computers to smartphones is never-ending. I think I’ve gone as far down the Operating System invention history as I wanted to. The GM-NAA system was the first operating system. Or, at least, the first one to gain wide attention and adoption. I suspect both of those are partly due to the pre-eminence of IBM: anything running on the 704 was going to get talked about. Others would take those ideas and apply them to other machines. And computer designers would start adding features (like memory protection) to make operating systems more efficient, and allow new ways of using the machine. How far is it from memory protection to memory partitioning to multi-programming?

I found a really great paper which covers developments in operating systems in more detail, and extends further into the late 60’s, rather than just the early 60’s as I have done here. In almost every book and paper on the history of the computer, I find references to this paper. You can find it here. If these two posts have whetted your appetite for the history of the OS, that paper should be your first stop.

This is, I hope, just the first step in my search for the machine which would be the granddaddy of the modern computer. I’m looking for a specific set of features, without which we wouldn’t recognize it as a computer. I’m not quite sure what that list of features is, but that just makes this an adventure. Figuring it out as I learn more and more.


Footnotes: