This part is in 3 HOWTOs: Modem, Serial, and Text-Terminal. There
are some minor differences, depending on which HOWTO it appears in.
Introduction
Don't ever use setserial with Laptops (PCMCIA).
setserial is a program which allows you to tell the device driver
software the I/O address of the serial port, which interrupt (IRQ) is
set in the port's hardware, what type of UART you have, etc. It can
also show how the driver is currently set. In addition, it can be
made to probe the hardware and try to determine the UART type and IRQ,
but this has severe limitations. See
Probing. Note that it can't set the IRQ or the port address
in the hardware of PnP serial ports.
If you only have one or two built-in serial ports, they will usually
get set up correctly without using setserial. Otherwise (or if there
are problems with the serial port) you will likely need to deal with
setserial. Besides the man page for setserial, check out info in
/usr/doc/setserial.../ or /usr/share/doc/setserial.
It should tell you how setserial is handled in your distribution of
Linux.
Setserial is often run automatically at boot-time by a start-up
shell-script for the purpose of assigning IRQs, etc. to the driver.
Setserial will only work if the serial module is loaded (or if the
equivalent was compiled into your kernel). If you should (for some
reason) unload the serial module later on, the changes previously made
by setserial will be forgotten by the kernel. So setserial
must be run again to reestablish them. In addition to running via a
start-up script, something akin to setserial also runs earlier
when the serial module is loaded (or the like). Thus when you watch
the start-up messages on the screen it may look like it ran twice, and
in fact it has.
Setserial can set the time that the port will keep operating after
it's closed (in order to output any characters still in its buffer in
main RAM). This is needed at slow baud rates of 1200 or lower. It's
also needed at higher speeds if there are a lot of "flow control"
waits. See "closing_wait" in the man pg.
Setserial does not set either IRQ's nor I/O addresses in the serial
port hardware itself. That is done either by jumpers or by
plug-and-play. You must tell setserial the identical values that have
been set in the hardware. Do not just invent some values that you
think would be nice to use and then tell them to setserial. However,
if you know the I/O address but don't know the IRQ you may command
setserial to attempt to determine the IRQ.
You can see a list of possible commands by just typing setserial
with no arguments. This fails to show you the one-letter options such
as -v for verbose which you should normally use when troubleshooting.
Note that setserial calls an IO address a "port". If you type:
setserial -g /dev/ttyS*
you'll see some info about how that device driver is configured for
your ports. Note that where it says "UART: unknown" it
probably means that no uart exists. In other words you probably have
no such serial port and the other info shown about the port is
meaningless and should be ignored. If you really do have such a
serial port, setserial doesn't recognize it and that needs to be
fixed.
If you add -a to the option -g you will see more info although few
people need to deal with (or understand) this additional info since
the default settings you see usually work fine. In normal cases the
hardware is set up the same way as "setserial" reports, but if you are
having problems there is a good chance that "setserial" has it wrong.
In fact, you can run "setserial" and assign a purely fictitious I/O
port address, any IRQ, and whatever uart type you would like to have.
Then the next time you type "setserial ..." it will display these
bogus values without complaint. Of course the serial port driver will
not work correctly (if at all) if you attempt to use such a port.
Thus when giving parameters to "setserial" anything goes. It gives
you no warning if what you tell it is incorrect and will allow you to
create conflicts in IRQs and I/O port addresses that will have
disastrous results later on.
While assignments made by setserial are lost when the PC is powered
off, a configuration file may restore them (or a previous
configuration) when the PC is started up again. In newer versions,
what you change by setserial gets automatically saved to a
configuration file. In older versions, the configuration file only
changes if you edit it manually so the configuration remains the same
from boot to boot. See
Configuration Scripts/Files
Probing
With appropriate options, setserial can probe (at a given I/O
address) for a serial port but you must guess the I/O address. If you
ask it to probe for /dev/ttyS2 for example, it will only probe at the
address it thinks ttyS2 is at (2F8). If you tell setserial that ttyS2
is at a different address, then it will probe at that address, etc.
See
Probing
The purpose of this is to see if there is a uart there, and if so,
what its IRQ is. Use "setserial" mainly as a last resort as there are
faster ways to attempt it such as wvdialconf to detect modems, looking
at very early boot-time messages, or using pnpdump
--dumpregs. To try to detect the physical hardware use the -v
(verbose) and autoconfig command to setserial. If the
resulting message shows a uart type such as 16550A, then you're OK.
If instead it shows "unknown" for the uart type, then there is
supposedly no serial port at all at that I/O address. Some cheap
serial ports don't identify themselves correctly so if you see
"unknown" you still might have a serial port there.
Besides auto-probing for a uart type, setserial can auto-probe for
IRQ's but this doesn't always work right either. In versions of
setserial >= 2.15, the results of your last probe test may be saved
and put into the configuration file /etc/serial.conf which
will be used next time you start Linux. At boot-time when the serial
module loads (or the like), a probe for UARTs is made automatically
and reported on the screen. But the IRQs shown may be wrong. The
second report of the same is the result of a script which usually does
no probing and thus provides no reliable information as to how the
hardware is actually set. It only shows configuration date someone
wrote into the script or data that got saved in /etc/serial.conf.
It may be that two serial ports both have the same IO address set in
the hardware. Of course this is not permitted but it sometimes
happens anyway. Probing detects one serial port when actually there
are two. However if they have different IRQs, then the probe for IRQs
may show IRQ = 0. For me it only did this if I first used
setserial to give the IRQ a ficticious value.
Boot-time Configuration
When the kernel loads the serial module (or if the "module
equivalent" is built into the kernel) then only ttyS{0-3} are
auto-detected and the driver is set to use only IRQs 4 and 3
(regardless of what IRQs are actually set in the hardware). You see
this as a boot-time message just like as if setserial had been
run. If you use 3 or more ports, this may result in IRQ conflicts.
To fix such conflicts by telling setserial the true IRQs (or for other
reasons) there may be a file somewhere that runs setserial again.
This happens early at boot-time before any process uses the serial
port. In fact, your distribution may have set things up so that the
setserial program runs automatically from a start-up script at
boot-time. More info about how to handle this situation for your
particular distribution might be found in file named "setserial..."
or the like located in directory /usr/doc/ or /usr/share/doc/.
Configuration Scripts/Files
Your objective is to modify (or create) a script file in the /etc
tree that runs setserial at boot-time. Most distributions provide
such a file (but it may not initially reside in the /etc tree). In
addition, setserial 2.15 and higher often have an /etc/serial.conf
file that is used by the above script so that you don't need to
directly edit the script that runs setserial. In addition just using
setserial on the command line (2.15+) may ultimately alter this
configuration file.
So prior to version 2.15 all you do is edit a script. After 2.15 you
may need to either do one of three things: 1. edit a script. 2. edit
/etc/serial.conf or 3. run "setserial" on the command line
which will result in /etc/serial.conf automatically being
edited. Which one of these you need to do depends on both your
particular distribution, and how you have set it up.
Edit a script (after version 2.15: perhaps not)
Prior to setserial 2.15 (1999) there was no /etc/serial.conf file
to configure setserial. Thus you need to find the file that runs
"setserial" at boot time and edit it. If it doesn't exist, you need
to create one (or place the commands in a file that runs early at
boot-time). If such a file is currently being used it's likely
somewhere in the /etc directory-tree. But Redhat <6.0 has supplied it
in /usr/doc/setserial/ but you need to move it to the /etc tree before
using it. You might use "locate" to try to find such a file. For
example, you could type: locate "*serial*".
The script /etc/rc.d/rc.serial was commonly used in the past.
The Debian distribution used /etc/rc.boot/0setserial.
Another file once used was /etc/rc.d/rc.local but it's
not a good idea to use this since it may not be run early enough.
It's been reported that other processes may try to open the serial
port before rc.local runs resulting in serial communication failure.
If such a file is supplied, it should contain a number of
commented-out examples. By uncommenting some of these and/or
modifying them, you should be able to set things up correctly. Make
sure that you are using a valid path for setserial, and a valid
device name. You could do a test by executing this file manually
(just type its name as the super-user) to see if it works right.
Testing like this is a lot faster than doing repeated reboots to get
it right. Of course you can also test a single setserial command
by just typing it on the command line.
If you want setserial to automatically determine the uart and the IRQ
for ttyS3 you would add something like:
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. In some
cases this will not work right due to the hardware so if you know what
the uart and irq actually are, may want to assign them explicitly with
"setserial". For example:
For versions >= 2.15 (provided your distribution implemented the
change, Redhat didn't) it may be more tricky to do since the file that
runs setserial on startup, /etc/init.d/setserial or the like was not
intended to be edited by the user. See
New configuration method using /etc/serial.conf.
New configuration method using /etc/serial.conf
Prior to setserial version 2.15, the way to configure setserial
was to manually edit the shell-script that ran setserial at boot-time.
See
Edit a script (after version 2.15: perhaps not). Starting with version 2.15 (1999) of setserial
this shell-script is not edited but instead gets its data from a
configuration file: /etc/serial.conf. Furthermore you may
not even need to edit serial.conf because using the "setserial"
command on the command line may automatically cause serial.conf to be
edited appropriately.
This was intended to make it so that you don't need to edit any file
in order to set up (or change) setserial so it will do the right thing
each time that Linux is booted. But there are serious pitfalls
because it's not really "setserial" that edits serial.conf. Confusion
is compounded because different distributions handle this differently.
In addition, you may modify it so it works differently.
What often happens is this: When you shut down your PC the script
that runs "setserial" at boot-time is run again, but this time it only
does what the part for the "stop" case says to do: It uses
"setserial" to find out what the current state of "setserial" is and
puts that info into the serial.conf file. Thus when you run
"setserial" to change the serial.conf file, it doesn't get changed
immediately but only when and if you shut down normally.
Now you can perhaps guess what problems might occur. Suppose you
don't shut down normally (someone turns the power off, etc.) and the
changes don't get saved. Suppose you experiment with "setserial" and
forget to run it a final time to restore the original state (or make a
mistake in restoring the original state). Then your "experimental"
settings are saved.
If you manually edit serial.conf, then your editing is destroyed when
you shut down because it gets changed back to the state of setserial
at shutdown. There is a way to disable the changing of serial.conf at
shutdown and that is to remove "###AUTOSAVE###" or the like from first
line of serial.conf. In at least one distribution, the removal of
"###AUTOSAVE###" from the first line is automatically done after the
first time you shutdown just after installation. The serial.conf file
will hopefully contain some comments to help you out.
The file most commonly used to run setserial at boot-time (in
conformance with the configuration file) is now /etc/init.d/setserial
(Debian) or /etc/init.d/serial (Redhat), or etc., but it should not
normally be edited. For 2.15 Redhat 6.0 just had a file
/usr/doc/setserial-2.15/rc.serial which you have to move to
/etc/init.d/ if you want setserial to run at boot-time.
To disable a port, use setserial to set it to
"uart none". The format of /etc/serial.conf appears to be just like
that of the parameters placed after "setserial" on the command line
with one line for each port. If you don't use autosave, you may edit
/etc/serial.conf manually.
BUG: As of July 1999 there is a bug/problem since with ###AUTOSAVE###
only the setserial parameters displayed by "setserial -Gg /dev/ttyS*"
get saved but the other parameters don't get saved. Use the -a flag
to "setserial" to see all parameters. This will only affect a small
minority of users since the defaults for the parameters not saved are
usually OK for most situations. It's been reported as a bug and may
be fixed by now.
In order to force the current settings set by setserial to be saved to
the configuration file (serial.conf) without shutting down, do what
normally happens when you shutdown: Run the shell-script
/etc/init.d/{set}serial stop. The "stop" command will save
the current configuration but the serial ports still keep working OK.
In some cases you may wind up with both the old and new configuration
methods installed but hopefully only one of them runs at boot-time.
Debian labeled obsolete files with "...pre-2.15".
IRQs
By default, both ttyS0 and ttyS2 will share IRQ 4, while ttyS1 and
ttyS3 share IRQ 3. But actually sharing serial interrupts (using them
in running programs) is not permitted unless you: 1. have kernel 2.2
or better, and 2. you've complied in support for this, and 3. your
serial hardware supports it. See
Interrupt sharing and Kernels 2.2+
If you only have two serial ports, ttyS0 and ttyS1, you're still OK
since IRQ sharing conflicts don't exist for non-existent devices.
If you add an internal modem and retain ttyS0 and ttyS1,
then you should attempt to find an unused IRQ and set it both on your
serial port (or modem card) and then use setserial to assign it to
your device driver. If IRQ 5 is not being used for a sound card, this
may be one you can use for a modem. To set the IRQ in hardware you
may need to use isapnp, a PnP BIOS, or patch Linux to make it PnP. To
help you determine which spare IRQ's you might have, type "man
setserial" and search for say: "IRQ 11".
isapnp is a program to configure Plug-and-Play (PnP) devices
on the ISA bus including internal modems. It comes in a package
called "isapnptools" and includes another program, "pnpdump" which
finds all your ISA PnP devices and shows you options for configuring
them in a format which may be added to the PnP configuration file:
/etc/isapnp.conf. It may also be used with the --dumpregs option to
show the current IO address and IRQ of the modem's serial port. The
isapnp command may be put into a startup file so that it runs each
time you start the computer and thus will configure ISA PnP devices.
It is able to do this even if your BIOS doesn't support PnP. See
Plug-and-Play-HOWTO.
wvdialconf will try to find which serial port (ttyS?) has a
modem on it. It also creates a configuration program for the wvdial
program. wvdial is used for simplified dialing out using the PPP
protocol to an ISP. But you don't need to install PPP in order to use
wvdialconf. It will only find modems which are not in use. It
will also automatically devise a "suitable" init strings but sometimes
gets it wrong. Since this command has no options, it's simple to use
but you must give it the name of a file to put the init string (and
other data) into. For example type: wvdialconf my_config_file_name.
stty is like setserial but it sets the baud rate and other
parameters of a serial port. Typing "stty -a < /dev/ttyS2" should show
you how ttyS2 is configured. Most of the settings are for things that
you never need to use with modems (such as some used only for old
terminals of the 1970s). Your communication package should
automatically set up all the setting correctly for modems. But stty
is sometimes useful for trouble-shooting.
Two items set by stty are: 1. Hardware flow control by "crtscts" and
2. Ignore the DCD signal from the modem: "clocal". If the modem is
not sending a DCD signal and clocal is disabled (stty shows -clocal)
then a program may not be able to open the serial port. If the port
can't open, the program may just hang, waiting (often in vain) for a DCD
signal from the modem.
Minicom sets clocal automatically when it starts up so there is no
problem. But version 6.0.192 of Kermit hung when I set -clocal and
tried to "set line ..." If -clocal is set and there is no DCD signal
then even the "stty" command will hang and there is seemingly no way
to set clocal (except by running minicom). But minicom will restore
-clocal when it exits. One way to get out of this is to use minicom
to send the "AT&C" to the modem (to get the DCD signal) and then
exit minicom with no reset so that the DCD signal remains on. Then
you may use stty again.