Linux是操作系统,ARM是在此上下文中引用的处理器。
TLB是否包含内核和用户空间虚拟地址?
内核内存从0xc000_0000
开始,然后转到0xFFFF_FFFF
前3 GB属于用户空间的位置。在进程之间的上下文切换之间,刷新TLB。
TLB是否包含内核和用户空间虚拟地址?
内核内存(虚拟)直接对应物理内存(只需用0xC000_0000
进行偏移即可为我们提供物理地址)。是否有必要在TLB中使用内核(虚拟)(如果你说它存在于TLB中)?它应该只有用户空间地址。
答案 0 :(得分:10)
我们在现代CPU中进行虚拟到物理地址转换的主要原因是为了让我们能够更高效,更好地控制内存使用:
页面表使这一切成为可能。
您确实希望能够在内核的虚拟地址空间中映射和取消映射物理内存,并且通常此转换机制可在整个系统中运行。当然,翻译是有代价的,因为您现在需要查阅和维护页面表,这会导致性能损失。但一切都没有丢失:
ARMv7-A
的{{1}}和large pages
)可以提供更多帮助,因为每个翻译后的内存需要更少的TLB条目。sections
这样的东西。当您在应用程序之间切换并需要刷新当前TLB时,可以通过使用应用程序的global pages
执行Invalidate TLB entries by ASID match
来避免TLB中的全局页面无效。如果将内核的页面标记为全局,则不会使其翻译无效,并且内核本身不会遭受不必要的TLB失效。有关ARM ASID
(VMSA),页表,TLB等的具体详细信息,请参阅“ARM®体系结构参考手册ARM®v7-A和ARM®v7-R版本”。
答案 1 :(得分:6)
Linux内核使用两种类型的虚拟地址:
第一个是使用MACRO完成的:
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时,将刷新相应的全局条目。