如何从结构页面中获取关联数据的物理地址?

Posted

技术标签:

【中文标题】如何从结构页面中获取关联数据的物理地址?【英文标题】:How to get the physical address of the associated data from a struct page? 【发布时间】:2012-04-17 22:50:20 【问题描述】:

假设我们从页面缓存文件的地址空间中获得了struct page

我们如何从struct page 中获取 4KB 数据的起始物理地址?

我想struct sk_buff里面应该有类似data指针的东西,但是我没找到。


编辑

感谢 Mat 和 llya 的回答。

看了答案后,我认为第一个问题是识别struct page是位于ZONE_NORMAL还是ZONE_HIGHMEM

在文件 I/O 期间,当我们没有找到缓存页面时,我们将首先使用page_cache_alloc_cold() 分配一个新页面。 page_cache_alloc_cold() 最终将调用alloc_pages(),看起来它将使用ZONE_HIGHMEM(在x86 中,是从PAGE_OFFSET+896M 开始的内核内存区域)来完成它的工作。

所以

我认为Mat的回答适合ZONE_NORMAL中的页面 假设我们使用kmap()来查找与struct page关联的4KB数据的起始物理地址,那么我们应该使用(unsigned long)(&page)-PAGE_OFFSET来查找存储结构本身的物理地址是否正确?

请更正。

【问题讨论】:

page 视为mem_map 数组中的一项。 【参考方案1】:

您需要将page 映射到内核内存中,如下所示:

void * mapping = kmap_atomic(page, KM_USER0);
// work with mapping...
kunmap_atomic(mapping, KM_USER0);

这个技巧是必需的,因为在 Linux 中有一个 HighMemory 概念(例如,请参阅 this 链接)。

UPD:您可以在非原子上下文中使用 kmap 而不是 kmap_atomic

【讨论】:

OP 说他已经有一个struct page,为什么他需要精确映射它? (顺便说一句:lwn.net/Articles/356378;kmap_atomic 的第二个参数在 2009 年的某个时候消失了) 嗯,在处理 HighMemory 时有一些限制。通用 32 位内核只能看到 1G 的内存(在 0xc000000 之后)。所以想象一下你有超过 4G 的 RAM。如何从内核访问它?

以上是关于如何从结构页面中获取关联数据的物理地址?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Linux 内核模块中的逻辑地址获取物理地址?

从逻辑地址转换为物理地址

如何更改虚拟内存页面位置?

linux内核 - 如何获取物理地址(内存管理)?

如何从接口获取物理接口 IP 地址

从 1 到 1 个映射页面执行