Linux
by Tim Parker
IN THIS CHAPTER
- Character and Block Mode Devices
- Printer Administration
- Terminals
- Adding a Modem
This chapter is devoted to devices that might be attached to your Linux system, such
as terminals, modems, and printers. It shows you how to add and manage the different
devices, and it also looks at many of the Linux commands you will need to properly
administer your system.
In this chapter, you will learn about the following topics:
- What a device driver is
- The difference between block mode and character mode devices
- Major and minor device numbers
- The mknod command
- How to manage printers and the print spooler
- How to add a printer
- How to add a terminal and modem
- The configuration files used by terminals
- The startup sequence used to permit logins
All of this information is necessary if you are to have a smoothly running system.
Even if you don't intend to add terminals or modems, you should know about the startup
process and how the configuration files are handled.
Everything attached to the computer you are using to run Linux is treated as a
device by the operating system. It doesn't matter whether the device is a terminal,
a hard disk, a printer, a CD-ROM drive, or a modem. Everything that accepts or sends
data to the operating system is a device.
The concept of treating everything on the system as a device is one of the benefits
of the UNIX architecture. Each device has a special section in the kernel, called
a device driver, which includes all the instructions necessary for Linux to communicate
with the device. When a new device is developed, it can be used with Linux by writing
a device driver, which is usually a set of instructions that explains how to send
and receive data.
Device drivers allow the Linux kernel to include only the operating system and
support software. By having the instructions for talking to devices within a set
of files, they can be loaded as needed (in the case of rarely used devices), or kept
in memory all the time when the operating system boots. As refinements are made to
a peripheral, small changes to the device driver file can be linked into the kernel
to keep the operating system informed of the new features and capabilities.
When an application instructs a device to perform an action, the Linux kernel
doesn't have to worry about the mechanism. It simply passes the request to the device
driver and lets it handle the communications. Similarly, when you're typing at the
keyboard, your terminal's device driver accepts the keystrokes and passes them to
the shell or application, filtering out any special codes that the kernel doesn't
know how to handle by translating them into something the kernel can perform.
Linux keeps device files in the /dev directory by default and convention.
It is permissible to keep device files anywhere on the file system, but keeping them
all in /dev makes it obvious that they are device files.
Every type of device on the Linux system communicates in one of two ways: character
by character or as a set of data in a predefined chunk or block. Terminals, printers,
and asynchronous modems are character devices, using characters sent one at a time
and echoed by the other end. Hard drives and most tape drives, on the other hand,
use blocks of data, because this is the fastest way to send large chunks of information.
These peripherals are called either character mode or block mode devices, based on
the way they communicate.
-
NOTE: Another way to differentiate
between character and block mode devices is by how the buffering to the device is
handled. Character mode devices want to do their own buffering. Block mode devices,
which usually communicate in chunks of 512 or 1,024 bytes, have the kernel perform
the buffering. Some devices can be both character and block mode devices. Some tape
drives, for example, can handle both character and block modes, and therefore have
two different device drivers. The device driver that is used depends on how the user
wants to write data to the device.
The device file has all the details about whether the device is a character mode
or block mode device. There is an easy way to tell which type of device a peripheral
is: Look at the output of the listing command that shows file permissions (such as
ls -l). If the first character is a b, the device is a block mode
device; a c indicates a character mode device.
Device files are usually named to indicate the type of device they are. Most terminals,
for example, have a device driver with the name tty followed by two or more
letters or numbers, such as tty1, tty1A, or tty04. The
letters tty identify the file as a terminal (tty stands for teletype),
and the numbers or letters identify the specific terminal referred to. When coupled
with the directory name /dev, the full device driver name becomes /dev/tty01.
There might be more than one device of the same type on a system. For example,
your Linux system might have a multiport card (multiple serial ports) with 10 Wyse
60 terminals hanging off it. Linux can use the same device driver for each of the
terminals because they are all the same type of device.
However, there must be a method for the operating system to differentiate which
one of the 10 terminals you want to address. That's where device numbers are used.
Each device is identified by two device numbers: The major number identifies the
device driver to be used, and the minor number identifies the device number. For
example, the 10 Wyse 60 terminals on the multiport card can all use a device file
with the same major number, but each will have a different minor number, thereby
uniquely identifying it to the operating system.
Every device on the system has both major and minor device numbers assigned in
such a way as to ensure that they are unique. If two devices are assigned the same
number, Linux can't properly communicate with them.
Some devices use the major and minor device numbers in a strange way. Some tape
drives, for example, use the minor number to identify the density of the tape and
adjust its output in that manner.
Device files are created with the command mknod (make node) and removed
with the standard rm command.
The mknod (make node) command is used for several different purposes
in Linux. It can create a FIFO (first in first out) pipe or a character or block
mode device file. The format of this com-mand is
mknod [options] device b|c|p|u major minor
The options can be one of the following:
--help |
Displays help information and then exits. |
-m [mode] |
Sets the mode of the file to mode instead of the default 0666 (only symbolic
notation is allowed). |
--version
|
Displays version information, then exits.
|
The argument after the device or pathname specifies whether the file is a block mode
device (b), character mode device (c), FIFO device (p),
or unbuffered character mode device (u). One of these arguments must be
present on the command line.
Following the type of file argument are two numbers for the major and minor device
numbers assigned to the new file. Every device on a UNIX system has a unique number
that identifies the type of device (the major number) and the specific device itself
(the minor number). Both a major and a minor number must be specified for any new
block, character, or unbuffered mode device. Device numbers are not specified for
a type p device.
Examples of using the mknod command are shown in several sections later
in this chapter, when devices are added to the system.
Printers are commonly used devices that can cause a few problems for system administrators.
They are quite easy to configure as long as you know something about the hardware.
Managing printer queues is also quite easy, but like many things in Linux, you must
know the tricks to make the system work easily for you.
Linux is based on the BSD version of UNIX, which unfortunately is not the most
talented UNIX version when it comes to printer administration. However, because it's
unlikely that the Linux system will be used on very large networks with many printers,
administration tasks can be reduced to the basics. Be warned, though, that the BSD
UNIX printer administration and maintenance commands have a reputation for quirky
and inconsistent behavior!
All printing on the Linux system is handled by the lpd daemon, which
is usually started when the system boots. During the startup process, the lpd
daemon reads through the file /etc/printcap to identify the sections that
apply to any of the printers known to be attached to the system. The lpd
daemon uses two other processes, called listen and accept, to handle incoming requests
for printing and to copy them to a spooling area.
In most cases, you won't have to modify the lpd daemon. However, there
might be times when you have to stop it manually and restart it. The command to load
lpd is
lpd [-l] [port]
The -l option invokes a logging system that notes each print request.
This option can be useful when you're debugging the printer system. The port number
allowed in the lpd command line is used to specify the Internet port number
if the system configuration information is to be overridden. You will probably never
have to use it.
The size of the print spool area is set by an entry in the file minfree
in each spool directory (each printer has its own spool directory). The contents
of minfree show the number of disk blocks to keep reserved so that spooling
large requests doesn't fill up the hard drive. The contents of the file can be changed
with any editor.
Access to the lpd daemon to allow printing of a user request must pass
a quick validation routine. Two files are involved: /etc/hosts.equiv and
/etc/hosts.lpd. If the machine name of the sending user is not in either
file, the print requests are refused. Because the local machine is always in hosts.equiv
(as localhost), users on the Linux machine should always have their print
requests granted.
To understand how the print daemon works, as well as how print requests are managed
by Linux, it is instructive to follow a print request. When a user requests a print
job with the lpr command, lpr assembles the data to be printed
and copies it into the spooling queue, where lpd can find it.
-
NOTE: The lpr
program is the only one in the Linux system that can actually queue files for printing.
Any other program that offers printing capabilities does so by calling lpr.
As part of its spooling task, lpr also checks for instructions on how
to print the file. It can get the information from three sources: the command line
(supplied as arguments), environment variables (set by the shell or the user), or
the system's default values.
The lpr program knows which spool to put the print request in because
of the destination printer designation. The printer destination can be specified
on the lpr command line, or through an environment variable. When the destination
printer name has been determined, lpr checks the file /etc/printcap
to look up the printer's information, including the spool directory. The spool directory
is usually of the form /usr/spool/printer_name, such as /usr/spool/lp1.
Within the spool directory, lpr creates two files. The first has the
letters cf (control file) followed by a print ID number. The cf
file contains information about the print job, including the owner's name. The second
file starts with df (data file) and has the actual contents of the file
to be printed with it. When lpr has finished creating the df file,
it sends a signal to lpd that informs the daemon that a print job is waiting
in the spool directory.
When lpd gets the signal from lpr, it checks the file /etc/printcap
to see whether the printer is for a local or remote printer. If the print job is
for a remote printer (one attached to another machine on the network), lpd
opens a connection to the remote machine, transfers both the control and data files,
and deletes the local copies.
If the print job is for a local printer, lpd checks to make sure the
printer exists and is active, and then sends the print request to the printing daemon
running that queue.
The /etc/printcap file is consulted by both the user's print command
lpr and the lpd print daemon. It contains information about every
printer that is accessible from the Linux machine.
The format of /etc/printcap is straightforward (and similar to the /etc/termcap
file for terminal descriptions). The following is an extract from /etc/printcap:
# HP Laserjet
lp|hplj|laserjet-acctng|HP LaserJet 4M in Room 425:\
:lp=/dev/lp0:\
:sd=/usr/spool/lp0:\
:lf=/usr/spool/errorlog:\
:mx#0:\
:of=/usr/spool/lp0/hpjlp:\
The first field in each entry is a list of all the allowable names for the printer.
These can be used with the environment variables set by a user's shell or by the
system, as well as with options on the lpr command line with a destination
printer specified. Valid names are separated by a vertical bar.
Usually, each entry includes at least three names: a short name that is four characters
or less (such as hplj); a more complete name with an owner, if necessary
(such as laserjet-acctng); and a full, descriptive name with any other information
necessary to identify the printer (such as HP LaserJet 4M in Room 425).
-
NOTE: If a print job
is submitted without a destination name, and one can't be determined from environment
variable values, it is routed to the printer lp. Therefore, one of the printers
(usually the system default printer) should also have the name lp as part
of its identifier.
A comment in the file is shown with a pound symbol (sometimes called a hash mark)
as the first character. Following the printer name is a set of two-character parameters
and values used by the printer. The format of these entries is always one of the
following:
NN |
A Boolean value |
NN=string |
Set equal to string |
NN#number
|
Set not equal to number
|
When a Boolean value is used (no assignment follows the two-character identifier),
the value is set to True by default. If the value of False was required, the two-character
identifier would not be included in the description.
Most assignments are shown with colons beginning and ending each definition to
enhance readability and make the file easier for the print utilities to parse. Null
values are valid assignments employed by putting two colons together.
A few of the parameters in the /etc/printcap file are worth highlighting
because they are useful for administration purposes. Not all of these parameters
might be present in every printer definition in the /etc/printcap file,
but most appear:
sd |
The spool directory |
lf |
The log directory for error messages |
af |
Accounting log file |
mx |
Determines the type of files that can be printed |
of
|
Output filter program to be used when printing
|
All printers should have their own spool directories, usually under the printer
name in /usr/spool, such as /usr/spool/hplj. Spool directories
are necessary for both remote and local printers. When a new printer is added to
the system, the spool directory might have to be created manually (using mkdir).
The permissions for the spool directory should be set to 775. The directory must
be owned by root or daemon. The group ID should be set to root
or daemon, too. In both cases, daemon theoretically is the better
ID for user and group, although root will work also.
The error log file can be located anywhere on the system. It can be shared by
all printers, if desired, because each log entry includes the name of the printer.
The accounting log file is used to record printouts for systems in which users
are charged. If accounting records are not to be used on the system, ignore the entry
entirely in the /etc/printcap file. The file can also be used for generating
statistics, however. Some heavily used systems might want to have the accounting
file for those purposes even when charges are not incurred by the users. An entry
is written to the accounting log file after a print job has completed. Account information
can be displayed with the Linux pac command. (Use the man pac command
to display the man pages for more information about pac.)
The mx character enables you to identify the types of files to be printed.
Usually this is set to mx#0, meaning that there are no restrictions on the
types of files.
Output filters modify the format of the outgoing file to the printer to fit its
requirements. For example, many laser printers can't handle 66 lines per page, so
the output filter repaginates to 60 lines (or whatever the number of lines per page
is set to). Sometimes, special codes must be added to force line feeds, font changes,
or paper bin selections. All these items are part of the output filter. Several other
types of filters are available, but the output filter is the one most commonly encountered.
Within each spool directory, there may be two status files: status and
lock. Each file is one line long and can be modified with an editor. These
files contain a description of the current state of the printer. They are created
and managed by the lpd printer daemon and used by several printer commands
for status information.
Linux supports both parallel and serial printer devices. Both parallel and serial
printers are character mode devices. Unfortunately, most Linux distributions do not
have an easy-to-use printer installation and configuration utilities like many UNIX
versions. Instead, the printer devices must be created and set up manually.
Parallel printers are referred to as devices lp0, lp1, or lp2,
depending on the address of the parallel port they are used with. (The most common
is the single parallel port on a PC, which is /dev/lp0.) Valid parallel
port devices, their addresses, and their usual equivalents under MS-DOS are as shown
here:
/dev/lp0 |
0x03bc |
LPT1 |
/dev/lp1 |
0x0378 |
LPT2 |
/dev/lp2
|
0x0278
|
LPT3
|
-
NOTE: To determine the
address of a parallel port, you can use a diagnostic utility (such as DOS's MSD.EXE).
Some BIOS versions display port addresses when the system is booting. If you are
unsure, try the ports starting with /dev/lp0, and wait to see whether a
printout is possible. The first parallel port on a PC is typically set to address
0x03bc.
Linux uses the mknod (make node) command to create a parallel printer
device file. After the device has been made, the ownership of the device driver file
must be altered to root or daemon.
The following is a command to make a parallel printer device on the first parallel
port (/dev/lp0):
mknod -m 620 /dev/lp0 c 6 0
chown root.daemon /dev/lp0
In this example, the file permissions are set to mode 620, the device
/dev/lp0 is created, and it is set to be a character mode device with a
major device number of 6 and a minor device number of 0. Usually,
minor device numbers start at 0 and are incremented upward; therefore, because
this is the first printer added, the minor device number is set to 0.
-
NOTE: The ownership root.daemon
is a special Linux convention for the daemons run by root. The entry root.daemon
does not appear in the /etc/passwd file. This uses a convention that lets
the first part of the entry (before the period) indicate the user and the second
part (after the period) represent the group.
If a different device is configured, the device name itself must be changed to
the device number. For each possible parallel port, the mknod commands are
as shown here:
mknod -m 620 /dev/lp0 c 6 0
mknod -m 620 /dev/lp1 c 6 1
mknod -m 620 /dev/lp2 c 6 2
In these examples, the minor device numbers have been incremented to correspond
to the port number. This is not necessary, but it can help with identification.
After the mknod and chown commands have been issued, it is advisable
to manually check to ensure that the ownerships are set properly and that a spool
directory has been created. If the spool directory doesn't exist, you have to create
it manually. The permissions and ownership requirements of the spool directory were
given earlier, in the section "The /etc/printcap File and Spooling
Directories."
Printers are controlled through a utility called lpc. The lpc
program lets you perform several important functions pertaining to the printers used
on your Linux system:
- Display printer status information
- Enable or disable the printer
- Enable or disable the printer queue
- Remove all print requests from a printer's queue
- Promote a particular print request to the top of the queue
- Make changes to the lpd printer daemon
The lpc program can't be used for remote printers. It affects only those
directly attached and configured on the local machine.
-
WARNING: Be warned that
lpc is one of the most unpredictable and unreliable programs included with
the Linux operating system! It can hang up for no obvious reason, and it can also
display erroneous status messages. In some cases, the only way to fix a severely
screwed-up printer system is to reset the machine completely!
When used without any arguments, lpc prompts you for a command. The following
are several valid lpc commands and their arguments (a vertical bar indicates
a choice of arguments): abort printer_name | all Is similar to
the stop command, except it doesn't allow any print job that is currently
being printed to finish before stopping the printer. When used with the all
argument, all printers are stopped. Any job that is abnormally terminated by the
abort command is requeued when the printer is started again. See the stop
command for more details about the printer daemon and lock files.
clean printer_name | all Removes all print jobs that are queued,
including any active print jobs. In many cases, the currently printing job proceeds
normally because it has been passed to the printer daemon or the printer's buffer.
All other jobs are removed, though. If the all argument is used, all printers
have their print queues cleaned.
disable printer_name | all Disables the spooling of print requests
to the printer (or all printers, depending on the argument). Any jobs that are already
queued are unaffected. Any user trying to send a print job to the disabled printer
receives a message indicating that the printer is disabled, and the print job is
refused. Printers are enabled and disabled through changes in the lock file
in the spool directory.
down printer_name message Is used to take a printer completely offline,
usually for an extended period. If a message is included, it can be as long as you
want. It is placed in the status file in the spool directory and displayed
to users trying to queue to the printer. The down command is usually used
when a printer has serious problems and must be removed from the system for more
than a day.
enable printer_name | all Enables the spooling of print requests
to the printer or all printers.
exit Exits from lpc (the same as quit).
help or ? Shows a short list of all lpc commands. If
an argument is supplied, it displays a one-line description of that command (such
as help abort).
quit Exits from lpc (the same as exit).
restart printer_name | all Restarts the printer daemon, and
is usually used after it has died for an inexplicable reason (which the BSD printer
daemons tend to do). If the argument all is supplied, all printer daemons
are restarted.
start printer_name Starts the printer, allowing it to print requests.
This command starts the printer queue daemon for that printer.
status printer_name Displays the printer name, whether it has the spool
queue enabled, whether printing is enabled, the number of entries in the print queue,
and the status of the daemon for that printer. If there are no entries in the queue,
no printer daemon will be active. However, if there are entries in the queue and
the printer daemon shows as no daemon present, the daemon has died and must
be started again with the restart command.
stop printer_name Stops the printer. Print requests can still be spooled,
but they are not printed until the printer is started. If a job is being printed
when the stop command is issued, the job completes the print process and
then stops printing. The start and stop commands alter the contents
of the lock file in the print spool directories. The stop command also kills
the daemon for spooling to that printer.
topq printer_name print_ID Moves the print request with print_ID to the
top of the print queue.
topq printer_name username Moves all print requests owned by username
to the top of the queue. (This is very handy for system administrators who don't
want to wait!)
up printer_name Is used to reactivate a printer that was taken down. See
the down command for more information.
The lpc utility isn't very user-friendly, but it's the only way to handle
printers and their queues in Linux. Several front-end menu-driven utilities are beginning
to appear that simplify this task.
Several commands help you administer the printer queue specifically, instead of
relying on the lpc command. Two tasks are commonly required by a system
administrator: displaying the current queue and removing print jobs in a queue.
To display the current print queue for any printer, use the lpq command.
It has the following syntax:
lpq [-l] [-Pprinter_name] [job_ID ...] [username ...]
With no arguments at all, lpq displays information about the current
printer queues. The lpq command normally displays information about who
queued the print job, where it is in the queue, the files being printed, and the
total size of the files. The -l option displays more information about each
entry in the printer queue. Usually, only one line of information is displayed.
A specific printer can be displayed with the -P option, followed by the
printer's name. If no name is supplied, the default system printer is displayed.
If one or more job_IDs or usernames are provided, only information about the job
or jobs queued by the user is shown.
-
NOTE: Because users can't
access the Linux printer spooling directories, they can remove queued print jobs
only with the lprm command. If you are a system administrator, you might
want to let all system users know how to use this command to keep unwanted print
jobs from printing.
The lprm command is used to remove files from a printer queue. This command
is often mistyped as lpr, which doesn't remove the file from the queue.
To use lprm, you must know the print job ID; or, if you are logged in as
root, you can remove all jobs for a particular printer. The syntax of the
lprm command is as follows:
lprm [-Pprinter_name] [-] [job_ID ...] [username ...]
If the single hyphen argument is used, lprm removes all jobs owned by
the user who issues the command. If you are logged in as root, all print
jobs are removed. A particular printer's jobs can be removed by using the -P
option. For example, the command
lprm -Phplj -
removes all print jobs queued on the printer hplj by the user who issues
the command, or all print jobs for that printer if issued by root.
-
WARNING: It is easy to
accidentally remove all print jobs for a printer when you use the lprm command
as root. Take care to use the proper syntax, or you may get frustrated at
having to requeue all the jobs!
If a print job ID or a username is supplied as an argument, lprm removes
that job or all jobs submitted by the user. If no arguments are supplied at all,
the currently active job submitted by the user is deleted.
When lprm removes files from the queue, it echoes a message to the display.
If there are no files to remove, nothing is echoed (and you will be left wondering
what, if anything, happened).
If you try to use lprm on a job that is currently being printed, it might
not be terminated properly because the file might already reside in the printer's
buffer. In some cases, terminating a job that is currently printing can cause the
printer to lock, because some output format files can't handle the termination instructions
and freeze when the lock file in the spool directory changes. In cases such as this,
the ps command must be used to find the output filter process ID, and then
it must be killed.
-
NOTE: In cases of printer
lockup that don't seem to solve themselves with the lpc utility, try killing
the lpd daemon and restarting it. If that doesn't work, you will probably
have to reboot the entire system.
Most Linux systems use only the system console that came with the PC (the PC's
screen and keyboard act as the system console). You won't have to make any configuration
changes to Linux to use the system console effectively.
Some system administrators want to add remote terminals to allow other users to
work with Linux simultaneously (it is a multiuser system, after all). New terminals
can be added to the system in one of two ways: through a serial port on the back
of the PC or through a multiport card with many serial ports on it.
Multiport cards provide an easy and effective method of adding many serial ports
to your system. Multiport cards are offered by dozens of vendors in different configurations.
They provide from two to 32 additional serial ports per card (for terminals, modems,
or printers), and can use several different types of connectors (such as DB25 connectors,
DB9 connectors, or RJ11 wide telephone-style jacks).
If you are going to use a multiport card, make sure you can find one with software
device drivers that are designed to work with Linux. You can't use any multiport
card designed for other versions of UNIX (or Xenix) without modification. Because
multiport card device drivers are complex binaries, modification is beyond the scope
of most people's programming abilities.
Multiport cards come with complete instructions for installing the device drivers
for the multiport card, as well as configuring the terminals. Because the details
of the configurations change depending on the manufacturer of the multiport card,
you should consult the documentation accompanying the card for more information.
You can use the serial ports on the PC to add remote terminals. The terminal can
be a dedicated terminal or another PC running terminal emulation software. Linux
doesn't really care about the identity of the remote machine, except when it comes
to sending instructions for screen displays.
The wiring of cables between the remote terminal and the PC hosting the Linux
operating system depends on the type of connectors at both ends. In most cases, the
cable is a DTE (Data Terminal Equipment)-to-DTE type, although some terminals and
PC serial ports require DCE (Data Communications Equipment) cabling. As a general
rule, terminals and remote computers use DTE, and modems use DCE. The difference
between DTE and DCE cabling is in the way the wires run from each end connector.
A typical DCE cable (such as for a modem) uses straight-through wiring, meaning
that pin 1 on the PC end goes to pin 1 on the modem end, pin 2 goes through to pin
2, and so on. This is called a straight cable (also called a modem cable by some).
When connecting a terminal, however, some of the pins must be crossed to permit
signals to pass properly. The wiring of such a cable (often called a null modem cable
or hard-wired cable) requires several crosses or shorts to make the connection valid.
Serial port connectors on a PC are either a DB9 (9-pin) or a DB25 (25-pin) connector.
Not all of the wires in the 25-pin (or the 9-pin, for that matter) are required for
a terminal device. A complete terminal cable can be made of only three pins (send,
receive, and ground), although Linux also uses the Carrier Detect wire to tell when
a terminal is attached and active.
The important pins and their meanings for DTE (computer to terminal) 25-pin cables
are shown in Table 39.1. The cable numbers are changed for 9-pin connectors, but
the crossings are the same.
Table 39.1. DTE cables for a 25-pin connector.
Terminal Pin |
Computer Pin |
Meaning |
1 |
1 |
Ground |
2 |
3 |
Transmit data/receive data |
3 |
2 |
Receive data/transmit data |
4 |
4 |
Ready to send |
5 |
5 |
Clear to send |
6 |
20 |
Data set ready/data terminal ready |
7 |
7 |
Ground |
8 |
20 |
Carrier detect/data terminal ready |
20 |
6, 8 |
Data terminal ready/data set ready, carrier detect |
Because most users want to purchase premade cables to connect remote terminals,
we won't deal with building your own cables. Instead, simply visit your local computer
store and explain the equipment at both ends, as well as whether you have DB9 (9-pin)
or DB25 (25-pin) connectors at each end. Also note whether the connectors at each
end are male (pins sticking out) or female (no pins). Usually, the PC has male serial
port connectors (requiring a female end on the cable), and a terminal has female
connectors (requiring a male connector on the cable); but, if you're connecting a
remote PC, you need female connectors at both ends.
-
NOTE: If the wiring of
a cable isn't clearly indicated and the vendor doesn't know whether it's a straight-through
or null modem cable, you might need to purchase a null modem device. A null modem
is a short connector that has the pin crossings within it, effectively converting
a straight-through cable to a null modem cable, and vice versa.
To understand the files involved in a terminal configuration, it is useful to
look at the process that occurs whenever a login occurs.
The process begins with the /etc/init daemon executing when the Linux
system is booted. The init daemon is responsible for running the /etc/getty
program for each terminal that is connected to the system. The init daemon
knows whether a terminal is connected because of entries in two files: /etc/ttys
and /etc/inittab. The /etc/ttys file lists all ports on the system
and the type of terminal that is connected. The /etc/inittab file has a
compete list of all terminals and their parameters. We'll look at both files in more
detail later, in the section "Terminal Files: /etc/ttys and /etc/inittab."
When the /etc/ttys and /etc/inittab files indicate that a terminal
is connected and active, the init daemon runs the /etc/getty program
for that terminal. The getty program sets the communications parameters
for the terminal and displays the login prompt on the screen.
When a user logs in on the terminal, the getty process executes the login
program to request a password. The login program then validates the username and
password against the entries in the /etc/passwd file. If the login is valid,
the login program displays the message of the day (stored in the file /etc/motd)
and executes whatever shell the user is supposed to run (as specified in /etc/passwd).
Finally, login sets the TERM environment variable and exits.
When the login process terminates, the shell continues to execute and reads the
startup files; then, it generates the shell prompt and waits for the user to issue
instructions.
As you have seen, many files are involved in the startup process, all in the /etc
directory. We can look at the important files (at least for terminal characteristics)
in more detail.
The sbin/getty (/etc/getty on some systems) program
is referred to quite a lot when dealing with terminals, but people often don't clearly
understand what the program does. Quite simply, /sbin/getty is a binary
program that sets the communications parameters between Linux and a terminal, including
the speed, protocol, and any special handling of the cable.
The /sbin/getty program is called by /etc/init when a user is
logging in. When called, /sbin/getty opens the serial port or other connection
to the terminal and sets the communications parameters based on information in the
file /etc/gettydefs (getty definitions). The getty process
then generates the login prompt on the remote terminal.
Many special handling and command options are available with the getty
process, but most of them are of little interest to users and casual system administrators.
If you want complete information on the getty command, consult the man pages
that accompany Linux.
The /etc/gettydefs file is used to supply the settings getty
uses for communications. The format of each line in the gettydefs file is
as follows:
label:initial flags: final flags: login prompt: next label
The label is used to identify each line, so that when /sbin/getty is
started with an argument (as it usually is, transparent to the user), the argument
is used to match the label and provide the configuration information. The initial
and final flags are used to set any behavior for the connection before and after
the login program has executed.
The login prompt is the prompt to be displayed on the terminal. Usually it is
just login:, but it can be any string. Finally, the next label is used to
send getty to another line, in case it can't use the current one. This is
typically used with modem lines, which start at a high speed (such as 9600 baud)
and go to 4800, 2400, and 1200 in sequence, trying to connect at each step. For terminals,
the next label is usually a pointer back to the line's first label.
An extract from a sample /etc/gettydefs file looks like this:
console# B19200 OPOST ONLCR TAB3 BRKINT IGNPAR ISTRIP IXON IXANY PARENB ECHO
ECHOE ECHOK ICANON ISIG CS8 CREAD # B19200 OPOST ONLCR TAB3 BRKINT IGNPAR ISTRIP
IXON IXANY PARENB ECHO ECHOE ECHOK ICANON ISIG CS8 CREAD #Console Login: #console
9600H# B9600 # B9600 SANE IXANY PARENB TAB3 HUPCL #login: #4800H
4800H# B4800 # B4800 SANE IXANY PARENB TAB3 HUPCL #login: #2400H
2400H# B2400 # B2400 SANE IXANY PARENB TAB3 HUPCL #login: #1200H
1200H# B1200 # B1200 SANE IXANY PARENB TAB3 HUPCL #login: #300H
300H# B300 # B300 SANE IXANY PARENB TAB3 HUPCL #login: #9600H
If you look at the file that accompanies your Linux system, you see that there
are many more lines, but they all have the same format as the preceding samples.
The easiest lines to look at are the shorter ones (the last five lines in the preceding
extract), but they all have the same format as the preceding samples.
These lines are for a modem, starting at 9600 baud. The initial flag is set to
B9600, which sets the baud rate at 9600 baud. The final flags, used when
a connection has been established, set the characteristics of the line (such as a
TAB meaning three spaces). Finally, the field at the end points to the next
lower speed to provide checks for slower modems or poor lines that prevent fast logins.
The first line in the preceding extract is typical for a terminal. It sets many
initial and final flags that control how the terminal behaves. The reference at the
end of the line is back to the same definition, because the terminal is hardwired
to the system.
-
NOTE: You shouldn't have
to change the entries in the gettydefs file, because the default file contains
many different configurations. You should examine the file carefully to find an entry
that will work with the terminal you are using. If you do make changes to the gettydefs
file, you should run the command getty -c gettydefs to make the
changes effective.
Terminal configuration information is stored in the files /etc/ttys and
/etc/inittab. These files can be modified by any editor. Some menu-driven
programs are now appearing that perform changes to the files for you.
-
WARNING: Before making
any changes to the terminal configuration files, make a safe copy in case the changes
aren't effective and the file can't be returned to its original state easily. Simply
copy the two files to new names such as /etc/tty.original and /etc/inittab.original.
The /etc/ttys file has two columns. The first shows the type of terminal,
and the second shows the device name. A typical /etc/ttys file from a new
installation of Linux looks like this:
console tty1
console tty2
console tty3
console tty4
console tty5
console tty6
vt100 ttyp0
vt100 ttyp1
vt100 ttyp2
vt100 ttyp3
The terminal type in the first column is used to set the TERM environment
variable when you log in, unless you override the value.
The /etc/inittab file is used to set the behavior of each terminal. The
format of the /etc/inittab file follows this pattern:
ID:runlevel:action:process
The ID is a one- or two-character string that uniquely identifies the entry. In
most cases, this corresponds to the device name, such as 1 for tty1.
The runlevel decides the capabilities of the terminal with the various states
that the Linux operating system can be in (run levels vary from 0 to 6,
and A, B, and C). If no entry is provided, all runlevels
are supported. Multiple runlevels may be mentioned in the field.
The action section shows how to handle the process field. The action field has
several valid entries:
boot |
Runs when inittab is first read. |
bootwait |
Runs when inittab is first read. |
initdefault |
Sets initial run level. |
off |
Terminates the process if it is running. |
once |
Starts the process once. |
ondemand |
Always keeps the process running (the same as respawn). |
powerfail |
Executes when init gets a power fail signal. |
powerwait |
Executes when init gets a power fail signal. |
sysinit |
Executes before accessing the console. |
respawn |
Always keeps the process running. |
wait
|
Starts the process once.
|
The action indicates the behavior of the terminal device when the system starts and
when a getty process is terminated on it.
A simple /etc/inittab file (taken from an earlier version of Linux for
clarity's sake because the latest version complicates the lines a little) looks like
this:
# inittab for Linux
id:1:initdefault:
rc::bootwait:/etc/rc
1:1:respawn:/etc/getty 9600 tty1
2:1:respawn:/etc/getty 9600 tty2
3:1:respawn:/etc/getty 9600 tty3
4:1:respawn:/etc/getty 9600 tty4
The first two lines (after the comment) are used when the system boots. The second
line tells the system to run /etc/rc in order to boot. The rest of the lines
indicate that a getty process should be started for tty1 through
tty4 at 9600 baud.
The /etc/termcap file holds the instructions for communicating with different
terminals. Most terminals that are supported by the operating system have an entry
inside this file. The termcap (terminal capabilities) file can be quite
large. If you are going to make changes, copy a version to a safe filename first.
The contents of the termcap file are similar to the printer definition
file /etc/printcap. Each entry in the termcap file has a name with
several variations, as well as a set of codes and values for different terminal characteristics.
Because terminals use many different codes for different actions, many codes can
be used with some of the more talented terminals.
An extract from a termcap file shows the definitions for two fairly simple
terminals, the Wyse 30 and Wyse 85:
w0|wy30-vb|wyse30-vb|wyse 30 Visible bell:\
:vb=\E`8\E`\072\E`9:\
:tc=wy30:
wc|wy85|wyse85|Wyse 85 in 80 column mode, vt100 emulation:\
:is=\E[61"p\E[13l\E>\E[?1l\E[?3l\E[?7h\E[?16l\E[?5W:\
:co#80:li#24:am:cl=\E[;H\E[2J:bs:cm=\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
:ce=\E[0K:cd=\E[0J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
:ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:\
:kh=\E[H:xn:\
:im=:CO=\E[?25h:CF=\E[?25l:ic=\E[1@:dc=\E[1P:\
:dl=\E[1M:al=\E[1L:GS=\EF:GE=\EG:pt:
The meaning of each set of codes is not really of interest to most users and system
administrators. You have to start changing or rewriting terminal entries only if
you are adding a terminal type that doesn't exist in the termcap file already.
-
NOTE: Most terminals
offer multiple emulations. If you can't find the terminal type in the termcap
file, look for an emulation that is supported. It's easier to emulate a different
terminal than to write a termcap entry for a new type.
The terminal characteristics in the /etc/termcap file are used by the
/etc/ttys file. The first column of the ttys file gives the default
terminal type used to set the TERM environment variable. Essentially, the
startup routine uses a pattern-matching utility to find a matching line in the termcap
file, and then reads the codes that follow.
Terminals are added to Linux in much the same manner as printers: using the mknod
command. To add a terminal, you must decide which port the terminal will be connected
to. The serial ports on a PC are referred to by Linux as /dev/ttyS0 (for
COM1 in DOS terms), /dev/ttyS1 (for COM2), and so on.
Most PC systems have one or two serial ports, although up to four can be accommodated
(ttyS0 to ttyS3). Linux uses the serial ports based on their addresses
in the BIOS. The usual addresses for the serial ports are as listed here:
ttyS0 (COM1) |
0x03f8 |
ttyS1 (COM2) |
0x02f8 |
ttyS2 (COM3) |
0x03e8 |
ttyS3 (COM4)
|
0x02e8
|
If you're not sure which serial port is which, you might have to either use a DOS-based
diagnostic utility (such as MS-DOS's MSD.EXE) or start at the lowest address and
work up, testing the terminal each time. If the PC has only one port, it is almost
always configured as COM1.
To create a new terminal device, you must run the mknod (make node) command
to create the new device driver file, and then change the permissions on the file
to let it be run by root or daemon. Most Linux distributions include
the terminal devices already.
-
NOTE: The mknod
command was covered in detail earlier in this chapter. Check out the section "The
mknod Command."
A typical command for creating a new terminal device is
mknod -m 660 /dev/ttyS0 c 4 64
The -m 660 sets the permissions on the file. /dev/ttyS0 specifies
the first serial port on the machine (COM1). The c indicates that
the terminal is a character device (almost all terminals, except very high-speed
high-end models, are character devices). The major device number is set to 4,
while the minor device number is set to 64. For the other serial ports
on the PC (COM1 through COM4), the commands would be as shown here:
mknod -m 660 /dev/ttyS1 c 4 65
mknod -m 660 /dev/ttyS2 c 4 66
mknod -m 660 /dev/ttyS3 c 4 67
The changes in the minor device number with the preceding different commands are
not required, but there must be a unique minor device number for each terminal.
After the mknod command has been executed, the device driver must be
set to the proper ownership. Issue the command
chown root.tty /dev/ttyS0
replacing the /dev/ttyS0 with whatever device the command applies to.
The ownership is set to root.tty.
You also want to change the entry in the /etc/ttys file to include the
terminal type and device that you have added so that the startup of the terminal
can be performed properly. Because the /etc/inittab file already contains
entries for the standard serial ports, you can edit the entry for your new terminal's
port (if necessary) to set the baud rate and other parameters that may be required.
The stty command enables you to change and query a terminal option. The
stty command is very complex, with dozens of options that modify the behavior
of the terminal device driver. Luckily, only the most intense system administrators
have to use the many options, so in this chapter we will ignore most of the details.
To see the current settings of a terminal, use the stty command without
any arguments. It displays a set of parameters. You can use this to verify that the
terminal has read the configuration information properly from the /etc/inittab
and /etc/gettydefs files.
Like stty, the tset command has many options, most of which
are seldom used (especially if you are not dealing with strange terminals and weird
connectors). The tset command is used to initialize the terminal driver.
If the tset command is given with a specific argument, it uses that. Otherwise,
the value in the TERM environment variable is used.
You can use tset within the startup files of a user who always logs in
from a remote terminal (through a modem). If you put the command
tset -m dialup:vt100
in the shell startup file (.profile, .cshrc, and so on), the
terminal type will be set to vt100 every time a connection is made through
the modem. Of course, this sets the terminal type even if someone isn't using a VT100
terminal, so you can use the command
tset -m dialup:?vt100
to have the user connecting through the modem prompted for the terminal type.
The prompt looks like this:
TERM=(vt100)?
If the user presses Enter, the TERM variable is set to vt100.
If the user doesn't want to use that value, she can enter the correct string at the
prompt.
So far, tset seems to be quite simple, but in fact it has a very complex
structure when dealing with hard wired terminals. To properly configure a terminal
connected through a serial port, you need a command such as this:
eval `tset -s -Q -m dialup:?vt100 -m switch:z29`
The full details of this type of command are unimportant for most system administrators.
If you want more information, check the man pages for tset and stty
that came with your Linux system.
Every now and then a terminal connected through a serial port starts acting screwy,
either not showing a prompt or generating garbage. There are two quick ways to try
to reset the terminal. If they don't work, the terminal should be shut down and restarted.
(You might have to kill the processes that were running on the terminal.)
The first approach is to issue a set of Ctrl-J characters on the screwy terminal,
and then type stty sane followed by another Ctrl-J. The command stty
sane should reset the terminal characteristics to normal. You probably won't
see the letters you are typing, so enter them carefully.
If the terminal isn't behaving at this point, try typing reset and pressing
Enter or Ctrl-J. If this doesn't work, the terminal has hung and should be reset
manually.
The process for adding a modem is very similar to that for adding a terminal.
In most cases, the procedure outlined earlier in "Adding a Terminal" can
be followed.
Modems are used for several purposes on a Linux system, such as networking, connecting
to remote systems, and accepting incoming calls. If the modem is to act as a conduit
into the Linux system for remote terminals to connect, the procedure given in "Adding
a Terminal" is followed, except for the entries that will be selected in the
/etc/inittab file. In the case of a modem, find a set of lines that move
through the different baud rates the modem supports.
Modems that are to be used for networking through the UUCP utility are dealt with
in Chapter 43, "Networking," and Chapter 44, "UUCP." It includes
information on setting the different configuration files properly.
For modems that are used to call out of the system, Linux has a menu-driven configuration
utility as part of the setup command, which can set the proper configuration
information automatically.
This chapter has shown you the basics of devices, device management, and how to
add new devices to your Linux system. The information presented applies to most distributions
of Linux, although there might be some slight changes in options and arguments as
the different utilities are enhanced or streamlined. If you want more information
about any of the commands, refer to the man pages that came with Linux, or consult
a comprehensive system administration book.
Contact
reference@developer.com with questions or comments.
Copyright 1998
EarthWeb Inc., All rights reserved.
PLEASE READ THE ACCEPTABLE USAGE STATEMENT.
Copyright 1998 Macmillan Computer Publishing. All rights reserved.