3.1.3 块设备与字符设备

3.1.3 块设备与字符设备#

块设备(Block Device)以“块”为单位进行I/O,支持随机访问与缓存,适合磁盘、SSD、LVM等;字符设备(Character Device)以“字节流”顺序访问,通常不走页缓存,适合TTY、串口、随机数设备等。

原理草图:I/O路径与缓存差异

文章图片

核心差异对比
- 访问方式:块设备支持随机读写;字符设备通常顺序读写
- 缓存与调度:块设备走页缓存与I/O调度器;字符设备多直接与驱动交互
- 节点类型/dev 下首字符为 b(块)或 c(字符)
- 典型用途:块设备用于分区/文件系统;字符设备用于终端/管道/熵源


识别与查看(带命令解释)

# 1) 查看设备节点类型(b/c)、主次设备号
ls -l /dev/sda /dev/tty
# 输出示例:
# brw-rw---- 1 root disk 8, 0 /dev/sda   # b=块设备
# crw-rw-rw- 1 root tty  5, 0 /dev/tty    # c=字符设备

# 2) 查看系统已识别的块设备树与挂载点
lsblk -f
# -f 显示文件系统类型、UUID、挂载点

# 3) 查看内核已注册的设备主设备号
cat /proc/devices
# 输出分为 Character devices 与 Block devices

块设备示例:创建文件系统并挂载(完整流程)

# 假设新增磁盘 /dev/sdb(块设备),创建分区并格式化
sudo parted -s /dev/sdb mklabel gpt
sudo parted -s /dev/sdb mkpart primary ext4 1MiB 100%

# 查看分区是否生成(/dev/sdb1)
lsblk /dev/sdb

# 格式化为 ext4(块设备上创建文件系统)
sudo mkfs.ext4 /dev/sdb1

# 创建挂载点并挂载
sudo mkdir -p /mnt/data
sudo mount /dev/sdb1 /mnt/data

# 验证挂载结果
df -hT /mnt/data

命令解释
- parted:分区工具;mklabel gpt 创建 GPT 分区表
- mkfs.ext4:在块设备上创建 ext4 文件系统
- mount:将块设备(或其分区)挂载到目录


字符设备示例:验证行为差异

# /dev/null 丢弃写入数据,适合作为“黑洞”
echo "test" > /dev/null

# /dev/zero 提供无限 0 字节流,常用于测试或清零
dd if=/dev/zero of=/tmp/zero.bin bs=1M count=10

# /dev/random 可能阻塞(熵不足),/dev/urandom 不阻塞
head -c 16 /dev/urandom | xxd

命令解释
- dd:按块拷贝数据,适用于块/字符设备测试
- head -c:读取指定字节数


排错与诊断

# 1) 将字符设备误当块设备挂载
sudo mount /dev/tty /mnt/test
# 典型报错:wrong fs type 或 bad superblock

# 2) 设备节点不存在
ls -l /dev/sdb
# 若不存在,可能硬件未识别或 udev 未创建设备节点

# 3) 查看内核日志定位设备识别问题
dmesg | tail -n 50

排错思路
- 挂载失败:确认目标是否为块设备(ls -l /dev/xxx
- 设备缺失:检查 lsblkdmesg、硬件连接
- 权限问题:检查设备节点属主属组(通常为 root:disk)


练习
1. 使用 ls -l 区分 /dev/null/dev/sda 的设备类型。
2. 用 dd/dev/zero 创建 20MB 测试文件,并删除验证空间变化。
3. 新建虚拟磁盘(如云盘或虚拟机磁盘),完成分区、格式化、挂载全过程。
4. 观察 cat /proc/devices 中块设备主设备号对应关系,查找你系统的 NVMe/SATA 设备类型。