Read Linux Device Major Numbers from /proc/devices
A device node under /dev looks wrong and you need to trace it back to the driver responsible, which is exactly what /proc/devices is for. This guide is a safe way to inspect the device groups known to the running kernel, work out whether a number belongs to a character or block device, and compare that against a device node under /dev. The examples were checked on Linux kernel 6.8.0-139-generic with the locally installed Linux man-pages package 6.7-2.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell and read access to /proc. Everything here is read-only: no command creates a device node, loads a driver, changes permissions or restarts a service. Do not use a major number as a reason to write to an unfamiliar device.
1. Read the file
Run this as an ordinary user:
$ cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
5 ttyprintk
7 vcs
10 misc
...
Block devices:
7 loop
8 sd
9 md
11 sr
...
Your list will differ: hardware, loaded drivers, kernel configuration and virtual devices all affect which names show up. The file has two sections, and each row is a decimal major number followed by a device group name. A major number identifies the driver or group responsible for a device; it is not the complete identity of one device.
Checkpoint
Confirm your output contains both Character devices: and Block devices:. If the file is missing, you're not looking at a normal proc filesystem mount. Check the mount before trying to repair anything:
$ findmnt -T /proc/devices
TARGET SOURCE FSTYPE OPTIONS
/proc proc proc rw,nosuid,nodev,noexec,relatime
The mount options and column spacing vary. What matters is a proc filesystem mounted at /proc, not an exact textual match.
2. Filter one section without losing its meaning
For a quick human check, print only the character-device section:
$ awk '/^Character devices:/{show=1; next} /^Block devices:/{show=0} show' /proc/devices
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
...
This filter stops at the block heading, so it can't accidentally present block devices as character devices. To search for a known group, keep the heading in view and match the second field:
$ awk '$2 == "tty" { print }' /proc/devices
4 tty
Trap: that search can return nothing even when a device exists. Names are kernel registration labels, not guaranteed file names. Search case-sensitively and check the complete output before treating an empty match as a missing driver.
3. Relate a /dev node to its major number
The stat command reports the major and minor numbers of a device node. Still a read-only check:
$ stat -c '%n major=%t minor=%T' /dev/null /dev/tty
/dev/null major=1 minor=3
/dev/tty major=5 minor=0
The %t and %T conversions print hexadecimal values. Convert them to decimal when comparing with /proc/devices:
$ printf 'major=%d minor=%d\n' "0x$(stat -c '%t' /dev/null)" "0x$(stat -c '%T' /dev/null)"
major=1 minor=3
/dev/null therefore belongs to the character-device group with major number 1, named mem in this kernel's listing. The minor number, 3, distinguishes this node within that major group. The name in /proc/devices is not a promise that every node in the group shares the same basename.
Checkpoint
Compare only like with like: a character node against the character section, a disk or partition node against the block section. Use ls -l if you also need to confirm the path is a device node:
$ ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 ... /dev/null
The leading c means character device, a leading b means block device. The displayed 1, 3 is the familiar major, minor pair in decimal.
4. Investigate a missing or unexpected node
Use the numbers to narrow an investigation, not to manufacture a fix. Check the path, type and numbers together first:
$ test -e /dev/EXAMPLE_NODE && stat -c '%F major=%t minor=%T %n' /dev/EXAMPLE_NODE
$ grep -E '^[[:space:]]+[0-9]+[[:space:]]+EXAMPLE_GROUP$' /proc/devices
Replace both placeholders with values from your system. The first command prints nothing when the path doesn't exist, and the second prints nothing when the exact group label isn't registered. That distinction matters: a registered major group doesn't guarantee that udev has created a particular path under /dev.
Warning
Do not run mknod merely because a number appears in /proc/devices. A manually created node can expose a real kernel interface with the wrong permissions or semantics. For normal hardware, investigate the driver, udev rules, permissions and kernel logs using the distribution's documented procedure. If you do need to change a node, record its original ownership and mode first and make the change during a maintenance window.
5. Keep scripts tolerant of changing output
Scripts should parse the headings and fields rather than assume today's list, row order or maximum major number. This small check reports whether a named group is registered in either section:
group='tty'
awk -v wanted="$group" '
/^Character devices:/ { section="character"; next }
/^Block devices:/ { section="block"; next }
$2 == wanted { print section, "major=" $1, "name=" $2; found=1 }
END { exit(found ? 0 : 1) }
' /proc/devices
On the example machine this prints character major=4 name=tty and exits successfully. An absent group produces no output and exit status 1. Treat that as a fact about the current kernel, not proof that a package or device is broken. The file is a snapshot of registered groups; it can change when drivers are loaded or removed.
Done means
- You can read the character and block sections of
/proc/devices. - You can compare a decimal major number with a
/devnode after convertingstat's hexadecimal output. - You check the node type and minor number as well as the major number.
- Your script parses headings and fields instead of relying on fixed rows.
- Nothing was created, changed or loaded: no nodes, permissions, drivers or services.