Adding New Hardware (2.204.2)

Candidates should be able to configure internal and external devices for a system including new hard disks, dumb terminal devices, serial UPS devices, multi-port serial card, and LCD panels.

Revision: $Revision: 1.11 $ ($Date: 2004-03-24 12:50:18 $)

Key files, terms and utilities include:

XFree86
modprobe
lsmod
lsdev
lspci
setserial
usbview
/proc/bus/usb

Resources: LinuxRef02; Robbins01.2; LinuxRef03; USBRef01; LinuxRef04; LinuxRef05; Will00; the man pages for the various commands.

Bus structures

Most Linux installations run on PC hardware. The PC architecture currently supports a number of bus-systems that allow easy extension of hardware by plugging cards into a bus slot. Currently (2001) the PCI bus is the most widely used bus. Many newer motherboards only support PCI. On older, but fairly recent systems, often a combination of PCI and ISA slots is used, simply because there were many ISA cards available on the market. See the next section for an overview of (formerly) commonly used PC bus structures.

The main PC bus-systems

ISA

16 or 8bit, cheap, slow (usually 8MHz), standard, many cards available, but not many new motherboards are shipped with ISA anymore;

EISA

32bit, expensive, fast, few cards available, but almost obsolete.

MCA

32 or 16bit ex-IBM-proprietary, fast, obsolete/rare.

VESA-Local-Bus

32bit, based on 486 architecture, cheap, fast, many cards available, obsolete.

PCI-Local-Bus

32bit (64 bit coming), cheap, fast, many cards available, the de facto standard

We will focus on PCI, the current standard. PCI (like EISA) is not proprietary. It is faster than EISA or MCA, and cheaper. PCI is also available on other than PC hardware, e.g. DEC Alpha and PowerPC. PCI is not processor dependent. This means you can use the a PCI card in an Alpha-driven-PCI computer as well as in a Pentium-driven PCI computer, given the appropriate BIOS and software. PCI will develop into a 64-bit version and other more enhanced versions.

Plug and play

The term Plug and Play is often used for systems that match up devices with their device drivers and specifies their communication channels (IRQ,DMA,I/O). On the ISA bus, before Plug-and-Play, the bus-resources were set in hardware devices by jumpers. Software drivers were assigned bus-resources by configuration files (or the like) or by probing for a device at pre-determined addresses. The PCI bus was PnP-like from the beginning so it was trivial to implement PnP for this bus. Since the PCI bus specifications don't use the term PnP it's not clear whether or not the PCI bus should be called PnP (but it supports in hardware what today is called PnP).

Querying your PCI bus

On Linux systems you can use lspci to get a rundown of your PCI bus. As a normal user, you may have to type /sbin/lspci. In newer kernels (as of 2.1.82) lspci can be run as either root or any other user. lspci reads the /proc/bus/pci interface. The PCI ID database (e.g. /usr/share/pci.ids) is used to translate PCI vendor and device codes to readable strings.

Table 4.1. Commonly used lspci parameters

-nshows PCI vendor and device codes as numbers instead of looking them up in the PCI ID database
-tshows a tree-like diagram of the buses, bridges, devices and connections between them
-Minvokes busmapping mode. This will find all devices, even those that are behind misconfigured bridges, etc. This is intended for debugging only, and can crash the machine. It is only available to root.
-vverbose mode, gives detailed information about the bus and devices. Use -vv for even more details.


A sample output of lspci on a laptop follows:

00:00.0 Host bridge: Intel Corporation 440BX/ZX - 82443BX/ZX Host bridge (AGP disabled) (rev 03)
00:04.0 VGA compatible controller: Neomagic Corporation [MagicGraph 256AV] (rev 12)
00:05.0 Bridge: Intel Corporation 82371AB PIIX4 ISA (rev 02)
00:05.1 IDE interface: Intel Corporation 82371AB PIIX4 IDE (rev 01)
00:05.2 USB Controller: Intel Corporation 82371AB PIIX4 USB (rev 01)
00:05.3 Bridge: Intel Corporation 82371AB PIIX4 ACPI (rev 02)
00:09.0 Communication controller: Toshiba America Info Systems FIR Port (rev 23)

To see the interconnection between the buses, bridges and connections between them, often the command lspci -vt is used, e.g.

-[00]-+-00.0  Intel Corporation 440BX/ZX - 82443BX/ZX Host bridge (AGP disabled)
      +-04.0  Neomagic Corporation [MagicGraph 256AV]
      +-05.0  Intel Corporation 82371AB PIIX4 ISA
      +-05.1  Intel Corporation 82371AB PIIX4 IDE
      +-05.2  Intel Corporation 82371AB PIIX4 USB
      +-05.3  Intel Corporation 82371AB PIIX4 ACPI
      \-09.0  Toshiba America Info Systems FIR Port

In our example one PCI bus is present (00), on which 4 devices are present (00, 04, 05 and 09) and device 5 has 4 functions (05.0..05.3).

PCI latency timers

One of the things listed by the lspci command is the latency timer value. The latency timer can influence the performance of your PCI devices significantly. To influence the behavior of the PCI bus and devices, you can use the command setpci. One of the settings this command can perform is the PCI bus latency timer.

The PCI bus latency timer can range from zero to 248. If a device has a setting of zero, then it will immediately give up the bus if another device needs to transmit. If a device has a high latency setting, it will continue to use the bus for a longer period of time before stopping, while the other device waits for its turn.

If all of your devices have relatively high PCI bus latency timer settings and a lot of data is being sent over the bus, then your PCI cards are generally going to have to wait longer before they gain control of the bus, but are able to burst a lot of data across it before giving up the bus to another device. On the other hand, if all your PCI devices have low PCI-bus latency settings, then they're going to gladly give up the bus if another card needs to transmit data. This results in a much lower data-transmit latency, since no device is going to hold on to the bus for an extended period of time, causing other devices to wait.

Low PCI-bus latency timer settings reduce the effective PCI bus bandwidth when two or more PCI devices are operating simultaneously, because large data bursts become much less frequent and control of the bus changes rapidly, increasing overhead.

Configuring PCI devices

Before you buy any PCI card, you may want to read the PCI HOWTO Will00 and the Hardware HOWTO to find out which cards are supported under Linux.

To add a PCI card to your system, you start by physically adding the PCI card. When you reboot your system, the BIOS should automatically detect the card[2].

Communication between the card and the kernel is done via the device driver for your card. Either you compile the driver into your kernel, or you compile it as a module which can be loaded using insmod or modprobe.

The documentation for your device driver will specify which parameters must be specified (if any) to the driver. Configuration of the device driver can be done either by specifying its parameters to the kernel (lilo, /etc/lilo.conf) or by adding them to the proper options line in /etc/conf.modules.

USB devices

As we saw in the example, our PCI bus contained a device called USB controller. The USB (Universal Serial Bus) is a special serial device that can be used to connect peripherals of all sorts to your computer. USB can be seen as a hot-pluggable auto detecting bus: you can actively add or remove devices to and from the bus and the type of device is automatically detected. Linux supports a growing number of USB devices.

To find out which USB devices are currently connected to your system you use the command usbview. It is explicitly listed in the exam objectives. This command provides a graphical display of the devices/hubs connected to the system. However, usbview depends on X and the GTK toolkit and is not always available on all USB aware distributions. An alternate way to obtain information about your USB devices is to inspect the contents of the USB filesystem.

The USB-device filesystem is a dynamically generated filesystem. On most Linux distributions that support USB, it is automatically mounted on startup. It can be mounted almost everywhere, but the most common location is /proc/bus/usb.

To mount it by hand, use:

        mount -t usbdevfs none /proc/bus/usb
      

The USB device filesystem contains directories th at correspond with each USB bus. These directories are named 001, 002 etc. In addition to these, there are two generated files - the drivers and devices files.

/proc/bus/usb/drivers just lists the currently registered drivers (even if the driver is not being used by any device). This is most useful when testing module installation, and checking for USB support in an unknown kernel.

/proc/bus/usb/devices lists information about the devices currently attached to the USB bus.

T:  Bus=00 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=12  MxCh= 2
B:  Alloc= 28/900 us ( 3%), #Int=  2, #Iso=  0
D:  Ver= 1.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=0000 ProdID=0000 Rev= 0.00
     
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr=  0mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=255ms
T:  Bus=00 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=12  MxCh= 4
D:  Ver= 1.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=0451 ProdID=1446 Rev= 1.00
  
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=255ms
T:  Bus=00 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#=  3 Spd=12  MxCh= 0
D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=0553 ProdID=0002 Rev= 1.00

The information in the /proc/bus/usb/devices output is arranged in groups. The lines starting with T: specify the USB topology. Lines that start with D: specify information from the device descriptor. Lines starting with P: contain information about the device descriptor, just like the D: lines. They are separated mainly because the information wouldn't all fit on one line. The lines that start with S:, if any, are the vendor and product strings that the device returned. The line that starts with C: give information from the configuration descriptor. The line that starts with I: is information from the interface descriptor. The line that starts with E: is information from the endpoint descriptor.

Configuring USB devices

With the release of the 2.4 kernel, Linux users gained serious USB support for a wide range of devices. The Linux USB subsystem, integrated in the kernel and supported by most Linux distributions, supports all necessary features like plug-and-play, USB bandwith allocation and more than 100 ports per bus.

Linux supports both the Universal Host Controller Interface (UHCI, used by Intel and Via motherboard chipsets) and the Open Host Controller Interface (OHCI, used by Compaq, Apple, SiS, OPTi, Lucent and ALi chipsets), making USB support available to anyone with a modern motherboard, or with a spare PCI or PcCard slot available to add in a cheap USB host controller board. Linux also supports USB hubs, which provide expansion for additional devices.

Linux 2.4 provides USB support for devices conforming to the USB Human Interface Device class, which includes USB keyboards, USB mice and touchpads, USB joysticks and USB graphics tablets. These devices appear to the computer as normal keyboards, mice and joysticks. This means that applications do not need to be updated to use the new kernel capabilities. In addition, the devices can also appear on a new event interface, which allows customized applications to take advantage of the additional capabilities offered by USB devices.

Configuring a new type of USB device usually requires either rebuilding the kernel or loading additional modules. Next, you'll need to create device nodes to enable communication between kernel and user programs (mknod). After that, the interface between kernel and userspace will be available in the form of device-files.

Additionally you'll need to configure your applications to make them aware of the newly created devices. E.g. to enable the use of USB- mice and -keyboards in an X environment, you will probably need to change sections in the XF86config file. To enable the use of USB-printers you probably will need to add an entry in /etc/printcap, etc.

Serial devices

The setserial command can be used to detect the configuration of your serial devices. Using the command

setserial /dev/ttyS0
  

will give you the the port type (i.e., 8250, 16450, 16550, 16550A, etc.), the hardware I/O port, the hardware IRQ line, its baud base[3] and some of its operational flags.

Multiport boards

Typical PC hardware comes with one or two serial ports. When you need to connect a larger number of serial devices, e.g. to monitor ranges of other computers or to steer industrial controllers[4], you can install a multiport adaptor, also known as multiport board or multiport card. These are plugged into your PCI or ISA bus and often have their own processing and buffering logic to ease the burden on your processor. Each multiport card has a number of external connecters (9 or 25 pin D-connectors or RJ45 telephone connectors). The smaller boards often have their connectors mounted directly on the board. If larger numbers of serial ports are supported, the connectors may be on the cables which come off (externally) the card (octopus cable), or can be on an external box (possibly rack mountable) which is connected by a cable to a multiport card.

Linux will need a device driver to work with multiport boards. There are many types of multiport boards, some of which work in Linux, others are not. However, often someone has figured out how to make them work or wrote a driver for them. Often, the driver is implemented as a kernel-module that needs to be (automatically) loaded. As usual, certain parameters may need to be passed to the driver via lilo's append command or via /etc/modules.conf). The manufacturer of the board should have info on their web-site and you can try kernel documentation, discussion groups and mailing list archives to obtain more information. There are kernel documentation files for Computone, Hayes-ESP, Moxa-smartio, Riscom8, Specialix, Stallion and SX (Specialix) boards.

Configuring serial devices

setserial

During the normal boot process, only COM ports 1-4 are initialized using default I/O ports and IRQ values. In order to initialize any additional serial ports, or to change the COM 1-4 ports to a non-standard configuration, the setserial program should be used.

setserial was created to configure the serial driver at runtime. The setserial command is most commonly executed at boot time from one of the bootscripts (e.g. 0setserial or rc.serial) This script is charged with the responsibility of initializing the serial driver to accommodate any nonstandard or unusual serial hardware in the machine.

The general syntax for the setserial command is:

      setserial device [parameters]
      

in which the device is one of the serial devices, such as ttyS0.

Table 4.2. Commonly used setserial parameters

port [portnumber]Specify the I/O port address in hexadecimal notation, e.g. 0x2f8
irq [irqnum]specify which IRQ line the serial device is using
uart [type]specify the UART type, e.g. 16550, 16450 or none (which disables the serial device)
autoirqspecify that the kernel should try to figure out the IRQ itself. Not always reliable.
skip_testspecify that the kernel should not bother with the UART type test during auto configuration (needed when the kernel has problems detecting the correct UART)
autoconfiginstructs the kernel to attempt to automatically determine the UART type located at the supplied port

powerd

powerd is a daemon process that sits in the background and monitors the state of an Uninterruptible Power Supply (UPS). Information comes to powerd from the status signals of a serial line, from a remote host or from a fifo.

Configuring disks

To install a new disk in your system, you need to physically install the hard drive and configure it in your computers BIOS. Linux will detect the new drive automatically in most cases. You could type dmesg | more to find out what the drive is called. The second IDE drive in your system will be named /dev/hdb. We will assume that the new drive is /dev/hdb.

You must now partition your new disk. As root in a shell type:

   fdisk /dev/hdb 
   

This will take you to a prompt that says Command (m for help):. At the prompt, type p to display the existing partitions. If you have partitions that you need to delete, type d, then at the prompt, type the number of the partition that you wish to delete. Next, type n to create the new partition. Type 1 (assuming that this will be the first partition on the new drive), and hit enter. Then you will be prompted for the cylinder that you want to start with on the drive. Next, you will be asked for the ending cylinder for the partition. Repeat these steps until all partitions are created.

To put a clean filesystem on the first partition of your newly partitioned drive, type:

    mkfs /dev/hdb1 
    

Repeat this step for all partitions. You can use the -t parameter to define the filesystem type to build, e.g. ext2, ext3, xfs, minix etc. (the section called “Creating Filesystems”).

You will now need to decide the mount point for each new partition on your drive. We will assume /data. Type:

    mkdir /new 
    

to create the mount point for your drive. Now you will need to edit /etc/fstab. You will want to make an entry at the end of the file similar to this:

    /dev/hdb1       /new     ext2          defaults       1   1
    

After you have created a similar entry for each partition, write the file.

    mount -a 
    

will mount the partitions in the directory that you specified in /etc/fstab.

Configuring output devices

Configuring CRT devices

On the hardware side you need to configure your graphic s card and hook-up your monitor. Next, you need to configure the X-server.

The standard X-server for Linux is XFree86. As of this writing both version 3 and 4 are widely in use. Check the XFree86 documentation to determine whether or not your chipset is supported. The suggested setup for XFree86 under Linux is a 486 or better with at least 8 megabytes of RAM, and a video card with a supported chipset. For optimal performance, you can use an accelerated card such as an S3-chipset card.

You can determine what type of chipset your video card uses by reading the card's documentation or asking the manufacturer for it. Another way to determine your chipset is by running the SuperProbe program included with the XFree86 distribution.

Configuring XFree86 to use your mouse, keyboard, monitor and video card correctly used to be something of a black art, requiring extensive hand-hacking of a complex configuration file.

XFree86 release 3 and later simplified this process by providing a program named XF86Setup. This program depends on the fact that all new PC hardware these days ships with EGA/VGA capable monitors. It invokes the VGA16 server and uses it to bring up X in a lowest-common-denominator 640x480 mode. Then it runs an interactive program that walks you through a series of five configuration panels -- mouse, keyboard, (video) card, monitor and miscellaneous server options. On Red Hat Linux, you may see a different program called xf86config. This works fairly similarly to XF86Setup, but does not itself use an X interface and the VGA16 server.

When the X-server does not come up properly or you suffer from poor quality, this is almost always due to a problem in your configuration file. Usually, the monitor timing values are off, or the videocard dotclocks are set incorrectly. Minor problems can be fixed with xvidtune; a really garbled screen usually means you need to go back into XF86Setup and choose a less-capable monitor type. If your display seems to roll or the edges are fuzzy, this is a clear indication that the monitor-timing values or dot clocks are wrong. Also be sure that you are correctly specifying your video card chipset, as well as other options for the Device section of XF86Config.

You will need to hand-hack your X configuration to get optimal performance if your monitor can support 1600x1200 -- the highest canned resolution XF86Setup supports is 1280x1024. If you want to hand-hack your video configuration for this or any other reason, go see the LDP XFree86 Video Timings HOWTO LinuxRef05

Configuring LCD devices

Computers using Liquid Crystal Displays are more tricky to set up in XFree86 than ones with a normal (CRT) monitor. This is mainly due to the displays themselves: LCDs basically have a fixed resolution, although some have extra hardware built in that can cope with several different resolutions.

The standard server XF_SVGA should work in almost all cases. However, it may result in a poor picture quality, e.g. due to wrong configuration of the Modelines class in file /etc/X11/XF86Config . The modelines settings define the horizontal and vertical refresh rates of the electron beam in a CRT. A lot of LCD/TFT displays are compatible and are able to display a lot of common modelines correctly, however, you may need to hack the video configuration for this or some other reason LinuxRef05.



[2] If your system additionally contains ISA cards be sure to set up your BIOS accordingly. Consult your computers documentation to find out the proper procedure.

[3] the baud base is the clock frequency divided by 16. Normally this value is 115200, which is also the fastest baud rate which the UART can support

[4] or, as in the good old days: modems and terminals

Copyright Snow B.V. The Netherlands