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)
- 设备缺失:检查 lsblk、dmesg、硬件连接
- 权限问题:检查设备节点属主属组(通常为 root:disk)
练习
1. 使用 ls -l 区分 /dev/null 与 /dev/sda 的设备类型。
2. 用 dd 从 /dev/zero 创建 20MB 测试文件,并删除验证空间变化。
3. 新建虚拟磁盘(如云盘或虚拟机磁盘),完成分区、格式化、挂载全过程。
4. 观察 cat /proc/devices 中块设备主设备号对应关系,查找你系统的 NVMe/SATA 设备类型。