Writing Linux Device Drivers A Guide With Exercises Pdf Download Install Update
In order to develop Linux device drivers, it is necessary to have an understanding of the following:. There are several different devices in Linux. For simplicity, this brief tutorial will only cover type char devices loaded as modules. The kernel offers several subroutines or functions in user space, which allow the end-user application programmer to interact with the hardware. Usually, in UNIX or Linux systems, this dialogue is performed through functions or subroutines in order to read and write files.
The reason for this is that in Unix devices are seen, from the point of view of the user, as files. On the other hand, in kernel space Linux also offers several functions or subroutines to perform the low level interactions directly with the hardware, and allow the transfer of information from kernel to user space.
Usually, for each function in user space allowing the use of devices or files , there exists an equivalent in kernel space allowing the transfer of information from the kernel to the user and vice-versa. This is shown in Table 1, which is, at this point, empty. It will be filled when the different device drivers concepts are introduced.
Device driver events and their associated interfacing functions in kernel space and user space. There are also functions in kernel space which control the device or exchange information between the kernel and the hardware. Table 2 illustrates these concepts. This table will also be filled as the concepts are introduced. Device driver events and their associated functions between kernel space and the hardware device.
Since the release of kernel version 2. First, you need to have a complete, compiled kernel source-code-tree. If you have a Debian Sarge system, you can follow the steps in Appendix B towards the end of this article. Next, you need to generate a makefile. The makefile for this example, which should be named Makefile , will be:. To compile it, you can type:. The insmod command allows the installation of the module in the kernel. It is possible to check that the module has been installed correctly by looking at all installed modules:.
By issuing the lsmod command again, you can verify that the module is no longer in the kernel. Device driver events and their associated interfacing functions between kernel space and user space. These tasks are performed, in kernel space, by two functions which need to be present and explicitly declared: The printk function has also been introduced. It is very similar to the well known printf apart from the fact that it only works inside the kernel.
In this way, besides getting the message in the kernel system log files, you should also receive this message in the system console. This module can be compiled using the same command as before, after adding its name into the Makefile. In the rest of the article, I have left the Makefiles as an exercise for the reader. A complete Makefile that will compile all of the modules of this tutorial is shown in Appendix A.
When the module is loaded or removed, the messages that were written in the printk statement will be displayed in the system console. This device will allow a character to be read from or written into it. To develop this driver, several new include statements which appear frequently in device drivers need to be added:. After the include files, the functions that will be defined later are declared. These will also be explained in detail later. Next, the initialization and exit functions—used when loading and removing the module—are declared to the kernel.
Finally, the global variables of the driver are declared: In UNIX and Linux, devices are accessed from user space in exactly the same way as files are accessed. To link normal files with a kernel module two numbers are used: The major number is the one the kernel uses to link a file with its driver.
To achieve this, a file which will be used to access the device driver must be created, by typing the following command as root:. In the above, c means that a char device is to be created, 60 is the major number and 0 is the minor number. It is called with three arguments: It is invoked, when installing the module, in this way:. Also, note the use of the kmalloc function. This function is used for memory allocation of the buffer in the device driver which resides in kernel space. Its use is very similar to the well known malloc function.
Finally, if registering the major number or allocating the memory fails, the module acts accordingly.
This will free the major number for the kernel. The buffer memory is also freed in this function, in order to leave a clean kernel when removing the device driver. The kernel space function, which corresponds to opening a file in user space fopen , is the member open: It takes as arguments: Neither of these functions will be covered in depth within this article.
In this simple example, though, these operations are not performed. The corresponding function for closing a file in user space fclose is the release: But, once again, due to the simplicity of this example, none of these operations are performed. To read a device with the user function fread or similar, the member read: If the position is at the beginning of the file, it is increased by one and the number of bytes that have been properly read is given as a return value, 1.
If not at the beginning of the file, an end of file 0 is returned since the file only stores one byte. To write to a device with the user function fwrite or similar, the member write: Before this module can be used, you will need to compile it in the same way as with previous modules.
The module can then be loaded with:. You can perform the operation like this:. The parallel port is effectively a device that allows the input and output of digital information. More specifically it has a female D connector with twenty-five pins. Internally, from the point of view of the CPU, it uses three bytes of memory.
In a PC, the base address the one from the first byte of the device is usually 0x The connection of the above-mentioned byte with the external connector pins is shown in figure 2.
Both have as arguments the base address of the memory region and its length. It will be very similar to the memory module but substituting the freeing of memory with the removal of the reserved memory of the parallel port. In this case, a real device reading action needs to be added to allow the transfer of this information to user space. The inb function achieves this; its arguments are the address of the parallel port and it returns the content of the port. The function outb accomplishes this; it takes as arguments the content to write in the port and its address.
You have to replace the word memory for the word parlelport throughout the code for the memory module. The final result is shown below:. In the initial section of the driver a different major number is used The reading function is similar to the memory one with the corresponding modifications to read from the port of a device.
Connecting devices to the parallel port can harm your computer. Make sure that you are properly earthed and your computer is turned off when connecting the device. Any problems that arise due to undertaking these experiments is your sole responsibility. In order to use it, you must first ensure that all hardware is correctly connected. Next, switch off the PC and connect the device to the parallel port.
The hotplug module of the Debian Sarge distribution is particularly annoying and should be removed. The module can now be installed, parlelport. The lights will flash successively one after the other! The flashing LEDs and the Linux computer running this program are shown in figure 4. Having followed this brief tutorial you should now be capable of writing your own complete device driver for simple hardware like a relay board see Appendix C , or a minimal device driver for complex hardware.
Learning to understand some of these simple concepts behind the Linux kernel allows you, in a quick and easy way, to get up to speed with respect to writing device drivers. And, this will bring you another step closer to becoming a true Linux kernel developer. Linux device drivers second edition. This book is available for free on the internet. Porting device drivers to the 2.
This is a very valuable resource for porting drivers to the new 2. Nowadays it is probably easier to surf the web for hardware projects like this one. To compile a 2. Three years have elapsed since the first version of this document was written.
It was originally written in Spanish and intended for version 2.
Writing device drivers in Linux: A brief tutorial
Share your knowledge at the LQ Wiki. You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today! Note that registered members see fewer ads, and ContentLink is completely disabled once you log in. Are you new to LinuxQuestions. Visit the following links:
Windows Programming/Device Driver Introduction
This article explains the creation process of a Linux kernel device driver for an undocumented USB device. In addition to the kernel driver I introduce a simple user-space tool that can be used to control the device. Although I have to delve into the specifics of a particular device, the process can be applied to other USB devices as well. Recently, I found a fancy device while searching eBay: The manufacturer neither provides a Linux driver nor publishes the USB protocol specification. The proper way to write a device driver for the missile launcher would hence be to leverage this API and ignore any kernel specifics. Nevertheless, I wanted to get involved with kernel programming and decided thus to write a kernel module despite the increased complexity and higher effort. The remainder of this article is structured as follows. After pointing to some related work, I give a quick USB overview. Thereafter, I present the reverse-engineering process to gather the unknown USB commands steering the missile launcher. To come up with a full-featured kernel device driver, I describe the kernel module architecture which incorporates the derived control commands. Finally, I demonstrate a simple tool in user-space that makes use of the driver.