vmalloc_to_pfn 在 Linux 32 系统上返回 32 位地址.为什么它会砍掉 PAE 物理地址的高位? [英] vmalloc_to_pfn returns 32 bit address on Linux 32 system. Why does it chop off higher bits of PAE physical address?

查看:16
本文介绍了vmalloc_to_pfn 在 Linux 32 系统上返回 32 位地址.为什么它会砍掉 PAE 物理地址的高位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 vmalloc_to_pfn() 来获取 32 位 PAE Linux 系统上的物理地址.看起来 vmalloc_to_pfn() 返回unsigned long",这意味着它在 32 位系统上是 32 位,在 64 位系统上是 64 位.在 64 位 Linux 上,unsigned long 是 64 位,我没有问题.

I'm using vmalloc_to_pfn() to get the physical address on a 32-bit PAE Linux system. It looks like vmalloc_to_pfn() returns "unsigned long" which means it is 32 bit on a 32 bit system, 64 bit on a 64-bit system. On 64-bit Linux, unsigned long is 64 bit and I've no issues.

问题:使用此函数将虚拟转换为物理:

Problem: Using this function to convert virtual to physical:

VA:0xf8ab87fc使用 vmalloc_to_pfn 的 PA:0x36f7f7fc.但我实际上期待:0x136f7f7fc.

VA: 0xf8ab87fc PA using vmalloc_to_pfn: 0x36f7f7fc. But I'm actually expecting: 0x136f7f7fc.

物理地址介于 4 GB 到 5 GB 之间.但是我无法获得确切的物理地址,我只能获得截断的 32 位地址.还有其他方法可以获得真实的物理地址吗?

The physical address falls between 4 to 5 GB. But I can't get the exact physical address, I only get the chopped off 32-bit address. Is there another way to get true physical address?

推荐答案

我自己正在研究这个,并且是 32 位的 - 所以这不完全是一个答案.但是挖掘相同的东西,我可以看到 vmalloc_to_pfn 的源代码说:

I am myself studying this, and am on 32 bit - so this is not exactly an answer. But digging through the same stuff, I can see the source for vmalloc_to_pfn says:

/*
 * Map a vmalloc()-space virtual address to the physical page frame number.
 */
unsigned long vmalloc_to_pfn(const void *vmalloc_addr)
{
        return page_to_pfn(vmalloc_to_page(vmalloc_addr));
}
EXPORT_SYMBOL(vmalloc_to_pfn);

所以,它实际上不应该返回一个地址——它应该返回一个页框号"(PFN).与此相关:

So, it should not actually return an address - it should return a "page frame number" (PFN). In relation to that:

http://www.tldp.org/LDP/tlk/mm/内存.html

再次使用上面的例子,进程 Y 的虚拟页框编号 1 映射到物理页框编号 4,它从 0x8000 (4 x 0x2000) 开始.加上 0x194 字节的偏移量,我们得到了 0x8194 的最终物理地址.

Using the above example again, process Y's virtual page frame number 1 is mapped to physical page frame number 4 which starts at 0x8000 (4 x 0x2000). Adding in the 0x194 byte offset gives us a final physical address of 0x8194.

显然,人们应该将 PFN 乘以 PAGE_SIZE 来得到一个实际地址——这很奇怪,你怎么会在 Linux 上返回 32 位 地址32 系统"来工作(但话说回来,我不是专家 - 也许 PFN 相当于 32 位的地址?).可能是问题 OP 中模块的最小工作示例,以及用于比较的两个平台上的输出,本来应该是有序的.

So apparently, one should multiply the PFN by PAGE_SIZE to get an actual address - which then makes it strange, how come you got "returns 32 bit address on Linux 32 system" to work at all (but then again, I'm no expert - maybe PFN is equivalent to an address for 32 bit?). Probably a minimal working example of a module in the question OP, and output on both platforms for comparison, would have been in order.

无论如何,我只是注意到您所拥有的 - 物理地址扩展 (PAE) 可能会对分页产生影响;显然,在页面全局目录 (PGD) 中存储为 PFN 的值是特定于体系结构的,并且根据它有不同的定义:

In any case, I just have noticed what you have - that Physical Address Extension (PAE) may make a difference in paging; apparently, the value stored as a PFN in Page Global Directory (PGD) is architecture-specific, and is defined differently depending on it:

typedef unsigned long   pgdval_t; // arch/x86/include/asm/pgtable-2level_types.h
typedef u64     pgdval_t;  // arch/x86/include/asm/pgtable-3level_types.h
typedef unsigned long   pgdval_t; // arch/x86/include/asm/pgtable_64_types.h

总结 - 仅使用 vmalloc_to_pfn() 可能不是获取物理地址的全部内容.

To summarize - just using vmalloc_to_pfn() is probably not the whole story in getting the physical address.

这篇关于vmalloc_to_pfn 在 Linux 32 系统上返回 32 位地址.为什么它会砍掉 PAE 物理地址的高位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆