Overview
- Minix RAM disk, continued
- Minix hard disk driver
- Minix Terminal Driver
Minix RAM disk implementation
- many functions (e.g. close, cleanup) are no-ops
- main in the memory driver calls
m_init (which sets up each device's pointers and sizes)
and then goes to the shared driver_task function
- open checks the device number
- exactly one ioctl is supported, to set the size of a RAM disk
(only FS may do this)
- doing this requires allocating memory, which eventually leads
to a call to the process manager (PM)
- the code in
servers/pm/alloc.c
implements the first-fit memory allocation algorithm (lines 74-96)
- m_geometry returns the (completely fake) geometry
- reading or writing of /dev/null is a question of returning
the correct number of bytes read or written (0 read, all written)
Reading or writing a RAM disk block
- m_transfer, p. 783-785
- ignore the optional bit -- all operations on a RAM disk
complete immediately
- one iteration per request in the vector
- for "normal" memory devices, check for address legality,
i.e. within the RAM disk, and truncate the transfer if necessary
- select the appropriate segment
- perform the virtual or physical copy
- update the number of bytes copied
Disk drives
- Disk drive controllers can be simple (e.g. for floppies) or
advanced (e.g. for hard disks)
- more advanced controllers allow for simpler drivers, and
simpler controllers require more complex drivers
- on a hard disk with variable geometry, the controller may
hide the actual geometry, in which case the device driver can simply
ignore all the details and address the blocks in linear order
- timing characteristics may vary a lot, e.g. for sample devices
(book 2nd ed., p. 202)
| floppy | hard disk |
| seek time (best) | 6ms | 4ms |
| seek time (avg) | 77ms | 11ms |
| rotation time | 200ms | 13ms |
| motor start time | 250ms | 9s |
| 1 sector transfer time | 22ms | 53us |
- the random access time to transfer one non-sequential block
is the sum of the seek time, the rotational delay (on average,
1/2 the rotation time), and the block transfer time
- the time to transfer successive blocks is much less than the
time to seek to a given position, so successive blocks should
be read if at all desirable
Disk scheduling
- because seek and rotational latency can dominate transfer time,
it can be best to reorder block transfers to minimize these
- this can only be done if the device driver has multiple
requests to satisfy, so they can be reordered
- the following algorithms can be adapted to two-dimensional
geometries, but are most easily explained in terms of a 1-dimensional
array of disk blocks
- first-come-first-served (FCFS): no reordering, latency per block is
one average seek plus half a rotation
- shortest-seek-first (SSF): satisfy next whatever request is nearest
the last request
- elevator algorithm: satisfy the nearest request in the current
direction. Once there are no more, either start over from the opposite
end, or (elevator-like), reverse direction
- SSF is usually efficient, but may lead to starvation if additional
requests are served before existing requests
Linux I/O scheduling
- anticipatory I/O scheduler predicts whether the next read will
be sequential (based on process statistics) and if so,
does nothing for 6ms after a read, optimizing for the case where
another read will request a nearby block
- deadline I/O scheduler keeps three queues of requests:
- sorted requests (for elevator), handled in FIFO order
- read requests, satisfied after at most 0.5s
- write requests, satisfied after at most 30s
- reads and writes are taken from the sorted queues (and removed
from the corresponding read or write queues), until/unless one of
the deadlines has expired, in which case the corresponding read/write
takes priority
- so elevator is used in most cases, but reads or writes are
not delayed too long
- Linux I/O scheduling is implemented in a device-independent
fashion, as in Minix3
Minix hard disk driver
- BIOS supports hard disk operations, but without multithreading
and only in 16-bit real mode (designed for MS-DOS)
- instead, write own driver:
- BIOS driver, uses BIOS support
- other drivers
- AT driver
- each of these may be compiled in or out, and, if compiled in,
may be selected at boot time
- BIOS may be most portable, but also slowest
- AT driver supports drivers from 80286 computers through EIDE (GB
capacity)
- system initializes almost completely without accessing the disk,
so booting a system without a hard disk driver or without a hard disk drive
proceeds most of the way -- no actual disk access until the first call
to w_do_open (p. 794)
AT hard disk control flow
- at_winchester_task called
- init_params checks the boot parameters and the BIOS,
to figure out which disks are present
- eventually, a DEV_OPEN message leads to calling
w_do_open, which calls w_prepare (almost every
message leads to calling w_prepare), w_identify, and
finally, if this is the first open for the device, partition
from drivers/libdriver/drvlib.c. partition calls
transfer (line 11566, in get_part_table) to get
the boot sector
- w_identify does the hard work of requesting and decoding
the device information
- the identification request is built by com_simple (p. 803),
and sent to the device by com_out (p. 801-802)
- com_out waits for the controller to not be busy (line 12960),
then selects the drive, then waits again
- the drive controller registers are shown in Figure 3-23 on p. 296
- the actual I/O to the controller is done in
kernel/system/do_vdevio.c, line 69, using outb
- the driver will use cylinder/head/sector addressing if necessary,
but LBA (Logical Block Addressing) if possible, with up to 48 bits for
a block number
- the final step in w_identify enables the interrupt from
the disk device (line 12701), specifying that interrupts should not
remain blocked while the device driver executes
AT hard disk read and write
- on a w_transfer (p. 800), adjacent requests are done
in a single operation, up to wn->max_count.
- the transfer request is built by do_transfer (p. 799-800),
and sent to the device by com_out (described above)
- after do_transfer, there is a loop that is executed
once per sector, beginning on line 12890
- read calls at_intr_wait (line 12909)
which calls w_intr_wait which calls receive, as previously
discussed in class
- on a read or a write, w_waitfor reads the status
from the disk (line 13190) until the status is STATUS_DRQ
(data transfer request, line 12190)
- bytes are finally copied with sys_insw or sys_outsw,
which is programmed I/O rather than DMA
- a write now waits for an interrupt (line 12920), to check whether
everything was written
- data is always transferred one sector at a time
- for either reads or writes, the next I/O descriptor is then
selected if this I/O descriptor has been satisfied
- in case of timeout (w_need_reset, p. 802, called from
line 13198), set a bit and request a re-initialization of the device
- in case of timeout on the interrupt, w_timeout, p. 803,
(called from line 13134) decreases the maximum size given to
do_transfer from n to 8 sectors, and from 8 sectors to 1,
in case that was what tripped up the drive
Minix Terminal Driver
- very complex: supports memory-mapped keyboard and displays, RS-232
serial terminals, and network-based logins (Pseudo-ttys, or PTYs, on other
systems)
- character devices, but with two-dimensional
positioning capabilities (screens)
- screens can be character-based or pixel-based (minix only supports
character-based)
- buffering can be reserved per terminal (as is the case in Minix)
or shared among all terminals (central buffer pool)
- terminal driver must perform line editing functions to
honor erase characters and possibly change newlines into CR-LF or
viceversa (or other combinations)
Terminal Modes
- editors will do their own screen redrawing, can handle erase
characters, so should be given the raw stream of characters
the user enters
- most programs take line input and would prefer to have the
operating system take care of editing: canonical or cooked
mode
- special characters can control freezing (^S) or restarting (^Q)
the output, mark end of file (^D), end of line, etc
- in non-canonical mode, Minix allows the specification of a
minimum number of characters to read and of a timeout for terminal
reads -- if either is satisfied, the read call completes
Reading from the terminal
- book, figure 3-33, p. 319
- user process sends message to file system
- file system sends message to TTY task, which may directly go to (6),
but most likely
- replies asking the file system to suspend the process
- when a key is pressed, the generic interrupt handler notifies
the TTY task
- the TTY task reads the I/O ports to determine which key was
pressed, and adds the character to a queue
- at the top of the TTY task, the task copies available
data directly to the user space using physical
memory copying
- the TTY task tells the file server (whenever it is ready to
receive the message) that it may wake up the user process
- the FS server wakes up the user process
- this complex technique gives acceptable performance for large bursts
of characters from the serial port on slow hardware, since the user process
and the file system are only involved when enough characters (or a timeout)
have been received
- serial lines may only interrupt after receiving several characters,
rather than once per character
Bitmapped displays
- each pixel (usually 1, 8, 16, 24, or 32 bits) represents one dot
on the display: one scan sweep position or one pixel on an LCD display
- more resolution requires more memory (1280x1024x24 requires 4MB
for each display, without counting virtual desktop space)
- data can be arranged in various fashions in memory, but usually
such that adjacent elements of a row are adjacent in memory
- basic display operations include moving a block (bitblt),
drawing a point or a line, or filling in a rectangle (can also be done
with bitblt)
- a window manager, which may be part of the OS, must create
windows, associate them with processes, and support opening, closing,
moving, iconifying, etc
- the X-window system is a user-level program (an X
server) that supports basic window operations for (possibly
remote) client programs
- one of these client programs is the X window manager
- other client programs show the time, check for mail, allow for
user command-line input (by running shells, perhaps remote shells),
support surfing the web, etc.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.