在Linux的世界里,有一类特殊的文件藏在/dev目录下,它们不是普通的文件,也不对应物理硬件,却能完成各种神奇的任务。
虚拟设备:什么是"一切皆文件"的真正体现
Linux哲学中的"一切皆文件"在这些虚拟设备上得到了完美体现。这些设备通过文件接口提供了特殊的系统功能:
[root@RHL ~]# ls -l /dev/null /dev/zero /dev/random /dev/full /dev/memcrw-rw-rw- 1 root root 1, 7 Dec 30 15:35 /dev/fullcrw-r----- 1 root kmem 1, 1 Dec 30 15:35 /dev/memcrw-rw-rw- 1 root root 1, 3 Dec 30 15:35 /dev/nullcrw-rw-rw- 1 root root 1, 8 Dec 30 15:35 /dev/randomcrw-rw-rw- 1 root root 1, 5 Dec 30 15:35 /dev/zero
主设备号都是1,次设备号不同。这告诉我们,它们都属于同一个驱动driver/char/mem.c!
static const struct memdev { const char *name; const struct file_operations *fops; fmode_t fmode; umode_t mode;} devlist[] = {#ifdef CONFIG_DEVMEM [DEVMEM_MINOR] = { "mem", &mem_fops, FMODE_UNSIGNED_OFFSET, 0 },#endif [3] = { "null", &null_fops, FMODE_NOWAIT, 0666 },#ifdef CONFIG_DEVPORT [4] = { "port", &port_fops, 0, 0 },#endif [5] = { "zero", &zero_fops, FMODE_NOWAIT, 0666 }, [7] = { "full", &full_fops, 0, 0666 }, [8] = { "random", &random_fops, FMODE_NOWAIT, 0666 }, [9] = { "urandom", &urandom_fops, FMODE_NOWAIT, 0666 },#ifdef CONFIG_PRINTK [11] = { "kmsg", &kmsg_fops, 0, 0644 },#endif};
/dev/zero:无尽的零字节之泉
功能特性
读取:返回无限多的零字节(0x00)
写入:数据被丢弃,但返回成功
内存映射:创建初始化为零的内存区域
实用场景
1. 创建空白文件
# 创建1GB的空白文件dd if=/dev/zero of=blank_file bs=1M count=1024# 新写法fallocate -l 1G blank_file
2. 安全擦除
# 用零覆盖文件内容cat /dev/zero > file
内核实现原理
/* * Zero Userspace */#ifndef __clear_userstatic inline __must_check unsigned long__clear_user(void __user *to, unsigned long n){ memset((void __force *)to, 0, n); return 0;}#endif
/dev/null:宇宙黑洞的数字版本
功能特性
读取:立即返回EOF(文件结束)
写入:数据被永久丢弃,如同进入黑洞
实用场景
1. 静默命令输出
[root@RHL ~]# ls temptemp[root@RHL ~]# ls temp > /dev/null[root@RHL ~]# ls temp1 > /dev/nullls: cannot access 'temp1': No such file or directory[root@RHL ~]# ls temp1 2> /dev/null
内核实现原理
staticssize_tread_null(struct file *file, char __user *buf, size_t count, loff_t *ppos){ return 0;}staticssize_twrite_null(struct file *file, constchar __user *buf, size_t count, loff_t *ppos){ return count;}
/dev/full:模拟磁盘已满的测试工具
功能特性
实用场景
1. 模拟错误处理
[root@RHL ~]# echo "a" > /dev/full -bash: echo: write error: No space left on device
内核实现原理
staticssize_twrite_full(struct file *file, constchar __user *buf, size_t count, loff_t *ppos){ return -ENOSPC;}
/dev/mem:直接访问物理内存的"后门"
功能特性
读取:读取物理内存内容
写入:直接修改物理内存
内存映射:映射物理内存到进程地址空间
实用场景
1. 硬件调试和开发
[root@RHL ~]# dd if=/dev/mem bs=1 count=256 skip=$((0x1000)) | hexdump -C256+0 records in256+0 records out256 bytes copied, 0.000643288 s, 398 kB/s00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|*00000100
2. 直接访问硬件寄存器
在嵌入式开发中,有时需要直接访问内存映射的I/O寄存器。
# 读内存地址devmem 0x12345000# 写内存地址devmem 0x12345000 32 0xdeadbeef
/dev/random和/dev/urandom:随机性的源泉
这对双胞胎提供加密安全的随机数,但行为有所不同:
功能对比
实用场景
1. 生成加密密钥
[root@RHL ~]# head -c 32 /dev/urandom | base645lqrsB1xNqUIRdiX3BbrfZJToaE6GzlTg5O/JcyyWZM=[root@RHL ~]# head -c 32 /dev/random | base648TdYSXZQcV3BVE87zcYqnDkrSroZOb74Ju5sOw4z/XA=
2. 创建随机密码
[root@RHL ~]# tr -dc 'A-Za-z0-9!@#$%^&*()' < /dev/urandom | head -c 12aGr9wwxqExK4
3. 生成随机数据文件
[root@RHL ~]# dd if=/dev/urandom of=test_data.bin bs=1M count=1010+0 records in10+0 records out10485760 bytes (10 MB, 10 MiB) copied, 0.10957 s, 95.7 MB/s[root@RHL-9F-DEV-132 ~]#