We've been talking quite a bit about network interfaces and general
TCP/IP issues, but we haven't really covered what happens when the
“networking code” in the kernel accesses a piece of
hardware. In order to describe this accurately, we have to talk a
little about the concept of interfaces and drivers.
First, of course, there's the hardware itself, for example an
Ethernet, FDDI or Token Ring card: this is a slice of Epoxy cluttered
with lots of tiny chips with strange numbers on them, sitting in a
slot of your PC. This is what we generally call a physical device.
For you to
use a network card, special functions have to be present in your Linux
kernel that understand the particular way this device is accessed. The
software that implements these functions is called a device
driver. Linux has device drivers for many different types
of network interface cards: ISA, PCI, MCA, EISA, Parallel port, PCMCIA,
and more recently, USB.
But what do we mean when we say a driver “handles” a device? Let's
consider an Ethernet card. The driver has to be able to communicate with the
peripheral's on-card logic somehow: it has to send commands and data to the
card, while the card should deliver any data received to the driver.
In IBM-style personal computers, this communication takes place through a
cluster of I/O addresses that are mapped to registers on the card and/or
through shared or direct memory transfers. All commands and data the kernel
sends to the card have to go to these addresses. I/O and memory addresses are
generally described by providing the starting or
base address. Typical base addresses for ISA bus Ethernet
cards are 0x280 or 0x300. PCI bus
network cards generally have their I/O address automatically assigned.
Usually you don't have to worry about any hardware issues such as the
base address because the kernel makes an attempt at boot time to
detect a card's location. This is called auto
probing, which means that the kernel reads several memory
or I/O locations and compares the data it reads there with what it
would expect to see if a certain network card were installed at that
location. However, there may be network cards it cannot detect
automatically; this is sometimes the case with cheap network cards
that are not-quite clones of standard cards from other
manufacturers. Also, the kernel will normally attempt to detect only
one network device when booting. If you're using more than one card,
you have to tell the kernel about the other cards explicitly.
Another parameter that you might have to tell the kernel about is the
interrupt request line. Hardware components usually interrupt the
kernel when they need to be taken care of—for example, when data
has arrived or a special condition occurs. In an ISA bus PC,
interrupts may occur on one of 15 interrupt channels numbered 0, 1,
and 3 through 15. The interrupt number assigned to a hardware
component is called its interrupt request
number (IRQ).[1]
As described in Chapter 2, the kernel accesses a piece
of network hardware through a software construct called an
interface.
Interfaces offer an abstract set of functions that are the same across all
types of hardware, such as sending or receiving a datagram.
Interfaces are identified by means of
names. In many other Unix-like operating systems, the network
interface is implemented as a special device file in the
/dev/ directory. If you type the ls -las
/dev/ command, you will see what these device files look
like. In the file permissions (second) column you will see that device
files begin with a letter rather than the hyphen seen for normal
files. This character indicates the device type. The most common
device types are b, which indicates the device is a
block device and handles whole blocks of data
with each read and write, and c, which indicates
the device is a character device and handles data
one character at a time. Where you would normally see the file length
in the ls output, you instead see two numbers,
called the major and minor device numbers. These numbers indicate the
actual device with which the device file is associated.
Each device driver registers a unique major number with the kernel.
Each instance of that device registers a unique
minor number for that major device. The tty
interfaces, /dev/tty*, are a character
mode device indicated by the “c”, and
each have a major number of 4, but
/dev/tty1 has a minor number of
1, and /dev/tty2 has a minor
number of 2. Device files are very useful for
many types of devices, but can be clumsy to use when trying to find an
unused device to open.
Linux interface names are defined internally in the kernel and are not
device files in the /dev directory. Some typical
device names are listed later in Section 3.2.” The assignment of interfaces to
devices usually depends on the order in which devices are
configured. For instance, the first Ethernet card installed will
become eth0, and the next will be
eth1. SLIP interfaces are handled differently
from others because they are assigned dynamically. Whenever a SLIP
connection is established, an interface is assigned to the serial
port.
Figure 3-1 illustrates the relationship
between the hardware, device drivers, and interfaces.
When booting, the kernel displays the devices it detects and the
interfaces it installs. The following is an excerpt from typical
boot messages:
.
. This processor honors the WP bit even when in supervisor mode./
Good.
Swansea University Computer Society NET3.035 for Linux 2.0
NET3: Unix domain sockets 0.13 for Linux NET3.035.
Swansea University Computer Society TCP/IP for NET3.034
IP Protocols: IGMP,ICMP, UDP, TCP
Swansea University Computer Society IPX 0.34 for NET3.035
IPX Portions Copyright (c) 1995 Caldera, Inc.
Serial driver version 4.13 with no serial options enabled
tty00 at 0x03f8 (irq = 4) is a 16550A
tty01 at 0x02f8 (irq = 3) is a 16550A
CSLIP: code copyright 1989 Regents of the University of California
PPP: Version 2.2.0 (dynamic channel allocation)
PPP Dynamic channel allocation code copyright 1995 Caldera, Inc.
PPP line discipline registered.
eth0: 3c509 at 0x300 tag 1, 10baseT port, address 00 a0 24 0e e4 e0,/
IRQ 10.
3c509.c:1.12 6/4/97 [email protected]
Linux Version 2.0.32 (root@perf) (gcc Version 2.7.2.1)
#1 Tue Oct 21 15:30:44 EST 1997
.
. |
This example shows that the kernel has been compiled with TCP/IP
enabled, and it includes drivers for SLIP, CSLIP, and PPP. The third
line from the bottom says that a 3C509 Ethernet card was detected and
installed as interface eth0. If you have some
other type of network card—perhaps a D-Link pocket adaptor, for
example—the kernel will usually print a line starting with its
device name—dl0 in the D-Link
example—followed by the type of card detected. If you have a
network card installed but don't see any similar message, the kernel
is unable to detect your card properly. This situation will be
discussed later in the section “Ethernet Autoprobing.”