对设备的操作都是通过与cdev绑定的file_operations结构中的函数来完成。
其中读写操作分别对于以下方法:
ssize_t read(struct file *filp, char __user *buff, size_t count, loff_t *offp);
ssize_t write(struct file *filp, const char __user *buff, size_t count, loff_t *offp);
struct file *filp是文件指针。
buff是指向用户空间的缓冲区。
count是请求传输的数据长度。
offp是一个指向“long offset type(长偏移量类型)”对象的指针,这个对象指明用户在文件中进行存取操作的位置。
返回值是“signed size type(有符号的尺寸类型)”
需要强调的是,read和write方法的buff参数是用户空间的指针。因此,内核代码不能直接引用其中的内容。
这里我们需要用到下面两个函数,它们可以提供在用户地址空间和内核地址空间之间进行整段数据拷贝的能力。
unsigned long copy_to_user(void __user *to, const void *from, unsigned long count);
unsigned long copy_from_user(void *to, const void __user *from, unsiged long count);
read方法的任务是从设备拷贝数据到用户空间使用copy_to_user
write方法的任务是从用户空间拷贝数据到设备上使用copy_from_user