One of the purposes of an operating system is to hide the peculiarities of the systme's hardware devices from its users. For example the Virtual File System presents a uniform view of the mounted filesystems irrespective of the underlying physical devices. This chapter describes how the Linux kernel manages the physical devices in the system.
The CPU is not the only intelligent device in the system, every physical device has a hardware controller. The keyboard, mouse and serial ports are controlled by a SuperIO chip, the IDE disks by an IDE controller, SCSI disks by a SCSI controller and so on. Each hardware controller has its own control and status registers (CSRs) and these differ between devices. The CSRs for an Adaptec 2940 SCSI controller are completely different from those of an NCR 810 SCSI controller. These CSRs are used to start and stop the device, to initialize it and to diagnose any problems with it. Instead of putting code to manage the hardware controllers in the system into every application, the code is kept in the Linux kernel. The software that handles or manages a hardware controller is known as a device driver. The Linux kernel device drivers are, essentially, a shared library of privileged, memory resident, low level hardware handling routines. It is Linux's device drivers which each handle the peculiarities of the devices that they are managing.
Every device in the system is represented by a device special file, for example the first IDE disk in the system is represented by /dev/hda. These device special files are created by the mknod command and they describe the device using major and minor device numbers. All devices controlled by the same device driver have a common major device number. The minor device numbers are used to distinquish between different devices, for example each partition on the primary IDE disk has a different minor device number. So, /dev/hda2, the second partition of the primary IDE disk has a major number of 3 and a minor number of 2. One of the basic features of Unix is that it abstracts the handling of devices. All hardware devices look like regular files; they can be opened, closed, read and written using the same, standard, system calls that are used to manipulate files. Linux's Virtual File System maps the device special file passed in the system calls to the device's device driver using the major device number.
Linux supports three types of hardware devices: character, block and network. Character devices are read and written directly without buffering, for example the system's serial ports /dev/cua0 and /dev/cua1. Block devices can only be written to and read from in multiples of the block size, typically 512 or 1024 bytes. Block devices are accessed via the buffer cache and may be randomly accessed, that is any block can be read or written no matter where it is on the device. Block devices can be accessed via their device special file but more commonly they are accessed via the filesystem. Only a block device can support a mounted file system. There are many different device drivers in the Linux kernel (that is one of Linux's strengths) but they all share some common attributes: