Writing a Linux Driver

The main goal of this article is to learn what a driver is, how to implement a driver for Linux and how to integrate it into the operating system—an article for the experienced C programmer.

The concept of an operating system (OS)
must be well understood before any attempt to navigate inside it is
made. Several definitions are available for an OS:

An OS is the set of manual and automatic procedures
which allow a set of users to share a computing system in an
efficient manner.

The dictionary defines an OS as a program or set of
programs which manage the processes of a computing system and allow
the normal execution of the other jobs.

The definition from the Tanenbaum book (see
Resources): An operating system is [the program] which controls all
the resources of the computer and offers the support where users
can develop application programs.

It is also very important to clearly distinguish a
program from a process. A
program is a block of data plus instructions, which is stored in a
file on disk and is ready to be executed. On the other hand, a
process is an image in memory of the program which is being
executed. This difference is highly important, because usually the
processes are running under OS control. Here, our program is the
OS, so we cannot speak about processes.

We will use the term kernel to refer to
the main body of the OS, which is a program written in the C
language. The program file may be named vmlinuz, vmlinux or zImage,
and has some things in common with the MS-DOS files COMMAND.COM,
MSDOS.SYS and IO.SYS, although their functionality is different.
When we discuss compilation of the kernel, we
mean that we will edit the source files in order to generate a new
kernel.

Peripheral or internal devices allow
users to communicate with the computer. Examples of devices are:
keyboards, monitors, floppy and hard disks, CD-ROMs, printers, mice
(serial/parallel), networks, modems, etc. A
driver is the part of the OS that manages
communication with devices; thus, they are usually called
device drivers.

What is a Driver?

Figure 1. Software/Hardware Scheme

Figure 1 shows the relation between user programs, the OS and
the devices. Differences between software and hardware are clearly
specified in this scheme. At the left side, user programs may
interact with the devices (for example, a hard disk) through a set
of high-level library functions. For example, we can open and write
to a file of the hard disk calling the C library functions
fopen,
fprintf and
close:

Each device can be referred to as a special file named /dev/*.
Internally, the OS is composed of a set of drivers, which are
pieces of software that perform the low-level communication with
each device. At this execute level, the kernel calls driver
functions such as lp_open() or
lp_write().

On the right side of Figure 1, the hardware is composed of
the device (a video display or an Ethernet link) plus an interface
(a VGA card or a network card). Finally, the device driver is the
physical interface between the software and the hardware. The
driver reads from and writes to the hardware through ports (memory
addresses where the hardware links physically), using the internal
functions out_p and
in_p:

out_p(0x3a, 0x1f);
data = in_p(0x3b);

Note that these functions are not available to the user.
Since the Linux kernel runs in protected mode, the low memory
addresses, where the ports addresses reside, are not user
accessible. Functions equivalent to the low-level functions
in and
out do not exist in the high-level
library, as in other operating systems such as MS-DOS.

This article twice uses the term "protected mode" where it should be using the term "supervisor mode".

Protected mode is a mode of the Intel x86 processor which provides various protection features, such as memory protection and the ability to disable privileged instructions. Under Linux, all software runs in protected mode, but user applications run at a different privilege level to the kernel.

Of course this article is quite out of date (though surprisingly much of it is still relevant) but on this point it was wrong even back when it was written.