“Do you pine for the nice days of Minix-1.1, when men were men and wrote their own device drivers?” Linus Torvalds Pre-requisites In order to develop Linux device drivers, it is necessary to have an understanding of the following:. C programming. Some in-depth knowledge of C programming is needed, like pointer usage, bit manipulating functions, etc. Microprocessor programming. It is necessary to know how microcomputers work internally: memory addressing, interrupts, etc.
All of these concepts should be familiar to an assembler programmer. There are several different devices in Linux. For simplicity, this brief tutorial will only cover type char devices loaded as modules. Kernel 2.6.x will be used (in particular, kernel 2.6.8 under Debian Sarge, which is now Debian Stable). 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.
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 ( kpresenter 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. All of this is shown in figure 1.
Figure 1: User space where applications reside, and kernel space where modules or device drivers reside Interfacing functions between user space and kernel space 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.
Events User functions Kernel functions Load module Open device Read device Write device Close device Remove module. Device driver events and their associated functions between kernel space and the hardware device. The first driver: loading and removing the driver in user space I’ll now show you how to develop your first Linux device driver, which will be introduced in the kernel as a module. For this purpose I’ll write the following program in a file named nothing.c = #include MODULELICENSE('Dual BSD/GPL'); Since the release of kernel version 2.6.x, compiling modules has become slightly more complicated.
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). In the following, I’ll assume that a kernel version 2.6.8 is being used. Next, you need to generate a makefile. The makefile for this example, which should be named Makefile, will be: = obj-m:= nothing.o Unlike with previous versions of the kernel, it’s now also necessary to compile the module using the same kernel that you’re going to load and use the module with.
To compile it, you can type: $ make -C /usr/src/kernel-source-2.6.8 M=`pwd` modules This extremely simple module belongs to kernel space and will form part of it once it’s loaded. In user space, you can load the module as root by typing the following into the command line: # insmod nothing.ko The insmod command allows the installation of the module in the kernel. However, this particular module isn’t of much use. It is possible to check that the module has been installed correctly by looking at all installed modules: # lsmod Finally, the module can be removed from the kernel using the command: # rmmod nothing By issuing the lsmod command again, you can verify that the module is no longer in the kernel. The summary of all this is shown in Table 3. Events User functions Kernel functions Load module insmod Open device Read device Write device Close device Remove module rmmod.
Device driver events and their associated functions between kernel space and the hardware device. The “parlelport” driver: writing to the device Again, you have to add the “writing to the device” function to be able to transfer later this data to user space.
The function outb accomplishes this; it takes as arguments the content to write in the port and its address. = /. Writing to the port./ outb(parlelportbuffer,0x378); Table 10 summarizes this new function. Events Kernel functions Read data inb Write data outb.
Windows does try to help. Microsoft bundles a lot of these manufacturer-provided drivers with Windows, and. When you plug in a new device to your Windows computer and you see the “Installing Driver” bubble pop up, Windows might be downloading a manufacturer-provided driver from Microsoft and installing it on your PC. Microsoft doesn’t write these drivers on its own — it gets them from the manufacturers and provides them to you after vetting them. If hardware isn’t working on Windows, there’s usually a driver to make it work.
Unless you have an ancient device that only works with older versions of Windows, the manufacturer has done the work of making it work with Windows. Hardware that doesn’t work is usually just a quick driver download away from working. How Hardware Drivers Work on Linux Things are different on Linux.
Most of the drivers for hardware on your computer are open-source and integrated into Linux itself. These hardware drivers are generally part of the Linux kernel, although bits of graphics drivers are part of Xorg (the graphics system), and printer drivers are included with CUPS (the print system). That means most of the available hardware drivers are already on your computer, included along with the kernel, graphics server, and print server. These drivers are sometimes developed by hobbyists. But they’re sometimes developed by the hardware manufacturer themselves, who contributes their code directly to the Linux kernel and other projects. In other words, most hardware drivers are included out-of-the-box. You don’t have to hunt down manufacturer-provided drivers for every bit of hardware on your Linux system and install them.
Your Linux system should automatically detect your hardware and use the appropriate hardware drivers. How to Install Proprietary Drivers Some manufacturers to provide their own, closed-source, proprietary drivers. These are hardware drivers that the manufacturers write and maintain on their own, and their closed-source nature means most Linux distributions won’t bundle and automatically enable them for you.
Most commonly, these include the proprietary graphics drivers for both NVIDIA and AMD graphics hardware, which provide more graphics performance for gaming on Linux. There are open-source drivers that can get your graphics working, but they don’t offer the same level of 3D gaming performance. Some Wi-Fi drivers are also still proprietary, so your wireless hardware may not work until you install them.
How you install proprietary drivers depends on your Linux distribution. On Ubuntu and Ubuntu-based distributions, there’s an “Additional Drivers” tool.
Open the dash, search for “Additional Drivers,” and launch it. It will detect which proprietary drivers you can install for your hardware and allow you to install them. Linux Mint has a “Driver Manager” tool that works similarly. Fedora is and doesn’t make them so easy to install. Every Linux distribution handles it in a different way. How to Install Printer Drivers You may need to install drivers for printers, however. When you use a printer-configuration tool to configure CUPS (the Common Unix Printing System), you’ll be able to choose an appropriate driver for your printer from the database.
Generally, this involves finding your printer’s manufacturer in the list and choosing the model name of the printer. You can also choose to provide a PostScript Printer Description, or PPD, file. These files are often part of the Windows driver for PostScript printers, and you may be able to hunt down a PPD file that makes your printer work better. You can provide a PPD file when setting up the printer in your Linux desktop’s printer configuration tool.
Printers can be a headache on Linux, and many may not work properly — or at all — no matter what you do. It’s a good idea to choose printers you know will work with Linux the next time you go printer-shopping. How to Make Other Hardware Work. Occasionally, you may need to install proprietary drivers your Linux distribution hasn’t provided for you.
For example, NVIDIA and AMD both offer driver-installer packages you can use. However, you should strive to use proprietary drivers packaged for your Linux distribution — they’ll work best. In general, if something doesn’t work on Linux out-of-the-box — and if it doesn’t work after installing the proprietary drivers your provides — it probably won’t work at all.
If you’re using an older Linux distribution, upgrading to a newer one will get you the latest hardware support and improve things. But, if something isn’t working, it’s likely that you can’t make it work simply by installing a hardware driver.
Searching for a guide to making a specific piece of hardware work on your specific Linux distribution might help. Such a guide might walk you through finding a manufacturer-provided driver and installing it, which will often require terminal commands. Older proprietary drivers may not work on modern Linux distributions that use modern software, so there’s no guarantee an old, manufacturer-provided driver will work properly. Linux works best when manufacturers contribute their drivers to the kernel as open-source software.
In general, you shouldn’t mess with hardware drivers too much. That’s the vision of Linux — the drivers are open-source and integrated into the kernel and other pieces of software. You don’t have to install them or tweak them — the system automatically detects your hardware and uses the appropriate drivers. If you’ve installed Linux, your hardware should just work — either immediately, or at least after you install some easy-to-install proprietary drivers provided by a tool like the Additional Drivers utility in Ubuntu. If you have to hunt down manufacturer-provided proprietary drivers and extended guides for installing them, that’s a bad sign.
The drivers may not actually work properly with the latest software in your Linux distribution. Image Credit.