Next Previous Contents

6. Configuring the Serial Port

6.1 PCI Bus Support Underway

The kernel 2.2 serial driver contains no special support for the PCI bus. But kernels 2.3 and 2.4 will eventually support some PCI serial cards (and modem cards). Many PCI cards need special support in the driver. The driver will read the id number digitally stored on the card to determine how (or if) to support the card. If you have a PCI card which you are convinced is not a winmodem but it will not work, you can help in attempting to create a driver for it. To do this you'll need to contact the maintainer of the serial driver, Theodore (Ted) Y. Ts'o. But first check out the modem list site http://www.o2.net/~gromitkc/winmodem.html for the latest info on PCI modems and related topic.

You will need to email Ted Ts'o a copy of the output of "lspci -vv" with full information about the model and manufacturer of the PCI modem (or serial port). Then he will try to point you to a test driver which might work for it. You will then need to get it, compile it and possibly recompile your kernel. Then you will test the driver to see if it works OK for you and report the results to Ted Ts'o. If you are willing to do all the above (and this is the latest version of this HOWTO) then email the needed info to him at: mailto:tytso@mit.edu.

PCI modems are not well standardized. Some use main memory for communication with the PC. It you see 8-digit hexadecimal addresses it's not likely to work with Linux. Some require special enabling of the IRQ. The output of "lspci" can help determine if one can be supported. If you see a 4-digit IO port and no long memory address, the modem might work by just telling "setserial" the IO port and the IRQ. Some people have gotten a 3COM 3CP5610 PCI Modem to work that way.

6.2 Configuring Overview

In many cases, configuring will happen automatically and you have nothing to do. But sometimes you need to configure (or just want to check out the configuration). If so, first you need to know about the two parts to configuring the serial port under Linux:

The first part (low-level configuring) is assigning it an IO address, IRQ, and name (such as ttyS2). This IO-IRQ pair must be set in both the hardware and told to the serial driver. We might just call this "io-irq" configuring for short. The setserial is used to tell the driver. PnP methods, jumpers, etc, are used to set the hardware. Details will be supplied later. If you need to configure but don't understand certain details it's easy to get into trouble.

The second part (high-level configuring) is assigning it a speed (such as 38.4k bits/sec), selecting flow control, etc. This is often done by communication programs such as PPP, minicom, or by getty (which you may run on the port so that others may log into your computer). However you will need to tell these programs what speed you want, etc. by using a menu or a configuration file. This high-level configuring may also be done with the stty program. stty is also useful to view the current status if you're having problems. See also the section Stty When Linux starts, some effort is made to detect and configure (low-level) a few serial ports. Exactly what happens depends on your BIOS, hardware, Linux distribution, etc. If the serial ports work OK, there may be no need for you to do any configuring. Application programs often do the high-level configuring but you may need to supply them with the required information. With Plug-and-Play serial ports (often built into an internal modem), the situation has become more complex. Here are cases when you need to do low-level configuring (set IRQ and IO addresses):

For kernel 2.2+ you may be able to use more that 2 serial ports without low-level configuring by sharing interrupts. This only works if the serial hardware supports it and may be no easier than low-level configuring. See Interrupt sharing and Kernels 2.2+

The low-level configuring (setting the IRQ and IO address) seems to cause people more trouble (than high-level), although for many it's fully automatic and there is no configuring to be done. Thus most all of this section is on that topic. Until the serial driver knows the correct IRQ and IO address the port will not work at all. It may not even be found by Linux. Even if it can be found, it may work extremely slow if the IRQ is wrong. See Extremely Slow: Text appears on the screen slowly after long delays.

In the Wintel world, the IO address and IRQ are called "resources" and we are thus configuring certain resources. But there are many other types of "resources" so the term has many other meanings. In review, the low-level configuring consists of putting two values (an IRQ number and IO address) into two places:

  1. the device driver (often by running "setserial" at boot-time)
  2. memory registers of the serial port hardware itself

You may watch the start-up (= boot-time) messages. They are usually correct. But if you're having problems, there's a good chance that some of these messages don't show the true configuration of the hardware (and they are not supposed to). See I/O Address & IRQ: Boot-time messages.

6.3 Common mistakes made re low-level configuring

Here are some common mistakes people make:

6.4 I/O Address & IRQ: Boot-time messages

In many cases your ports will automatically get low-level configured at boot-time (but not always correctly). To see what is happening, look at the start-up messages on the screen. Don't neglect to check the messages from the BIOS before Linux is loaded (no examples shown here). These BIOS messages may be frozen by pressing the Pause key. Use Shift-PageUp to go back to all the messages after they have flash by. Shift-PageDown will scroll in the opposite direction. The dmesg command may be used at any time to view some of the messages but it often misses important ones. Here's an example of the start-up messages (as of mid 1999). Note that ttyS00 is the same as /dev/ttyS0.

At first you see what was detected (but the irq is only a wild guess):

Serial driver version 4.27 with no serial options enabled
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS01 at 0x02f8 (irq = 3) is a 16550A
ttyS02 at 0x03e8 (irq = 4) is a 16550A

Later you see what was saved, but it's not necessarily correct either:

Loading the saved-state of the serial devices...
/dev/ttyS0 at 0x03f8 (irq = 4) is a 16550A
/dev/ttyS1 at 0x02f8 (irq = 3) is a 16550A
/dev/ttyS2 at 0x03e8 (irq = 5) is a 16550A

Note that there is a slight disagreement: The first message shows ttyS2 at irq=4 while the second shows it at irq=5. Your may only have the first message. In most cases the last message is the correct one. But if your having trouble it may be misleading. Before reading the explanation of all of this complexity in the rest of this section, you might just try using your serial port and see if it works OK. If so it may not be essential to read further.

The second message is from the setserial program being run at boot-time. It shows what the device driver thinks is the correct configuration. But this too could be wrong. For example, the irq could actually be set to irq=8 in the hardware (both messages wrong). The irq=5 could be there because someone incorrectly put this into a configuration file (or the like). The fact that Linux sometimes gets IRQs wrong is because it doesn't probe for IRQs. It just assumes the "standard" ones (first message) or accepts what you told it when you configured it (second message). Neither of these is necessarily correct. If the serial driver has the wrong IRQ the serial port is very slow or doesn't seem to work at all.

The first message is a result of Linux probing the serial ports but it doesn't probe for IRQs. If a port shows up here it exists but the IRQ may be wrong. Linux doesn't check IRQs because doing so is not foolproof. It just assumes the IRQs are as shown because they are the "standard" values. Your may check them manually with setserial using the autoconfig and auto_irq options but this isn't guaranteed to be correct.

The data shown by the BIOS messages (which you see at first) is what is set in the hardware. If your serial port is Plug-and-Play PnP then it's possible that the isapnp will run and change these settings. Look for messages about this after Linux starts. The last serial port message shown in the example above should agree with the BIOS messages (as possibly modified by isapnp). If they don't agree then you either need to change the setting in the port hardware or use setserial to tell the driver what is actually set in the hardware.

Also, if you have Plug-and-Play (PnP) serial ports, Linux will not find them unless the IRQ and IO has been set inside the hardware by Plug-and-Play software. This is a common reason why the start-up messages do not show a serial port that physically exists. The PC hardware (a PnP BIOS) may automatically low-level configure this. PnP configuring will be explained later.

6.5 What is the current IO address and IRQ of my Serial Port ?

The previous section indicated how to attempt to do this by looking at the start-up messages. If they give you sufficient info then you may not need to read this section. If they don't then there are some other ways to look into this.

There are really two answers to the question "What is my IO and IRQ?" 1. What the device driver thinks has been set (This is what setserial usually sets and shows). 2. What is actually set in the hardware. They both should be the same. If they're not it spells trouble since the driver has incorrect info on the physical serial port. If the driver has the wrong IO address it will try to send data to a non-existing serial port --or even worse, to an actual device that is not a serial port. If it has the wrong IRQ the driver will not get interrupt service requests from the serial port, resulting in a very slow or no response. See Extremely Slow: Text appears on the screen slowly after long delays. If it has the wrong model of UART there is also apt to be trouble. To determine if both I0-IRQ pairs are identical you must find out how they are set in both the driver and the hardware.

What does the device driver think?

This is easy to find out. Just look at the start-up messages or type "setserial -g /dev/ttyS*". If everything works OK then what it tells you is likely also set in the hardware. There are some other ways to find this info by looking at "files" in the /proc directory. An important reason for understanding these other ways is to warn you that they only show what the device driver thinks. Some people view certain "files" in the /proc directory and erroneously think that what they see is set in the hardware but "it ain't necessarily so".

/proc/ioports will show the IO addresses that the drivers are using. /proc/interrupts shows the IRQs that are used by drivers of currently running processes (that have devices open). Note that in both cases above you are only seeing what the driver thinks and not necessarily what is actually set in the hardware. /proc/interrupts also shows how many interrupts have been issued (often thousands) for each device. You can get a clue from this because if you see a large number of interrupts that have been issued it means that there is a piece of hardware somewhere that is using that interrupt. Sometimes a showing of just a few interrupts doesn't mean that that interrupt is actually being physically generated by any serial port. Thus if you see almost no interrupts for a port that you're trying to use, that interrupt might not be set in the hardware and it implies that the driver is using the wrong interrupt. To view /proc/interrupts to check on a program that you're currently running (such as "minicom") you need to keep the program running while you view it. To do this, try to jump to a shell without exiting the program.

What is set in my serial port hardware ?

How do you find out what IO address and IRQ are actually set in the device hardware? Perhaps the BIOS messages will tell you some info before Linux starts booting. Use the shift-PageUp key to step back thru the boot-time messages and look at the very first ones which are from the BIOS. This is how it was before Linux started. Setserial can't change it but isapnp or pciutils can.

One crude method is try probing with setserial using the "autoconfig" option. You'll need to guess the addresses to probe at. See What is Setserial. For a PCI serial port, use the "lspci" command (for kernels <2.2 look at /proc/pci). If your serial port is is Plug-and-Play see the next two subsections.

For a port set with jumpers, its how the jumpers were set. If the port is not Plug-and-Play (PnP) but has been setup by using a DOS program then it's set at whatever the person who ran that program set it to.

What is set in my PnP serial port hardware ?

PnP ports don't store their configuration in the hardware when the power is turned off. This is in contrast to Jumpers (non-PnP) which remain the same with the power off. If you have an ISA PnP port, it can reach a state where it doesn't have any IO address or IRQ and is in effect disabled. It should still be possible to find the port using the pnpdump program.

For Plug-and-Play (PnP) on the ISA bus one may try the pnpdump program (part of isapnptools). If you use the --dumpregs option then it should tell you the actual IO address and IRQ set in the port. The address it "trys" is not the device's IO address, but a special

For PnP ports checking on how it's configured under DOS/Windows may not be of much help. Windows stores its configuration info in its Registry which is not used by Linux. It may supply the BIOS's non-volatile memory with some info but it may not be kept in sync with the current Window configuration in the Registry ?? If you let a PnP BIOS automatically do the configuring when you start Linux (and have told the BIOS that you don't have a PnP operating system when running Linux) then Linux should use whatever configuration is in the BIOS's non-volatile memory.

6.6 Choosing Serial IRQs

If you have a true Plug-and-Play set up where either the OS or a PnP BIOS configures all your devices, then you don't choose your IRQs. PnP determines what it thinks is best and assigns them. But if you use the tools in Linux for Plug-and-Play (isapnp and pcitools) then you have to choose. If you already know what IRQ you want to use you could skip this section except that you may want to know that IRQ 0 has a special use (see the following paragraph).

IRQ 0 is not an IRQ

While IRQ 0 is actually the timer (in hardware) it has a special meaning for setting a serial port with setserial. It tells the driver that there is no interrupt for the port 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.

Interrupt sharing and Kernels 2.2+

The general rule is that every device should use a unique IRQ and not share them. But there are situations where sharing is permitted such as with most multi-port boards. Even when it is permitted, it may not be as efficient since every time a shared interrupt is given a check must be made to determine where it came from. Thus if it's feasible, it's nice to allocate every device its own interrupt.

Prior to kernel 2.2, serial IRQs could be shared with each other only for most multiport boards. Starting with kernel 2.2 serial IRQs may be sometimes shared between all serial ports. In order for sharing to work in 2.2 the kernel must have been compiled with CONFIG_SERIAL_SHARE_IRQ, and the serial port hardware must support sharing (so that if two serial cards put different voltages on the same interrupt wire, only the voltage that means "this is an interrupt" will prevail). Thus even if you have 2.2, it may be best to avoid sharing.

What IRQs to choose?

The serial hardware often has only a limited number of IRQs it can be set at. Also you don't want IRQ conflicts. So there may not be much of a choice. Your PC may normally come with ttyS0 and ttyS2 at IRQ 4, and ttyS1 and ttyS3 at IRQ 3. Looking at /proc/interrupts will show which IRQs are being used by programs currently running. You likely don't want to use one of these. Before IRQ 5 was used for sound cards, it was often used for a serial port.

Here is how Greg (original author of Serial-HOWTO) set his up in /etc/rc.d/rc.serial. rc.serial is a file (shell script) which runs at start-up (it may have a different name of location). For versions of "setserial" after 2.15 it's not always done this way anymore but this example does show the choice of IRQs.

/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

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, 7, 10, 11, 12 or 15 are possible choices. 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 very old serial board it may not be able to use IRQs 8 and above.

Make sure you don't use IRQs 1, 6, 8, 13 or 14! These are used by your motherboard. 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.

6.7 Choosing Addresses --Video card conflict with ttyS3

The IO address of the IBM 8514 video board (and others like it) is allegedly 0x?2e8 where ? is 2, 4, 8, or 9. This may conflict (but shouldn't if the serial port is well designed) with the IO address of ttyS3 at 0x02e8 if the serial port ignores the leading 0 hex digit (many do). That is bad news if you try to use ttyS3 at this IO address.

In most cases you should use the default addresses if feasible. Addresses shown represent the first address of an 8-byte range. For example 3f8 is really the range 3f8-3ff. Each serial device (as well as other types of devices that use IO addresses) needs its own unique address range. There should be no overlaps (conflicts). Here are the default addresses for the serial ports:

ttyS0 address 0x3f8
ttyS1 address 0x2f8
ttyS2 address 0x3e8
ttyS3 address 0x2e8

6.8 Set IO Address & IRQ in the hardware (mostly for PnP)

After it's set in the hardware don't forget to insure that it also gets set in the driver by using setserial. For non-PnP serial ports they are either set in hardware by jumpers or by running a DOS program ("jumperless") to set them (it may disable PnP). The rest of this subsection is only for PnP serial ports. Here's a list of the possible methods of configuring PnP serial ports:

The IO address and IRQ must be set (by PnP) in their registers each time the system is powered on since PnP hardware doesn't remember how it was set when the power is shut off. A simple way to do this is to let a PnP BIOS know that you don't have a PnP OS and the BIOS will automatically do this each time you start. This might cause problems in Windows (which is a PnP OS) if you start Windows with the BIOS thinking that Windows is not a PnP OS. See Plug-and-Play-HOWTO.

Plug-and-Play was designed to automate this io-irq configuring, but for Linux at present, it has made life more complicated. The standard kernels for Linux don't support plug-and-play very well. If you use a patch to the Linux kernel to covert it to a plug-and-play operating system, then all of the above should be handled automatically by the OS. But when you want to use this to automate configuring devices other that the serial port, you may find that you'll still have to configure the drivers manually since many Linux drivers are not written to support a Linux PnP OS. If you use isapnptools or the BIOS for configuring plug-and-play this will only put the two values into the registers of the serial port section of the modem card and you will likely still need to set up setserial. None of this is easy or very well documented as of early 1999. See Plug-and-Play-HOWTO and the isapnptools FAQ.

Using a PnP BIOS to I0-IRQ Configure

While the explanation of how to use a PnP OS or isapnp for io-irq configuring should come with such software, this is not the case if you want to let a PnP BIOS do such configuring. Not all PnP BIOS can do this. The BIOS usually has a CMOS menu for setting up the first two serial ports. This menu may be hard to find and for an "Award" BIOS it was found under "chipset features setup" There is often little to choose from. Unless otherwise indicated in a menu, these first two ports normally get set at the standard IO addresses and IRQs. See Serial Port Device Names & Numbers

Whether you like it or not, when you start up a PC a PnP BIOS starts to do PnP (io-irq) configuring of hardware devices. It may do the job partially and turn the rest over to a PnP OS (which you probably don't have) or if thinks you don't have a PnP OS it may fully configure all the PnP devices but not configure the device drivers. This is what you want but it's not always easy to figure out exactly what the PnP BIOS has done.

If you tell the BIOS that you don't have a PnP OS, then the PnP BIOS should do the configuring of all PnP serial ports --not just the first two. An indirect way to control what the BIOS does (if you have Windows 9x on the same PC) is to "force" a configuration under Windows. See Plug-and-Play-HOWTO and search for "forced". It's easier to use the CMOS BIOS menu which may override what you "forced" under Windows. There could be a BIOS option that can set or disable this "override" capability.

If you add a new PnP device, the BIOS should change its PnP configuration to accommodate it. It could even change the io-irq of existing devices if required to avoid any conflicts. For this purpose, it keeps a list of non-PnP devices provided that you have told the BIOS how these non-PnP devices are io-irq configured. One way to tell the BIOS this is by running a program called ICU under DOS/Windows.

But how do you find out what the BIOS has done so that you set up the device drivers with this info? The BIOS itself may provide some info, either in its setup menus of via messages on the screen when you turn on your computer. See What is set in my serial port hardware?

6.9 Giving the IRQ and IO Address to Setserial

Once you've set the IRQ and IO address in the hardware (or arranged for it to be done by PnP) you also need to insure that the "setserial" command is run each time you start Linux. See the subsection Boot-time Configuration

6.10 High-level Configuring: stty, etc.

As a rule, your application program will do most (or all) of this. The command which does it is stty. See Stty

Configuring Flow Control: Hardware Flow Control is Best

See Flow Control for an explanation of it. It's usually better to use hardware flow control rather than software flow control using Xon/Xoff. To use full hardware flow control you must normally have two wires for it in the cable between the serial port and the device. If the device is on a card, then it should always be possible to use hardware flow control.

Many applications (and the getty program) give you an option regarding flow control and will set it for you. It might even set hardware flow control by default. Like the IRQ and IO address, it must be set both in the serial driver and the hardware connected to the serial port. How it's set into the hardware is hardware dependent. Often there is a certain "init string" you send to the hardware device via the serial port from your PC. For a modem, the communication program should set it in both places.

If a program you use doesn't set flow control in the serial driver, then you may do it yourself using the stty command. Since the driver doesn't remember the setting after you stop Linux, you could put the stty command in a file that runs at start-up or when you login (such as /etc/profile for the bash shell). Heres what you would add for hardware flow control for port ttyS2:

 
stty crtscts < /dev/ttyS2 
or for stty version >= 1.17:
stty -F /dev/ttyS2 crtscts

crtscts stands for a Control setting to use the RTS and CTS pins of the serial port for hardware flow control. The upper case letters of the last sentence spell: crtscts.


Next Previous Contents