Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


a unique port number, and the data are forwarded tothe attached device for processing. A separate vir-
tual address space managed by the processor is used for the management of all I/O addresses. However,
it must also be supported by the remaining system hardware.

The I/O address space isnotusually linked with normal system memory. This often
gives rise to confusion because ports can also be mapped into memory.

There are different types of ports. Some are Read Only and some are Write Only, but typically they
operate bidirectionally so that data can be exchanged in both directions between the processor (and
therefore the application and the kernel) and the peripheral.

On IA-32 architectures, the port address space consists of 2^16 (i.e., approximately 64,000) different 8-bit
addresses that are uniquely identified by means of numbers ranging from0x0to0xFFFFH. Each resulting
port has a device assigned to it or is unused. It is not possible for several peripherals to share a port.

In view of today’s complex technology, 8 bits is not much when it comes to exchanging data with external
units. For this reason, it is possible to combine two successive 8-bit ports into a 16-bit port. Furthermore,
two successive 16-bit ports (in reality, four successive 8-bit ports) can be regarded as a 32-bit port. The
processor features suitable assembler statements to perform input and output operations.

Each processor type implements access to its ports differently. Consequently, the kernel must provide an
appropriate abstraction layer. Commands such asoutb(to write a byte),outw(to write a word), andinb
(to read a byte) are implemented inasm-arch/io.h. These are very processor-specific definitions so there
is no need to discuss them here.^2

I/O Memory Mapping


Programmers must address many devices in a similar way to RAM memory. For this reason, modern
processors provide the option ofmemory mappingof I/O ports in which the port addresses of a specific
peripheral are mapped into normal memory, where they can be manipulated with the same statements
used to handle regular memory. Graphic cards typically use this type of operation because it is easier
to process extensive image data with normal processor commands than with specific port commands.
System buses such as PCI are also often addressed by means of mapped I/O addresses.

To work with memory mappings, I/O ports must first be mapped into regular system memory (using
processor-specific routines). Because the methods used to do this differ greatly between the various
underlying architectures, the kernel once again provides a small abstraction layer consisting primarily of
theioremapandiounmapcommands to map and unmap I/O areas. I don’t deal specifically with their
implementation.

Polling and Interrupts


Besides the technical details of access to peripheral devices, another question is also interesting. How
does the system know whether and when data are ready to be read from a device? There are two ways
of finding out — by means of polling or by using interrupts.

Pollingis the less elegant alternative, but the strategy behind polling is very simple. The device is repeat-
edly asked if data are available — when this is the case, the processor then fetches the data. It’s more than

(^2) Nevertheless, the implementation of the I/O functions for IA-32 processors is interesting from a certain point of view because
include/asm-i386/io.hdelves quite deeply into the pre-processor’s box of tricks.

Free download pdf