块设备与字符设备管理深度解析(基于OpenEuler 24.03)
文章目录
- [块设备与字符设备管理深度解析(基于OpenEuler 24.03)](#块设备与字符设备管理深度解析(基于OpenEuler 24.03))
-
- 一、设备基础概念体系
-
- [1.1 块设备的核心特性与分类](#1.1 块设备的核心特性与分类)
- [1.2 字符设备的流式数据模型](#1.2 字符设备的流式数据模型)
- [1.3 设备标识系统:主设备号与次设备号](#1.3 设备标识系统:主设备号与次设备号)
- 二、设备信息查询与管理工具
-
- [2.1 系统设备注册表:/proc/devices](#2.1 系统设备注册表:/proc/devices)
- [2.2 块设备可视化工具:lsblk](#2.2 块设备可视化工具:lsblk)
-
- [2.2.1 基本用法与输出解析](#2.2.1 基本用法与输出解析)
- [2.2.2 高级查询功能](#2.2.2 高级查询功能)
- [2.3 设备号查询工具:ls -l](#2.3 设备号查询工具:ls -l)
- 三、设备文件操作与管理
-
- [3.1 手动创建设备文件:mknod](#3.1 手动创建设备文件:mknod)
- [3.2 自动创建设备文件:MAKEDEV](#3.2 自动创建设备文件:MAKEDEV)
- 四、udev设备管理系统
-
- [4.1 udev概述与发展历程](#4.1 udev概述与发展历程)
- [4.2 udev核心配置文件](#4.2 udev核心配置文件)
-
- [4.2.1 udev.conf配置文件](#4.2.1 udev.conf配置文件)
- [4.2.2 规则文件目录:/etc/udev/rules.d](#4.2.2 规则文件目录:/etc/udev/rules.d)
- [4.3 udev规则语法详解](#4.3 udev规则语法详解)
-
- [4.3.1 操作符类型](#4.3.1 操作符类型)
- [4.3.2 常用匹配键](#4.3.2 常用匹配键)
- [4.3.3 常用赋值键](#4.3.3 常用赋值键)
- [4.4 udev规则实例解析](#4.4 udev规则实例解析)
- [4.5 udev设备信息查询工具:udevadm](#4.5 udev设备信息查询工具:udevadm)
-
- [4.5.1 查询设备路径信息](#4.5.1 查询设备路径信息)
- [4.5.2 全面设备信息查询](#4.5.2 全面设备信息查询)
- [4.6 udev服务控制](#4.6 udev服务控制)
- 五、实战案例:自定义udev规则
-
- [5.1 案例:为USB打印机分配固定名称](#5.1 案例:为USB打印机分配固定名称)
- [5.2 案例:设置串口设备权限](#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中查看设备号的典型方法:
bash
# 查看光驱设备号
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中分为字符设备和块设备两部分:
bash
cat /proc/devices
# 输出片段:
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
14 sound
21 sg
29 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 rtc
Block devices:
1 ramdisk
259 blkext
7 loop
8 sd
9 md
11 sr
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 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 基本用法与输出解析
bash
# 列出所有块设备及其挂载关系
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 高级查询功能
bash
# 显示文件系统信息
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
命令可以直接查看设备文件的主设备号和次设备号,这是最基础的设备信息查询方式:
bash
# 查看硬盘设备号
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文件:
bash
# 命令语法
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中的设备文件自动创建脚本,基于预设规则生成标准设备文件:
bash
# 命令语法
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的基本行为:
bash
# 查看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
目录中,文件名通常以两位数字开头表示执行顺序:
bash
# 查看规则文件列表
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规则示例及其解析:
bash
# 规则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 查询设备路径信息
bash
# 查询/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 全面设备信息查询
bash
# 查询所有设备信息
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服务的常用命令:
bash
# 重启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
,避免因插拔顺序导致设备名变化。
实现步骤:
- 查询打印机硬件信息:
bash
# 插入打印机后执行
udevadm info -a -n /dev/usb/lp0
# 记录关键信息:
# - 厂商ID(ATTRS{idVendor})
# - 产品ID(ATTRS{idProduct})
# - 序列号(ATTRS{serial})
- 创建自定义规则:
bash
# 在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
- 应用规则并验证:
bash
# 重新加载规则
udevadm control --reload-rules
# 移除并重新插入打印机
ls -l /dev/usb_printer
# 应看到指向实际设备文件的符号链接
5.2 案例:设置串口设备权限
需求:将串口设备/dev/ttyS0
的权限设置为允许dialout组用户访问。
实现步骤:
- 创建规则文件:
bash
vi /etc/udev/rules.d/60-serial-port.rules
# 添加内容:
KERNEL=="ttyS0", GROUP="dialout", MODE="0660"
# 解析:
# - 匹配ttyS0设备
# - 属组设为dialout
# - 权限设为0660(dialout组可读写)
- 应用规则:
bash
systemctl restart udev
# 或
udevadm control --reload-rules
- 验证权限:
bash
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组可读写)
- 应用规则:
bash
systemctl restart udev
# 或
udevadm control --reload-rules
- 验证权限:
bash
ls -l /dev/ttyS0
# 应显示权限为crw-rw----,属组为dialout
通过上述内容,我们全面解析了OpenEuler 24.03中块设备与字符设备的管理体系,从基础概念到高级配置,结合具体命令和案例,帮助读者深入理解Linux设备管理的核心机制。无论是设备信息查询、手动/自动创建设备文件,还是通过udev实现动态设备管理,都提供了完整的操作指南和实践案例,适用于系统管理员和开发人员掌握设备管理的关键技术。