Updated: Aug 7, 2019
Device driver in Linux:
There are a number of reasons to be interested in the writing a Linux device driver. The rate at which new hardware becomes available (and obsolete!) alone guarantees that driver writers will be busy for the foreseeable future.The Linux kernel remains a large and complex body of code, Where device drivers take on a special role in them, look at your device driver from a different perspective: it is a software layer that lies between the applications and the actual device as shown in the pictures. This privileged role of the driver allows the driver programmer to choose exactly how the device should appear: different drivers can offer different capabilities, even for the same device.The programming interface has become easy to write for Linux device drivers from the kernel as there are hundreds of them available.
Things to keep in mind while writing device driver:
When writing a driver, programmer should pay particular attention to this fundamental concept: The distinction between Mechanism and Policy is one of the best ideas behind this. Most programming problems can indeed be split into two parts, "What capabilities to be provided" (the mechanism) and "How those capabilities can be used" (the policy). If the two issues are addressed by different parts of the program, or even by different programs altogether, the software package is much easier to develop and to adapt to particular needs, write kernel code to access the hardware but don’t force particular policies on the user, since different users have different needs. To do this, the driver programmer has complete freedom to determine how to handle concurrency, memory mapping etc Many device drivers, indeed, are released together with user programs to help with configuration and access to the target device. Those programs can range from simple utilities to complete graphical application. In device driver there are MAJOR and MINOR number representing the hardware to which driver to be assigned, kernel looks up for major number and allocates the driver respectively but the kernel necessarily need minor number, it is used for tracking which devices which are using the driver.
Splitting the Kernel:
The kernel is the big chunk of executable code in charge of handling all such requests, it's role
can be split into following parts:
Process management: The kernel is in charge of creating, destroying and handling process connection to the input and output. The communication between different processes will be done through signals, pipes or inter-process communication.
Memory Management: The computer's memory is a major resource in the system. The kernel builds up a virtual addressing space for processes and can be interacted through set of function calls, ranging from simple malloc/free to more complex functionalities.
File System: Linux is heavily based on the file system concept. The kernel builds a structured file system on top of unstructured hardware and the resulting file abstraction is heavily used throughout the whole system.
Device Control: The kernel must have embedded in it a device driver for every peripheral present on a system, from the hard drive to the keyboard and the tape drive.
Networking: The system is in charge of delivering data packets across program and network interfaces, and it must control the execution of programs according to their network activity.
One of the good feature of Linux is the ability to add the functionalities to the kernel at the run time. Any piece of code that is added at the run time is known as Modules. We can add these modules through insmod and can be removed through rmmod.
We will be discussing about loadable modules in the upcoming series in-depth, letting you understand how do they work, syntax and declaration.
Different types of device drivers:
The Linux way of looking devices distinguishes between three fundamental device types.
Character Device: A character (char) devices is accessed through stream of bytes and is also responsible to implement this kind of behavior. These drivers usually implements at-least OPEN, CLOSE, READ and WRITE system calls. Char devices are accessed by means of file system nodes /dev/tty1 and /dev/lp0 (these miht vary), the only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially.
Block Device: Block devices are also accessed by file system nodes in the /dev directory (these might vary). Unlike UNIX, Linux allows the applications to read and write with 512 bytes in length (It will be varied) It also permits to transfer any number of bytes at a time. As a result, block and char devices differ only in the way data is managed internally by the kernel-making difference between them is transparent to the users.
Network Device: A network interface is in charge of sending and receiving data packets, this interface might be hardware or software devices. A network driver knows nothing about individual connections, it only handles packets. Communication between the kernel and a network device driver is completely different from char and block drivers instead of read and write, the kernel calls functions related to packet transmission.
We will be discussing about the device drivers in-depth in the upcoming series!