Linux Device Drivers — Chapter One

Niranjhana Narayanan
5 min readFeb 4, 2018

--

Published around 20 years ago, this classic by Alessandro Rubini provides all the information you’ll need to write drivers for a wide range of devices.

Since this book is huge and requires thorough reading to understand and implement, I am going to attempt to summarize and break down the most important points chapter by chapter (of the 3rd edition) in my posts, so programmers can get a basic understanding and a starting point to dwell deeper into the chapters of their interest. Let’s begin with few basic points followed by Chapter One.

Device Drivers — the software interface to the hardware devices

Brief Introduction

In any operating system, a kernel is a program that manages input/output requests from software and translates them into data processing instructions for CPU and other electronic components.

Overview of the Kernel
  • Kernel is responsible for process management, memory management, filesystems, device control, networking, etc.

Device drivers are programs that run in kernel mode, meaning they can interact directly with the hardware of the respective device.

The main purpose of device drivers is to provide abstraction by acting as a translator between a hardware device and the applications or operating systems that use it.

Why do we need device drivers?

  • It is dangerous to give user applications direct access to the hardware. User activities run in user space and when in need of hardware resources, implement a set of device-independent standardized calls. The role of the device driver is to map those calls to device-specific operations that can act on real hardware.
  • Programmers can then write the higher-level application code independently of whatever specific hardware the end-user is using.

A nice thing about Linux Device Drivers

The Device Driver programming interface of Linux is such that drivers can be built separately from the rest of the kernel and can be used at runtime when needed. This modularity makes Linux drivers easier to write and maintain — which brings us to Loadable Modules:

  • piece of code that can be added to the kernel at runtime is called a module.
  • one of the supported modules are device drivers, which can be dynamically linked to the up and running kernel by the insmod program and unlinked by the rmmod program.

Unix Design: Distinction between Mechanism and Policy

Mechanism — what capabilities are to be provided; Policy — how those capabilities can be used.

A good software package should address these two issues with different parts of a program or even better, with different programs. Example, the Unix management of the graphic display is split between the X server (the mechanism — which knows hardware) and the session managers (implement a policy — which is hardware independent).

When writing drivers for Linux, it is important to write code that

  • separates mechanism and policy and
  • is as policy-free as possible (since different users have different needs)

The driver should deal with making the hardware available, leaving all the issues about how to use the hardware to the applications.

Classes of Devices

Linux distinguishes between three fundamental device types:

  • Character devices: char device is one that can be accessed as a stream of bytes (like a file); a char driver usually implements the open, close, read and write system calls. Examples of this stream abstraction are the text console — /dev/console and the serial ports — /dev/ttyS0
  • Block devices: block devices are like a hard disk, that can host a filesystem. They are treated like char devices in Linux (unline in most Unix systems where blocks need to be 512 bytes or more in length). Like char devices, they permit transfer of any number of bytes; and can be accessed by filesystem nodes in the /dev directory — they only differ in the kernel/software interface where data is managed differently for both.
  • Network devices: network interfaces/devices are usually hardware, that is capable of data exchange with other hosts. A network driver knows nothing about the individual connections, it only handles packets — sending, receiving, etc driven by the network subsystem of the kernel. Unlike char and block devices, a network interface such as eth0 is not directly mapped to a node in the filesystem; and communication between kernel and driver is different too — instead of read and write, the kernel calls functions related to packet transmission.

Other classes of device drivers have been added to the kernel in recent times, such as FireWire drivers and I2O drivers.

“Almost everything in Unix can be treated as a file”

The Filesystem concept of Unix design

A filesystem type is a software driver, because it must implement the lowest level of the system calls that access directories and files, by mapping filenames and paths (as well as other information, such as access modes) to the higher level data structures stored in data blocks.

Linux supports the concept of a filesystem module, whose software interface declares the different operations that can be performed on a filesystem inode, directory, file, and superblock.

Security Issues

  1. When possible, driver writers should avoid encoding security policy in their code; security checks in the system is enforced by kernel code. For example, when you want to load a driver module, the system call init_module checks if the invoking process is authorized to load the module into the kernel, and only an authorized user by the kernel can do so. There are exceptions, such as when driver operations can affect global resources, damage hardware (egs: interrupt lines, loading firmware, etc) or other users then the checks should be made in the driver itself.
  2. Driver writes should be careful to avoid introducing security bugs.
  3. Any input from user processes must never be trusted, unless verified.
  4. Any memory from the kernel should be zeroed or initialized before being made to the user process or device, to avoid information leakage.
  5. Specific operations affecting the system should be restricted to privileged users only.

Well, that’s about the summary. You can read the whole chapter (Chapter 1: An Introduction to Device Drivers) for a more detailed understanding, feel free to contact me in case of doubts or errors. Stay tuned for a summary on Chapter 2: Building and Running Modules.

Reference: Linux Device Drivers, 3rd Edition, O’Reilly Books

--

--

Niranjhana Narayanan

Love all kinds Physics & Computing — Quantum, Meta, Astro, AI, Crypto, OS, FOSS