The kernel runs as a single process. In Linux kernel (modular kernel) there is a facility to insert and remove “loadable kernel module” at run time. These loadable kernel modules are called device drivers if they provide the mechanism to access a device from the user space application. The most of the part of the Linux kernel is the device drivers.
There are 3 types of drivers – character driver, block driver and pipe driver. In character drivers one byte of the data is accessed at a instant of time.
One most important part of the driver is the Major and Minor numbers. The kernel distinguishes between various driver through their Major numbers and the Driver distinguishes between various devices (those are using the same driver) by a assigning a unique Minor number to it. The Major Minor combination is used to represent a unique device into a system.
Whenever we have to insert a loadable kernel module in the kernel we can use the “insmod” command. As the “insmod” command executes the initialization routine of the driver executes. And when the “rmmod” mode command runs the cleanup routine of the module executes.
To write a kernel code we generally use the kernel objects which are already present in the kernel symbol table. These symbols are exported by the other routines of the kernel code which is already present in the kernel.
In writing of a character driver, we first have to write the initialization function and the cleanup function. These functions provide the facilities to insert the module into the Linux kernel and to remove the module from the Linux kernel. While writing the driver whatever the functionality we want that “This should run when the module will be inserted in the Linux kernel”, we have to include those in the initialization function e.g.- registration of driver. And whatever we want that “This should run when the module will be removed from the Linux kernel”, we have to include those in the cleanup function.
To access a device through the driver we first has to open that device. The open driver routine is written for this purpose. To write the data on the memory of the device the write driver routine is used and to read the data present on the memory of the device the read driver routine is written.
These driver routines are mapped to the system calls. System calls are used by the application to access the device. Although system calls have some by default routines but in the driver we defines the system call according to the requirement of the device. These driver routines and the system calls of the user level interacts with each others via node present in the virtual filesystem. The driver routines uses various kernel data structures for various representations and uses various kernel macros for different operations and finally various logics implemented according to the requirement of the device. These logics defines the functionality of the device and hence the complete driver provides the mechanism
to access the device.