为什么这些特殊设备文件读取最小的PAGE SIZE字节?

时间:2013-11-05 07:34:34

标签: linux kernel

我正在编写我的第二个内核模块。我试图提供用户空间访问固件核心,作为演示。该演示属于petalinux(专为Zynq或Microblaze量身定制的嵌入式操作系统)。我在用户空间和内核模块之间添加了虚拟文件系统挂钩,它似乎在读取和写入时都有效。唯一的打嗝是,在我的用户应用程序和我的内核模块之间,操作系统将我的请求大小扩展到PAGE SIZE(4096)。

一位同事评论说我可能将模块安装为块设备而不是字符设备。这很有道理。我的模块上游的某个人肯定会缓存我的结果(如果我对块驱动程序的理解是准确的,那么对于硬盘驱动器来说是完全合理的),但是我们被绑定到易失性设备,所以这不是适当。但是我能找到的所有诊断都表明它是作为角色设备安装的......

mknod /dev/myModule **c** (Dynamically specified Major Number) (Zero)
ls -la /dev/myModule
   **c**rw-r--r--     1   root    root 252, -    Jan 1 01:05 myModule

这是我用来注册虚拟文件IO hooks的模块源.....

alloc_chrdev_region (&moduleMajorNumber, 0, 1, "moduleLayerCDMA");
register_chrdev_region  (&moduleMajorNumber,    1, "moduleLayerCDMA");    
cdevP = cdev_alloc();
cdevP->ops = &moduleLayerCDMA_fileOperations;
cdevP->owner = THIS_MODULE;
cdev_add(cdevP, moduleMajorNumber, 1);

任何线索?

1 个答案:

答案 0 :(得分:0)

您的问题来自于标准C库缓冲I / O例程(fopenfclosefreadfgetch及其朋友)保留的事实每个打开的文件/设备的用户空间缓冲区,当程序尝试从该文件/设备读取时,库例程尝试进行预读,为以后的读取调用做准备,以提高I / O的效率。类似地,使用fwrite的写操作会通过写缓冲区,并且只有在缓冲区已满或关闭文件/设备或显式执行fflush时才会通过系统调用刷新到系统。

有两种方法可以解决这个问题:

  • 更简单的方法是简单地将用户空间程序转换为使用非缓冲I / O(openclosereadwrite&他们的朋友们,这些只是以1:1为基础进行相应的系统调用。
  • 或者处理内核模块中的问题:忽略read中询问的字节数,如果它超过您希望在单个系统调用中返回的字节数。您可以将该值视为调用者提供的缓冲区长度,并且您不必完全填写它。当然,在返回值中,您必须指出实际读取的字节数。