这个问题旨在填补关于该主题的良好免费信息的真空.
我相信一个好的答案将适合一个大的答案或至少在几个答案.
主要目标是为完整的初学者提供足够的信息,以便他们可以自己学习手册,并能够理解与分页相关的基本操作系统概念.
建议的指导方针:
相关问题以及为什么我认为它们不是愚蠢的:
x86页表如何工作?:标题与此问题几乎相同,但是正文询问与cr3和TLB相关的具体问题.那个问题是这个问题的一个子集.
x86虚拟化如何工作:正文仅询问源.
我是一个操作系统爱好者,我的内核运行在80486+,并且已经支持虚拟内存.
从80386开始,英特尔的x86处理器系列及其各种克隆通过分页支持虚拟内存.众所周知,当设置PG位时CR0,处理器使用虚拟地址转换.然后,CR3寄存器指向顶级页面目录,即用于将虚拟地址映射到物理地址的2-4级页表结构的根.
处理器不会为生成的每个虚拟地址查询这些表,而是将它们缓存在名为Translation Lookaside Buffer或TLB的结构中.但是,当对页表进行更改时,需要刷新TLB.在80386处理器上,此刷新将通过使用顶级页面目录地址或任务切换重新加载(MOV)来完成CR3.这应该无条件地刷新所有TLB条目.据我所知,虚拟内存系统在任何更改后总是重新加载CR3是完全有效的.
这是浪费,因为TLB现在会抛出完全好的条目,因此在80486处理器INVLPG中引入了指令.INVLPG将使与源操作数地址匹配的TLB条目无效.
然而,从Pentium Pro开始,我们还拥有全局页面,这些页面不会被移动到CR3任务切换; 和AMD x86-64 ISA表示某些高级页面表结构可能会被高速缓存而不会失效INVLPG.为了获得每个ISA所需内容和不需要内容的连贯图片,我们真的需要为80年代以来发布的大量ISA下载1000页的数据表来阅读其中的几页,即使这样,文档似乎也是如此对TLB失效特别模糊,如果TLB未正确无效,会发生什么.
为简单起见,可以假设我们正在讨论单处理器系统.此外,可以假设在更改页面结构后不需要任务切换.(因此INVLPG总是被认为至少是重新加载CR3寄存器的好选择).
基本假设是CR3每次更改页面表和页面目录后都需要重新加载,这样的系统是正确的.但是,如果想要避免不必要地冲刷TLB,则需要回答2个问题:
如果INVLPGISA支持,经过哪种更改可以安全地使用它而不是重新加载CR3?例如"如果一个取消映射一个页面框架(将相应的表条目设置为不存在),则可以始终使用INVLPG"?
在不触及CR3或执行的情况下,可以对表和目录进行哪些更改INVLPG?例如"如果一个页面根本没有映射(不存在),那么就可Present=1以为它编写一个PTE 而不用刷新TLB"?
即使在阅读了大量的ISA文档以及与INVLPGStack Overflow 相关的所有内容之后,我也不确定我在那里提供的任何一个例子.事实上,一篇值得注意的帖子马上说:"我不知道你何时应该使用它,什么时候不应该使用它." 因此,您可以提供任何特定的,正确的示例,最好是文档,以及您可以给出的IA32或x86-64.