应用程序适用于虚拟内存。这是一个很好的概念,我们可以将它视为一个连续的块,无需关心它是否在物理RAM中是连续的,或者它是否在硬盘上。
据我所知,虚拟地址和物理地址之间的映射是由CPU(或至少在硬件中)使用转换后备缓冲区直接完成的。
我认为内核以某种方式维护了TLB的内容,但是这里我有点卡住了,所以我有3个问题:
查询,读取和写入TLB内容的具体汇编指令是什么?我不是很幸运谷歌搜索与此主题相关的操作码。我刚刚发现了INVLPG和TLBWI。因为我是那种深度的新手,也许我只是使用了错误的搜索词。如果您立即找到,您使用哪些搜索字词?
所有这些汇编指令都需要特权CPU模式吗?
TLB的初始内容是什么?如果TLB在开头是空的,那是否意味着操作系统的第一个汇编指令将直接映射到物理内存(这样虚拟地址==物理地址)?
答案 0 :(得分:2)
我想总结一下这个社区wiki帖子中的评论,结合我目前的理解。 如果您从抽象的角度开始了解页表和转换后备缓冲区,您可能希望阅读此内容。但是,这篇文章可能无法保证比特和字节的100%正确性。
启动电脑
i386 PC在real mode启动。此模式仅使用物理内存,并不关心虚拟内存。所有指令都以高权限执行。我们可以将其视为处于内核模式。
在此模式下执行操作系统(如果是Linux或Windows,则无关紧要)。它将设置页面表,然后将CPU切换到protected mode。
; set PE bit
mov eax, cr0
or eax, 1
mov cr0, eax
; far jump (cs = selector of code segment)
jmp cs:@pm
@pm:
; Now we are in protected mode.
撰写网页表的操作码
page table驻留在物理内存中,永远不会交换到磁盘。由于页表不在转换后备缓冲区中,因此我们可以使用简单的内存写入指令(如mov
)来填充页表。不需要特定的汇编程序指令来设置页表。
翻译后备缓冲区
转换后备缓冲区只是页表的缓存。为了不与“普通”缓存混淆,它驻留在CPU的不同部分。
如果操作系统写入页表(在RAM中,而不是在高速缓存中),则每个CPU上至少需要有一条特定的汇编指令:用于清除TLB,以便CPU重新读取来自记忆的页表。
清除完整的TLB可能会浪费性能,因为只有单个页面可以交换到磁盘。因此,i486汇编程序指令invlpg
仅使单页无效。
是否有特权TLB操作码?
清除TLB似乎对应用程序不是很关键。即使可以在用户模式下执行指令,CPU也只会再次读取原始页表。但是,因为只有内核可以写入页表,所以清除TLB的汇编指令是一个高权限指令听起来是个好主意。
TLB的初始内容
初始内容并不重要。操作系统将设置页面表,然后
答案 1 :(得分:2)
第一次启动时,分页被禁用,因此线性地址=物理地址。
x86-64 UEFI固件必须设置某种简单的页表,可能是身份映射物理内存,因此虚拟=物理(但是IDK,请检查规范是否需要),因为x86-64长模式要求分页已启用。
要在旧版BIOS模式下启动,固件会在CPU运行之前将CPU切换回实模式并安装旧版BIOS int 10h
等处理程序。
在x86上,TLB由硬件管理(响应TLB丢失(软件看不见)的分页浏览)。页表必须位于硬件知道如何直接读取的基数树数据结构中(使用物理地址作为级别之间的指针)。 (https://wiki.osdev.org/Paging / https://wiki.osdev.org/Page_Tables)。
有关{H3页面遍历获取数据本身并创建TLB条目,以便可以完成加载或存储(或代码获取)的事实,请参见What happens after a L2 TLB miss?。
唯一的控制软件是invlpg
,以使一个4k页面的缓存信息无效(例如,在更改其页面表条目之后),因此硬件将在下一次访问时使用页面遍历重新加载它。 (或者重新加载CR3会使除“全局”条目之外的所有内容失效。还具有PCID(进程上下文ID)硬件支持,用ID标记TLB条目,因此不必在同一物理核心上的几个不同页表之间频繁地交换性能灾难。)
使用mov cr3, reg
告诉CPU在哪里可以找到页表,以设置顶级页目录的物理地址。 (还有一个控制寄存器位来控制是否启用分页;在保护模式下它是可选的。)
相比之下,某些ISA(例如MIPS do )使用 software TLB管理,其中TLB未命中陷阱是由OS提供的处理程序,有点像页面错误处理程序,它使用自己的数据结构(在不能TLB遗失的特殊内存区域中)。 TLBWI
is a MIPS instruction,而不是x86。
这不是x86的选项。