如何将kmalloc()地址转换为物理地址

如何将kmalloc()地址转换为物理地址,c,memory-management,linux-device-driver,C,Memory Management,Linux Device Driver,我有一个PCI设备,它公开了一个条,条中有几个偏移量,用于访问设备。 在其中一个条偏移量上,我需要编程一个64KB的分配内存。在我的Linux驱动程序中,我使用kmalloc()分配了64KB的内存,据我所知,它返回虚拟地址。如果将其编程到偏移量中,HW将无法看到相同的偏移量。如何将此虚拟地址转换为物理地址? 当我在谷歌上搜索时,我看到很少有指向virt_to_phys()的链接,但很少有人回答说这对kmalloc()不起作用。知道怎么做吗?您通常在内核驱动程序中使用pci\u资源\u star

我有一个PCI设备,它公开了一个条,条中有几个偏移量,用于访问设备。 在其中一个条偏移量上,我需要编程一个64KB的分配内存。在我的Linux驱动程序中,我使用kmalloc()分配了64KB的内存,据我所知,它返回虚拟地址。如果将其编程到偏移量中,HW将无法看到相同的偏移量。如何将此虚拟地址转换为物理地址?
当我在谷歌上搜索时,我看到很少有指向virt_to_phys()的链接,但很少有人回答说这对kmalloc()不起作用。知道怎么做吗?

您通常在内核驱动程序中使用pci\u资源\u start()/pci\u资源\u end()。我想你正在写一个设备驱动程序

我不会自己映射内存:这就是内核函数的用途。这样,您就可以确定它在所有平台上都能工作。我假设64k块是PCI设备提供的内存映射?如果是,则上述内容是正确的。如果没有,请提供更多信息。

使用alloc_pages()函数而不是使用kmalloc()

结构页面*alloc_页面(gfp_t gfp_掩码,4)


一个页面是4K的,因此它将分配2^4=16个页面,这相当于16*4K=64K内存并返回物理地址。

您可能应该使用类似于
dma\u alloc\u coherent
的方法,而不是像zch所说的
kmalloc
。或者其他一些dma机制。您应该阅读LDD3中的DMA。它的部分仍然是相关的。下面是正在发生的事情。我有一个busif驱动程序,它映射了前面提到的PCI空间,并按如下方式存储物理空间:base\u addr=PCI\u resource\u start()。现在,它再次使用ioremap_nocache()获得到虚拟地址的映射。在总线层的顶部,我有另一个模块,它负责使用write()/read()调用读取/写入寄存器。此外,我还需要为硬件到DMA操作、输入用户请求等编程一些带有物理内存位置的条偏移量。。。由于HW需要64K的页面,我做了一个kmalloc(),它的物理地址需要转到offset…感谢所有的回复。我唯一关心的是所有这些内存是否都可以DMA分配?在进一步阅读之后,我决定使用pc_alloc_consistent(),它分配一个页面并支持DMA。有人能解释一下为什么使用kmalloc()、\uu get\u free\u pages()等(提供内核虚拟地址的任何其他函数)分配的页面以及在转换为物理地址时不建议DMA使用这些页面吗?我有一个解决方案,但我不清楚为什么?因为您的要求是处理物理地址空间。因此,这些函数满足了您的需求。您所说的DMA'ble是什么意思?DMA'ble意味着硬件可以在分配的区域上进行DMA传输。我的硬件需要将用户区数据DMA到此位置,以便驱动程序拾取并处理它。ok。我对此不太了解。但我所知道的是,如果您想访问物理地址,那么使用page_alloc()函数,而不是kmalloc(),如果这有助于解决您的问题的话。