UNIX System Administration Handbook - Evi Nemeth [153]
The minor device number is sometimes used by the driver to select the particular characteristic of a device. For example, a single tape drive can have several files in /dev representing it in various configurations of recording density and rewind characteristics. In essence, the driver is free to interpret the minor device number in whatever way it wants. Look up the man page for the driver to determine what convention it’s using.
There are actually two types of device files: block device files and character device files. A block device is read or written one block (a group of bytes, usually a multiple of 512) at a time; a character device can be read or written one byte at a time. Some devices support access through both block and character device files. Disks and tapes lead dual lives; terminals and printers do not.
Device drivers present a standard interface to the kernel. Each driver has routines for performing some or all of the following functions:
attach close dump ioctl open probe
psize read receive reset select stop
strategy timout transmit write
It is sometimes convenient to implement an abstraction as a device driver even when it controls no actual device. Such phantom devices are known as pseudo-devices. For example, a user who logs in over the network is assigned a PTY (pseudo-TTY) that looks, feels, and smells like a serial port from the perspective of high-level software. This trick allows programs written in the days when everyone used a TTY to continue to function in the world of windows and networks.
When a program performs an operation on a device file, the kernel automatically catches the reference, looks up the appropriate function name in a table, and transfers control to it. To perform an unusual operation that doesn’t have a direct analog in the filesystem model (for example, ejecting a floppy disk), the ioctl system call can be used to pass a message directly from user space into the driver.
Drivers and their corresponding configuration files are typically stashed in a nonobvious location to prevent the uninitiated from mucking with them. Table 12.8 outlines the default locations of drivers and their config files.
Table 12.8 Driver configuration files by system
In the sections below, we show three scenarios for adding a new driver to the kernel: for Solaris, Linux, and FreeBSD. We won’t cover adding a driver to HP-UX because third-party devices are relatively rare in that environment (HP-UX comes with drivers for all HP hardware).
Adding a Solaris device driver
Adding a device driver to Solaris is the easiest of all. Solaris drivers are usually distributed as a package. You can use pkgadd to automatically add the device driver to the system. When device drivers are not distributed as a package or when package addition fails, it’s trivial to add the drivers by hand because they are all implemented as loadable kernel modules.
Solaris drivers are almost always distributed as object files, not as source code as is common on FreeBSD and Linux systems. In this example, we add the device “snarf” to Solaris. The snarf driver should come with at least two files, including snarf.o (the actual driver) and snarf.conf (a configuration file). Both files should go into the /platform/sun4u/kernel/drv directory.
Once the .conf file has been copied over, you can edit it to specify particular device parameters. You should not normally need to do this, but sometimes configuration options are available for fine-tuning the device for your application.
After the files have been copied into place, you’ll need to load the module. You insert loadable kernel modules into the running kernel with the add_drv command. (More on loadable kernel modules later in this chapter.) In this case, we’ll load snarf into the kernel by running the command add_drv snarf. That’s it! This is definitely the least painful of our three examples.
Adding a Linux device driver
On Linux systems, device drivers are typically distributed