块设备与字符设备管理深度解析(基于OpenEuler 24.03)
文章目录
- 块设备与字符设备管理深度解析(基于OpenEuler 24.03)
- 一、设备基础概念体系
- 1.1 块设备的核心特性与分类
- 1.2 字符设备的流式数据模型
- 1.3 设备标识系统:主设备号与次设备号
- 二、设备信息查询与管理工具
- 2.1 系统设备注册表:/proc/devices
- 2.2 块设备可视化工具:lsblk
- 2.2.1 基本用法与输出解析
- 2.2.2 高级查询功能
- 2.3 设备号查询工具:ls -l
- 三、设备文件操作与管理
- 3.1 手动创建设备文件:mknod
- 3.2 自动创建设备文件:MAKEDEV
- 四、udev设备管理系统
- 4.1 udev概述与发展历程
- 4.2 udev核心配置文件
- 4.2.1 udev.conf配置文件
- 4.2.2 规则文件目录:/etc/udev/rules.d
- 4.3 udev规则语法详解
- 4.3.1 操作符类型
- 4.3.2 常用匹配键
- 4.3.3 常用赋值键
- 4.4 udev规则实例解析
- 4.5 udev设备信息查询工具:udevadm
- 4.5.1 查询设备路径信息
- 4.5.2 全面设备信息查询
- 4.6 udev服务控制
- 五、实战案例:自定义udev规则
- 5.1 案例:为USB打印机分配固定名称
- 5.2 案例:设置串口设备权限
- 移除并重新插入打印机
- 应看到指向实际设备文件的符号链接
一、设备基础概念体系
1.1 块设备的核心特性与分类
块设备是Linux系统中以"数据块"为基本单位进行数据传输的设备类型,其核心特征是支持随机访问。在OpenEuler 24.03中,块设备的典型代表包括:
- 存储介质类:硬盘(HDD/SSD)、U盘、SD卡等,这类设备以512字节或其整数倍的块为单位读写数据
- 光学存储类:CD-ROM、DVD驱动器,数据组织为固定大小的逻辑块
- 虚拟存储类:Loop设备(用于挂载镜像文件)、RAM磁盘(基于内存的块设备)
块设备在文件系统中的标识遵循特定规范:
- SCSI/SATA设备:
/dev/sd[a-z]
,如/dev/sda
表示第一块SCSI磁盘 - 光驱设备:
/dev/sr[0-9]
,如/dev/sr0
对应系统识别的第一个光驱 - 软RAID设备:
/dev/md[0-9]
,用于软件磁盘阵列 - 内存磁盘:
/dev/ram[0-0]
至/dev/ram19
,基于物理内存创建的块设备
1.2 字符设备的流式数据模型
字符设备以字节为单位顺序处理数据,不支持随机寻址,适用于数据流式传输场景。OpenEuler 24.03中的典型字符设备包括:
- 输入输出设备:键盘(
/dev/input/event*
)、串口(/dev/ttyS[0-9]
) - 虚拟设备:空设备(
/dev/null
)、零设备(/dev/zero
) - 控制台设备:
/dev/console
(系统控制台)、/dev/tty[0-31]
(虚拟终端) - 多媒体设备:帧缓冲设备(
/dev/fb[0-31]
)、声卡设备(/dev/snd/*
)
字符设备的访问特性决定了其应用场景:
/dev/null
:数据写入后会被丢弃,常用于屏蔽命令输出/dev/zero
:读取时返回无限零数据流,可用于文件填充/dev/tty
:指向当前终端,实现终端无关的输入输出
1.3 设备标识系统:主设备号与次设备号
Linux系统通过设备号对设备进行唯一标识,设备号由两部分组成:
- 主设备号(Major Number):标识设备驱动程序,范围0-255
- 次设备号(Minor Number):标识具体的设备实例,范围0-65535
在OpenEuler中查看设备号的典型方法:
# 查看光驱设备号
ls -l /dev/cdrom
# 输出示例:lrwxrwxrwx. 1 root root 3 7月 1 2016 /dev/cdrom -> sr0
ls -l /dev/sr0
# 输出示例:brw-rw----+ 1 root cdrom 11, 0 7月 1 2016 /dev/sr0
# 解析:主设备号11,次设备号0# 查看帧缓冲设备号
ls -l /dev/fb
# 输出示例:lrwxrwxrwx. 1 root root 3 7月 1 2016 /dev/fb -> fb0
ls -l /dev/fb0
# 输出示例:crw-rw----. 1 root root 29, 0 7月 1 2016 /dev/fb0
# 解析:主设备号29,次设备号0
二、设备信息查询与管理工具
2.1 系统设备注册表:/proc/devices
/proc/devices
文件记录了系统中所有已注册的设备类型及其主设备号,在OpenEuler中分为字符设备和块设备两部分:
cat /proc/devices
# 输出片段:
Character devices:1 mem4 /dev/vc/04 tty4 ttyS5 /dev/tty5 /dev/console5 /dev/ptmx7 vcs10 misc13 input14 sound21 sg29 fb
116 alsa
128 ptm
136 pts
162 raw
180 usb
189 usb_device
202 cpu/msr
203 cpu/cpuid
249 hidraw
250 usbmon
251 bsg
252 pcmcia
253 watchdog
254 rtcBlock devices:1 ramdisk
259 blkext7 loop8 sd9 md11 sr65 sd66 sd67 sd68 sd69 sd70 sd71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
253 device-mapper
254 mdp
2.2 块设备可视化工具:lsblk
lsblk
是OpenEuler中用于查看块设备层次结构的强大工具,包含在util-linux
包中(已默认安装)。其核心功能包括:
2.2.1 基本用法与输出解析
# 列出所有块设备及其挂载关系
lsblk
# 输出示例:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 4.2G 0 rom /media/cdrom
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 500M 0 part /boot
└─sda2 8:2 0 49.5G 0 part ├─VolGroup-lv_root (dm-0) 253:0 0 47.6G 0 lvm /└─VolGroup-lv_swap (dm-1) 253:1 0 2G 0 lvm [SWAP]# 字段解析:
# NAME:设备名称
# MAJ:MIN:主设备号:次设备号
# RM:是否可移动设备(1为可移动)
# SIZE:设备容量
# RO:是否只读(0为可写)
# TYPE:设备类型(disk=磁盘,part=分区,rom=光驱等)
# MOUNTPOINT:挂载点
2.2.2 高级查询功能
# 显示文件系统信息
lsblk -f
# 输出示例:
NAME FSTYPE LABEL UUID MOUNTPOINT
sr0 iso9660 CentOS_6.5_Final /media/cdr
sda
├─sda1 ext4 294ad562-2483-41ce-b5c8-22feb620a766 /boot
└─sda2 LVM2_mem sPD7DF-cTL5-R8XK-fl0y-9Hlr-8uic-LDgOpH ├─VolGroup-lv_root (dm-0)ext4 95161875-59c2-4777-a7ba-599f1cc1fffc /└─VolGroup-lv_swap (dm-1)swap 17981850-c0ec-4b36-8f93-5c4e36165af5 [SWAP]# 显示权限信息
lsblk -m
# 输出示例:
NAME SIZE OWNER GROUP MODE
sr0 4.2G root cdrom brw-rw----
sda 50G root disk brw-rw----
├─sda1 500M root disk brw-rw----
└─sda2 49.5G root disk brw-rw----├─VolGroup-lv_root (dm-0) 47.6G root disk brw-rw----└─VolGroup-lv_swap (dm-1) 2G root disk brw-rw----# 显示拓扑结构
lsblk -t
# 输出示例:
NAME ALIGNMENT MIN-IO OPT-IO PHY-SEC LOG-SEC ROTA SCHED RQ-SIZE RA
sr0 0 2048 0 2048 2048 1 cfq 128 128
sda 0 512 0 512 512 1 cfq 128 128
├─sda1 0 512 0 512 512 1 cfq 128 128
└─sda2 0 512 0 512 512 1 cfq 128 128├─VolGroup-lv_root (dm-0)0 512 0 512 512 1 128 128└─VolGroup-lv_swap (dm-1)0 512 0 512 512 1 128 128
2.3 设备号查询工具:ls -l
通过ls -l
命令可以直接查看设备文件的主设备号和次设备号,这是最基础的设备信息查询方式:
# 查看硬盘设备号
ls -l /dev/sda
# 输出示例:brw-rw----. 1 root disk 8, 0 7月 1 2016 /dev/sda
# 解析:主设备号8,次设备号0# 查看串口设备号
ls -l /dev/ttyS0
# 输出示例:crw-rw----. 1 root dialout 4, 64 7月 1 2016 /dev/ttyS0
# 解析:主设备号4,次设备号64
三、设备文件操作与管理
3.1 手动创建设备文件:mknod
mknod
命令用于在OpenEuler中手动创建设备文件,支持块设备、字符设备和FIFO文件:
# 命令语法
mknod [选项] 设备文件 类型 主设备号 次设备号# 选项说明:
# -Z:设置安全上下文
# -m:设置权限模式(如0666)
# --help:显示帮助信息
# --version:显示版本信息# 示例1:创建/dev/sda设备文件
ls -l /dev/sda # 确认设备文件存在
# 输出示例:brw-rw----. 1 root disk 8, 0 7月 1 2016 /dev/sda
rm -rf /dev/sda # 删除原有设备文件
mknod /dev/sda b 8 0 # 创建块设备文件
ls -l /dev/sda # 验证创建结果
# 输出示例:brw-r--r--. 1 root root 8, 0 3月 24 21:24 /dev/sda# 示例2:创建字符设备文件
mknod /dev/test_char c 249 0 # 创建hidraw字符设备
ls -l /dev/test_char
# 输出示例:crw-r--r--. 1 root root 249, 0 3月 24 21:30 /dev/test_char# 示例3:创建FIFO文件
mknod /tmp/myfifo p # 创建命名管道
ls -l /tmp/myfifo
# 输出示例:prw-r--r--. 1 root root 0 3月 24 21:35 /tmp/myfifo
3.2 自动创建设备文件:MAKEDEV
MAKEDEV
是OpenEuler中的设备文件自动创建脚本,基于预设规则生成标准设备文件:
# 命令语法
MAKEDEV [选项] [设备类型]# 选项说明:
# -a:强制创建设备文件,覆盖已存在的文件
# -d <目录>:指定设备文件创建目录
# -m <最大设备数>:限制创建的设备数量
# -n:仅显示操作,不实际执行
# -v:显示详细执行过程# 示例1:自动创建/dev/sda设备文件
ls -l /dev/sda # 确认设备文件存在
# 输出示例:brw-rw----. 1 root disk 8, 0 7月 1 2016 /dev/sda
rm -rf /dev/sda # 删除原有设备文件
MAKEDEV sda # 自动创建sda设备文件
ls -l /dev/sda # 验证结果
# 输出示例:brw-r-----. 1 root disk 8, 0 3月 25 08:30 /dev/sda# 示例2:创建所有磁盘设备文件
MAKEDEV -a disk # 强制创建所有磁盘相关设备文件
四、udev设备管理系统
4.1 udev概述与发展历程
udev是OpenEuler中负责动态管理/dev目录设备文件的用户空间工具,其发展背景如下:
- 早期阶段:静态设备文件(通过mknod手动创建)
- devfs阶段:内核动态设备文件系统(2.3内核引入,2.6.13后移除)
- udev阶段:用户空间设备管理(当前主流方案,解决了devfs的诸多问题)
udev的核心优势:
- 动态管理:自动识别热插拔设备,实时更新/dev目录
- 稳定命名:基于设备硬件特征(如序列号)分配固定名称
- 灵活配置:可自定义设备权限、属主、符号链接等属性
- 资源优化:仅创建系统实际存在的设备文件,减少资源消耗
4.2 udev核心配置文件
4.2.1 udev.conf配置文件
/etc/udev/udev.conf
是udev的主配置文件,控制udev的基本行为:
# 查看udev.conf内容
cat /etc/udev/udev.conf
# 输出示例:
# The initial syslog(3) priority: "err", "info", "debug" or its
# numerical equivalent. For runtime debugging, the daemons internal
# state can be changed with: "udevadm control --log-priority=<value>".
udev_log="err"# 主要配置参数:
udev_log="err" # 日志级别(err/info/debug)
udev_root="/dev" # 设备文件根目录
udev_db="/dev/.udevdb" # udev数据库路径
udev_rules="/dev/udev/rules.d" # 规则文件目录
4.2.2 规则文件目录:/etc/udev/rules.d
udev规则文件存储在/etc/udev/rules.d
目录中,文件名通常以两位数字开头表示执行顺序:
# 查看规则文件列表
ls -l /etc/udev/rules.d/
# 输出示例:
总用量 44
-rw-r--r--. 1 root root 1652 11月 12 2010 60-fprint-autosuspend.rules
-rw-r--r--. 1 root root 1060 11月 12 2010 60-pcmcia.rules
-rw-r--r--. 1 root root 316 11月 22 2013 60-raw.rules
-rw-r--r--. 1 root root 789 7月 1 2016 70-persistent-cd.rules
-rw-r--r--. 1 root root 420 7月 1 2016 70-persistent-net.rules
-rw-r--r--. 1 root root 320 9月 12 2012 90-alsa.rules
-rw-r--r--. 1 root root 83 7月 20 2011 90-hal.rules
-rw-r--r--. 1 root root 2486 11月 11 2010 97-bluetooth-serial.rules
-rw-r--r--. 1 root root 308 11月 23 2013 98-kexec.rules
-rw-r--r--. 1 root root 54 12月 8 2011 99-fuse.rules
-rw-r--r--. 1 root root 341 7月 1 2016 99-vmware-scsi-udev.rules
4.3 udev规则语法详解
4.3.1 操作符类型
udev规则由键值对组成,通过操作符连接,主要操作符包括:
- 匹配操作符:
==
:等于!=
:不等于
- 赋值操作符:
=
:赋值(可覆盖)+=
:追加值:=
:赋值(不可覆盖)
4.3.2 常用匹配键
键名 | 说明 | 示例 |
---|---|---|
ACTION | 设备事件(add/remove等) | ACTION==“add” |
KERNEL | 内核设备名 | KERNEL==“sd*” |
DEVPATH | 设备在sysfs中的路径 | DEVPATH==“/devices/*” |
SUBSYSTEM | 设备子系统 | SUBSYSTEM==“block” |
BUS | 总线类型 | BUS==“usb” |
DRIVER | 驱动程序名 | DRIVER==“ide-cdrom” |
ATTRS{key} | sysfs属性值 | ATTRS{removable}==“1” |
ENV{key} | 环境变量 | ENV{ID_FS_TYPE}==“ext4” |
4.3.3 常用赋值键
键名 | 说明 | 示例 |
---|---|---|
NAME | 设备文件名 | NAME=“mydevice” |
SYMLINK | 符号链接名 | SYMLINK+=“link1 link2” |
OWNER | 设备属主 | OWNER=“root” |
GROUP | 设备属组 | GROUP=“disk” |
MODE | 设备权限 | MODE=“0666” |
ATTR{key} | 设置sysfs属性 | ATTR{power/state}==“on” |
RUN | 执行外部程序 | RUN+=“/sbin/modprobe sg” |
OPTIONS | 特殊选项 | OPTIONS=“last_rule” |
4.4 udev规则实例解析
以下是OpenEuler中典型的udev规则示例及其解析:
# 规则1:默认设备权限设置
KERNEL=="*", OWNER="root", GROUP="root", MODE="0600"
# 解析:匹配所有设备,设置属主为root,属组为root,权限0600(仅root可读写)# 规则2:终端设备配置
KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666", OPTIONS="last_rule"
# 解析:
# - 匹配所有tty设备
# - 设备名为内核名称(%k)
# - 属组为tty
# - 权限0666(所有用户可读写)
# - OPTIONS="last_rule"表示这是终端规则# 规则3:光驱符号链接
KERNEL=="scd[0-9]*", SYMLINK+="cdrom cdrom-%k"
# 解析:匹配SCSI光驱设备,创建符号链接cdrom和cdrom-内核名# 规则4:ATA光驱识别
KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", SYSFS{device/media}=="cdrom", SYMLINK+="cdrom cdrom-%k"
# 解析:
# - 匹配ATA设备(hd[a-z])
# - 总线类型为IDE
# - 可移动设备(removable=1)
# - 媒体类型为cdrom
# - 创建光驱符号链接# 规则5:SCSI设备驱动加载
ACTION=="add", SUBSYSTEM=="scsi_device", RUN+="/sbin/modprobe sg"
# 解析:当SCSI设备添加时,加载sg驱动模块
4.5 udev设备信息查询工具:udevadm
udevadm
是OpenEuler中用于查询和管理udev数据库的命令行工具:
4.5.1 查询设备路径信息
# 查询/dev/sda的系统设备路径
udevadm info -q path -n /dev/sda
# 输出示例:/devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda# 查询符号链接信息
udevadm info -q symlink -n /dev/sda
# 输出示例:block/8:0 disk/by-path/pci-0000:00:10.0-scsi-0:0:0:0
4.5.2 全面设备信息查询
# 查询所有设备信息
udevadm info -q all -n /dev/sda
# 输出片段:
P: /devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda
N: sda
W: 27
S: block/8:0
S: disk/by-path/pci-0000:00:10.0-scsi-0:0:0:0
E: UDEV_LOG=3
E: DEVPATH=/devices/pci0000:00/0000:00:10.0/host2/target2:0:0/2:0:0:0/block/sda
E: MAJOR=8
E: MINOR=0
E: DEVNAME=/dev/sda
E: DEVTYPE=disk
E: SUBSYSTEM=block
# (省略更多输出)# 基于sysfs路径查询
udevadm info -a -p /sys/block/sda
# 输出包含从设备到总线的完整层次结构信息
4.6 udev服务控制
在OpenEuler中控制udev服务的常用命令:
# 重启udev服务使规则生效
systemctl restart udev# 查看udev进程状态
ps -ef | grep udev
# 输出示例:
root 42737 1 1 12:20 ? 00:00:00 /sbin/udevd -d
root 43263 12851 0 12:20 pts/0 00:00:00 grep udev# 重新加载udev规则
udevadm control --reload-rules
五、实战案例:自定义udev规则
5.1 案例:为USB打印机分配固定名称
需求:为特定USB打印机分配固定设备名/dev/usb_printer
,避免因插拔顺序导致设备名变化。
实现步骤:
- 查询打印机硬件信息:
# 插入打印机后执行
udevadm info -a -n /dev/usb/lp0
# 记录关键信息:
# - 厂商ID(ATTRS{idVendor})
# - 产品ID(ATTRS{idProduct})
# - 序列号(ATTRS{serial})
- 创建自定义规则:
# 在rules.d目录创建新规则文件
vi /etc/udev/rules.d/99-usb-printer.rules
# 添加以下内容:
SUBSYSTEM=="usb", ATTRS{idVendor}=="0419", ATTRS{idProduct}=="0050", ATTRS{serial}=="PRN001", SYMLINK+="usb_printer"
# 解析:
# - 匹配USB子系统
# - 厂商ID 0419,产品ID 0050
# - 序列号PRN001
# - 创建符号链接usb_printer
- 应用规则并验证:
# 重新加载规则
udevadm control --reload-rules
# 移除并重新插入打印机
ls -l /dev/usb_printer
# 应看到指向实际设备文件的符号链接
5.2 案例:设置串口设备权限
需求:将串口设备/dev/ttyS0
的权限设置为允许dialout组用户访问。
实现步骤:
- 创建规则文件:
vi /etc/udev/rules.d/60-serial-port.rules
# 添加内容:
KERNEL=="ttyS0", GROUP="dialout", MODE="0660"
# 解析:
# - 匹配ttyS0设备
# - 属组设为dialout
# - 权限设为0660(dialout组可读写)
- 应用规则:
systemctl restart udev
# 或
udevadm control --reload-rules
- 验证权限:
ls -l /dev/ttyS0
# 应显示权限为crw-rw----,属组为dialout
ol --reload-rules
移除并重新插入打印机
ls -l /dev/usb_printer
应看到指向实际设备文件的符号链接
### 5.2 案例:设置串口设备权限需求:将串口设备`/dev/ttyS0`的权限设置为允许dialout组用户访问。实现步骤:1. **创建规则文件**:
```bash
vi /etc/udev/rules.d/60-serial-port.rules
# 添加内容:
KERNEL=="ttyS0", GROUP="dialout", MODE="0660"
# 解析:
# - 匹配ttyS0设备
# - 属组设为dialout
# - 权限设为0660(dialout组可读写)
- 应用规则:
systemctl restart udev
# 或
udevadm control --reload-rules
- 验证权限:
ls -l /dev/ttyS0
# 应显示权限为crw-rw----,属组为dialout
通过上述内容,我们全面解析了OpenEuler 24.03中块设备与字符设备的管理体系,从基础概念到高级配置,结合具体命令和案例,帮助读者深入理解Linux设备管理的核心机制。无论是设备信息查询、手动/自动创建设备文件,还是通过udev实现动态设备管理,都提供了完整的操作指南和实践案例,适用于系统管理员和开发人员掌握设备管理的关键技术。