我有现有的代码,它获取列表struct page *
并构建描述符表以与设备共享内存。该代码的上层当前期望使用vmalloc
用户空间或从用户空间分配的缓冲区,并用于vmalloc_to_page
获取相应的struct page *
.
现在上层需要处理各种内存,而不仅仅是通过vmalloc
. 这可能是使用 获得的缓冲区kmalloc
、内核线程堆栈内的指针或我不知道的其他情况。我唯一的保证是这个上层的调用者必须确保有问题的内存缓冲区在那个时候被映射到内核空间中(即此时所有的访问都是有效的buffer[i]
)0<=i<size
。如何获得struct page*
与任意指针对应的?
把它放在伪代码中,我有这个:
lower_layer(struct page*);
upper_layer(void *buffer, size_t size) {
for (addr = buffer & PAGE_MASK; addr <= buffer + size; addr += PAGE_SIZE) {
struct page *pg = vmalloc_to_page(addr);
lower_layer(pg);
}
}
我现在需要改变upper_layer
以应对任何有效的缓冲区(不改变lower_layer
)。
我发现virt_to_page
,Linux 设备驱动程序指示在“逻辑地址,[不是]来自内存vmalloc
或高内存”上运行。此外,is_vmalloc_addr
测试一个地址是否来自vmalloc
,并virt_addr_valid
测试一个地址是否是一个有效的虚拟地址(用于virt_to_page
; 这包括kmalloc(GFP_KERNEL)
内核堆栈)。其他情况呢:全局缓冲区、高内存(总有一天会出现,尽管我现在可以忽略它),可能还有其他我不知道的类型?所以我可以将我的问题重新表述为:
- 内核中的所有类型的内存区域是什么?
- 我如何区分它们?
- 我如何获取它们中的每一个的页面映射信息?
如果重要的话,代码在 ARM 上运行(带有 MMU),内核版本至少为 2.6.26。