在不使用ioremap或mmap的情况下写入linux内核中的可缓存物理地址

时间:2012-02-08 12:51:43

标签: linux memory-management linux-kernel

我正在更改linux内核调度程序,以在已知的物理内存位置打印下一个进程的pid。 mmap用于用户空间程序,而我读到ioremap将页面标记为不可缓存,这会减慢程序的执行速度。我想快速写入已知的物理内存。 phys_to_virt是我认为可行的选择。任何想法不同的技术。

PS:我在qemu上运行这个linux内核。 qemu将使用物理地址来读取来宾内核发送的信息。写入已知的io-port是不可行的,因为每次访问设备时都会调用支持此io设备的设备代码。

编辑:我希望pid的物理地址位置安全。如何确保内核正在使用的物理地址未分配给任何进程。据我所知,ioremap会将页面标记为可缓存,因此不会有很大用处。

2 个答案:

答案 0 :(得分:1)

执行此操作的最简单方法是执行kmalloc()以获取内核中的内存。然后,您可以通过将指针传递给virt_to_phys()来获取返回的指针的物理地址。这是一个彻头彻尾的黑客,但对于你在qemu下调试/跟踪的情况,它应该可以正常工作。

编辑:我误解了这个问题。如果您想使用特定的物理地址,您可以做一些事情。也许最干净的事情是修改qemu传入的e820映射以将RAM页面标记为保留,然后内核不会使用它。 (即传递ACPI表的方式相同)。

如果您不想修改qemu,您还可以修改早期内核启动(可能在arch/x86/kernel/setup.c左右)以在要保护的特定物理页面上执行reserve_bootmem()以免被使用。

要实际使用指定的物理地址,您可以像使用ACPI驱动程序访问其表格一样使用ioremap_cache()

答案 1 :(得分:0)

我似乎误解了VM和主机部分之间的缓存一致性,这是一个更新的答案。 你想要的是" VM中的虚拟地址" < - > " QEMU地址空间中的虚拟或物理地址"。 然后你可以kmalloc它,但它可能因实例而异, 或者只是在内核中声明一个全局变量。

然后virt_to_phys将允许您访问VM空间中的物理地址,我想您可以在QEMU地址空间中进行翻译。你是什​​么意思"内核使用的物理地址没有分配给任何进程?"您担心可能会交换包含变量的页面吗? kmalloced memory is not swappable

原始(和错误的)答案

如果您要撰写的地址位于其自己的页面中,我无法查看ioremap的方式 这个页面会减慢在不同页面中执行的代码。

无论如何你都需要缓存刷新,如果没有SSE,我就看不到MMU和缓存打开时如何绕过缓存。我只能看到这两个选项:

  • ioremap并声明特定页面不可缓存

  • 使用"正常"地址,并在每次写入时手动执行缓存刷新。