Linux Device Files

Last updated: 12/15/2022

We were debugging an issue of missing boot drives on an emulated CPU board, thus leading to the bootlaoder not being able to find an OS to boot into. It is obvious that the bootloader was not able to find any boot partitions that are specified in code, e.g./dev/sda, or /dev/nvme0n1p1. In particular, device files are missing. So what went wrong? One idea is figure out where and when Linux is supposed to identify the boot drives and have relevant device files created under /dev. So I went digging...and following is a summary of my learnings.

Basics

What is it? Files under /dev/ like /dev/mem are special file(s), or device nodes. Two main types are character and block devices. Block devices handles data in blocks, with individual block size between 128 bytes and 1k bytes. Character devices handle data in a stream of characters (bytes), without a structure. Character devices are read from and written to with blocking read() and write() calls, which do not return until the operations finish. While block devices do not implement read() and write() functions, they simply have blocks access functions for blocks access and read and write blocks to the device. See kernel's record of all devices devices.txt.

How they are created? Device files normally get created during installation*. But, in a booted OS, you can create them with mknod utility. For a simple example, you can run the command, mknod [-F format] name [c | b] major minor (see man page for more). So you can create a new device file like,


 ✗ sudo mknod tstdevice c 0 9
 ✗ ls -l tstdevice
 0x9 Dec 16 00:41 tstdevice
 ✗

You then created a character device file of a major number as 0, and minor number as 9, and which is called tstdevice.Basically, major version allows Linux to identify which driver to talk to, and the minor number tells the device driver which device it is talking to. For example, you have multiple ram disks block devices, all talking through same driver, but need different numbers to identify which ram disk is being talked to,

   1 block	RAM disk
		  0 = /dev/ram0		First RAM disk
		  1 = /dev/ram1		Second RAM disk
		    ...
		250 = /dev/initrd	Initial RAM disk

So 1 as part of "1 block" on the left is major number identifying "RAM disk" accessed via block drivers, while 0 ~ 249 identify as many ram disks there are. One exception here is that 250 is reserved as "Initial RAM disk", which is picked up as initial ramfs to boot. RAM disk (also called RAM drive) is a block of random-access memory that computer is treating as if the memory were a disk drive.

A device file can be seen as an interface to device driver that appears in a file system as if it were an ordinary file.

Examples:

Block Devices