Device Drivers for Dummies
23 May 2020Disclaimer : This article is intended to act as an entry point for beings interested in Linux kernel development and learning about the Linux kernel alongside. I’m aware of numerous such posts on the Internet by kernel veterans but what I intend to bring on the table is the same journey but with a fellow layman, trying to wrap his head around the magnificient piece of art - the Linux kernel - in the hopes of a fun, collaborative approach towards learning.
Device drivers are like Iris - the messenger God - of the digital Universe. They provide the world of hardware with the constructs of software. The software (the driver) is laid out minimally for the consumer to interact with the piece of hardware (the device); it abstracts away the granular details of how the device works, from the consumer. In the words of my professor, “Drivers bridge digital signals from the perceptual world with their corresponding entities in the conceptual world and help in moving data smoothly across the two worlds.”
Lets break it down for the laymen; you have a peripheral optical (c’mon, it’s the 21st century!) mouse attached to your “system” which provides you a gateway to shoot the heads of the terrorists in the game of CS:GO. The mouse speaks in the language of events (mouse clicks) and span of movements (mouse sweeps) to detect relative motion w.r.t the surface. Now, to translate the movement of the mouse to the movement of the cursor on your display screen is where we’d need to embed some logic. We’d have to provide a “translator” to the system which enables it to understand the language spoken by the peripheral device, the optical mouse, in this case. With such an interface, we’re hiding away the technicalities of the mouse - how much of a sweep would correspond to moving 100 pixels on the screen, what should the maximum interval of my second click after the first one to be considered as a ‘double-click’ event, etc. This puts a lot of onus on the device driver developer - he needs to be familiar inside-out with how the device operates by digesting the manufacturer’s datasheet, what interfaces should be exposed to the user, communication protocols with the device, security concerns to defuse attempts to make the device go rogue and many others.
The programming interface the Linux kernel provides, in the form of loadable kernel modules, enables such drivers to be “plugged in” to the kernel at runtime [1]! Modules make it easy to develop drivers without rebooting [2]. One can load the driver, unload the driver, rebuild only the driver and dynamically link it to the running kernel…
Drivers play a colossal role in the Linux kernel, pictorially visualized in the figure below. I’m going to let you take a pause here and let the magnitude of devices you’d encounter almost everyday that’d need driver support for you to be able to employ it - keyboards, displays, sensors, actuators, buttons, eMMC, hard-disk, speakers - you name it and it can be appended to the list!
Hardware is always going to pour in to the market which makes talking about the role of a device driver for them increasingly relevant. As the authors of LDD3 put it, the role of a device driver is to provide mechanism and not policy. A device driver should address “what capabilities are to be provided” (the mechanism) rather than “how those capabilities can be used” (the policy) which should be taken care of by a different piece of code (applications) [1] simply because users have different needs and forcing them a particular policy ain’t the attractive approach. “The driver should deal with making the hardware available, leaving all the issues about how to use the hardware to the applications”. I’d encourage you to look into the examples mentioned in the book and grasp these roots of understanding before glugging down your preferred hot beverage whilst devising a driver.
References
[1] Linux Device Drivers, 3rd Edition (by Jonathan Corbet, Greg Kroah-Hartman, Alessandro Rubini)