Linux – Trying to understand how Device Drivers work

driverslinuxlinux-kernel

I am trying to understand how Device Drivers work, based on what I know so far, a Device Driver is simply a "middle-man" between the Operating System and the Device. I have created the following diagram to show my understanding of Device Drivers:

enter image description here

Also, an Application cannot interact directly with a Device Driver, only the Operating System can do that (so for example, if an Application wants to print something, it "tells" the Operating System, and the Operating system tells the Device Driver).

Is my understanding correct? And is the concept of Device Drivers the same on Windows and macOS as it is on Linux?

Best Answer

Very briefly:

The most important thing about a device driver is that it runs in kernel space, with the same permissions as the kernel, and therefore can access hardware directly. Applications are (usually) not permitted to do that.

So you can think of device drivers as the parts of the kernel that organize access to certain hardware (the "device").

An application can interact with the kernel on various levels: From higher abstractions (e.g. a file system) to middling abstractions (a block device) to really low level abstractions (some files in /proc/ or /sys, some ioctls in devices in /dev). So the low level interactions will sometimes be talking to a device driver very directly, there's only a very thin layer where the kernel redirects the call to the device driver. So "an Application cannot interact directly with a Device Driver, only the Operating System can do that" is sort of true and also sort of false.

Also, there are many abstraction layers in the kernel like the one you describe in your picture ("the messages the OS sends are the same, the device driver uses differnent messages to talk to the hardware). For example, the block layer receives one kind of messages, but passes them on to different block devices. The USB layer receives one kind of messages, but can use different USB host controllers. And so on.

So the picture is much more difficult, there are layers and subsystems in the kernel, and the device drivers that actually talk to the hardware are at the bottom of that hierarchy. To confuse things more, both the device drivers and other layers come in the form of modules (for Linux). If you type lsmod, you can see which modules are active, and which module uses which other modules.

Also, printing is a very bad example; most of the printer-specific processing happens in user space, and not in a device driver.

All of Windows, Linux and MacOS follow these principles, but the details are very different.

Does that help?

Edit:

Printing on Linux is today usually done with cups. Cups has a collection of programs that can render documents for various printers. All of these programs take a file (the document as pdf/postscript/...) and convert it to another file in a format the printer understands. All of this happens outside of the kernel, because none of this needs to access actual hardware. It just reads and writes files. Only the very last part, when the converted data is sent to the printer, uses the kernel. And then it can uses various paths, even for the same type of printer: via the network, via USB, via a serial connection, etc. And this last part often isn't printer specific.

So Linux doesn't really have printer-specific device drivers for the large majority of printers. (For a few printers, you may need one).

Related Question