How Linux Uses the /dev Directory for Hardware

In the Linux operating system, hardware devices are represented as special files within the /dev (device) directory. This article explains how Linux applies the foundational "everything is a file" philosophy to hardware abstraction, the differences between block, character, and pseudo-devices, how the kernel identifies hardware through major and minor numbers, and how dynamic managers like udev keep the directory up to date.

The "Everything Is a File" Abstraction

Linux abstracts physical and virtual hardware components into the filesystem hierarchy via the /dev directory. Instead of requiring applications to use specialized, low-level hardware APIs, Linux exposes hardware devices as device nodes (or device files). Standard system calls used for regular files—such as read(), write(), and open()—can interact directly with hardware through these nodes, with the Linux kernel translating those requests into driver-specific actions.

Device Types in /dev

Files inside /dev do not consume physical storage space on a disk; instead, they serve as access portals to device drivers. These files primarily fall into three categories:

Major and Minor Numbers

When viewing device files using ls -l /dev, the file listing displays two numbers separated by a comma where a standard file's size would normally appear:

  1. Major Number: Identifies the specific device driver within the kernel responsible for handling communication with the hardware.
  2. Minor Number: Distinguishes between specific individual devices or partitions managed by that same driver.

For instance, /dev/sda1 and /dev/sda2 share the same major number because they utilize the same storage driver, but they have distinct minor numbers to indicate separate partitions on that drive.

Dynamic Device Management with devtmpfs and udev

In modern Linux distributions, the /dev directory is not a static set of files stored on the root partition. It is mounted as an in-memory virtual filesystem called devtmpfs.

When new hardware is connected (such as plugging in a USB drive), the kernel detects the event and creates a base device node in devtmpfs. Simultaneously, the user-space device manager, udev, receives a kernel event. The udev daemon applies user-defined rules to assign persistent names, manage access permissions, and generate user-friendly symbolic links (such as those found in /dev/disk/by-uuid/ or /dev/disk/by-id/). When hardware is unplugged, the kernel and udev remove the corresponding device nodes automatically.