Chapter 3. Char Drivers

The goal of this chapter is to write a complete char device driver. We’ll develop a character driver because this class is suitable for most simple hardware devices. Char drivers are also easier to understand than, for example, block drivers. Our ultimate aim is to write a modularized char driver, but I won’t talk about modularization issues in this chapter.

Throughout the chapter, I’ll present code fragments extracted from a real device driver: scull, short for “Simple Character Utility for Loading Localities.” scull is a char driver that acts on a memory area as though it were a device. A side effect of this behavior is that as far as scull is concerned, the word ``device'' can be used interchangeably with ``the memory area used by scull.''

The advantage of scull is that it isn’t hardware dependent, since every computer has memory. scull just acts on some memory, which is allocated using kmalloc. Anyone can compile and run scull, and scull is portable across the computer architectures on which Linux runs. On the other hand, the device doesn’t do anything ``useful'' other than demonstrating the interface between the kernel and char drivers and allowing the user to run some tests.

The Design of scull

The first step of driver writing is defining the capabilities (the ``mechanism'') the driver will offer to user programs. Since our ``device'' is part of the computer’s memory, we’re free to do what we want with it. It can be a sequential or random-access device, one device or many, and so on.

In order for scull to be useful as a template for writing real drivers for real devices, I’ll show you how to implement several device abstractions on top of the computer memory, each with a different personality.

The scull source implements the following devices. Each kind of device implemented by the module is referred to as a ``type'':

scull0-3

Four devices consisting of four memory areas that are both global and persistent. ``Global'' means that if the device is opened multiple times, the data is shared by all the file descriptors that opened it. ``Persistent'' means that if the device is closed and reopened, data isn’t lost. This device can be fun to work with, because it can be accessed and tested using conventional commands, like cp, cat, and the shell I/O redirection; we’ll examine its internals in this chapter.

scullpipe0-3

Four ``fifo'' devices, which act like pipes. One process reads what another process is writing. If more processes read the same device, they contend for data. The internals of scullpipe will show how blocking and nonblocking read and write can be implemented; this happens without having to resort to interrupts. Although real drivers synchronize with their devices using hardware interrupts, the topic of blocking and nonblocking operations is an important one and is conceptually detached from interrupt handling (covered in Chapter 9).

scullsingle , scullpriv , sculluid , scullwuid

These devices are similar to scull0, but with some limitations on when an open is permitted. The first (scullsingle) allows only one process at a time to use the driver, while scullpriv is private to each virtual console (the device is private to the console). sculluid and scullwuid can be opened multiple times, but only by one user at a time; the former returns -EBUSY if another user is locking the device, while the latter implements blocking open. These devices will be used to show how different access policies can be implemented.

Each of the scull devices demonstrates different features of a driver, and presents different difficulties. This chapter covers the internals of scull0-3; the more advanced devices will be covered in Chapter 5: scullpipe is described in Section 5.2.5 and the others in Section 5.6.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.174.76