Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


implementation of this function is based on theioctlsystem call that is handled bysys_ioctlin the
kernel (see Chapter 13 for information on the implementation of system calls).

fs/ioctl.c
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
...
}

The ioctl code (cmd) is passed to an opened file identified by its file descriptor (fd) in the form of a more
or less easily readable pre-processor constant. A third parameter (arg) transfers further information
(detailed tables of all ioctls and parameters supported by the kernel are provided in numerous manuals
on system programming). Section 6.5.9 discusses the kernel-side implementation of ioctls in more detail.

Network Cards and Other Devices


Character and block devices are not the only device categories managed by the kernel. Network cards
occupy a special position in the kernel because they do not fit into this category scheme (Chapter 12 deals
extensively with why this is so). This is revealed by the fact that there are no device files for network
cards. Instead, user programs must use sockets to communicate with network cards, the sockets being
an abstraction layer to provide an abstract view of all network cards. Access takes place by means of
thesocketcallsystem call invoked by the network-related functions of the standard library to support
communication and interaction with the kernel.

There are also other system devices that do not have device files; these are accessed either by specially
defined system calls or are simply not accessed from userspace. An example of the latter is all expansion
buses such as USB and SCSI. Although these are addressed by a device driver, the corresponding func-
tions are made available within the kernel only (accordingly, USB expansion cards do not have device
files via which they can be addressed). It is left to lower-level device drivers to provide functions that are
exported into userspace.

6.2.4 Representation of Major and Minor Numbers


For historical reasons, there are two ways of managing the major and minor numbers of a device in a
compound data type. During the development of 2.6, a 16-bit integer (typicallyunsigned short)was
used to represent major and minor numbers. The integer was split in a 1:1 ratio, that is, 8 bits for the
major number and 8 bits for the minor number. This meant that exactly 256 major numbers and 256
minor numbers were possible. This is not sufficient on today’s much bigger systems — one need only
consider the example of SCSI storage arrays comprising a very large number of hard disks.

The 16-bit integer definition was therefore replaced with a 32-bit integer (dev_tis the associated abstract
type), but this had certain consequences. It was realized that 16 bits are more than enough for the major
numbers. As a result, 12 bits were reserved for the major and 20 for the minor numbers. This gave rise to
the following problems.

❑ Many drivers make the incorrect assumption that only 16 bits are available to represent the num-
bers.
❑ Device file numbers stored on old filesystems use only 16 bits but must still function correctly.
The problem of the now non-symmetrical division of bits between major and minor numbers
must therefore be resolved.
Free download pdf