Device file


In Unix-like operating systems, a device file, device node, or special file is an interface to a device driver that appears in a file system as if it were an ordinary file. There are also special files in DOS, OS/2, and Windows. These special files allow an application program to interact with a device by using its device driver via standard input/output system calls. Using standard system calls simplifies many programming tasks, and leads to consistent user-space I/O mechanisms regardless of device features and functions.

Overview

Device files usually provide simple interfaces to standard devices, but can also be used to access specific unique resources on those devices, such as disk partitions. Additionally, device files are useful for accessing system resources that have no connection with any actual device, such as data sinks and random number generators.
There are two general kinds of device files in Unix-like operating systems, known as character special files and block special files. The difference between them lies in how much data is read and written by the operating system and hardware. These together can be called device special files in contrast to named pipes, which are not connected to a device but are not ordinary files either.
MS-DOS borrowed the concept of special files from Unix but renamed them devices. Because early versions of MS-DOS did not support a directory hierarchy, devices were distinguished from regular files by making their names reserved words that cannot be used as folder or file names; for example: the word CON is a reserved word. These were chosen for a degree of compatibility with CP/M and are still present in modern Windows for backwards compatibility. Names are not case-sensitive, so "con", "Con", and "CON" are all invalid names.
In Windows XP, entering "Con" into the Run command returns the error message, "This file does not have a program associated with it for performing this action. Create an association in the Folder Options control panel." Attempting to rename any file or folder using a reserved name silently reverts the file or folder to its previous name, with no notification or error message. In Windows Vista and later, attempting to use a reserved name for a file or folder brings up an error message saying, "The specified device name is invalid."
In some Unix-like systems, most device files are managed as part of a virtual file system traditionally mounted at /dev, possibly associated with a controlling daemon, which monitors hardware addition and removal at run time, making corresponding changes to the device file system if that's not automatically done by the kernel, and possibly invoking scripts in system or user space to handle special device needs. The FreeBSD, DragonFly BSD and Darwin have a dedicated file system devfs; device nodes are managed automatically by this file system, in kernel space. Linux used to have a similar devfs implementation, but it was abandoned later, and then removed since version 2.6.17; Linux now primarily uses a user space implementation known as udev, but there are many variants.
In Unix systems which support chroot process isolation, such as Solaris Containers, typically each chroot environment needs its own /dev; these mount points will be visible on the host OS at various nodes in the global file system tree. By restricting the device nodes populated into chroot instances of /dev, hardware isolation can be enforced by the chroot environment.
MS-DOS managed hardware device contention by making each device file exclusive open. An application attempting to access a device already in use would discover itself unable to open the device file node. A variety of device driver semantics are implemented in Unix and Linux concerning concurrent access.

Unix and Unix-like systems

Device nodes correspond to resources that an operating system's kernel has already allocated. Unix identifies those resources by a major number and a minor number, both stored as part of the structure of a node. The assignment of these numbers occurs uniquely in different operating systems and on different computer platforms. Generally, the major number identifies the device driver and the minor number identifies a particular device that the driver controls: in this case, the system may pass the minor number to a driver. However, in the presence of dynamic number allocation, this may not be the case.
As with other special file types, the computer system accesses device nodes using standard system calls and treats them like regular computer files. Two standard types of device files exist; unfortunately their names are rather counter-intuitive for historical reasons, and explanations of the difference between the two are often incorrect as a result.

Character devices

Character special files or character devices provide unbuffered, direct access to the hardware device. They do not necessarily allow programs to read or write single characters at a time; that is up to the device in question. The character device for a hard disk, for example, will normally require that all reads and writes be aligned to block boundaries and most certainly will not allow reading a single byte.
Character devices are sometimes known as raw devices to avoid the confusion surrounding the fact that a character device for a piece of block-based hardware will typically require programs to read and write aligned blocks.

Block devices

Block special files or block devices provide buffered access to hardware devices, and provide some abstraction from their specifics. Unlike character devices, block devices will always allow the programmer to read or write a block of any size and any alignment. The downside is that because block devices are buffered, the programmer does not know how long it will take before written data is passed from the kernel's buffers to the actual device, or indeed in what order two separate writes will arrive at the physical device. Additionally, if the same hardware exposes both character and block devices, there is a risk of data corruption due to clients using the character device being unaware of changes made in the buffers of the block device.
Most systems create both block and character devices to represent hardware like hard disks. FreeBSD and Linux notably do not; the former has removed support for block devices, while the latter creates only block devices. To get the effect of a character device from a block device on Linux, one must open the device with the Linux-specific flag.

Pseudo-devices

Device nodes on Unix-like systems do not necessarily have to correspond to physical devices. Nodes that lack this correspondence are called pseudo-devices. They provide various functions handled by the operating system. Some of the most commonly used pseudo-devices include:
  • accepts and discards all input written to it; provides an end-of-file indication when read from.
  • accepts and discards all input written to it; produces a continuous stream of null characters as output when read from.
  • produces a continuous stream of null characters as output when read from, and generates an error when attempting to write to it.
  • produces bytes generated by the kernel's cryptographically secure pseudorandom number generator. Its exact behavior varies by implementation, and sometimes variants such as or are also provided.
  • ,, access the process's standard streams.
  • n accesses the process's file descriptor n.
  • references the current process's controlling terminal device, if it has one, whether or not the process has any open file descriptors that refer to it
The POSIX standard requires only three device special files by name,, and, but does not require that be either readable or writable. A usable system may have many more.
Additionally, BSD-specific pseudo-devices with an interface may also include:
  • allows userland processes to control PF through an interface.
  • provides access to devices otherwise not found as nodes, used by to implement RAID management in OpenBSD and NetBSD.
  • used by NetBSD's envsys framework for hardware monitoring, accessed in the userland through by the utility.

    Node creation

Nodes are created by the system call. The command-line program for creating nodes is also called. Nodes can be moved or deleted by the usual filesystem system calls and commands.
Some Unix versions include a script named makedev or MAKEDEV to create all necessary devices in the directory. It only makes sense on systems whose devices are statically assigned major numbers.
Some other Unix systems such as FreeBSD use kernel-based device node management via devfs only and do not support manual node creation. system call and command exist to keep compatibility with POSIX, but manually created device nodes outside devfs will not function at all.

Naming conventions

The following prefixes are used for the names of some devices in the hierarchy, to identify the type of device:
  • : line printers
  • : pseudo-terminals
  • : terminals
Some additional prefixes have come into common use in some operating systems:
  • : frame buffer
  • : floppy disks, though this same abbreviation is also commonly used to refer to file descriptor
  • : IDE driver
  • * : the primary device on the first ATA channel
  • * : the secondary device on the first ATA channel
  • * : the primary device on the second ATA channel
  • * : the secondary device on the second ATA channel
  • , : parallel ports
  • : Main memory
  • : Network block device: Abstraction that represents block devices that are mounted through the network
  • NVMe driver:
  • * : first registered device's device controller
  • * : first registered device's first namespace
  • * : first registered device's first namespace's first partition
  • MMC driver:
  • * : storage driver for MMC media
  • ** : first registered device
  • ** : first registered device's first partition
  • SCSI driver, also used by libATA, USB, IEEE 1394, etc.:
  • * : mass-storage driver
  • ** : first registered device
  • **, etc.: second, third, etc. registered devices
  • * : Enclosure driver
  • * : generic SCSI layer
  • * : "ROM" driver
  • * : magnetic tape driver
  • : terminals
  • * : serial port driver
  • * : USB serial converters, modems, etc.
The canonical list of the prefixes used in Linux can be found in the Linux Device List, the official registry of allocated device numbers and directory nodes for the Linux operating system.
For most devices, this prefix is followed by a number uniquely identifying the particular device. For hard drives, a letter is used to identify devices and is followed by a number to identify partitions. Thus a file system may "know" an area on a disk as, for example, or "see" a networked terminal session as associated with.
On disks using the typical PC master boot record, the device numbers of primary and the optional extended partition are numbered 1 through 4, while the indexes of any logical partitions are 5 and onwards, regardless of the layout of the former partitions.
Device names are usually not portable between different Unix-like system variants, for example, on some BSD systems, the IDE devices are named,, etc.