Next Previous Contents

3. The Plug-and-Play (PnP) Solution

3.1 Introduction to PnP

The term Plug-and-Play (PnP) has various meanings. In the broad sense it is just auto-configuration where one just plugs in a device and it configures itself. In the sense used in this HOWTO, PnP means the configuring PnP bus-resources (setting them in the physical devices) and letting the device drivers know about it. For the case of Linux, it is often just a driver determining how the BIOS has set bus-resources and if necessary, giving a command to change (reset) the bus-resources. "PnP" sometimes just means PnP on the ISA bus so that the message from isapnp: "No Plug and Play device found" just means that no ISA PnP devices were found. The standard PCI specifications (which were invented before coining the term "PnP") provide the equivalent of PnP for the PCI bus.

PnP matches up devices with their device drivers and specifies their communication channels (by allocating bus-resources). It electronically communicates with configuration registers located inside the physical devices using a standardized protocol. On the ISA bus before Plug-and-Play, the bus-resources were formerly set in hardware devices by jumpers or switches. Sometimes the bus-resources could be set into the hardware electronically by a program (usually for a MS OS) on a floppy supplied with the hardware. This was something like PnP but there was no standardized protocol used so it wasn't PnP. For Linux, software drivers were assigned bus-resources by configuration files (or the like) or by probing the for the device at addresses where it was expected to reside. The PCI bus was PnP-like from the beginning, but at first it wasn't called PnP (and often still isn't called PnP).

3.2 How It Works (simplified)

Here's how PnP should work in theory. The PnP configuration program finds all PnP devices and asks each what bus-resources it needs. Then it checks what bus-resources (IRQs, etc.) it has to give away. Of course, if it has reserved bus-resources used by non-PnP (legacy) devices (if it knows about them) it doesn't give these away. Then it uses some criteria (not specified by PnP specifications) to give out the bus-resources so that there are no conflicts and so that all devices get what they need (if possible). It then indirectly tells each physical device what bus-resources are assigned to it and the devices set themselves up to use only the assigned bus-resources. Then the device drivers somehow find out what bus-resources their devices use and are thus able to communicate effectively with the devices they control.

For example, suppose a card needs one interrupt (IRQ number) and 1 MB of shared memory. The PnP program reads this request from the configuration registers on the card. It then assigns the card IRQ5 and 1 MB of memory addresses space, starting at address 0xe9000000. The PnP program also reads identifying information from the card telling what type of device it is, its ID number, etc. Then it directly or indirectly tells the appropriate device driver what it's done. If it's the driver itself that is doing the PnP, then there's no need to find a driver for the device (since it's driver is already running). Otherwise a suitable device driver needs to be found and sooner or later told how it's device is configured.

It's not always this simple as the card (or routing table for PCI) may specify that it can only use certain IRQ numbers or that the 1 MB of memory must lie within a certain range of addresses. The details are different for the PCI and ISA buses with more complexity on the ISA bus.

One way commonly used to allocate resources is to start with one device and allocate it bus-resources. Then do the same for the next device, etc. Then if finally all devices get allocated resources without conflicts, then all is OK. But if allocating a needed resource would create a conflict, then it's necessary to go back and try to make some changes in previous allocations so as to obtain the needed bus-resource. This is called rebalancing. Linux doesn't do rebalancing but MS Windows does in some cases. For Linux, all this is done by the BIOS and/or kernel and/or device drivers. In Linux, the device driver doesn't get it's final allocation of resources until the driver starts up, so one way to avoid conflicts is just not to start any device that might cause a conflict. However, the BIOS often allocates resources to the physical device before Linux is even booted and the kernel checks PCI devices for addresses conflicts at boot-time.

There are some shortcuts that PnP software may use. One is to keep track of how it assigned bus-resources at the last configuration (when the computer was last used) and reuse this. MS PnP Windows and PnP BIOSs do this but standard Linux doesn't. Windows stores this info in its "Registry" on the hard disk and a PnP/PCI BIOS stores it in non-volatile memory in your PC (known as ESCD; see The BIOS's ESCD Database). Some say that not having a registry (like Linux) is better since with Windows, the registry may get corrupted and is difficult to edit. But PnP in Linux has problems too.

While MS Windows (except for Windows 3.x and NT4) were PnP, Linux was not originally a PnP OS but has been gradually becoming a PnP OS. PnP originally worked for Linux because a PnP BIOS would configure the bus-resources and the device drivers would find out (using programs supplied by the Linux kernel) what the BIOS has done. Today, most drivers can issue commands to do their own bus-resource configuring and don't need to always rely on the BIOS. Unfortunately a driver could grab a bus-resource which another device will need later on. Some device drivers may store the last configuration they used in a configuration file and use it the next time the computer is powered on.

If the device hardware remembered its previous configuration, then there wouldn't be any hardware to PnP configure at the next boot-time. But hardware seems to forget its configuration when the power is turned off. Some devices contain a default configuration (but not necessarily the last one used). Thus a PnP device needs to be re-configured each time the PC is powered on. Also, if a new device has been added, then it too needs to be configured too. Allocating bus-resources to this new device might involve taking some bus-resources away from an existing device and assigning the existing device alternative bus-resources that it can use instead. At present, Linux can't allocate with this sophistication (and MS Windows XP may not be able to do it either).

3.3 Starting Up the PC

When the PC is first turned on the BIOS chip runs its program to get the computer started (the first step is to check out the hardware). If the operating system is stored on the hard-drive (as it normally is) then the BIOS must know about the hard-drive. If the hard-drive is PnP then the BIOS may use PnP methods to find it. Also, in order to permit the user to manually configure the BIOS's CMOS and respond to error messages when the computer starts up, a screen (video card) and keyboard are also required. Thus the BIOS must always PnP-configure devices needed to load the operating system from the hard-drive.

Once the BIOS has identified the hard-drive, the video card, and the keyboard it is ready to start booting (loading the operating system into memory from the hard-disk). If you've told the BIOS that you have a PnP operating system (PnP OS), it should start booting the PC as above and let the operating system finish the PnP configuring. Otherwise, a PnP-BIOS will (prior to booting) likely try to do the rest of the PnP configuring of devices (but not inform the device drivers of what it did). But the drivers can still find out this by utilizing functions available in the Linux kernel.

3.4 Buses

ISA is the old bus of the old IBM-compatible PCs while PCI is a newer and faster bus from Intel. The PCI bus was designed for what is today called PnP. This makes it easy (as compared to the ISA bus) to find out how PnP bus-resources have been assigned to hardware devices. To see what's on the PCI bus type lspci or lspci -vv. Or type scanpci -v for more detail but it's more difficult to decipher. Or look at the "file" /proc/pci. The boot-time messages on your display show devices which have been found on various buses (use shift-PageUp to back up thru them). See Boot-time Messages

For the ISA bus there was a real problem with implementing PnP since no one had PnP in mind when the ISA bus was designed and there are almost no I/O addresses available for PnP to use for sending configuration info to a physical device. As a result, the way PnP was shoehorned onto the ISA bus is very complicated. Whole books have been written about it. See PnP Book. Among other things, it requires that each PnP device be assigned a temporary "handle" by the PnP program so that one may address it for PnP configuring. Assigning these "handles" is call "isolation". See ISA Isolation for the complex details.

As the ISA bus becomes extinct, PnP will be a little easier. It will then not only be easier to find out how the BIOS has configured the hardware, but there will be less conflicts since PCI can share interrupts. There will still be the need to match up device drivers with devices and also a need to configure devices that are added when the PC is up and running. The serious problem of some devices not being supported by Linux will remain.

3.5 How Linux Does PnP

Linux has had serious problems in the past in dealing with PnP but most of those problems have now been solved (as of mid 2004). Linux has gone from a non-PnP system originally, to one that is a non-centralized Pnp system (each device for itself). One can argue that it still isn't fully PnP. To a significant extent it relies on device drivers (with help from the kernel) and the PnP BIOS to configure bus-resources for devices.

When the PC starts up you may note from the messages on the screen that some Linux device drivers often find their hardware devices and get configured.

The kernel provides help for the drivers in the form of programs they may call on that do PnP. In many cases, the device driver, with the help of such programs, does all the needed configuring. In other cases the BIOS may configure and then the device driver may find out how the BIOS has configured it and accept it. Thus, the kernel provides the drivers with functions (program code) that the drivers may use to find out if their device exists, how it's been configured, and functions to modify the configuration. Kernel 2.2 could do this only for the PCI bus but Kernel 2.4 has this feature for both the ISA and PCI buses (provided that the PNP options have been selected when compiling the kernel). This by no means guarantees that all drivers will fully and correctly use these features.

In addition, the kernel helps avoid resource conflicts by not allowing two devices to use the same bus-resources at the same time. Originally this was only for IRQs, and DMAs but now it's for address resources as well. For PCI, the kernel checks for possible address conflicts while booting.

Prior to Kernel 2.4, the standalone program: isapnp was often run to configure and/or get info from PnP devices on the ISA bus. isapnp is still needed for cases where the device driver is not fully PnP for the ISA bus. There was at least one early rejected attempt to make Linux a true PnP operating system. See http://www.astarte.free-online.co.uk. While developed around 1998 it never was put into the kernel (but probably should have been).

To see what help the kernel may provide to device drivers see the directory /usr/.../.../Documentation where one of the ... contains the word "kernel-doc" or the like. Warning: documentation here tends to be out-of-date so to get the latest info you would need to read messages on mailing lists sent by kernel developers and possibly the computer code that they write including comments. In this kernel documentation directory see pci.txt ("How to Write Linux PCI Drivers") and the file: /usr/include/linux/pci.h. Unless you are a driver guru and know C Programming, these files are written so tersely that they will not actually teach you how to write a driver. But it will give you some idea of what PnP type functions are available for drivers to use.

For kernel 2.4 see isapnp.txt. For kernel 2.6, isapnp.txt is replaced by pnp.txt which is totally different than isapnp.txt and also deals with the PCI bus.

3.6 Problems with Linux PnP

But there are a number of things that a real PnP operating system could handle better:

Since it's each driver for itself, a driver could grab bus-resources that are needed by other devices (but not yet allocated to them by the kernel). Thus a more sophisticated PnP Linux kernel would be better, where the kernel did the allocation after all requests were in. Another alternative would be a try to reallocate resources already assigned if a devices couldn't get the resources it requested.

The "shortage of bus-resources" problem is becoming less of a problem for two reasons: One reason is that the PCI bus is replacing the ISA bus. Under PCI there is no shortage of IRQs since IRQs may be shared (even though sharing is a little less efficient). Also, PCI doesn't use DMA resources (although it does the equivalent of DMA without needing such resources).

The second reason is that more address space is available for device I/0. While the conventional I/O address space of the ISA bus was limited to 64KB, the PCI bus has 4GB of it. Since more physical devices are using main memory addresses instead of IO address space, there is still more space available, even on the ISA bus. On 32-bit PCs there is 4GB of main memory address space and much of this bus-resource is available for device IO (unless you have 4GB of main memory installed).


Next Previous Contents