【发布时间】:2011-05-12 17:42:50
【问题描述】:
我现有的代码采用struct page * 的列表并构建描述符表以与设备共享内存。该代码的上层当前期望分配有vmalloc 或来自用户空间的缓冲区,并使用vmalloc_to_page 获取对应的struct page *。
现在上层需要处理各种内存,而不仅仅是通过vmalloc获得的内存。这可能是使用kmalloc 获得的缓冲区、内核线程堆栈内的指针或我不知道的其他情况。我唯一的保证是这个上层的调用者必须确保有问题的内存缓冲区在那个时候被映射到内核空间中(即此时访问所有0<=i<size 的buffer[i] 是有效的)。 如何获取任意指针对应的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 Device Drivers 表示在“逻辑地址,[不是]来自vmalloc 的内存或高端内存”上运行。此外,is_vmalloc_addr 测试地址是否来自vmalloc,virt_addr_valid 测试地址是否是有效的虚拟地址(virt_to_page 的素材;这包括kmalloc(GFP_KERNEL) 和内核堆栈)。其他情况呢:全局缓冲区、高内存(总有一天会出现,尽管我现在可以忽略它),可能还有其他我不知道的类型?所以我可以将我的问题重新表述为:
- 所有内核中的内存区域有哪些?
- 如何区分它们?
- 如何获取每个页面的映射信息?
如果重要的话,代码在 ARM 上运行(带有 MMU),内核版本至少为 2.6.26。
【问题讨论】:
-
buffer的目标是否需要任何对齐或大小要求? -
@Karmastan:不,没有对齐约束。无论如何,较低层将映射整个页面。我可以用
buffer &= ~(PAGE_SIZE-1)(干净的等价物)开始upper_layer。
标签: linux-kernel virtual-memory