其中,register_chrdev函数中的参数MAJOR_NUM为主设备号,"exampledev"为设备名,exampledev_fops 为包含基本函数入口点的结构体,类型为file_operations。当执行exampledev_init时,它将调用内核函数 register_chrdev,把驱动程序的基本入口点指针存放在内核的字符设备地址表中,在用户进程对该设备执行系统调用时提供入口地址。
较早版本内核的file_operations结构体定义为(代码及图示):
struct file_operations { int (*lseek)(); int (*read)(); int (*write)(); int (*readdir)(); int (*select)(); int (*ioctl)(); int (*mmap)(); int (*open)(); void(*release)(); int (*fsync)(); int (*fasync)(); int (*check_media_change)(); void(*revalidate)(); }; |
随着内核功能的加强,file_operations结构体也变得更加庞大。但是大多数的驱动程序只是利用了其中的一部分,对于驱动程序中无需提供的功能,只需要把相应位置的值设为NULL。对于字符设备来说,要提供的主要入口有:open ()、release ()、read ()、write ()、ioctl ()等。
open()函数 对设备特殊文件进行open()系统调用时,将调用驱动程序的open () 函数:
int (*open)(struct inode * inode,struct file *filp); |
其中参数inode为设备特殊文件的inode (索引结点) 结构的指针,参数filp是指向这一设备的文件结构的指针。open()的主要任务是确定硬件处在就绪状态、验证次设备号的合法性(次设备号可以用 MINOR(inode-> i_rdev) 取得)、控制使用设备的进程数、根据执行情况返回状态码(0表示成功,负数表示存在错误) 等;
release()函数 当最后一个打开设备的用户进程执行close ()系统调用时,内核将调用驱动程序的release () 函数:
void (*release) (struct inode * inode,struct file *filp) ; |
release 函数的主要任务是清理未结束的输入/输出操作、释放资源、用户自定义排他标志的复位等。
|