Read Linux Device Major Numbers from /proc/devices
You will finish with a safe way to inspect the device groups known to the running kernel, identify whether a number belongs to a character or block device, and compare that information with 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 in this guide 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 affect which names are present. The file has two sections. Each row contains 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 that your output contains both Character devices: and Block devices:. If the file is missing, you are 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. The useful result 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 does not 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
That search can return nothing even when a device exists. Names are kernel registration labels, not guaranteed file names. Search case-sensitively and inspect 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. This is 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 has the same basename.
Checkpoint
Compare only like with like. A character node must be compared with the character section, and a disk or partition node with the block section. Use ls -l if you also need to confirm that 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. First check the path, type and numbers together:
$ 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 does not exist, and the second prints nothing when the exact group label is not registered. That distinction matters: a registered major group does not guarantee that udev has created a particular path under /dev.
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 as 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.
- You have not created nodes, changed permissions, loaded drivers or altered services.