第31篇:块设备与字符设备管理深度解析(基于OpenEuler 24.03)

块设备与字符设备管理深度解析(基于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,避免因插拔顺序导致设备名变化。

实现步骤:

  1. 查询打印机硬件信息
bash 复制代码
# 插入打印机后执行
udevadm info -a -n /dev/usb/lp0
# 记录关键信息:
# - 厂商ID(ATTRS{idVendor})
# - 产品ID(ATTRS{idProduct})
# - 序列号(ATTRS{serial})
  1. 创建自定义规则
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
  1. 应用规则并验证
bash 复制代码
# 重新加载规则
udevadm control --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组可读写)
  1. 应用规则
bash 复制代码
systemctl restart udev
# 或
udevadm control --reload-rules
  1. 验证权限
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组可读写)
  1. 应用规则
bash 复制代码
systemctl restart udev
# 或
udevadm control --reload-rules
  1. 验证权限
bash 复制代码
ls -l /dev/ttyS0
# 应显示权限为crw-rw----,属组为dialout

通过上述内容,我们全面解析了OpenEuler 24.03中块设备与字符设备的管理体系,从基础概念到高级配置,结合具体命令和案例,帮助读者深入理解Linux设备管理的核心机制。无论是设备信息查询、手动/自动创建设备文件,还是通过udev实现动态设备管理,都提供了完整的操作指南和实践案例,适用于系统管理员和开发人员掌握设备管理的关键技术。

相关推荐
tan77º13 分钟前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
czhc114007566325 分钟前
Linux 76 rsync
linux·运维·python
小白爱电脑38 分钟前
光纤的最小弯曲半径是多少?
网络
szxinmai主板定制专家1 小时前
【精密测量】基于ARM+FPGA的多路光栅信号采集方案
服务器·arm开发·人工智能·嵌入式硬件·fpga开发
你不知道我是谁?1 小时前
负载均衡--四层、七层负载均衡的区别
运维·服务器·负载均衡
蓝易云1 小时前
Qt框架中connect()方法的ConnectionType参数使用说明 点击改变文章字体大小
linux·前端·后端
dyj0952 小时前
【Rancher Server + Kubernets】- Nginx-ingress日志持久化至宿主机
运维·nginx·rancher
花落已飘2 小时前
多线程 vs 异步
linux·网络·系统架构
PanZonghui2 小时前
Centos项目部署之Nginx部署项目
linux·nginx
九丝城主3 小时前
2025使用VM虚拟机安装配置Macos苹果系统下Flutter开发环境保姆级教程--中篇
服务器·flutter·macos·vmware