background preloader

LDD

Facebook Twitter

Device Drivers, Part 1: Linux Device Drivers for Your Girl Friend. This series on Linux device drivers aims to present the usually technical topic in a way that is more interesting to a wider cross-section of readers. “After a week of hard work, we finally got our driver working,” were Pugs’ first words when he met his girlfriend, Shweta. “Why? What was your driver up to? Was he sick? And what hard work did you do?” Asked Shweta. Confused, Pugs responded, “What are you talking about?” Now it was Shweta’s turn to look puzzled, as she replied, “Why ask me? When understanding dawned on him, Pugs groaned, “Ah c’mon! “I know about car and bus drivers, pilots, and even screwdrivers; but what is this ‘device driver’?” That was all it took to launch Pugs into a passionate explanation of device drivers for the newbie — in particular, Linux device drivers, which he had been working on for many years.

Of drivers and buses A driver drives, manages, controls, directs and monitors the entity under its command. Figure 1: Device and driver interaction Verticals Summing up. Device Drivers, Part 10: Kernel-Space Debuggers in Linux. Shweta, back from hospital, was relaxing in the library, reading various books. Ever since she learned of the ioctl way of debugging, she was impatient to find out more about debugging in kernel-space. She was curious about how and where to run the kernel-space debugger, if there was any. This was in contrast with application/user-space debugging, where we have the OS running underneath, and a shell or a GUI over it to run the debugger (like gdb, and the data display debugger, ddd). Then she came across this interesting kernel-space debugging mechanism using kgdb, provided as part of the kernel itself, since kernel 2.6.26. The debugger challenge in kernel-space As we need some interface to be up to run a debugger to debug anything, a kernel debugger could be visualised in two possible ways: Put the debugger into the kernel itself, accessible via the usual console.

Setting up the Linux kernel with kgdb First of all, the kernel to be debugged needs to have kgdb enabled and built into it. Device Drivers, Part 7: Generic Hardware Access in Linux. Device Drivers, Part 6: Decoding Character Device File Operations. This article, which is part of the series on Linux device drivers, continues to cover the various concepts of character drivers and their implementation, which was dealt with in the previous two articles [1, 2].

So, what was your guess on how Shweta would crack the problem? Obviously, with the help of Pugs. Wasn’t it obvious? In our previous article, we saw how Shweta was puzzled by not being able to read any data, even after writing into the /dev/mynull character device file. Suddenly, a bell rang — not inside her head, but a real one at the door. And for sure, there was Pugs. “How come you’re here?” “I saw your tweet. “I’ll tell you, on the condition that you do not play spoil sport,” replied Shweta. Pugs smiled, “Okay, I’ll only give you advice.” “And that too, only if I ask for it! Pugs perked up, saying, “I have an idea. Shweta felt that was a good idea. However, the return types of both my_read() and my_write() are not int, rather, it is ssize_t. Reading the device file “Aha!! Device Drivers, Part 5: Character Device Files -- Creation & Operations.

In my previous article, I had mentioned that even with the registration for the <major, minor> device range, the device files were not created under /dev — instead, Shweta had to create them manually, using mknod. However, on further study, Shweta figured out a way to automatically create the device files, using the udev daemon. She also learnt the second step to connect the device file with the device driver — linking the device file operations to the device driver functions. Here is what she learnt. Automatic creation of device files Earlier, in kernel 2.4, the automatic creation of device files was done by the kernel itself, by calling the appropriate APIs of devfs.

However, as the kernel evolved, kernel developers realised that device files were more related to user-space and hence, as a policy, that is where they ought to be dealt with, not at the kernel. Udev can be further configured via its configuration files to tune the device file names, their permissions, their types, etc. Device Drivers, Part 2: Writing Your First Linux Driver in the Classroom. This article, which is part of the series on Linux device drivers, deals with the concept of dynamically loading drivers, first writing a Linux driver, before building and then loading it.

Shweta and Pugs reached their classroom late, to find their professor already in the middle of a lecture. Shweta sheepishly asked for his permission to enter. An annoyed Professor Gopi responded, “Come on! You guys are late again; what is your excuse, today?” Pugs hurriedly replied that they had been discussing the very topic for that day’s class — device drivers in Linux. Pugs was more than happy when the professor said, “Good! He explained, “As we know, a typical driver installation on Windows needs a reboot for it to get activated.

This impressed the professor. Dynamically loading drivers These dynamically loadable drivers are more commonly called modules and built into individual files with a .ko (kernel object) extension. Figure 1: Linux pre-built modules Figure 2: Linux module operations Summing up. Concurrency in the Kernel. As the Linux kernel has grown in complexity to support Symmetric Multi-Processing (SMP) and kernel preemption, more and more scenarios generate multiple threads of execution. Because threads can simultaneously operate on shared kernel data structures, access to such data structures has to be serialized. In this column, let’s learn the basics of protecting shared kernel resources from concurrent access, starting with a simple example and slowly introducing complexities like interrupts, kernel preemption, and SMP. Spinlocks and Semaphores A code area that accesses shared resources is called a critical section.

Spinlocks and semaphores are the two mechanisms used to protect critical sections in the kernel. A spinlock ensures that only a single thread enters a critical section at any time. Any other thread that wants to enter the critical section must wait “spinning its wheels” until the first thread exits. #include <linux/spinlock.h> /* Initialize */spinlock_t mylock = SPIN_LOCK_UNLOCKED; Device Drivers, Part 4: Linux Character Drivers.

This article, which is part of the series on Linux device drivers, deals with the various concepts related to character drivers and their implementation. Shweta, at her PC in her hostel room, was all set to explore the characters of Linux character drivers, before it was taught in class. She recalled the following lines from professor Gopi’s class: “… today’s first driver would be the template for any driver you write in Linux. Writing any specialised/advanced driver is just a matter of what gets filled into its constructor and destructor…” With that, she took out the first driver’s code, and pulled out various reference books, to start writing a character driver on her own. She also downloaded the online book, Linux Device Drivers by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman.

Here is the summary of what she learnt. W’s of character drivers We already know what drivers are, and why we need them. The complete connection Figure 1: Character driver overview Summing up. Device Drivers, Part 9: I/O Control in Linux. “Get me a laptop, and tell me about the x86 hardware interfacing experiments in the last Linux device drivers’ lab session, and also about what’s planned for the next session,” cried Shweta, exasperated at being confined to bed due to food poisoning at a friend’s party. Shweta’s friends summarised the session, and told her that they didn’t know what the upcoming sessions, though related to hardware, would be about. When the doctor requested them to leave, they took the opportunity to plan and talk about the most common hardware-controlling operation, ioctl(). Introducing ioctl() Input/Output Control (ioctl, in short) is a common operation, or system call, available in most driver categories.

It is a one-bill-fits-all kind of system call. The question is: how can all this be achieved by a single function prototype? However, from kernel 2.6.35, it changed to: Querying driver-internal variables Using these, the driver’s ioctl() implementation in query_ioctl.c would be as follows: The Linux Kernel Module Programming Guide. Peter Jay SalzmanMichael BurianOri Pomerantz Copyright © 2001 Peter Jay Salzman 2007-05-18 ver 2.6.4 The Linux Kernel Module Programming Guide is a free book; you may reproduce and/or modify it under the terms of the Open Software License, version 1.1.

You can obtain a copy of this license at This book is distributed in the hope it will be useful, but without any warranty, without even the implied warranty of merchantability or fitness for a particular purpose. The author encourages wide distribution of this book for personal or commercial use, provided the above copyright notice remains intact and the method adheres to the provisions of the Open Software License. Derivative works and translations of this document must be placed under the Open Software License, and the original copyright notice must remain intact.

So, you want to write a kernel module. What exactly is a kernel module? How do these modules find their way into the kernel? Or: 1.2.1.