【问题标题】:Unknown symbol flush_cache_range in linux device driverLinux设备驱动程序中的未知符号flush_cache_range
【发布时间】:2014-07-05 08:01:31
【问题描述】:

我正在编写我的第一个 linux 设备驱动程序,但遇到了问题。我想防止一个内存区域被缓存,所以我一直在尝试使用flush_cache_range()flush_tlb_range() 来刷新这个内存区域的缓存。一切都编译得很好,但是当我尝试加载内核模块时,出现以下错误:

Unknown symbol flush_cache_range (err 0)
Unknown symbol flush_tlb_range (err 0)

我觉得这很奇怪。它们不应该在内核中定义吗?

我知道我也可以使用dma_alloc_coherent() 来分配非缓存内存区域。但我没有设备结构,为此参数传递 NULL 不会导致任何错误,但我也看不到任何应该存在的数据。

关于我的系统的一些信息:我正试图让它在带有集成 FPGA(Xilinx Zynq)的 ARM 微控制器上运行。 FPGA 将一些数据复制到 CPU 指定的内存位置。现在我想在不从缓存中获取旧数据的情况下访问此内存。

非常感谢任何帮助。

【问题讨论】:

    标签: linux-kernel linux-device-driver


    【解决方案1】:

    您不能使用诸如flush_cache_range() 之类的函数,因为它们不是供模块使用的。

    要分配可由 DMA 设备访问的内存,您必须使用dma_alloc_coherent()。 这需要一个有效的设备结构,以便它可以在内存地址和总线地址之间进行正确的映射。

    如果您的设备不在由现有框架(例如 PCI)处理的总线上,您必须创建一个平台设备。

    【讨论】:

    • 谢谢,我想我终于让它运行起来了,即使没有设备结构。在为设备传递 NULL 指针时,它似乎确实有效。我的问题实际上出在其他地方。
    【解决方案2】:

    几点说明:

    1- flush_cache_range 不会“阻止一个内存区域被缓存”.. 它只是简单地刷新(清理 + 无效)缓存。以后通过同一虚拟范围对该内存区域的任何写入/读取都将再次通过缓存。

    2- 如果 FPGA 正在写入内存,然后 CPU 将从该内存中读取,那么刷新缓存可能不是正确的做法。通常你需要做的是使内存区域无效,然后告诉 FPGA 去写。

    3- 请查看内核源代码中的“${kernel-src}/Documentation/DMA-API.txt”。它提供了大量关于如何安全地(缓存维护 + phys_to_dma 转换)使用特定内存区域进行 DMA 的信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多