In Linux and other Unix-like operating systems, every device connected to the system is represented by a file in the /dev directory. These device files contain metadata that identifies each device to the operating system and allows processes to interact with them.
Part of this identifying metadata is the major and minor device number assigned to each device file. But what do these numbers mean and how are they different?
What Are Major and Minor Device Numbers?
The major and minor numbers are part of the identification system used by the Linux kernel to differentiate between different devices and their drivers. Here’s a quick overview:
- Major number – Identifies the device driver class or type
- Minor number – Identifies a specific device among a group of related devices associated with the same driver
For example, all hard drives connected to the system may share the same major number, while each individual disk would have a different minor number.
Together, the major and minor number values form a unique identifier that pairs a specific device to the correct device driver in the kernel.
How Are Major Numbers Assigned?
Major numbers are statically assigned and centralized to ensure each device class has a unique major number across the whole system.
There are three ranges for assigning major numbers:
- 0 to 255 – Reserved for statically assigned native kernel device drivers
- 256-383 – Reserved for dynamically allocated major numbers for transient devices like USB
- 384 and up – Available for general device number assignment, typically handled dynamically by udev
Some common major number assignments include:
Major Number | Device Class |
---|---|
1 | RAM disks |
3 | Console terminal |
4 | TTY devices |
7 | Loopback devices |
8 | SCSI disk devices |
10 | Ethernet network adapters |
As you can see, major numbers are assigned to broad classes of devices that require similar handling by the kernel. This allows the kernel to quickly identify the general driver module that needs to be invoked when a device file is accessed.
How Are Minor Numbers Assigned?
Minor numbers are used to enumerate individual devices within a single device class that shares the same major number. This provides a way to differentiate between multiple similar devices.
Unlike major numbers, there is no central authority for handing out minor device numbers. It is left to each device driver to assign minor numbers to devices as they are detected and initialized.
Some common techniques for minor number assignment include:
- Sequential – Simple incrementing numbers starting from 0
- Index-based – Derived from device index/order detected
- Bus-specific – Encode bus location into the number
For example, the driver for a SATA controller may assign minor numbers sequentially as each disk is found during boot. This allows the operating system to identify disk “sda” from “sdb” from “sdc” and so on.
The main criterion is that the minor numbers are unique among devices sharing the same major number to avoid conflicts. Drivers have flexibility in their assignment scheme.
How Are Major and Minor Numbers Used?
When the Linux kernel needs to interact with a device, it uses the major and minor numbers in a few key ways:
- Match devices to drivers – Find the correct driver based on major number
- Differentiate devices – Use minor number to identify specific device instance
- Permissions checking – Device node access uses major/minor for security
- Provide interface to apps – apps look up devices using major/minor pairs
For example, when an application tries to read from the “/dev/sda1” device file, here is what happens:
- Kernel sees major=8, minor=1 on inode for /dev/sda1
- Major 8 = SCSI disk driver class is needed
- Minor 1 selects first SCSI disk managed by driver
- SCSI disk driver handles request for operation on that specific disk
Without the major and minor number pair, the kernel would not know which device driver implementation and device instance is being accessed.
Viewing Major and Minor Numbers
You can view the major and minor numbers associated with device files in the /dev directory using ls:
ls -l /dev/sda1 brw-rw---- 1 root disk 8, 1 Feb 10 22:05 /dev/sda1
The major and minor numbers are the two decimal values after the permission bits. Here we can see major=8, minor=1 for this device.
You can also view details on block device nodes in /dev with lsblk:
lsblk -o name,maj:min NAME MAJ:MIN sda 8:0 sda1 8:1 sda2 8:2
This shows the full list of major:minor pairs for the “sda” block device and its partitions.
How Are Major/Minor Numbers Assigned at Boot Time?
The Linux kernel handles major/minor number assignments in a multi-step process during system startup:
- Native kernel subsystems assign major numbers to their device classes
- udev dynamically allocates available major numbers as needed
- As devices are detected, drivers assign unique minor numbers
- udev creates the /dev nodes using the supplied major:minor pairs
This ensures each device gets a unique combination of major and minor numbers when device files are created.
Initially, udev will try to use persistent device naming based on attributes like connection bus ID. This maps the same real devices to consistent names like /dev/sda between reboots.
If the boot order changes, the minor numbers may be different but functionality remains consistent thanks to the device mapping abstraction in /dev.
Persistence of Major/Minor Numbers
Major numbers persist as long as the corresponding kernel driver remains registered.
Minor numbers are not guaranteed to remain persistent across reboots. Depending on the assignment scheme, they may change if devices are detected in a different order.
For example, on a system with multiple USB disks that get minor numbers assigned sequentially, unplugging one disk could result in a different /dev file for each disk after rebooting.
This is why mechanisms like udev persistent naming are important – to map consistently between physical devices and names like /dev/sdc.
Are Major/Minor Numbers Still Relevant on Modern Linux?
While the Linux world has moved towards more user-friendly device identifiers like /dev/disk/by-id, major and minor numbers are still very relevant on modern systems:
- Required for core device identification in the kernel
- Necessary for tears and compatibility with UNIX syscalls
- Used by udev for creating symbolic links from identifiers to devices
- Used by libraries and utilities for managing permissions and access
- Provide a consistent interface for applications to open devices
Applications generally don’t need to look up major/minor programmatically anymore thanks to udev symlinks. But under the hood, they provide the foundation for the Linux device model.
Use Cases for Major and Minor Numbers
While major and minor numbers are usually handled automatically by the OS and drivers, there are some cases where working with them directly can be useful:
- Identifying specific drives – Use a minor number pattern to map drives to slots
- Creating custom device nodes – Make nodes like /dev/mydevice with a chosen major/minor pair
- Interfacing with hardware – Read major/minor numbers over a bus protocol
- Device filtering – Filter by major/minor numbers when processing /dev
- Userspace driver – Implement a driver in userspace using allocated major/minor numbers
For example, an IoT device that needs to talk to custom hardware over I2C may look for a specific major/minor pair to identify the peripheral device.
Or an industrial control system could create symbolic links based on the minor numbers corresponding to specific drive slots in a chassis.
So while not commonly needed, the major/minor number abstraction provides capabilities to handle devices in a very low-level manner.
Major and Minor Numbers in Other Unix-Like OSes
The concept of major and minor device numbers originated in Unix and is also commonly used in other Unix-like systems besides Linux:
- BSD – BSD variants like FreeBSD use the same major/minor number scheme
- macOS – Based on BSD so implements the same /dev model and device nodes
- Illumos – Solaris derived OS uses major/minor numbers for devices
- AIX – IBM’s UNIX OS for POWER systems
The specifics like standard assignments for common major numbers can vary between different Unix flavors. But the overall concept remains the same across the board.
One notable exception is Android, which being based on the Linux kernel uses a different userspace model not based around major/minor device numbers.
Conclusion
Major and minor device numbers are an integral part of how Linux and other Unix-like systems identify and interface with devices. While often abstracted away, they still provide the foundation for the /dev filesystem and much of how the Linux kernel operates.
Understanding the distinction between the device type identifying major number and the instance differentiating minor number is key to grasping how Linux handles devices.
And while they may seem esoteric, major/minor pairs still have relevance on modern systems as an abstraction that offers power and flexibility for interfacing with hardware at a low level.