Next Previous Contents

6. Configuring the I/O Address, IRQ, and Name

6.1 Introduction

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.

6.2 Set I/O Address & IRQ

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.

6.3 Can I Use More Than Two Serial Devices? Interrupt Conflicts

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.

Choosing Serial IRQs (required only if your kernel version < 2.2)

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.

Setting Serial Device Addresses

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.

Giving the IRQ and IO Address to Setserial

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.

6.4 Can Linux Configure The Serial Devices Automagically?

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.

6.5 Notes For Multiport Boards

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.

6.6 Devices: modem, mouse

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.

6.7 The cua Device

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.

6.8 Serial Port Devices and Numbers in the /dev directory

/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*

Creating Devices In the /dev Directory

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.

6.9 Notes For Dumb Multiport Boards

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.

6.10 Notes For Intelligent Multiport Boards

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.

Next Previous Contents