Linux Device Driver
Have you ever wondered how a computer plays audio, shows video, Gets Input from a keyboard or Mouse, and how it is understanding like it is an input device named as a mouse? The answer is: by using device drivers. A few years ago we would always install audio or video drivers after installing MS Windows XP. Only then we were able to listen to the audio. Let us explore device drivers in this column.
One of the many advantages of free operating systems, as typified by Linux, is that their internals is open for all to view. The operating system, once a dark and mysterious area whose code was restricted to a small number of programmers, can now be readily examined, understood, and modified by anybody with the requisite skills. Linux has helped to democratize operating systems. The Linux kernel remains a large and complex body of code, however, and would-be kernel hackers need an entry point where they can approach the code without being overwhelmed by complexity. Often, device drivers provide that gateway.
The device drivers take on a special role in the Linux kernel. They are distinct “black boxes” that make a particular piece of hardware respond to a well-defined internal programming interface; they hide completely the details of how the device works. User activities are performed by means of a set of standardized calls that are independent of the specific driver; mapping those calls to device-specific operations that act on real hardware is then the role of the device driver. This programming interface is such that drivers can be built separately from the rest of the kernel and “plugged in” at runtime when needed. This modularity makes Linux drivers easy to write, to the point that there are now hundreds of them available.
What is a User space and kernel space?
When you write device drivers, it’s important to make the distinction between “user space” and “kernel space”.
- Kernel space: The Linux (which is a kernel) manages the machine’s hardware in a simple and efficient manner, offering the user a simple and uniform programming interface. In the same way, the kernel, and in particular its device drivers, form a bridge or interface between the end-user/programmer and the hardware. Any subroutines or functions forming part of the kernel (modules and device drivers, for example) are considered to be part of kernel space.
- User-space: End-user programs, like the UNIX shell or other GUI based applications (presenter for example), are part of the user-space. Obviously, these applications need to interact with the system’s hardware. However, they don’t do so directly, but through the kernel supported functions.
Linux has a monolithic kernel. For this reason, writing a device driver for Linux requires performing a combined compilation with the kernel. Another way around is to implement your driver as a kernel module, in which case you won’t need to recompile the kernel to add another driver. We’ll be concerned with this second option: kernel modules.
A Linux module is a specifically designed object file. When working with modules, Linux links them to its kernel by loading them to its address space. The Linux kernel was developed using the C programming language and Assembler. C implements the main part of the kernel, and Assembler implements parts that depend on the architecture. Unfortunately, these are the only two languages we can use for writing Linux device drivers. We cannot use C++, which is used for the Microsoft Windows operating system kernel, because some parts of the Linux kernel source code – header files, to be specific – may include keywords from C++ (for example, delete or new), while in Assembler we may encounter lexemes such as :
We run the module code in the kernel context. This requires a developer to be very attentive, as it entails extra responsibilities: if a developer makes a mistake when implementing a user-level application, this will not cause problems outside the user application in most cases; but if a developer makes a mistake when implementing a kernel module, the consequences will be problems at the system level. Luckily for us, the Linux kernel has a nice feature of being resistant to errors in module code. When the kernel encounters non-critical errors (for example, null pointer dereferencing), you’ll see the oops message (insignificant malfunctions during Linux operation are called oops), after which the malfunctioning module will be unloaded, allowing the kernel and other modules to work as usual. In addition, you’ll be able to find a record in the kernel log that precisely describes this error. But be aware that continuing work after an oops message is not recommended, as doing so may lead to instability and kernel panic.
The kernel and its modules essentially represent a single program module – so keep in mind that a single program module uses a single global namespace. In order to minimize it, you must watch what is being exported by the module: exported global characters must be named uniquely (a commonly used workaround is to simply use the name of the module that’s exporting the characters as a prefix) and must be cut to the bare minimum.
What is a Linux Device Driver?
A device driver is a particular form of software application that is designed to enable interaction with hardware devices. Without the required device driver, the corresponding hardware device fails to work. A device driver usually communicates with the hardware by means of the communications subsystem or computer bus to which the hardware is connected. Device drivers are operating system-specific and hardware-dependent. A device driver acts as a translator between the hardware device and the programs or operating systems that use it.
Simply if I will explain to you what is a device driver that it is a program running in the kernel module and called by application software to control the external electronic devices connected with Main Processor as per the functional requirement. We can also say as A program which drives the devices to function as per application program request called a Device driver.
How does Device Driver work in Linux System?
If the meaning of the device driver we understood, then let’s go discuss how it really works. But mostly since we are discussing here on the Linux system, we should have the overall knowledge about it. If not I would like to request you please go through my Linux System Architecture tutorial.
The Device Driver basically having a set of programs. Each program is a function that can do a particular job with given input data or value. If you are going to design any computer system, it is nothing like you will need a single processor that can control the full system. It is very difficult to run all the programs in a single processor. Though you can do it, you can not design all the hardware for your system. So you need to divide the total system into different slave parts and that also can be controlled by the master machine or processor. The advantage is that instead of worrying about each module functionality nothing but device hardware, you can purchase it from other vendors, and quickly you can program it so that your main processor can understand it. Then easily at low cost and less time, you will be having a full system.
For example, you can purchase a computer desktop from a company, and then we can purchase any device from the market like a mouse, keyboard, speaker camera, etc. as per our requirement. Then install the device driver if it is not available as default in the Operating system, then connect it with the computer and use it. Generally a device nothing but a slave machine that can do a specific job controlled by a master machine. The slave machine nothing but a device. To communicate that slave machine with the Main processor, we need three things. One is what kind of device it is, the second is what it can understand, and the third is how it can understand. To fulfill it we need two modules of the Linux Operating System.
How Does The Processor Understand a Device?
A firmware program module by which the Operating System or the main master machine can communicate with the slave device. Basically, we can not say what protocol the device is able to understand. When we will purchase it we should know that this protocol should be available in our system. then only we can write that protocol firmware program module for interfacing that device. There are so many communication methods like I2C, SPI, CAN, LIN, etc. We can use any of them so that we need to write the firmware program in our processor first.
How Does The Processor Control a Device?
Second is the commands nothing but the device driver programs. The commands are nothing but the specific and unique instructions to the device. By using these commands, the device can be controlled. Because these commands are already have been implemented in this device so that if you will send that particular command it will execute a set of programs inside it to do a specific task. Not only the task but also initialize, de-initialize, open, close, etc. Like suppose you want to on that device, then for this, the Device OEM will be having a specific command. These commands are basically in the hexadecimal number system. So before we use that device or start to write the device driver program for it, we need to understand all these commands and the process of control like when to on, when to off and how to do it.
All these concepts with specific commands will be available in the document provided by the device manufacturer. The commands are like 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xB0, 0xB1 are defined in this document. We need to go through this document, understand it properly, and then we will start to write a program. Suppose to initialize the device, the command is A0, to de-initialize, it is A1, to Open, it is A2, to close it is A3, etc. So we need to use all these commands and make a frame packet for each commands as per the protocol supported in that device. Which we have already written a firmware program for it. Then we can write each program for a specific task nothing but a function. So when we need that specific task we can call that function and that can do this task.
Generally, to interface and control any device by our processor, we need to have very basic functions. These are open(), close(), Read(), Write(), Control(). For any device driver program, we are going to write at least we should have these functions to interface any device with our system. So for a particular device, we need to write all these functions make a module with a name as per the device functionality. Then we can add this in the kernel module. Then all the file header files need to be added in the application functionality module so that we can call these functions in our application layer to make a full system ready for work. Actually there are different types of devices for different purposes like Memory card which only for data read or write but a keyboard which only for reading a character of data etc. Let’s go discuss different types of the device driver.
Linux Device Driver Types
(1) Character Device Driver
A char file is a hardware file that reads/writes data in character by character fashion. Some classic examples are keyboard, mouse, serial printer. If a user uses a char file for writing data no other user can use the same char file to write data that block access to other users. Character files use synchronize Technic to write data. Of you observe char files are used for communication purpose and they can not be mounted.
You can follow this link to learn Linux Character Driver
(1) Block Device Driver
A block file is a hardware file that reads/writes data in blocks instead of character by character. This type of file is very much useful when we want to write/read data in a bulk fashion. All our disks such are HDD, USB, and CDROMs are block devices. This is the reason when we are formatting we consider block size. The write of data is done in an asynchronous fashion and it is CPU intensive activity. These devices files are used to store data on real hardware and can be mounted so that we can access the data we have written.
(1) Network Device Driver
A network device is, so far as Linux’s network subsystem is concerned, an entity that sends and receives packets of data. This is normally a physical device such as an ethernet card. Some network devices though are software only such as the loopback device which is used for sending data to yourself.