Operating Systems

================ Start of Lectures #11 and #12 ================

Lecture 11 was given by Prof. Ernie davis. It covered material from the next chapter.

================ Start Lecture #12 ================

4.8: Segmentation

Up to now, the virtual address space has been contiguous.

Homework: 37.

** Two Segments

Late PDP-10s and TOPS-10

** Three Segments

Traditional (early) Unix shown at right.

** Four Segments

Just kidding.

** General (not necessarily demand) Segmentation

** Demand Segmentation

Same idea as demand paging, but applied to segments.

The following table mostly from Tanenbaum compares demand paging with demand segmentation.

Consideration Demand
Paging
Demand
Segmentation
Programmer aware NoYes
How many addr spaces 1Many
VA size > PA size YesYes
Protect individual
procedures separately
NoYes
Accommodate elements
with changing sizes
NoYes
Ease user sharing NoYes
Why invented let the VA size
exceed the PA size
Sharing, Protection,
independent addr spaces

Internal fragmentation YesNo, in principle
External fragmentation NoYes
Placement question NoYes
Replacement question YesYes

** 4.8.2 and 4.8.3: Segmentation With (demand) Paging

(Tanenbaum gives two sections to explain the differences between Multics and the Intel Pentium. These notes cover what is common to all segmentation+paging systems).

Combines both segmentation and demand paging to get advantages of both at a cost in complexity. This is very common now.

Although it is possible to combine segmentation with non-demand paging, I do not know of any system that did this.

Homework: 38.

Homework: Consider a 32-bit address machine using paging with 8KB pages and 4 byte PTEs. How many bits are used for the offset and what is the size of the largest page table? Repeat the question for 128KB pages. So far this question has been asked before. Repeat both parts assuming the system also has segmentation with at most 128 segments.

4.9: Research on Memory Management

Skipped

4.10: Summary

Read

Some Last Words on Memory Management

================ Start Lecture #11 ================

Chapter 5: Input/Output

5.1: Principles of I/O Hardware

5.1.1: I/O Devices

5.1.2: Device Controllers

These are the “devices” as far as the OS is concerned. That is, the OS code is written with the controller spec in hand not with the device spec.

5.1.3: Memory-Mapped I/O

Think of a disk controller and a read request. The goal is to copy data from the disk to some portion of the central memory. How do we do this?

5.1.4: Direct Memory Access (DMA)

We now address the second question, moving data between the controller and the main memory.

Homework: 12

5.1.5: Interrupts Revisited

Skipped.

5.2: Principles of I/O Software

As with any large software system, good design and layering is important.

5.2.1: Goals of the I/O Software

Device independence

We want to have most of the OS, unaware of the characteristics of the specific devices attached to the system. (This principle of device independence is not limited to I/O; we also want the OS to be largely unaware of the CPU type itself.)

This works quite well for files stored on various devices. Most of the OS, including the file system code, and most applications can read or write a file without knowing if the file is stored on a floppy disk, a hard disk, a tape, or (for reading) a CD-ROM.

This principle also applies for user programs reading or writing streams. A program reading from ``standard input'', which is normally the user's keyboard can be told to instead read from a disk file with no change to the application program. Similarly, ``standard output'' can be redirected to a disk file. However, the low-level OS code dealing with disks is rather different from that dealing keyboards and (character-oriented) terminals.

One can say that device independence permits programs to be implemented as if they will read and write generic devices, with the actual devices specified at run time. Although writing to a disk has differences from writing to a terminal, Unix cp, DOS copy, and many programs we write need not be aware of these differences.

However, there are devices that really are special. The graphics interface to a monitor (that is, the graphics interface presented by the video controller--often called a ``video card'') does not resemble the ``stream of bytes'' we see for disk files.

Homework: 9

Uniform naming

Recall that we discussed the value of the name space implemented by file systems. There is no dependence between the name of the file and the device on which it is stored. So a file called IAmStoredOnAHardDisk might well be stored on a floppy disk.

Error handling

There are several aspects to error handling including: detection, correction (if possible) and reporting.
  1. Detection should be done as close to where the error occurred as possible before more damage is done (fault containment). This is not trivial.

  2. Correction is sometimes easy, for example ECC memory does this automatically (but the OS wants to know about the error so that it can schedule replacement of the faulty chips before unrecoverable double errors occur).

    Other easy cases include successful retries for failed ethernet transmissions. In this example, while logging is appropriate, it is quite reasonable for no action to be taken.

  3. Error reporting tends to be awful. The trouble is that the error occurs at a low level but by the time it is reported the context is lost. Unix/Linux in particular is horrible in this area.

Creating the illusion of synchronous I/O

Buffering

Sharable vs dedicated devices

For devices like printers and tape drives, only one user at a time is permitted. These are called serially reusable devices, and were studied in the deadlocks chapter. Devices like disks and Ethernet ports can be shared by processes running concurrently.

5.2.2: Programmed I/O

5.2.3: Interrupt-Driven (Programmed) I/O

5.2.4: I/O Using DMA

5.3: I/O Software Layers

Layers of abstraction as usual prove to be effective. Most systems are believed to use the following layers (but for many systems, the OS code is not available for inspection).

  1. User-level I/O routines.

  2. Device-independent (kernel-level) I/O software.

  3. Device drivers.

  4. Interrupt handlers.

We will give a bottom up explanation.

5.3.1: Interrupt Handlers

We discussed an interrupt handler before when studying page faults. Then it was called “assembly language code”.

In the present case, we have a process blocked on I/O and the I/O event has just completed. So the goal is to make the process ready. Possible methods are.

Once the process is ready, it is up to the scheduler to decide when it should run.

5.3.2: Device Drivers

The portion of the OS that is tailored to the characteristics of the controller.

The driver has two “parts” corresponding to its two access points. Recall the figure on the right, which we saw at the beginning of the course.

  1. Accessed by the main line OS via the envelope in response to an I/O system call. The portion of the driver accessed in this way is sometimes call the “top” part.
  2. Accessed by the interrupt handler when the I/O completes (this completion is signaled by an interrupt). The portion of the driver accessed in this way is sometimes call the “bottom” part.

Tanenbaum describes the actions of the driver assuming it is implemented as a process (which he recommends). I give both that view point and the self-service paradigm in which the driver is invoked by the OS acting in behalf of a user process (more precisely the process shifts into kernel mode).

Driver in a self-service paradigm

  1. The user (A) issues an I/O system call.

  2. The main line, machine independent, OS prepares a generic request for the driver and calls (the top part of) the driver.
    1. If the driver was idle (i.e., the controller was idle), the driver writes device registers on the controller ending with a command for the controller to begin the actual I/O.
    2. If the controller was busy (doing work the driver gave it previously), the driver simply queues the current request (the driver dequeues this request below).

  3. The driver jumps to the scheduler indicating that the current process should be blocked.

  4. The scheduler blocks A and runs (say) B.

  5. B starts running.

  6. An interrupt arrives (i.e., an I/O has been completed) and the handler is invoked.

  7. The interrupt handler invokes (the bottom part of) the driver.
    1. The driver informs the main line perhaps passing data and surely passing status (error, OK).
    2. The top part is called to start another I/O if the queue is nonempty. We know the controller is free. Why?
      Answer: We just received an interrupt saying so.

  8. The driver jumps to the scheduler indicating that process A should be made ready.

  9. The scheduler picks a ready process to run. Assume it picks A.

  10. A resumes in the driver, which returns to the main line, which returns to the user code.

Driver as a process (Tanenbaum) (less detailed than above)

5.3.3: Device-Independent I/O Software

The device-independent code does most of the functionality, but not necessarily most of the code since there can be many drivers, all doing essentially the same thing in slightly different ways due to slightly different controllers.

5.3.4: User-Space Software

A good deal of I/O code is actually executed by unprivileged code running in user space. Some of this code consists of library routines linked into user programs, some are standard utilities, and some is in daemon processes.

Homework: 10, 13.

5.4: Disks

The ideal storage device is

  1. Fast
  2. Big (in capacity)
  3. Cheap
  4. Impossible

When compared to central memory, disks are big and cheap, but slow.

================ Continuation of Lecture #12 ================

5.4.1: Disk Hardware

Show a real disk opened up and illustrate the components.

================ Continuation of Lecture #11 ================

Consider the following characteristics of a disk.

Overlapping I/O operations is important. Many controllers can do overlapped seeks, i.e. issue a seek to one disk while another is already seeking.

As technology increases the space taken to store a bit decreases, i.e.. the bit density increases. This changes the number of cylinders per inch of radius (the cylinders are closer together) and the number of bits per inch along a given track.

(Unofficial) Modern disks cheat and have more sectors on outer cylinders as on inner one. For this course, however, we assume the number of sectors/track is constant. Thus for us there are fewer bits per inch on outer sectors and the transfer rate is the same for all cylinders. The modern disks have electronics and software (firmware) that hides the cheat and gives the illusion of the same number of sectors on all tracks.

(Unofficial) Despite what tanenbaum says later, it is not true that when one head is reading from cylinder C, all the heads can read from cylinder C with no penalty. It is, however, true that the penalty is very small.

Choice of block size

================ Continuation of Lecture #12 ================

Homework: Consider a disk with an average seek time of 10ms, an average rotational latency of 5ms, and a transfer rate of 10MB/sec.

  1. If the block size is 1KB, how long would it take to read a block?
  2. If the block size is 100KB, how long would it take to read a block?
  3. If the goal is to read 1K, a 1KB block size is better as the remaining 99KB are wasted. If the goal is to read 100KB, the 100KB block size is better since the 1KB block size needs 100 seeks and 100 rotational latencies. What is the minimum size request for which a disk with a 100KB block size would complete faster than one with a 1KB block size?

================ Continuation of Lecture #11 ================

RAID (Redundant Array of Inexpensive Disks)

================ Continuation of Lecture #12 ================

5.4.2: Disk Formatting

Skipped.

5.4.3: Disk Arm Scheduling Algorithms

There are three components to disk response time: seek, rotational latency, and transfer time. Disk arm scheduling is concerned with minimizing seek time by reordering the requests.

These algorithms are relevant only if there are several I/O requests pending. For many PCs this is not the case. For most commercial applications, I/O is crucial and there are often many requests pending.

  1. FCFS (First Come First Served): Simple but has long delays.

  2. Pick: Same as FCFS but pick up requests for cylinders that are passed on the way to the next FCFS request.

  3. SSTF or SSF (Shortest Seek (Time) First): Greedy algorithm. Can starve requests for outer cylinders and almost always favors middle requests.

  4. Scan (Look, Elevator): The method used by an old fashioned jukebox (remember “Happy Days”) and by elevators. The disk arm proceeds in one direction picking up all requests until there are no more requests in this direction at which point it goes back the other direction. This favors requests in the middle, but can't starve any requests.

  5. C-Scan (C-look, Circular Scan/Look): Similar to Scan but only service requests when moving in one direction. When going in the other direction, go directly to the furthest away request. This doesn't favor any spot on the disk. Indeed, it treats the cylinders as though they were a clock, i.e. after the highest numbered cylinder comes cylinder 0.

  6. N-step Scan: This is what the natural implementation of Scan gives.