What is a device Driver?

Classes of Devices and Modules

Loading and removing device drivers

User space and Kernel space

Module initialization and shutdown

Module parameter values

like options to a command line program
here's an example.

insmod my_module ival=92 sval="my driver"

To read these in the kernel code, the code would look like the following:

int ival=0;
char *sval;

MODULE_PARM (ival, "i");
MODULE_PARM (sval, "s");

The "i" indicates the value is an integer, the "s" indicates the value is a string.

More appropriately for the lab:

int base_port = 0x300;
MODULE_PARM (base_port, "i");
MODULE_PARM_DESC (base_port, "The base I/O port (default 0x300)");

Major and Minor numbers

Here is an example from ls -l

crw-rw-rw- 1 root dialout 4, 64 Jun 30 11:19 ttyS0
crw-rw-rw- 1 root dialout 4, 65 Aug 16 00:00 ttyS1

The first letter in the permissions says that the device is a char device. After the group and owner, we see the device uses driver 4. ttyS0 hase minor 64 while ttyS1 has minor 65.

Adding a new driver to the system means assigning a major number to it. The assignment should be made at driver (module) initialization by calling the following function, defined in < linux/fs.h >:

int register_chrdev(unsigned int major, const char *name,
      struct file_operations *fops);

Once the driver has been registered in the kernel table, its operations are associated with the given major number.

For example:
mknod /dev/ibus0 c 40 1

You may use dynamic allocation of major numbers in your driver by using 0 as the major number of register_chrdev.

Use unregister_chrdev to unregister the driver.

File Operations

The read and write methods copy data from and to application code. It is important to use (and understand)

unsigned long copy_to_user(void *to, const void *from,
      unsigned long count);

unsigned long copy_from_user(void *to, const void *from,
      unsigned long count);

In the driver code you need to write (in the read method), you may have a line such as:

copy_to_user(buf, &portdata,retval);

Before you use this, you will want to read data from the port

portdata=inb(port);

Look at the online O'Reilly book to see what the return values of read and write should be. Also read chapter 3 (and ideally the first two chapters for more detailed information about writing device drivers.