我正在编写我的第二个内核模块。我试图提供用户空间访问固件核心,作为演示。该演示属于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);
任何线索?
答案 0 :(得分:0)
您的问题来自于标准C库缓冲I / O例程(fopen
,fclose
,fread
,fgetch
及其朋友)保留的事实每个打开的文件/设备的用户空间缓冲区,当程序尝试从该文件/设备读取时,库例程尝试进行预读,为以后的读取调用做准备,以提高I / O的效率。类似地,使用fwrite
的写操作会通过写缓冲区,并且只有在缓冲区已满或关闭文件/设备或显式执行fflush
时才会通过系统调用刷新到系统。
有两种方法可以解决这个问题:
open
,close
,read
,write
&他们的朋友们,这些只是以1:1为基础进行相应的系统调用。read
中询问的字节数,如果它超过您希望在单个系统调用中返回的字节数。您可以将该值视为调用者提供的缓冲区长度,并且您不必完全填写它。当然,在返回值中,您必须指出实际读取的字节数。