01、Linux设备分类
一、字符设备(是以字节为单位进行输入输出)
字符设备没有固定的大小,也没有缓冲区,数据会立即被传输。
字符设备驱动通过面向流的I/O接口,以字节流传输机制实现用户空间程序与设备之间的异步数据交互,其操作模式与传统串行通信终端设备具有功能对等性。此类设备在Linux系统中遵循"Everything is a file"的核心设计哲学,通过虚拟文件系统(VFS)框架在/dev目录下创建设备文件节点,该特殊文件系统入口不仅提供了标准化的I/O操作接口(read/write),还通过ioctl系统调用向用户提供设备控制通道,实现设备属性配置及状态管理功能。
在内核实现层面,字符设备驱动以struct cdev抽象数据结构为核心,该结构体定义于<linux/cdev.h>系统头文件中,负责封装设备号(dev_t)、操作函数指针表(file_operations)以及模块引用计数等关键元数据。通过cdev_init/cdev_add等内核API完成设备注册后,该结构体实例将建立设备逻辑表示与物理硬件之间的映射关系,实现系统调用向底层硬件操作的转换。这种模块化设计使得字符设备驱动能够以统一的方式处理来自用户空间的I/O请求,同时保持与具体硬件实现的解耦特性,体现了Linux设备模型的抽象化与可扩展性优势。
值得注意的是,字符设备驱动作为Linux设备驱动框架的基础组件,其设计模式深刻影响了后续块设备、网络设备等驱动类型的开发范式,展现了操作系统内核设计中"接口抽象先行"的核心理念。
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
2
3
4
5
6
7
8
以下是关于字符设备驱动的简化说明:
1.1、字符设备驱动的核心特点
- 像文件一样使用:字符设备在Linux中被当作普通文件处理,用户可以通过
读(read)
、写(write)
等文件操作命令直接与设备交互。 - 功能简单直接:主要处理单个字节或连续数据流(比如串口、键盘),不涉及复杂的数据块管理(如硬盘属于块设备)。
- 模块化开发:驱动通常以内核模块形式存在,可以动态加载/卸载。
1.2、如何创建和注册字符设备
1. 创建设备的步骤
- 分配设备号:每个设备都有唯一编号(主设备号+次设备号),类似文件系统的"身份证"。
- 创建设备文件:用户通过
mknod
命令在文件系统中生成对应的设备文件(如/dev/mydevice
)。
2. 注册到系统
- 定义功能接口:用
file_operations
结构体列出设备支持的操作(如打开、读、写等)。 - 调用注册函数:用
register_chrdev
或register_chrdev_region
告诉内核这个设备的存在。
1.3、设备文件方法:如何让用户程序控制设备
内核通过struct file_operations
结构,将设备功能包装成标准文件操作:
struct file_operations {
int (*open)(设备, 参数); // 打开设备时触发
int (*read)(设备, 数据缓冲区); // 用户读数据时调用
int (*write)(设备, 数据缓冲区); // 用户写数据时调用
// 还有close、ioctl等其他方法...
};
2
3
4
5
6
关键点:
- 用户程序通过
open()
、read()
等系统调用,自动找到并执行驱动中对应的函数。 - 例如:当用户执行
cat /dev/mydevice
时,内核会调用驱动里的read
函数完成数据读取。
总结
字符设备驱动 = 功能函数(如读写操作) + 设备注册(告诉内核设备存在) + 设备文件(让用户可见)。用户只需像操作普通文件一样,就能通过系统调用间接调用驱动中的功能。
二、块设备:块设备是以块为单位进行输入输出
硬盘、U盘。块设备是有缓冲区,数据下发以后会在缓冲区中缓存。
块设备可以被分区,还可以格式化文件系统。
块设备主要有以下两种。
- 机械硬盘:机械硬盘的读写单位是扇区。访问机械硬盘的时候,需要首先沿着半径方向移动磁头寻找磁道,然后转动盘片找到扇区。
- 闪存类块设备:使用闪存作为存储介质,里面的控制器运行固化的驱动程序,驱动程序的功能之一是闪存转换层(Flash Translation Layer,FTL),把闪存转换为块设备,对外表现为块设备。常见的闪存类块设备是在个人计算机和笔记本电脑上使用的固态硬盘(Solid State Drives,SSD),以及在手机和平板电脑上使用的嵌入式多媒体存储卡(embedded Multi Media Card,eMMC)和通用闪存存储(Universal Flash Storage,UFS)。
闪存类块设备相对机械硬盘的优势是:访问速度快,因为没有机械操作;抗振性很高,便于携带。
闪存(Flash Memory)的主要特点如下。
- 在写入数据之前需要擦除一个擦除块,因为向闪存写数据只能把一个位从1变成0,不能从0变成1,擦除的目的是把擦除块的所有位设置为1。
- 一个擦除块的最大擦除次数有限,NOR闪存的擦除块的最大擦除次数是104~105,NAND闪存的擦除块的最大擦除次数是105~106。
闪存按存储结构分为NAND闪存和NOR闪存,两者的区别如下。
- NOR闪存的容量小,NAND闪存的容量大。
- NOR闪存支持按字节寻址,支持芯片内执行(eXecute In Place,XIP),可以直接在闪存内执行程序,不需要把程序读到内存中;NAND闪存的最小读写单位是页或子页,一个擦除块分为多个页,有的NAND闪存把页划分为多个子页。
- NOR闪存读的速度比NAND闪存块,写的速度和擦除的速度都比NAND闪存慢。
- NOR闪存没有坏块;NAND闪存存在坏块,主要是因为消除坏块的成本太高。
NOR闪存适合存储程序,一般用来存储引导程序,比如U-Boot程序;NAND闪存适合存储数据。
三、网络设备
ifconfig