【问题标题】:Does a kernel driver implementing mmap() have to create a character device?实现 mmap() 的内核驱动程序是否必须创建字符设备?
【发布时间】:2012-06-25 21:33:39
【问题描述】:

我正在尝试编写一个内核驱动程序来管理一些物理上连续和可 DMA 内存的内存块(我正在使用kmalloc(),因为这些只是 DMA 流)。为了将一些功能拉入用户空间,这个内存将被mmap()ed 和它自己的mmap() 实现。我一直在使用 Linux 设备驱动程序 以及 Google 中出现的不良示例作为我的主要信息来源。

我的mmap()(现在叫它my_mmap())需要在内核中注册。这似乎是使用struct file_operations 执行此操作的唯一有效方法,但这需要为其创建字符设备和物理位置。我不想那样做。我只想为用户空间应用程序创建一个虚拟地址来访问内存缓冲区,而不是创建任何文件来映射内存缓冲区。这可能吗?

我确实发现帧缓冲区也有一个与mmap() 实现等效的结构,但这太过分了。这增加了更多的未知数。

据我了解,my_mmap() 可以完成繁重的工作并使用remap_pfn_range(),只要我对失去的灵活性感到满意。否则我将不得不实现一个本地nopages() 并使用struct vm_operations_struct 注册它。这是正确的吗?

【问题讨论】:

    标签: linux-kernel buffer driver mmap dma


    【解决方案1】:

    mmap() 操作是来自用户空间的请求,将某些源映射到其虚拟地址空间。用户空间程序识别哪个它感兴趣的源的方式是提供一个文件描述符(它实际上只是内核已知资源的句柄)。

    这意味着您必须使您的设备可以表示为文件描述符,以便用户空间程序可以告诉内核它对它感兴趣(并且内核知道调用您的mmap() 实现) - 注册字符设备是这样做的典型方法。请注意,帧缓冲设备也可以通过字符设备访问。

    如果对您的设备没有意义,您不必实现其他字符设备操作,例如 read()write()。字符设备只是用户空间程序打开设备的内核管理句柄的一种方式。

    【讨论】:

    • 我已经在使用 Netlink 进行一些通信。所以我可以获取传递给 netlink_create 的struct socket * sock,访问ops 字段(struct struct_proto_ops)并修改ops 中的mmap 字段。这行得通吗?
    • 更正,Netlink 使用netlink_ops 变量来指向所有 sock->ops。所以我必须复制netlink_ops并修改mmap字段。
    • @Joshua,你的建议可能会奏效,但我只是不明白破解内核而不是以正常方式做事的意义。以正常方式,您有更好的机会避免意外。
    • @Joshua:将mmap() 处理程序添加到您的netlink 套接字可能会起作用,但会有点奇怪。
    • @Joshua,我不能说 mmap() 是否可以在没有任何文件的情况下使用,但没有必要完全创建字符设备。在我的项目中,我在 debugfs 中创建了一个文件,这更容易,并使用它能够将内核空间中的缓冲区映射到用户空间并通过它传递数据。 Here is the code,参见buffer_mmap_fault()buffer_file_mmap()。也许它会有所帮助。
    猜你喜欢
    • 2017-12-13
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 2017-03-02
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    相关资源
    最近更新 更多