StackrootServer-side web stacks and the Linux systems that hold them, from config to debug.

Linux Devices

A linux device is a file: on a modern system, roughly 2,400 of them sit under /dev, from the block file for a disk to the character file for a serial port.

A system information window listing connected hardware devices and drivers.

The device model in the Linux Kernel is the contract between user space and hardware. A driver registers a device node, the kernel exposes that node as a file, and the rest of the system treats the hardware the way it treats a document on a disk, because that is exactly what the file represents. This page works through the model from the nodes in /dev to the drivers behind them, and then to the commands and tables a server administrator uses to inspect disks, interfaces and everything between them.

Every node in /dev carries a major and a minor number, and those two numbers are the address of the hardware. The major number identifies the driver; the minor number picks the individual device that driver manages. The same major number, 8, covers every sd disk, and the minor numbers run 0, 1, 8, 16 and on. The file itself is only a stub. The real work happens when a process opens it: the open call hands the major and minor numbers to the kernel, which routes the call into the driver that registered that major number.

What a Device Node Actually Is

A device node is a small file that maps to hardware, and the node is defined by three things: its type, its major number and its minor number. The type is either b for block or c for character, and the choice decides how the kernel buffers reads and writes. A block file accepts data in fixed pages, typically 4,096 bytes, and the block layer queues those pages and reorders them so the disk head, or the flash controller, does the least wasted work. A character file passes bytes through with no reordering, which is what a serial port or a terminal needs.

Node typeMajorMinorWhat it addresses
/dev/sda80first SATA or SCSI disk
/dev/sda181first partition of that disk
/dev/nvme0n12590first NVMe disk
/dev/sr0110first optical drive
/dev/ttyS040first serial port

On a system using udev, the nodes are not static. The kernel reports an event when hardware appears, udev matches the event against its rules, and udev creates the node with the permissions, the group and the symbolic names that the rules demand. The names that stick in an administrator's head, such as sda, vda and nvme0n1, come from that matching step rather than from the kernel alone.

How the Driver Layer Exposes Hardware

The driver is the half of the contract that runs in kernel space, and it is the part that makes a device node more than a stub. When a driver is built into the Linux Kernel or loaded as a module, it registers a major number and then implements the operations the kernel will call on its behalf: open, read, write, ioctl, and the release path when the last file descriptor closes. A process that issues a read on /dev/sda never sees the driver by name. It issues the read, the block layer breaks it into 4,096 byte pages, and the driver translates those pages into the commands the hardware understands, an ATA command for a spinning disk or an NVMe queue entry for a solid state drive.

Some devices sit outside the machine, and the same model still applies. A USB storage device is plugged in, the usbcore driver detects it, the uas or the usb-storage driver attaches, a block device appears, and udev names it. The whole chain from connector to node can finish in about 2 seconds, and nothing in user space ever needs to know that the disk is behind a bus that negotiates speed and power.

Block Devices and Character Devices

Block devices and character devices are the two shapes a device node can take, and the difference shows up the moment a process issues its first request. A block device is the shape a disk takes. The kernel writes into a page cache, the block layer coalesces and reorders the pending pages, and the driver ships them to the hardware in an order that the hardware prefers. A character device is the shape a terminal takes. Bytes move as they arrive, in order, with no reordering, because a keystroke that arrives out of sequence is a bug, not an optimisation.

The practical split runs like this. A disk, a partition, a loop file and a device mapper volume are all block devices. A serial port, a pseudo terminal, a hardware random number generator such as /dev/urandom and a network interface accessed through a special file are character devices. When you choose between the two in a configuration, the rule is that any data where order matters goes through a character device, and any data where throughput matters goes through a block device.

Seeing Disks from the Server

A server sees its disks as nodes in /dev, and the standard tools read the same metadata the kernel holds. The Linux Commands an administrator reaches for first are the ones that print that metadata back out. lsblk lays out the tree of devices, partitions and their parents in one screen. fdisk or sgdisk reads the partition table. ls -l /dev/disk/by-id shows the stable identity names that survive a reboot. df -h reports how much of the mounted filesystem is in use. Four commands, and together they answer every day's disk questions.

  • lsblk, to see the whole tree of disks, partitions and device mapper volumes
  • fdisk, to read or edit a partition table on a specific disk
  • ls -l /dev/disk/by-id, to copy the stable identifier of a disk
  • df -h, to report usage of a mounted filesystem in human readable sizes

Two of those details matter for a long running server. The names sda and sdb are not guaranteed to stay attached to the same physical disk after a reboot, which is why the by-id names exist. And the size a tool reports for a partition is the size of the partition, not the size of the disk behind it, a difference that matters when a disk is being grown in place.

Seeing Network Interfaces

Interfaces are where the device model stops being a file in /dev and becomes an object inside the kernel, which is worth stating plainly. A network interface is not a device node. It is a structure in kernel space with a file descriptor handed to the socket layer, so the commands that inspect it read kernel state rather than a file. The first thing to notice is that the names eth0 and ens3 are not guaranteed to survive a rename, because the names come from the same udev matching that names disks. A second thing to notice is that one interface can carry addresses for more than one family, an IPv4 address and an IPv6 address at the same time.

The commands that read that state are short. ip addr show lists the interfaces and their addresses. ip link show shows the administrative state and the MAC address. ethtool -i reports which driver module serves the card, and ethtool -S prints the driver's own counters, including dropped packets, which are the first number to check when throughput falls. None of these touch /dev, and all of them read the same kernel object that a socket sees.

Where a Linux Device Shows Up in Daily Work

A linux device is a file, and that identity shows up in the daily work of a server in four places. The first is the mount. When a filesystem is mounted from /dev/sdb1, the mount command asks the kernel to treat that block device as a tree of directories, and from that moment the data lives in a page cache that the block layer flushes on a schedule the kernel controls. The second is the loop file. A plain file, a disk image or an archive, can be attached as a block device with losetup, and the loop module presents it to the rest of the stack as a disk. The third is the device mapper. A volume from lvm is a device mapper block device, and it is named /dev/mapper/name, so it sits in the same namespace as the physical disks even though it is a layer on top of them. The fourth is the pseudo device, the node with no hardware behind it at all, such as /dev/null, which swallows whatever is written to it, and /dev/zero, which returns a stream of zero bytes on demand.

The model is small, and the smallness is the point. A disk, an NVMe drive, a serial port, a USB stick and a loop file all arrive through the same two paths. The kernel exposes them as nodes, the drivers translate the calls, and the tools read the metadata. Once the major and minor numbers are understood, a new piece of hardware on a server stops being a mystery, because the hardware is a file, and a file is something the whole system already knows how to handle.

Where to go next