TLB中的内核内存(虚拟地址条目)?

时间:2011-12-12 07:39:36

标签: linux memory-management hardware kernel tlb

Linux是操作系统,ARM是在此上下文中引用的处理器。

TLB是否包含内核和用户空间虚拟地址? 内核内存从0xc000_0000开始,然后转到0xFFFF_FFFF 前3 GB属于用户空间的位置。在进程之间的上下文切换之间,刷新TLB。

TLB是否包含内核和用户空间虚拟地址?

内核内存(虚拟)直接对应物理内存(只需用0xC000_0000进行偏移即可为我们提供物理地址)。是否有必要在TLB中使用内核(虚拟)(如果你说它存在于TLB中)?它应该只有用户空间地址。

2 个答案:

答案 0 :(得分:10)

我们在现代CPU中进行虚拟到物理地址转换的主要原因是为了让我们能够更高效,更好地控制内存使用:

  1. 分配任何物理内存,RAM(连续或不连续),并使其可以在虚拟地址空间的任何位置访问(连续或不连续),而不会浪费内存碎片。
  2. 使用磁盘或其他内存扩展物理内存,RAM。
  3. 使地址空间的某些部分仅可读或不可执行或仅内核等,并保护它们免受未经授权或错误的访问。
  4. 将应用程序的内存彼此隔离,以进一步提高保护,安全性和可靠性。
  5. 分享记忆。 ...
  6. 页面表使这一切成为可能。

    您确实希望能够在内核的虚拟地址空间中映射和取消映射物理内存,并且通常此转换机制可在整个系统中运行。当然,翻译是有代价的,因为您现在需要查阅和维护页面表,这会导致性能损失。但一切都没有丢失:

    1. TLBs在一定程度上缓解了这个问题。他们缓存翻译。
    2. 较大的网页(例如ARMv7-A的{​​{1}}和large pages)可以提供更多帮助,因为每个翻译后的内存需要更少的TLB条目。
    3. 还有像sections这样的东西。当您在应用程序之间切换并需要刷新当前TLB时,可以通过使用应用程序的global pages执行Invalidate TLB entries by ASID match来避免TLB中的全局页面无效。如果将内核的页面标记为全局,则不会使其翻译无效,并且内核本身不会遭受不必要的TLB失效。
    4. 有关ARM ASID(VMSA),页表,TLB等的具体详细信息,请参阅“ARM®体系结构参考手册ARM®v7-A和ARM®v7-R版本”。

答案 1 :(得分:6)

Linux内核使用两种类型的虚拟地址:

  1. 您在“内核内存(虚拟)”行中直接提及的内容 对应物理内存(只需与0xC000_0000进行偏移即可 给我们物理地址)“。这映射到连续的物理地址。
  2. 使用vmalloc。
  3. 第一个是使用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时,将刷新相应的全局条目。