%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%									%
%	Copyright (C) 1992, 1993 Michael K. Johnson,			%
%	johnsonm@SunSITE.unc.edu					%
%									%
%	This file is freely copyable, but you must preserve this	%
%	copyright notice on all copies, it must only be distributed	%
%	as part of the Linux Kernel Hackers' Guide, and its use is	%
%	is subject to the conditions expressed in the copyright for	%
%	the whole guide, in the file prelim/copyright.tex		%
%									%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\chapter{Device Drivers}\label{chap-driver}

\section{What is a Device Driver?}

Making hardware work is tedious.  To write to a hard disk, for
example, requires that you write magic numbers in magic places, wait
for the hard drive to say that it is ready to receive data, and then
feed it the data it wants, very carefully.  To write to a floppy disk
is even harder, and requires that the program supervise the floppy
disk drive almost constantly while it is running.

Instead of putting code in each application you write to control each
device, you share the code between applications.  To make sure that
that code is not compromised, you protect it from users and normal
programs that use it.  If you do it right, you will be able to add and
remove devices from your system without changing your applications at
all.  Furthermore, you need to be able to load your program into
memory and run it, which the operating system also does.  So, an
operating system is essentially a preiviledged, general, sharable
library or low-level hardware and memory and process control functions
and routines.

All versions of \unix\ have an abstract way of reading and writing
devices.  By making the devices act as much as possible like regular
files, the same calls ({\tt read()}, {\tt write()}, etc.) can be used
for devices and files.  Within the kernel, there are a set of
functions, registered with the filesystem, which are called to handle
requests to do I/O on ``device special files,'' which are those which
represent devices.\footnote{See {\tt mknod(1,2)} for an explanation of
how to make these files.}

All devices controlled by the same device driver are given the same
{\bf major number,} and of those with the same major number, different
devices are distinguished by different {\bf minor
numbers.}\footnote{This is not strictly true, but is close enough.  If
you understand where it is not true, you don't need to read this
section, and if you don't but want to learn, read the code for the tty
devices, which uses up 2 major numbers, and may use a third and
possibly fourth by the time you read this.}

This chapter explains how to write any type of \linux\ device driver
that you might need to, including character, block, SCSI, and network
drivers. {\bf [Well, it will when it is done\dots]}  It explains what
functions you need to write, how to initialize your drivers and obtain
memory for them efficiently, and what function are built in to \linux\
to make your job easier.

Creating device drivers for \linux\ is easier than you might think.
It merely involves writing a few functions and registering them with
the Virtual Filesystem Switch (VFS), so that when the proper device
special files are accessed, the VFS can call your functions.

However, a word of warning is due here: Writing a device driver {\bf
is} writing a part of the \linux\ kernel.  This means that your driver
runs with kernel permissions, and can do anything it wants to: write
to any memory, reformat your hard drive, damage your monitor or video
card, or even break your dishes, if your dishwasher is controlled by
your computer.  Be careful.

Also, your driver will run in kernel mode, and the \linux\ kernel,
like most \unix\ kernels, is non-pre-emptible.  This means that if you
driver takes a long time to work without giving other programs a
chance to work, your computer will appear to ``freeze'' when your
driver is running.  Normal user-mode pre-emptive scheduling does not
apply to your driver.

If you choose to write a device driver, you must take everything
written here as a guide, and no more.  I cannot guarantee that this
chapter will be free of errors, and I cannot guarantee that you will
not damage your computer, even if you follow these instructions
exactly.  It is highly unlikely that you will damage it, but I cannot
guarantee against it.  There is only one ``infallible'' direction I can
give you: {\bf Back up!}  Back up before you test your new device
driver, or you may regret it later.

\input{devices/fake}

\input{devices/basics}

\input{devices/char}

\input{devices/block}

\input{devices/reference}

\input{devices/scsi}

\input{devices/network}