Linux 是操作系统,ARM 是本文所指的处理器。
TLB 是否同时包含内核和用户空间虚拟地址?内核内存开始于前 3 0xc000_0000
GB0xFFFF_FFFF
属于用户空间的位置。在进程之间的上下文切换之间,TLB 被刷新。
TLB 是否同时包含内核和用户空间虚拟地址?
内核内存(虚拟)直接对应于物理内存(只是偏移0xC000_0000
就会给我们物理地址)。是否有必要在 TLB 中拥有内核内存(虚拟)(如果您说它存在于 TLB 中)?它应该只存在用户空间地址。
Linux 是操作系统,ARM 是本文所指的处理器。
TLB 是否同时包含内核和用户空间虚拟地址?内核内存开始于前 3 0xc000_0000
GB0xFFFF_FFFF
属于用户空间的位置。在进程之间的上下文切换之间,TLB 被刷新。
TLB 是否同时包含内核和用户空间虚拟地址?
内核内存(虚拟)直接对应于物理内存(只是偏移0xC000_0000
就会给我们物理地址)。是否有必要在 TLB 中拥有内核内存(虚拟)(如果您说它存在于 TLB 中)?它应该只存在用户空间地址。
我们在现代 CPU 中进行虚拟到物理地址转换的主要原因是为了更有效和更好地控制内存使用,这让我们可以:
页表使这一切成为可能。
您确实希望能够在内核的虚拟地址空间中映射和取消映射物理内存,并且通常这种转换机制适用于整个系统。当然,翻译是有代价的,因为您现在需要查阅和维护页表,这会导致性能下降。但一切都没有丢失:
ARMv7-A
'slarge pages
和sections
)帮助更大,因为它们每单位翻译内存需要更少的 TLB 条目。global pages
。当您在应用程序之间切换并需要刷新当前 TLB 时,您可以通过执行Invalidate TLB entries by ASID match
应用程序的ASID
. 如果您将内核的页面标记为全局,则不会使它们的翻译无效,并且内核本身也不会遭受不必要的 TLB 无效。例如,请参阅“ARM® 架构参考手册 ARM®v7-A 和 ARM®v7-R 版本”,了解与 ARM Virtual Memory System Architecture
(VMSA)、页表、TLB 等相关的具体细节。
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 时,会刷新相应的全局条目。