
一、图解字符驱动模块设计思路
- 用户空间调用
- VFS 层 (虚拟文件系统)
- 字符设备层
- 驱动程序实现
二、应用代码
用户程序通过标准的系统调用(如 open、read、write 等)与字符设备交互。例如:
c
int fd = open("/dev/mydevice", O_RDWR);
write(fd, buffer, size);
read(fd, buffer, size);
close(fd);1
2
3
4
2
3
4
目标:将用户的请求从用户空间传递到内核空间的字符驱动。
三、VFS 层 (虚拟文件系统)
系统调用会通过VFS(虚拟文件系统)进入内核。VFS的作用是把不同文件系统的操作统一管理,具体来说:
VFS的作用
- VFS通过
file_operations结构体找到设备驱动中对应的操作实现。例如,当你读写文件时,VFS会根据这个结构体里的信息找到具体硬件的操作方法。 file_operations是驱动程序的核心配置表,它记录了驱动如何处理各种操作(如读、写、打开文件等)。可以把它想象成驱动的"操作说明书",告诉操作系统每个动作该调用哪个具体函数。
这样设计的好处是让操作系统不用关心具体硬件细节,只要通过VFS和 file_operations 就能兼容不同设备的文件操作。
c
struct file_operations {
.open = my_open,
.read = my_read,
.write = my_write,
.release = my_close,
// 其他操作
};1
2
3
4
5
6
7
2
3
4
5
6
7
四、驱动程序实现
应用程序通过执行 open() 系统调用打开字符设备文件节点后,内核首先解析设备节点的类型标识符(device type)与主设备号(major number)。随后,内核利用主设备号作为索引,定位到字符设备注册表(chrdevs 数组)中对应的驱动注册槽位。该注册表作为 Linux 字符设备框架的核心数据结构,维护着所有已注册驱动的元信息。通过该槽位的索引值,系统可直接获取驱动在注册阶段通过 register_chrdev() 或 alloc_chrdev_region() 接口注册的 file_operations(fops)函数指针结构体。该结构体封装了驱动程序实现的系统调用处理函数,包括 read(), write(), ioctl() 等关键 IO 操作的底层实现逻辑,这些函数直接映射到设备驱动的硬件交互层,构成用户空间进程与设备控制器间的核心通信接口。
此机制体现了 Linux 设备模型中"设备-驱动匹配"的核心设计原理:通过设备号空间到驱动注册表的映射关系,结合 fops 结构体的函数指针动态绑定,实现了用户空间 IO 请求到设备特定操作的抽象化转换与高效路由。

五、驱动流程
- 主次设备号:
dev_t类型变量设备号、MAJOR、MINOR - 设备号的分配:
alloc_chrdev_region - 方法操作集:
cdev_init、file_operations、cdev_add - 节点的创建:
class_create、device_create