CS322: Hardware Requirements for Modern Operating Systems

The operating system lies between user programs and the bare machine. It's roles are varied depending on the particular hardware and user programs it is designed to work with.

In this section we want to examine the hardware requirements of the bare machine necessary for a modern multiprogramming operating system.

A term used throughout these notes is kernel. The kernel is the central part of the operating system. In case of monolithic operating systems such as UNIX, the kernel is the same thing as the OS. In other operating systems, the kernel may only be part of code that handles the duties of the operating system.

I. Protection Facilities

If the operating system is to provide any protection mechanism at all then there must be some hardware support for this.

A. CPU Modes

At a minimum, the CPU must have some sort of processor status word that has one or more mode bits. These bits are used to indicate the current mode the processor is executing in. There is usually at least one bit, providing two modes: kernel (or monitor) mode and user mode. VAX systems have two mode bits and four modes: user, supervisor, executive and kernel.

In the simple case of two modes, the kernel runs the CPU in kernel mode, and all other program code runs in user mode. Certain instructions are only permitted in kernel mode.

In most operating systems changes from one mode to another are accomplished several ways:

B. Multiple Stack Pointer Registers

The CPU must have a different stack pointer register for each mode. This prevents the user from loading an invalid address into the stack pointer just before the CPU switches to kernel mode.

C. Memory Protection

The CPU must have some way of protecting different areas of memory from user programs. This includes protecting not only the kernel memory from user programs, but also other user memory as well.

There are several ways that this can be accomplished:

  1. Use one or more registers to bracket the memory that may be accessed at any given time (depends on processor mode and/or which user process is running).

  2. Use a Memory Management Unit, (MMU) to map addresses between user programs and physical memory. (This is required for virtual memory). Different CPU modes can be associated with different mapping tables in the MMU.

D. Privileged Operations

Certain CPU operations must only be executed in kernel mode. For example:

For the reasons listed above, it is imperative that any code running when the CPU is in kernel mode must be trusted. On some systems when any part of the kernel is executing the CPU is in kernel mode. In other, usually more modern, systems many tasks of the kernel operate in user mode, and only the operations that require privileged operations are carried out in kernel mode.

For example, UNIX has a monolithic kernel -- the scheduler, device drivers, file system, etc. all are part of a single kernel and all operate when the CPU is in kernel mode. Other systems have a smaller kernel that runs in kernel mode and have other processes (e.g. processes that control the file system and various device drivers) that run in user mode, with traps back to the kernel for privileged IO instructions.

II. Memory Management Facilities

We will discuss this in some detail later on during the semester.

III. Interrupt Facilities

A. Before Interrupts...

Before computers supported operations like spooling and other designed to reduce the amount of CPU idle time, IO operations were performed by polling, where the computer entered a loop that repeatedly checked the status of the IO device until it entered the desired state. Pseudo-code for this might look like:

	for i := 1 to number_of_units_to_transfer do
	begin
		start transfer of one unit
		while not done with transfer do
			{null}
	end;

B. Interrupt-driven IO

To be able to overlap computation with IO, the devices that performed the IO operations needed a way of signaling the CPU that an operation was ready to proceed or that an operation had completed. In addition, the CPU needed to be able to respond to these signals in such a way that it could be "interrupted" from its computation, perform the next task in the stream of IO events and then return to its computation. The signals sent by the IO device are called interrupts.

At this point we won't discuss the hardware adaptations to the IO devices necessary for interrupts. Once the OS receives an interrupt, it does some housekeeping so that it can pick up its computation once it is through servicing the interrupt. A lookup is then performed in the interrupt vector or interrupt table, a table in kernel-memory space that contains the address of the code in the device driver that is to service the interrupt. The interrupt handler is then executed. When the handler is done control of the CPU is returned to the code that was executing before the interrupt occurred.

            /    -----------
            |    0 |
            |    -----------
            |    1 |
            |    -----------
            |    2 |
  Interrupt |    -----------
   Vector   |    3 |   |---------\        <- CPU looks here for 
            |    -----------     |
            |    4 |             |
            |    -----------     |
            |    5 |             |
            \    -----------     |
                                 |
                                 |
	    /                    |
            |                    |
  Device    |                    |
  Drivers   |    -----------     |
            |    Driver for  <---/
	    |    int 3
	    |
	    |    iret        --------------> CPU returns to pre-int code
	    |    -----------
            |
	    |
	    \

Question: What happens if an interrupt occurs while another interrupt is being serviced? This may or may not be a problem. Systems typically can disable interrupts so that some code can be designated as uninterruptable. Another possibility is to have different priority levels of interrupts so that some interrupts can be ignored but other will be handled properly.

C. Non-IO interrupts

Interrupts are also used for purposes other than IO.

  1. timer interrupts

  2. illegal operation traps

  3. system calls (software generated interrupts)

D. Interrupt Handlers

Each interrupt has an associated handler in the operating system.

  1. Depending on the nature of the interrupt that it handles, a handler may be entered because of

    • an external event (IO, timer, etc.)
    • an illegal instruction in current program (e.g. divide by zero)
    • a software generated interrupt (request for IO, etc.)

  2. When an interrupt occurs, the CPU must save information about the current process. This is usually done by pushing some information on the stack - at least the program counter and the processor status registers.

  3. When the handler is called it will perform some action and then either:

    • return control to the code that was interrupted
    • choose another process to run


$Id: hardware.html,v 1.3 2000/01/07 17:03:35 senning Exp $

These notes are based on a set of notes by Prof. R. Bjork, Gordon College and the textbooks Operating System Concepts by Silberschatz and Galvin, Addison-Wesley, 1998 and Operating Systems: Design and Implementation by Tanenbaum and Woodhull, Prentice-Hall, 1997.