日期:2014-05-16  浏览次数:20599 次

关于linux字符驱动设备的一个疑问
字符驱动设备的驱动函数通过结构体file_operations指定函数调用的位置,但是这里面函数定义的参数为什么与调用它的参数对不上呢?

比如:file_operations中read函数为 static ssize_t device_read(struct file *file,
  char * buffer,
  size_t length,
  loff_t * offset);

可是在用户空间open了该设备文件后,使用的read函数为 read(fd,buf,2);

很显然这里两个read函数的参数个数都对不上,可是系统为什么还能正确调用该驱动模块读取底层的数据呢?

求指点。


------解决方案--------------------
应用程序的open 会调用内核系统调用sys_read
asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count);

关于这个,网上很容易搜到
------解决方案--------------------
用户态的read是系统提供给用户程序的接口,而内核态的read函数是驱动程序的实现,用户程序使用read的时候并不是直接就调用驱动程序中对应的read函数。Linux内核会对其进行封装并提供给用户程序一个通用的接口。当用户程序open设备的时候系统会根据设备号找到对应设备及其对应的驱动程序,用户程序read的时候会使用对应驱动程序中read封装过后提供给应用程序的接口。
如果研究内核源码你就会发现不同版本的file_operations结构都会有很多不同,其中一些方法的都会不同(例如以前叫做ioctl的函数,最新版本的内核中已经没有,而叫做unlocked_ioctl),然而对应的用户程序的接口却不会改变,这样就有利于用户程序的兼容。
------解决方案--------------------
简单的理解,参数很符合要求啊,每个参数的属性都对上,至于个数,采用的是动态输入的方式,少于或者等于驱动的参数都没问题,多就不行了,一句话,个数只能少不能多,否则驱动就实现不了。
------解决方案--------------------
按照你给的程序: device_read(struct file *file, char * buffer, size_t length, loff_t * offset);与 read(fd,buf,2); 函数名本来就不同, 因此,本身就不是一个函数。

如果read(fd,buf,2)是用户态的, 那么,它还将在函数中调用驱动程序device_read( )吧。