2

我正在为该设备编写一个Linux设备驱动程序以及一个模拟器。为了让设备驱动程序正常工作,我需要为它提供内存资源。如果使用模拟器,我需要在模拟器中分配这些资源。在Linux中模拟设备 - 需要一种方法来分配RAM中的资源

问题是,我不能在系统RAM中分配资源,因为系统RAM地址上不允许使用ioremap()。

我现在使用的方法是使用内核命令行中的mem选项来限制系统可见的内存量。我宁愿使用其他方法,因为我不想告诉所有用户编辑他们的GRUB设置并限制他们的RAM使用。

理想情况下,我希望保留模拟器模块中的内存,并在模拟器模块卸载后释放它。另一个好的方法是尽可能少选择首次加载模拟器并保存在内存中的内存。

据我所知,模拟器应该将内存标记为保留或断开连接。但是我没有看到任何可以做到的导出函数。我需要从一个内核模块来完成。要求用户重新编译他们的内核是不现实的。

对于使用可选内核接口(如内存热插拔),我很确定。它们在流行的发行版内核上启用,所以大多数用户应该可以使用它。但是我找不到任何可用于模块的API来保留或“断开”存储器块。

+0

我不太确定你将能够从模块做到这一点。当然可以使用你提到的mem参数,或者https://www.kernel.org/doc/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt设备树绑定,甚至可以窃取内核的启动码。你不能只是'kmalloc'模拟器的内存,然后让你的驱动程序更聪明,所以它区分phy和虚拟地址? –

+0

*“在系统RAM地址上不允许使用ioremap()”。* - 这可能取决于体系结构甚至是该体系结构的版本。对于ARM,请参阅[ARM的乘法映射内存混乱](https://lwn.net/Articles/409689/)。你想在特定的物理地址记忆吗?否则,查看用于DMA可用内存的各种内存分配器。 – sawdust

+0

我能够通过使用mark_page_reserved()来处理ioremap(),但我仍在挣扎着资源分配,这是一个单独的问题。 – proski

回答

0

我能找到一个很好的解决方案。有两个方面的问题,资源保留和资源重新映射到内核地址空间。

可通过查找包含RAM资源并使用request_resource()在其下分配仿真器资源来解决预留问题。被测驱动程序可以调用request_region(),但它应该使用设备资源的父资源而不是iomem_resource。我认为这是一种合理的方法,可以从父代获取资源,而不是遍历整个资源树,尽管后者在内核中是很常见的做法。

更激进的方法是在RAM资源上取消设置IORESOUCE_BUSY。这将容纳预留iomem_resource下的资源的司机,但对我来说似乎相当不安全。

重映射问题通过将每个“资源”内存页标记为保留来解决。有一个宏,它操纵页面标志。只要确保分配页面对齐的内存。

该网站的工作代码太长;它可以在http://marc.info/?l=linux-mm&m=149280134601521

相关问题