Configuring can be divided into two parts: The low level configuring is done by assigning the port an I/O address, an IRQ number and a name (such as ttyS1). It's done by setting jumpers (or using plug-and-play methods to do the equivalent) and by the "setserial" program. That's the topic of this section.
The high level configuring uses the "stty" program (or the equivalent done by an application program). It assigns the serial port a speed (baud rate), sets up the possible translation of certain characters sent to the serial port, etc. It's covered (but not in detail) by the manual page "stty". The meaning of some of the settings used by the stty command are sometimes better explained in the "termios" manual page.
In simple cases the serial ports configure themselves without the user doing anything. Communication programs that use the serial port often do the high level configuring. If you have a valid name for a serial port such as /dev/ttyS1, then the low level configuring has already been done. It often is done automatically by a call to "setserial" which is made by a startup file which runs each time you start your computer. Major distributions of Linux provide such a file with the "setserial" command residing in it. See Boot-time Configuration.
See I/O Address & IRQ for an explanation of what these are. Each serial port must have an I/O address, and an interrupt (IRQ). There are the four serial ports corresponding to COM1 - COM4:
ttyS0 (COM1) address 0x3f8 IRQ 4
ttyS1 (COM2) address 0x2f8 IRQ 3
ttyS2 (COM3) address 0x3e8 IRQ 4
ttyS3 (COM4) address 0x2e8 IRQ 3
When Linux boots, the kernel may detect at least the first two
serial ports and display a message to that effect. Notice that by
default these devices have overlapping IRQs. Unless you use kernel
2.2 or better you cannot use all of the ports in this default
configuration, and you must reassign different IRQs. See section
Can I Use More Than Two Serial Devices? on
setting IRQs.
You don't need to read this section, unless you want to use three or more serial devices... (assuming you don't have a multiport board).
The number of serial ports you can use may be limited by the number of port I/O addresses available (and prior to kernel 2.2 by the availability of IRQs). These limits are not a Linux limitation, but a limitation of the PC architecture. Each serial device must be assigned it's unique I/O address range (and prior to kernel 2.2 its unique IRQ). Unless you are using a multiport board designed for interrupt sharing or using a kernel version 2.2 or better, Linux is not designed to share interrupts. If you try to share an interrupt when you shouldn't it may work out OK provided the two devices are not operating at the same time. Otherwise, one device may work OK but the other one will not and the program using it will hang (or be very slow).
Multiport serial boards (at least the "intelligent" ones) are specially designed to have multiple serial ports that share the same IRQ for all serial ports on the board. This is one of the reasons why they need special drivers (some of which are built into Linux). Linux gets data from them by using a different I/O address for each port on the board.
Even if your kernel version is 2.2 or greater, you may want to set
up IRQs to avoid conflicts with other devices, or get slightly greater
efficiency by avoiding the sharing of IRQs. Your PC may normally come
with ttyS0
and ttyS2
at IRQ 4, and ttyS1
and ttyS3
at IRQ 3. You can see what the driver thinks the assigned IRQs are by
typing: setserial -g /dev/ttyS*. These are not necessarily the same
as set in the hardware.
Looking at /proc/interrupts
will show which IRQs are being
used by programs currently running. To use more than two serial
devices, you will have to reassign an interrupt. One choice is to
reassign an interrupt from your parallel port (provided it's not
already taken by a sound card). Your PC normally comes with IRQ 5 and
IRQ 7 set up as interrupts for your parallel ports, but few people use
two parallel ports. You can reassign one of the interrupts to a
serial device, and still happily use a parallel port. You will need
the setserial
program to do this. In addition, you may have to
set the jumpers on your boards, or use plug-and-play methods.
You should set things up so that there is one, and only one
interrupt for each serial device unless you have kernel 2.2 or later.
Here is how Greg set his up in /etc/rc.d/rc.serial
- you
should do it in a file which runs upon startup:
/sbin/setserial /dev/ttyS0 irq 3 # my serial mouse
/sbin/setserial /dev/ttyS1 irq 4 # my Wyse dumb terminal
/sbin/setserial /dev/ttyS2 irq 5 # my Zoom modem
/sbin/setserial /dev/ttyS3 irq 9 # my USR modem
Standard IRQ assignments:
IRQ 0 Timer channel 0 (May mean "no interrupt". See below.) IRQ 1 Keyboard IRQ 2 Cascade for controller 2 IRQ 3 Serial port 2 IRQ 4 Serial port 1 IRQ 5 Parallel port 2, Sound card IRQ 6 Floppy diskette IRQ 7 Parallel port 1 IRQ 8 Real-time clock IRQ 9 Redirected to IRQ2 IRQ 10 not assigned IRQ 11 not assigned IRQ 12 not assigned IRQ 13 Math coprocessor IRQ 14 Hard disk controller 1 IRQ 15 Hard disk controller 2
IRQ 0 is special for the serial port. It tells the driver that there is no interrupt for it and the driver then will use polling methods. This is quite inefficient but can be tried if there is an interrupt conflict or mis-set interrupt. The advantage of assigning this is that you don't need to know what interrupt is set in the hardware. It should be used only as a temporary expedient until you are able to find a real interrupt to use.
There is really no Right Thing to do when choosing interrupts. Just make sure it isn't being used by the motherboard, or any other boards. 2, 3, 4, 5, or 7 is a good choice. ``not assigned'' means that currently nothing standard uses these IRQs. Also note that IRQ 2 is the same as IRQ 9. You can call it either 2 or 9, the serial driver is very understanding. If you have a serial board with a 16-bit bus connector, you can also use IRQ 10, 11, 12 or 15.
Just make sure you don't use IRQs 1, 6, 8, 13 or 14! These are
used by your mother board. You will make her very unhappy by taking
her IRQs. When you are done, double-check /proc/interrupts
when programs that use interrupts are being run and make sure there
are no conflicts.
Next, you must set the port address. Check the manual on your board for the jumper settings or use plug-and-play methods (See Plug-and-Play-HOWTO). There can only be one serial device at each address. Your ports will usually come configured as follows:
ttyS0 address 0x3f8
ttyS1 address 0x2f8
ttyS2 address 0x3e8
ttyS3 address 0x2e8
Choose which address you want each serial device to have and set the
jumpers (or use plug-and-play) accordingly. Greg had his modem on
ttyS2
, his mouse and printer on ttyS1
, and his
text-terminal on ttyS0
.
Now you need to edit the "setserial" command which is run each time you start linux. If it uses the autoconfig option then it will show the type of uart found. If it reports "unknown" there may be no uart there. When you reboot, Linux should display the IRQ and IO addresses the serial that driver the serial driver thinks is correct (It may be wrong).
If you look at the boot-time messages on the screen, the IRQ Linux
first reports may not correspond to the IRQ you gave to setserial. In
this case wait and see if you see the same message later with the
correct IRQ. The first message is when running setserial was
initiated by the kernel and not by the setserial command in a file.
Linux does not normally do any IRQ detection when it boots, because
IRQ detection is dicey and can be fooled. You can check
/proc/ioports
to see what I/O port addresses are in use by
currently running processes after Linux boots.
Yes. If it's not already set up like this (or close to it) you may set Linux up to detect and set up the serial devices automatically on startup. If needed add the line:
/sbin/setserial /dev/ttyS3 auto_irq skip_test autoconfig
to your /etc/rc.d/rc.serial
or
/etc/rc.boot/0setserial
file. Do this for every serial port
you want to auto configure. Be sure to give a device name that really
does exist on your machine.
For board addresses, and IRQs, look at the rc.serial
or /etc/rc.boot/0setserial
that comes with the setserial
program. It has a lot of detail on multiport boards, including I/O
addresses and device names.
On some installations, two extra devices will be created,
/dev/modem
for your modem and /dev/mouse
for your
mouse. Both of these are symbolic links to the appropriate
device in /dev
which you specified during the
installation (unless you have a bus mouse, then /dev/mouse
will point to the bus mouse device).
There has been some discussion on the merits of
/dev/mouse
and /dev/modem
. I discourage the use of
these links. In particular, if you are planning on using your modem
for dialin you may run into problems because the lock files may not
work correctly if you use /dev/modem
. Use them if you like,
but be sure they point to the right device. However, if you
change or remove this link, some applications (minicom
for
example) might need reconfiguration.
Each ttyS device has a corresponding cua device. It is planned to abolish cua so it's best to use ttyS instead (unless you know cua is required). There is a difference between cua and ttyS but a savvy programmer can make a ttyS port behave just like a cua port so there is no real need for the cua anymore. Except that some older programs may need to use the cua.
What's the difference? The main difference between cua and ttyS has to do with what happens in a C_program when an ordinary "open" command tries to open the port. If a cua port has been set to check modem control signals, the port can be opened even if the DCD modem control signal says not to. Astute programming can force a ttyS port to behave this way also. Thus a cua port can be easily opened for dialing out on a modem even when the modem fails to assert DCD (since no one has called into it and it's not connected). That's why cua was once used for dial-out and ttyS used for dial-in.
/dev/ttyS0 major 4, minor 64 /dev/cua0 major 5, minor 64
/dev/ttyS1 major 4, minor 65 /dev/cua1 major 5, minor 65
/dev/ttyS2 major 4, minor 66 /dev/cua2 major 5, minor 66
/dev/ttyS3 major 4, minor 67 /dev/cua3 major 5, minor 67
Note that all distributions should come with ttyS devices already made
correctly (and possibly with cua devices also). You can verify this by
typing:
linux% ls -l /dev/cua*
linux% ls -l /dev/ttyS*
If you don't have a device, you will have to create it with the
mknod
command. Example, suppose you needed to create devices
for ttyS0
:
linux# mknod -m 666 /dev/ttyS0 c 4 64
linux# mknod -m 666 /dev/cua0 c 5 64
You can use the MAKEDEV
script, which lives in /dev
.
This simplifies the making of devices. For example, if you needed
to make the devices for ttyS0
you would type:
linux# cd /dev
linux# ./MAKEDEV ttyS0
This should also set the correct permissions.
The devices your multiport board uses depends on what kind of board
you have. Some of these may be listed in detail in rc.serial
or in 0setserial
. These files may be in the
setserial
package. I highly recommend getting the latest
version of setserial
if you are trying to use multiport boards.
You will probably need to create these devices. Either use the
mknod
command, or the MAKEDEV
script. Devices for multiport
boards are made by adding ``64 + port number''. So, if you wanted to
create devices for ttyS17
, you would type:
linux# mknod -m 666 /dev/cua17 c 5 81
linux# mknod -m 666 /dev/ttyS17 c 4 81
Note that ``64 + 17 = 81''. Using the MAKEDEV
script, you would
type:
linux# cd /dev
linux# ./MAKEDEV ttyS17
Note: the SIIG manual for the IO1812 listing for COM5-COM8 is wrong. They should be COM5=0x250, COM6=0x258, COM7=0x260, and COM8=0x268.
Note: the Digi PC/8 Interrupt Status Register is at 0x140.
Note: for an AST Fourport, you might need to specify skip_test
in rc.serial
.
Read the information that comes with the driver. These boards use special devices, and not the standard ones. This information varies depending on your hardware.