Classes of Devices and Modules

The Unix way of looking at devices distinguishes between three device types, each devoted to a different task. Linux can load each device type in the form of a module, thus allowing users to experiment with new hardware while still being able to run up-to-date kernel versions and to follow development.

As far as modules are concerned, each module usually implements only one driver, and thus is classifiable, for example, as a char module, or a block module. This division of modules into different types, or classes, is not a rigid one; the programmer can choose to build huge modules implementing different drivers in a single chunk of code. Good programmers, nonetheless, usually create a different module for each new functionality they implement.

Going back to devices, the three flavors are the following:

Character devices

A character (char) device is one that can be accessed like a file, and a char driver is in charge of implementing this behavior. Such a driver usually implements the open, close, read, and write system calls. The console and the parallel ports are examples of char devices, as they are well represented by the stream abstraction. Char devices are accessed by means of filesystem nodes, such as /dev/tty1 and /dev/lp1. The only relevant difference between a char device and a regular file is that you can always step back and forth in the regular file, while most char devices are just a data channel, which you can only access sequentially. There exist, nonetheless, char devices that look like a data area, and you can step back and forth in them.

Block devices

A block device is something that can host a filesystem, such as a disk. In most Unix systems, a block device can only be accessed as multiples of a block, where a block is usually one kilobyte of data. Linux allows you to read and write a block device like a char device--it permits the transfer of any number of bytes at a time. As a result, block and char devices differ only in the way data is managed internally by the kernel, and thus in the kernel/driver software interface. Like a char device, each block device is accessed through a filesystem node and the difference between them is transparent to the user. A block driver interfaces with the kernel through the same interface as a char driver, as well as through an additional block-oriented interface that is invisible to the user or application.

Network interfaces

Any network transaction is made through an interface, i.e., a device that is able to exchange data with other hosts. Usually, an interface is a hardware device, but it might also be a software tool, like the loopback interface. A network interface is in charge of sending and receiving data packets, driven by the network subsystem of the kernel, without knowing how individual transactions map to the actual packets being transmitted. Though both ``telnet'' and ``ftp'' connections are stream-oriented, they transmit using the same device; the device doesn’t see the individual streams, but only the data packets.

Not being a stream-oriented device, a network interface isn’t easily mapped to a node in the filesystem, as /dev/tty1 is. The Unix way to call interfaces is by assigning a unique name to them (such as eth0). Such a name doesn’t have a corresponding entry in the filesystem. Communication between the kernel and a network device driver is completely different from that used with char and block drivers. Instead of read and write, the kernel calls functions related to packet transmission.

As a matter of fact, there is another class of ``driver modules'' in Linux: the SCSI[1] drivers. Although every peripheral connected to the SCSI bus appears in /dev as either a char device or a block device, the internal organization of the software is different.

Just as network interfaces provide the network subsystem with hardware-related functionality, a SCSI controller provides the SCSI subsystem with access to the actual interface cable. SCSI is a communication protocol between the computer and peripheral devices, and every SCSI device responds to the same protocol, independently of what controller board is plugged into the computer. The Linux kernel therefore embeds a SCSI ``implementation'' (i.e., the mapping of file operations to the SCSI communication protocol). The driver writer has to implement the mapping between the SCSI abstraction and the physical cable. This mapping depends on the SCSI controller and is independent of the devices attached to the SCSI cable.

In addition to device drivers, there are other drivers, both hardware and software, that are modularized in the kernel. The most important class of modules not specifically implementing a device driver is that of filesystems. A filesystem type is concerned with the way information is organized on a block device in order to represent a tree of directories and files. Such an entity is not a ``device driver,'' in that there’s no explicit device associated with the way the information is laid down; the filesystem type is instead a software driver, because it structures raw data into higher level information.

If you think of how strongly a Unix system depends on the underlying filesystem, you’ll realize that such a software concept is vital to system operation. The ability to decode filesystem information stays at the lowest level of the kernel hierarchy and is of utmost importance; even if you write a block driver for your new CD-ROM, it is useless if you are not able to run ls or cp on the data it hosts. Linux supports filesystem modules, whose software interface declares the different operations that can be performed on a filesystem inode, directory, file, and superblock. Such an interface is completely independent of the actual data transfer to and from the disk, which is accomplished by a block device driver. It’s quite unusual for a programmer to actually need to write a filesystem module, because the official kernel already includes code for the most important filesystem types.

[1] SCSI is an acronym for Small Computer Systems Interface; it is an established standard in the workstation market and is becoming common also for PCs.

Get Linux Device Drivers now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.