Tech Tuesday: Operating Systems (Making It All Work)

I ended last week’s Tech Tuesday on Input/Output saying I might write next about programming in assembly language, but it has since occurred to me that I should cover at least one other high level topic first: operating systems.  That seems more logical since the operating system (OS) is what makes all the parts of a computer system work together.  In fact, I alluded to that last week in the context of the device drivers that are used by the OS to get data to and from peripherals such as a keyboard or a monitor.

Without an OS any computer system is really just a bunch of parts that are fairly useless by themselves.  The OS handles such critical tasks as scheduling which program to run, reading from and writing to files (in storage), communicating over networks, accessing peripherals.  Today most people have at least a couple of different operating systems in their lives because in addition to their personal computer they also have a smart phone – which is really just a portable computer.  You might have a Windows laptop and a Blackberry OS phone.  Or an OS X Macintosh and an iOS iPhone or iPad.  Or a Linux Laptop and an Android phone.  Or some other combination of these or some other OS altogether.  And of course when you are accessing servers you are talking to another set of OSes such as Windows Server or Linux or some UNIX variant.  Along the way some of the networking gear, which are really custom computers, have their own OS, such as Cicso’s IOS (yup just off by a capitalization) or Juniper’s JUNOS.

Now if you look at the list of things that the OS is responsible for at the beginning of the previous paragraph, you may wonder – if the OS is responsible for scheduling which program to run and if the OS deals with reading files, then how in the world does the OS itself get into the computer and start running when I turn the computer on?  That turns out to be an important question.  In the early days there was a simple answer: the OS was stored in so called read only memory (ROM) and when the computer started the program counter of the CPU pointed to the beginning of the code for the OS. ROM is a type of memory that retains its contents even without power but cannot ever be changed (written), hence the name.

But a modern OS is huge and also changing relatively frequently with new versions being released, so storing it all in ROM doesn’t work.  Instead, what happens is that a tiny bit of code is loaded with the sole purpose of then loading more code which then loads the operating system from disk.  That process is known as booting, which is derived from boot strapping which carries with it the wonderful image of pulling oneself over some obstacle by one’s own boot straps (or in the case of the Baron von Muenchhausen pulling oneself out of a swamp by one’s pigtail which in turn reminds me to write a post about Terry Gilliam some day).  That tiny bit of code that gets loaded at the very beginning is known as the boot loader and was referred to in the comments on the previous Tech Tuesday!

If you are still skeptical (as you should be based on the Muenchhausen reference) you might say, but how does the boot loader get data from the disk?  Didn’t you say last week that disk IO is handled by the OS?  Ah, I failed to mention that thing known as the Basic Input Output System (BIOS).  It is a bunch of code that does in fact sit in ROM or these days often Flash memory.  It allows for primitive input output usually with a monitor (just characters, no graphics), a keyboard, a disk, and more recently also the network.  Without that “hard wired” code the whole boot process could not work.

Every modern operating system consists of two fundamentally different parts.  The so-called kernel and everything else.  As the name suggests, the kernel is central and is where all the really hard stuff happens, such as switching between different programs or writing data to an output device.  By everything else I mean programs such as utilities for searching through files (e.g. grep).  I wrote this distinction intentionally somewhat vague, because if you look through the Wikipedia page on Kernels you find that a lot of OS design and development work has gone into figuring out what to put into the Kernel.  No matter where the line is drawn, the programs that end users run on top of the operating system are all allowed to only access memory in what is known as user space or sometimes user land, which is kept separate from kernel space.  Only code executing inside the kernel can access kernel memory.

Kernel programming is some of the most difficult programming there is.  At Harvard there was an amazing class called CS 161 in which students essentially wrote an OS kernel from scratch.  CS 161 even made it into the Social Network.  For anyone truly interested in learning how an OS works nothing compares to going through that process and I would highly recommend getting Andrew Tanenbaum’s Operating Systems: Design and Implementation and start coding away (and/or get a copy of Minix to play with).  In looking for a link to CS 161, I am somewhat dismayed to see that it seems like CS 161 was last taught in 2009. Can this really be true?.  Maybe because it was most horrifically time intensive.

Enhanced by Zemanta
Loading...
highlight
Collect this post to permanently own it.
Continuations logo
Subscribe to Continuations and never miss a post.
#tech tuesday#operating system