有两种类型的虚拟地址的Linux内核使用:
- 你已经在该行的“内核内存(虚拟)直接 对应的物理内存提到什么(只是0xC000_0000将 给予补偿我们的实际地址)“。这映射到连续的物理地址。
- 使用vmalloc。
第一种是使用宏完成:
include/asm-x86/page_32.h
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
_pa(x)的确实的虚拟到物理转换。请注意,这个翻译是在编译时内联的。没有页面表翻译发生。这最后一句话非常重要。
另一方面,使用第二种方法,您可以分配虚拟内存中连续的内存,但物理内存中可能不会这样。现在,在这种情况下,当您第一次访问虚拟地址时,需要整页表格转换。问题是这是谁?
在CISC机器(如x86)的情况下,MMU(硬件)在TLB未命中(首次访问虚拟地址)的情况下执行该操作并更新页表。对于内核虚拟地址(通过vmalloc获取),它们保留为TLB条目。它们被称为全局条目,当进程上下文切换发生时,它们大多被忽略,而不像其他进程地址空间条目那样被刷新。但是,当您执行vfree以释放关联的虚拟内存时,这些条目将被删除。
在RISC机器(如MIPS)的情况下,页面转换由软件处理。 TLB未命中后,硬件引发异常。陷阱句柄以内核模式运行以执行翻译并使用特殊指令更新TLB。从陷阱处理程序返回后,运行相同的代码行并发生TLB命中。
请参考:http://pages.cs.wisc.edu/~remzi/OSFEP/vm-tlbs.pdf
的底线是,并非所有的内核地址映射您所描述的方式。对于你的情况,物理地址是在编译时本身生成的。那么,为什么要添加一个TLB条目。对于来自vmalloc的地址,存在TLB条目。当进程之间发生上下文切换时,不需要刷新整个TLB,并且可以保留内核的vmalloc创建的全局条目。当你使用vfree时,相应的全局条目将被刷新。
ARM是一款RISC机器,我想它的工作方式与MIPS描述的相同。但我不确定。不过,我相信您的问题可以在不考虑处理器架构的情况下得到充分回答。 – trans1st0r
看起来像[ARM does硬件页面漫游](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0333h/I1029222.html)。除了TLB未命中开销较低的显而易见的优势之外,这允许推测TLB预取,这对于软件TLB未命中处理来说并不可行。另外http://stackoverflow.com/questions/28019266/arm-mmu-and-arm-linux-page-table-walk。我发现的ARM文档提到了关于禁用页面漫游位的一些内容,所以也许ARM可以使用软件页面漫游,而不像x86。 –