Red Hat Linux 7 Unleashed

Red Hat Linux 7 Unleashed

By William Ball

Character Devices

Character devices offer a flow of data that must be read in order. Whereas block devices enable a seek to select the next block of data transferred, for example, from one edge or the other of a diskette, character devices represent hardware that doesn't have this capability. An example is a terminal, for which the next character to be read is whatever key you type at the keyboard.

In fact, because there are only two basic types of devices, block and character, all hardware is represented as one or the other, rather like the animal and vegetable kingdoms of biological classification. Inevitably, this means that a few devices don't quite fit into this classification scheme. Examples include tape drives, generic SCSI devices, and the special memory devices such as /dev/port and /dev/kmem.

Parallel Ports

Parallel ports are usually used for communicating with printers, although they are versatile enough to support other things too—for example, scanners, Zip drives, CD-ROM drives, and even networking.

The hardware itself offers character-at-a-time communication. The parallel port can provide an interrupt to notify the kernel that it is now ready to output a new character, but because printers are usually not performance-critical on most PCs, this interrupt is often borrowed for use by some other hardware, often sound hardware. This has an unfortunate consequence: The kernel often needs to poll the parallel hardware, so driving a parallel printer often requires more CPU work than it should.

The good news is that if your parallel printer interrupt is not in use by some other hardware, it can be enabled with the printer driver configuration program tunelp. The -i option for tunelp sets the IRQ for use with each printer device. You might set the IRQ for the printer port to 7 like this:

# /usr/sbin/tunelp /dev/lp1 -i 7
/dev/lp1 using IRQ 7

If this results in the printer ceasing to work, going back to the polling method is easy:

# /usr/sbin/tunelp /dev/lp1 -i 0
/dev/lp1 using polling

The best way to test a printer port under Red Hat Linux is from the Control Panel's Printer Configuration tool (/usr/bin/printtool). The Tests menu offers the option of printing a test page directly to the device rather than via the normal printing system. This is a good starting point. You can find more information on setting up printers in Chapter 19, "Printing with Linux."

Tape Drives

Tape drives provide I/O of a stream of bytes to or from the tape. Although most tape drives can be repositioned (that is, rewound and wound forward like audio or video tapes), this operation is very slow by disk standards. Although access to a random part of the tape is at least feasible, it is very slow, so the character device interface is workable for using tape drives.

For most UNIX workstations, the interface of choice for tape drives is SCSI because this fits in well with the SCSI disks and so on. SCSI provides the capability to plug in a new device and start using it. (Of course, you can't do this with the power on.) SCSI has traditionally been more expensive than most other PC technologies, so it wasn't used for many tape drives developed for use with PCs. Several interfaces have been used for tape drives for IBM PCs:

Type Device Names Major Number
SCSI /dev/st* 9
Floppy /dev/rft* 27
QIC-02 /dev/rmt 12
IDE /dev/ht* 37
Parallel Port (Currently unsupported)  

All these tape drives have the feature that when the device is closed, the tape is rewound. All these drives except the QIC-02 drive have a second device interface with a name prefixed with n—for example /dev/nst0, /dev/nst3, or /dev/nht0. The n-variant of the devices are non-rewinding versions of the tape devices. All tape devices support the magnetic tape control program, mt, which is used for winding tapes past files, rewinding them, and so on. Many commands, particularly the more advanced mt commands, are only available for SCSI tape drives.

Apart from the mt command for the basic control of a tape drive, there are many commands that you can use for storing and retrieving data on tape. Because the character devices are "just files," you could use cat to store data on the tape, but this is not very flexible. A great many programs are particularly or partly designed with tape drives in mind:

tar This is widely used for creating archives in regular files but was originally created for making tape backups. In fact, tar stands for tape archiver. Archives made by tar can be read on a wide variety of systems.
cpio Another program principally intended for backups and so on, cpio stands for copy in–out. The GNU version of cpio, which is used by Linux distributions, supports eight different data formats—some of which are varieties of its "native" format, two are varieties of tar archives, and some are obsolete. If you want to unpack an unknown archive, cpio, along with file and dd, is very useful.
dump The dump utility is of use only to system administrators because it backs up an ext2 filesystem by raw access to the block device on which the filesystem exists. (For this reason, it is better to do this when the filesystem is either not mounted or is mounted read-only.) This has the advantage, among other things, that the access times of the backed-up directories are left unmodified. (GNU tar will also do this.) Although tapes written with dump are not always readable on other versions of UNIX, unlike those written by tar and cpio, dump is a popular choice.
dd Designed for blockwise I/O, dd is a general-purpose tool for doing file manipulations and can often be useful.
afio A variant of cpio, afio compresses individual files into the backup. For backups, this is preferable to tar's compression of the whole archive because a small tape error can make a compressed tar archive useless, although a tar archive that isn't compressed doesn't have this vulnerability. afio isn't widely used outside the Linux world.
AMANDA AMANDA is a powerful backup system that schedules, organizes, and executes backups for you. It uses either tar or dump to do the actual work and will effortlessly allow you to automate all the backups for one machine or a multitude. One of its most useful features is its ability to perform fast backups across the network from several client machines to a single server machine containing a tape drive.
BRU BRU (Backup and Restore Utility) is a commercial product for making backups.

For more information about some of these tape utilities, see Chapter 22.

Terminals

The terminal is the principal mode of communication between the kernel and the user. When you type keystrokes, the terminal driver turns them into input readable by the shell or whatever program you are running.

For many years, UNIX ran only on serial terminals. Although most computers now also have video hardware, the terminal is still a useful concept. Each window in which you can run a shell provides a separate pseudoterminal, each one rather like a traditional serial terminal. Terminals are often called ttys because the device nodes for many of them have names like /dev/tty*.

The terminal interface is used to represent serial lines to "real" terminals, to other computers (via modems), mice, printers, and so on. The large variety of hardware addressed by the terminal interface has led to a wide range of capabilities offered by the terminal device driver, and explaining all the facilities offered could easily occupy an entire chapter. This section just offers an overview of the facilities.

For more complete information on terminals and serial I/O, refer to the Linux Documentation Project's excellent HOWTO documents. These are provided on the Red Hat Linux 7 CD-ROM (you need to install them) and are also available on the Web at http://www.linuxdoc.org/. Specific HOWTOs dealing with this are the Serial HOWTO and the Serial Port Programming mini-HOWTO. Many documents deal with using modems for networking.

The Terminal Device Driver

The terminal device driver gathers the characters you type at the keyboard and sends them to the program you're working with, after some processing. This processing can involve gathering the characters into batches a line at a time and taking into account the special meanings of some keys you might type.

Some special keys of this sort are used for editing the text that is sent to the program you're interacting with. Much of the time, the terminal driver is building a line of input that it hasn't yet sent to the program receiving your input. Keys that the driver will process specially include the following:

Return (CR) or Line Feed (LF)
CR is usually translated into LF by the terminal driver. (See the icrnl option in the manual page for stty.) This ends the current line, which is then sent to the application. (It is waiting for terminal input, so it wakes up.)
Backspace/Delete
Only one of these two keys can be selected as the erase key, which erases the previous character typed. For more information, read the Linux Keyboard Setup mini-HOWTO.
End-of-File, Usually Ctrl+D
When a program is reading its standard input from the keyboard and you want to let it know that you've typed everything, you press Ctrl+D. ("Usually" indicates that this option is shell dependent and may differ depending upon which shell you are using.)
Word-Erase, Usually Ctrl+W
This combination deletes the last word you typed.
Kill-Line, Usually Ctrl+U
This kills the entire line of input so that you can start again.
Interrupt, Usually Ctrl+C
This kills the current program. Some programs block this at times when the program might leave the terminal in a strange state if it were unexpectedly killed.
Suspend, Usually Ctrl+Z
This key sends a suspend signal to the program you're using. The result is that the program is stopped temporarily, and you get the shell prompt again. You can then put that program (job) in the background and do something else. See Chapter 25, "Shell Scripting," for more information.
Quit, Usually Ctrl+\(Ctrl+Backslash)
Sends a Quit signal to the current program; programs that ignore Ctrl+C can often be stopped with Ctrl+\, but programs ignoring Ctrl+C are often doing so for a reason.
Stop, Usually Ctrl+S, and Start, Usually Ctrl+Q
These keys stop and restart terminal output temporarily, which can be useful if a command produces a lot of output, although it can often be more useful to repeat the command and pipe it through less.

You can examine many other terminal modes and settings with the stty command. This command has a built-in set of sensible settings for terminals, and typing stty to find the current settings usually shows you only the differences from its "sane" settings:

$ stty
speed 9600 baud; line = 0;

Programs can turn off the processing that the line driver does by default; the resulting behavior (raw mode) allows programs to read unprocessed input from the terminal driver (for example, CR is not mapped to LF), and control characters don't produce the signals described in the table earlier in this section. The stty sane command will return things to normal.

Serial Communications

Although the terminal interfaces used most commonly under Linux are the console driver and the pseudo-terminals driven by programs such as xterm, script, and expect, the original terminal interface involved serial communications. In fact, this still lingers; a pseudo-tty associated with an xterm window still has an associated baud rate as shown in the example in the section The Terminal Device Driver earlier in this chapter. Changing this baud rate has no actual effect. For real serial ports, however, the baud rate and many other parameters have a direct relevance. The device nodes relating to the serial ports are composed of two "teams," with the names /dev/cua* and /dev/ttyS*. Starting with version 2.2 of the kernel, /dev/ttyS* is the "correct" name to use. /dev/cua* will, most likely, disappear from the next version or two. The device nodes allow you to use the same serial hardware for both incoming and outgoing serial connections.

Configuring the Serial Ports

Serial port configuration is mostly done either with the stty command or directly by programs using the interface outlined in the termios manual page. The stty command offers almost all the configuration possibilities provided by termios; however, there are configuration issues for serial hardware that are not addressed by stty. The setserial command allows the configuration of the correct IRQ settings for each serial port and of extra-fast baud rates that the standard termios specification doesn't provide. For more detailed information, refer to the Linux Serial HOWTO and the manual page for setserial.

Generic SCSI Devices

Not all SCSI devices are hard disks, CD-ROM drives, or tape drives. Some are optical scanners, CD-ROM recorders, or even electron microscopes. The kernel can't possibly abstract the interfaces for all possible SCSI devices, so it gives user programs direct access to SCSI hardware via the generic SCSI devices. These enable programs to send arbitrary SCSI commands to hardware. Although this arrangement offers the opportunity of wreaking havoc by mistake, it also offers the capability of driving all sorts of interesting hardware, of which the principal examples are CD-ROM recorders. The SCSI device nodes all have names starting with /dev/sg. SCSI commands are sent to the devices by writing data to the device, and the results are read back by reading from the device.

CD-ROM Recorders

CD-ROM recorders are devices for recording data on special media that can be read in ordinary CD-ROM drives. There are two stages in the writing of a CD: generating the CD image and writing that image to the media.

The surface of a CD-R (recordable CD) is only writable once, so if mkisofs worked like the other mkfs tools, it would always generate image files representing empty CDs. For this reason, mkisofs populates the filesystem with files as it generates the image file. The same principles apply to CD-RW, which are CD-R that are rewriteable. Under Linux they are treated just as CD-R, the only difference being that you can record over them a second time, or many more times for that matter.

The CD image file is produced by the mkisofs program, which generates the structures for an ISO 9660 filesystem and populates it with the files from a directory tree. CDs are not writable in the same sense as block devices; this is why they are not actually block devices. The image file must be written to the CD-R with a specialized program, cdrecord, which understands all the various proprietary schemes used for driving CD writers. All the CD writers supported by Linux (as of version 2.0.30 of the kernel) are SCSI devices, so the kernel accommodates this by providing access to the generic SCSI device interface that enables a program to send SCSI commands to these devices. However, there is also support for some IDE CD writers, but these are all handled by using a special driver that lets IDE emulate SCSI.

While burning (writing) a CD, it is usually important that the flow of data to the writer keeps up with the speed at which the writer is going; otherwise, if the writer runs out of data to write, the CD-R is ruined. For this reason, it is usual to use mkisofs to generate an image file and then separately use cdrecord to write this image file to the CD writer.

It is possible to use a pipe to send the data from mkisofs directly to cdrecord. This often works either because a fast machine can ensure that mkisofs supplies the data fast enough to keep the CD writer busy or because the CD writer is not sensitive to data underruns. (Some of the more expensive ones have internal hard disks or very big RAM caches to which the data is written during an intermediate stage.) This technique is not recommended, however, because the generation of the intermediate image file has other benefits; it enables you to test your CD image before the final writing of the data takes place.

Testing CD Images

Just as you can use mkfs to create a filesystem inside an ordinary file, you can mount filesystems contained in ordinary files by using the loopback device driver described previously. The first example of mounting a loopback filesystem is a demonstration of how you can test a CD image.

Other Character Devices

Several other varieties of character devices, such as /dev/null, are used frequently.

The Controlling Terminal Device—/dev/tty

Most processes have a controlling terminal, particularly if they were started interactively by a user. The controlling terminal, which I refer to as simply /dev/tty, is used for initiating a conversation directly with the user (for example, to ask him something). An example is the crypt command:

$ fmt diary.txt | crypt | mail -s Diary confidant@linux.org
Enter key:
$

Here, the crypt command has opened /dev/tty to obtain a password. It was not able to use its own standard output to issue the prompt and its standard input to read the password because they are being used for the data to be encrypted.

More useful examples are commands that need to ask the operator something even if the input and output are redirected. A case in point is the cpio command, which prompts the operator for the name of a new tape device when it runs out of space. See the section /dev/null and Friends later in this chapter for another example.

Nonserial Mice

Many computers have bus or PS/2 mice instead of serial mice. This arrangement has the advantage of keeping both of the two standard serial ports free, but the disadvantage of using up another IRQ. These devices are used by gpm and the X Window System, but most other programs don't interact with them directly. Setting up your system with these mice is easy; the Red Hat Linux installation process pretty much takes care of it for you. If you have problems with your mouse, however, you should read the manual page for gpm and the Linux BusMouse HOWTO.

Audio Devices

There are several audio-related device nodes on Linux systems, and they include the following:

/dev/sndstat Indicates the status of the sound driver
/dev/audio* Sun-compatible audio output device
/dev/dsp* Sound sampling device
/dev/mixer For control of the mixer hardware on the sound card
/dev/music A high-level sequencer interface
/dev/sequencer* A low-level sequencer interface
/dev/midi* Direct MIDI port access

Setting up the sound driver under Linux can sometimes be difficult, but the sndconfig utility included with Red Hat makes this easier for most cards. If you have problems be sure to check out the Linux Sound HOWTO provides useful advice.

Random Number Devices

Many program features require the generation of apparently random sequences. Examples include games, numerical computations, and various computer-security–related applications. Numerical computing with random numbers requires that the sequence of random numbers be repeatable but also that the sequence "look" random. Games require apparently random numbers, but the quality of the random numbers is not quite as critical as for numerical computation programs. The system libraries produce repeatable sequences of "pseudo-random" numbers that satisfy these requirements well.

On the other hand, in many aspects of computer security, it is advantageous to generate numbers that really are random. Because you can assume that an attacker has access to the same sorts of random number generators that you do, using them is not very safe; an attacker can use these generators to figure out what random number you'll use next. Sequences that are genuinely random must in the end be produced from the real world and not from the internals of some computer program. For this reason, the Linux kernel keeps a supply of random numbers internally. These numbers are derived from very precise timings of the intervals between "random" external events—for example, the user's key presses on the keyboard, mouse events, and even some interrupts (such as from the floppy disk drive and some network cards). These "real" random numbers are used in security-critical contexts—for example, the choosing of TCP sequence numbers.

The two random number devices differ in what happens when the rate of reading exceeds the rate at which random data is collected inside the kernel. The /dev/random device makes the calling program wait until some more randomness arrives, and the /dev/ urandom device falls back on the difficult-to-guess MD5 hash to produce a stream of random data. When more random information arrives later, it is added to the randomness of /dev/urandom. To summarize, /dev/random doesn't sacrifice quality in favor of speed, but /dev/urandom does.

/dev/null and Friends

In the following segment, the special devices /dev/full and /dev/null first simulate a tape-full condition and then discard the output:

$ echo test | cpio -o >/dev/full
Found end of tape.  To continue, type device/file name when ready.
/dev/null
1 blocks

In the real world, when the tape on /dev/st0 becomes full, you probably just change the tape in the drive and type /dev/st0 a second time. However, /dev/full is occasionally useful for testing purposes, and /dev/null is used all the time for discarding unwanted output. The device /dev/full produces a stream of zero bytes when read. (/dev/null, on the other hand, produces no output at all.)

Memory Devices

The memory devices have the same major device number as /dev/null and /dev/full but are used differently. They are as follows:

/dev/mem Provides access to physical memory
/dev/kmem Provides access to the kernel's virtual memory
/dev/port Provides access to I/O ports

These devices are not frequently used in many programs; the X Window System's X server uses memory mapping on /dev/mem to access the video memory, and many programs use /dev/port to access I/O ports on those architectures that have a separate I/O space. (Many modern processors do not.)

Virtual Console Screen Devices

The virtual console (VC) screen devices provide read access to the VCs memory. This can be used to get screen capture capabilities for virtual consoles, for example. The devices are not readable by ordinary users; hence, other users cannot eavesdrop on your session.

There are two sets of device nodes for this purpose:

$ ls -l /dev/vcs[012] /dev/vcsa[012]
crw--w----    1 root     tty        7,   0 Jul 21 16:29 /dev/vcs0
crw--w----    1 wsb      tty        7,   1 Jul 21 16:29 /dev/vcs1
crw--w----    1 root     tty        7,   2 Jul 21 16:29 /dev/vcs2
crw--w----    1 root     tty        7, 128 Jul 21 16:29 /dev/vcsa0
crw--w----    1 wsb      tty        7, 129 Jul 21 16:29 /dev/vcsa1
crw--w----    1 root     tty        7, 130 Jul 21 16:29 /dev/vcsa2

Each set is numbered from 0 to 63, corresponding to the numbering system for the /dev/tty* console devices. The device /dev/vcs0, like the device dev/tty0, always refers to the currently selected VC.

The /dev/vcs* files provide a snapshot of what is in view on the corresponding VC. This snapshot contains no newlines because there are none actually on the screen; after all, a newline character just moves the cursor. To make the captured data into the kind of thing you usually see in text files or send to printers, you need to add newlines in the appropriate places. This can be done with the dd command:

$ dd cbs=80 conv=unblock </dev/vcs1 | lpr

This example works only if the screen actually is 80 columns wide. This is not always true; the kernel can set up a different video mode at boot time, and you can use the SVGATextMode command to change it at any time.

You can overcome this problem by using the other set of devices, /dev/vcsa*. Reading from these devices gives a header, followed by the screen data with attribute bytes. The header consists of two bytes indicating the screen size (height first), followed by two bytes indicating the cursor position. The screen data is provided at a rate of two bytes per character cell, the first containing the attribute byte and the second containing the character data (as with /dev/vcs*). You can use this data to provide full-color screen dumps and so on. The following script uses a /dev/vcsa device to determine the width of the VC and to get the conversion of the corresponding /dev/vcs device right:

#! /bin/sh

#Insist on exactly one argument (the VC number to dump)
[$# -eq 1] || { echo "usage: $0 [vc-number]">2; exit 1}

vc=$1 #Which VC to dump

#Extract the VC's width from the second byte of the vcsa device
#The "unpack" expression extracts the value of the second
#character of the input (the vcsa device).
Width=`dd if=/dev/vcsal bs=1 count=1 skip=1 2>/dev/null|hexdump -e '"%d"'`

#Use dd(1) to convert the output now that we know the width
dd cbs=${ width}  conv=unblock</dev/vcs${ vc}  2>/dev/null

Share ThisShare This

Informit Network