ls -l 文件类型标识

ls -l 输出第一列的第一个字符表示文件类型:

字符 类型
- 普通文件
d 目录
l 符号链接(symbolic link)
c 字符设备(character device)
b 块设备(block device)
p 命名管道(named pipe / FIFO)
s socket

例如 /dev/pts/2 这样的伪终端设备文件,ls -l 第一个字符是 c,因为它是字符设备:数据按字节流顺序读写,不支持像块设备那样按"块"随机寻址。下面分别展开字符设备和块设备的区别。

字符设备, character device

提供连续的数据流,应用程序只能顺序读取,没有寻址(seek)的概念——不能像访问数组那样跳到任意位置读取。此类设备按字节/字符读写数据,键盘、串口、调制解调器都是典型的字符设备。

块设备, block device

块设备以"块"为单位存储数据,典型的如磁盘设备、硬盘、软盘、光盘或者优盘/闪存。在 Linux 系统中一切皆文件,磁盘设备也是文件。应用程序可以随机访问设备数据,自行确定读取数据的位置;数据的读写只能以块(通常是 512 字节)的倍数进行。

ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 Apr  1 07:15 /dev/sda
brw-rw---- 1 root disk 8, 1 Apr  1 07:15 /dev/sda1
brw-rw---- 1 root disk 8, 2 Apr  1 07:15 /dev/sda2
brw-rw---- 1 root disk 8, 3 Apr  1 07:15 /dev/sda3

字符设备与块设备:谁支持随机访问

两者的根本区别在于能否被随机访问——即能否在访问设备时随意跳转到任意位置。

举个例子,键盘提供的是一个数据流:当敲入 “fox” 时,键盘驱动会按输入顺序原样返回这三个字符组成的数据流;让驱动打乱顺序读,或者跳过去只读某一个字符,都没有意义。所以键盘是典型的字符设备,只能顺序读到一个字符流:先 f,再 o,最后 x,然后是 EOF。没人按键时,字符流就是空的。字符设备支持的是按字节顺序读写,不支持随机寻址。

硬盘则不同:驱动可能先读磁盘上某个块,然后跳去读另一个块,这些块在磁盘上的位置不需要连续,所以硬盘可以被随机访问而不是被当作流来访问,这正是块设备的特征——块设备支持按块随机寻址。

内核管理块设备要比管理字符设备细致得多:字符设备只需要维护一个位置——当前位置;块设备访问的位置则必须能在介质的不同区间前后跳转,因此内核专门有一个子系统来管理块设备(对性能要求也更高),而字符设备不需要这样的专门子系统。

用 ls -l 区分字符设备与块设备

每个字符设备或块设备都在 /dev 目录下对应一个设备文件,通过查看文件属性就能区分类型:

cd /dev
ls -l
crw-rw----+ 1 root root  14,  12 12-21 22:56 adsp
crw------- 1 root root  10, 175 12-21 22:56 agpgart
crw-rw----+ 1 root root  14,   4 12-21 22:56 audio
brw-r----- 1 root disk 253,   0 12-21 22:56 dm-0
brw-r----- 1 root disk 253,   1 12-21 22:56 dm-1
crw-rw---- 1 root root  14,   9 12-21 22:56 dmmidi

第 1 字段第一个字符 c 表示字符设备,b 表示块设备(完整对照见上文表格);第 2-4 字段对驱动开发没有影响;第 5、6 字段分别是主设备号和次设备号;第 7 字段是最后修改时间;第 8 字段是设备名。由此可知 adsp 是字符设备(主设备号 14,次设备号 12),dm-0 是块设备。

网络设备:不在 /dev 下

网络设备是特殊设备的驱动,负责收发帧数据(物理帧或 IP 数据包,具体由网络驱动决定)。它不存在于 /dev 下,与一般设备不同:网络设备是一个 net_device 结构,通过 register_netdev 注册到系统里,可以用 ifconfig -a 查看。

作者:CodeMyLove 来源:简书,著作权归作者所有,商业转载请联系作者授权,非商业转载请注明出处。

BDEV 与 CDEV 的 IO 差异

BDEV 和 CDEV 在 IO 操作上差异很大:

  • CDEV 很直接:用户进程发起文件操作系统调用,系统调用直接进到驱动的 file_operations,调用栈就完成了
  • BDEV 要用到内核更多机制,比如缓冲、IO 调度、请求队列等
  • BDEV 只能以 block 为单位接受输入/输出,CDEV 是以 byte 为单位;大多数设备属于 CDEV,因为它们不需要块缓冲,size 也不固定
  • BDEV 对 IO 请求有对应的块缓冲,会先对请求排序,再按排序后的顺序发起实际 IO
  • BDEV 可以随机访问,因为具有 position pointer;CDEV 只能顺序 IO
  • BDEV 通常不由用户进程直接通过文件操作访问,而是在 BDEV 上部署 IO 调度,调度层之上再部署文件系统(如 ext4);用户通过文件操作访问文件系统,文件系统把请求映射成 BDEV 的实际 IO 请求,经过调度后发给 BDEV。不过 Linux 也保留了 direct_access 方式可以直接访问 BDEV,比如直接读写 /dev/sdb1

版权声明:本节整理自 CSDN 博主「Huskar_Liu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,原文链接:https://blog.csdn.net/weixin_42418557/article/details/106112364

bdev 伪文件系统

文件系统是对磁盘数据进行组织和管理的一种机制。它可以通过装载,以目录和文件的形式向用户层呈现;但文件和目录只是文件系统的前端,是用户视图,本质还是 inode 这个数据结构。

纯粹从 inode 角度描述文件系统,就是伪文件系统:它不能被装载,不可能从用户空间看到,但不会带来任何信息损失——看不到不等于不存在。伪文件系统包括:负责管理块设备 inode 的 bdev、负责处理管道的 pipefs、处理套接字的 sockfs,这些都出现在 /proc/filesystems 中。

伪文件系统对内核来说就是一个普通文件系统,按通用方法使用即可;对用户来说它不存在。所有表示块设备的 inode 都保存在伪文件系统 bdev 中,这些对用户层不可见,这使得可以用标准的 VFS 函数来处理块设备 inode。

读取一个文件,首先要确定文件块所属的磁盘块,也就是文件的元数据,由 get_block 函数负责(不同文件系统有不同实现,裸设备也有对应函数),这种对应关系记录在 buffer_head 中,记录了磁盘块和文件块的映射关系。读到的元数据会缓存到该文件对应块设备 block_device 的地址空间 address_space 中,下次再读同一文件时,元数据就可以直接从对应 bdev 的缓存中取得。

如果直接对块设备文件(如 /dev/sdx)进行读写,块设备文件也会被缓存到内存中对应的基树 address_space 中。对 bdev 这种特殊文件来说,不仅缓存常规文件的元数据,也缓存真实数据,dd 命令就是这种应用:

dd if=/dev/sda of=/tmp/dest bs=1 count=4096

执行前可以先用 sysctl -w vm.drop_caches=3 清空文件缓存,再用 free 观察 cache 的变化。对文件系统层的代码来说,它不关心你是块设备、常规文件还是字符设备文件,只要你提供 file_operations 函数集合,不会平白给任何文件系统特权。

伪文件系统和普通文件系统的区别在于:其 inode 对用户不可访问,仅在内核态可见,从用户层视角看该文件系统并不存在。伪文件系统的作用是把操作系统中的一些元素(块设备 bdevfs、管道文件 pipefs、套接字 socketfs 等)封装成和普通文件统一的接口,正是通过这种封装,才实现了 Linux “一切皆文件” 的思想。

来源:https://ty-chen.github.io/linux-kernel-block-device/

loop 设备

在类 UNIX 系统里,loop 设备是一种伪设备(pseudo-device),也可以说是仿真设备,它能让我们像访问块设备一样访问一个文件。

使用之前,一个 loop 设备必须先和一个文件建立连接,这种结合方式给用户提供了一个替代块特殊文件的接口——如果这个文件包含一个完整的文件系统,它就可以像磁盘设备一样被 mount 起来。

常见的这类文件格式有 CD/DVD 的 ISO 光盘镜像文件,或者软盘(硬盘)的 *.img 镜像文件。通过 loop mount(回环挂载)的方式,这些镜像文件可以被 mount 到当前文件系统的某个目录下。

顺便理解一下 “loop” 这个名字的含义:第一层文件系统直接安装在物理设备之上;而被 mount 起来的镜像文件(本身也包含文件系统)建立在第一层文件系统之上——看起来就像是在第一层文件系统之上又绕了一圈的文件系统,所以称为 loop。

维护记录

时间 修改内容 原因
2026-07-26 categories 由 Inbox 改为 Linux;新增 lastmod;补充「ls -l 文件类型标识」小节(-/d/l/c/b/p/s 完整对照表);标签 reprint 改为 remix + AI-assisted,新增 device-file、file-types 原文档只零散提到 c/b 两种类型,缺少完整的 ls -l 文件类型对照;分类与内容不符