如何解决如何在 Linux 中调用 mmap() 时获取设备中某个字段的偏移量
我目前正在 Linux 设备驱动程序中实现 mmap()
。
基本上,假设已经定义了一个名为 data
的结构。我的设备结构定义如下,
struct test_dev{
struct cdev cdev;
struct mutex lock;
struct data *data;
};
在设备的 open()
方法中,data
是通过调用 vmalloc() 分配的。假设我想让用户调用mmap()
映射到数据字段,用户需要知道offset
字段的data
:
int fd = open("/dev/testdev",O_RDWR);
int ret = mmap(NULL,4096,PROT_READ | PROT_WRITE,MAP_SHARED,fd,offset);
我在试图找到 data
的偏移量时卡住了。
我查看了 mmap() 的联机帮助页,它说
文件映射的内容(相对于匿名 映射;见下面的 MAP_ANONYMOUS),使用长度初始化 从文件(或其他对象)中的 offset 偏移量开始的字节 由文件描述符 fd 引用。
Q1:由于data
字段是用vmalloc()分配的,所以在高内存,但是test_dev
结构是用kmalloc()分配的,在低内存,addr( data) - addr(test_dev) 小于 0。因此,我们不能以这种方式计算偏移量。我可以知道是否有另一种方法来获取 offset
,以便用户可以使用此 offset
到 mmap()
到 data
字段? >
问题 2:如果使用 data
分配 kmalloc()
字段,vmalloc()
方法之间是否有任何区别?
在Linux Device Drivers中,声明kmalloc()
返回的内存地址也是虚拟地址,位于低内存。我不确定使用“addr(data) - addr(test_dev)”是否有效。根据我自己的理解,这不太可能奏效。
此外,由于 kmalloc()
manpage 说 kmalloc()
是内核中为小于页面大小的对象分配内存的正常方法,因此在实现 mmap() 时,我们可能不会选择映射到 kmalloc()
返回的地址,因为 mmap() 映射在页面边界上。
解决方法
偏移量将传递给您在设备驱动程序中编写的 mmap 处理程序。您可以将其视为任意 off_t
参数,表示您想要的任何内容。只需忽略它并始终 mmap data
。或者将其用作 data
开头的偏移量,这对于您的驱动程序来说可能是最正确的语义。
您在驱动程序初始化时使用 kmalloc() 的结构与 mmap 无关。 offset
不是该结构体开头的偏移量。
要 mmap vmalloc 内存,您需要获取每个页面,因为它们不连续,并将其添加到 vma。请参阅 vmalloc_to_page
和 vm_insert_page
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。