cdev、file_operations 与字符设备驱动
先放一张图,这张图简略描述了 cdev 结构体在字符设备驱动中的地位,及其依赖关系。这张图中被方框框起来的部分是内核空间。
很明显,无论是加载模块、卸载模块,都是直接对 cdev 进行操作,因为它描述了整个字符设备,包括 file_operations 结构体变量。

cdev结构体分析(简):

file_operations ,这个结构体包含很多内核操作函数(运行在用户空间的程序只能通过系统调用来间接调用它们),我们的每个字符设备驱动都要注册一个 file_operations 结构体变量。如下图所示,file_operations 作为一个内核操作函数集合,充当从“系统函数”映射到“内核函数”的桥梁。
我们通过 cdev_init() 函数将 cdev 结构体变量与 file_operations 结构体变量建立连接。我们之后对内核进行操作时,实际的途径是:应用程序 -> 系统调用 -> cdev -> file_operations -> 内核函数。
注册与注销字符设备:
从用户空间来看,我们执行 insmod、rmmod 来加载和卸载模块,映射到内核空间则是分别通过 cdev_add() 和 cdev_del() 来注册和注销 cdev(在注册和注销时还会分别申请和释放设备号,略)。其中 cdev_add() 和 cdev_del() 分别会将对应的 cdev 添加到 cdev_map 散列表当中。
操作字符设备:
用户空间应用程序的读写等操作最终会映射到内核空间的读写等操作函数,内核空间中的操作函数即 file_operations 结构体里包含的那些操作函数(file_operations 中的操作函数本身也会调用其他内核函数去执行最终的读写操作,即内核函数调用内核函数,也就是存在内核函数间依赖)。



浙公网安备 33010602011771号