这个问题不是特定于任何CPU实现,而是欢迎特定于CPU的答案。
我目前正在实现一个完整的MMU启用的CPU,并出现了一个简单的问题。
因此,想象一下由指令流(或指令缓存)引起的简单TLB未命中的情况。这将触发TLB未命中。现在,如果找不到PTE,将触发一些异常,例如" Page Translation Fault"。到目前为止,完全没问题。
现在,为了调用错误处理程序,指令流(或缓存)需要获取异常处理程序代码。为此,它需要再次搜索TLB中的相关PTE条目,并最终再次搜索表格。
想象一下,再次找不到PTE条目。可以预期会调用一些其他异常处理程序。
现在,在最后一个异常处理程序上,由于处理程序本身可能找不到或无效,MMU会在获取和执行处理程序之前被禁用(从而绕过每个MMU,包括Phys-Virt映射),或者是有另一种技术(非致命)来处理这种情况吗?
Alvie
答案 0 :(得分:1)
我不能肯定地说现实世界的操作系统,但是从查看小内核的经验来看,重点似乎始终在于确保页面错误处理程序本身永远不会被分页。总是在一个永远不会引发页面错误的位置。这样可以确保您的问题中描述的情况永远不会出现。
一般来说,核心内核代码的某些部分静态驻留在具有已知映射的物理内存上似乎是有道理的;但鉴于你无论如何试图编写一个完整的虚拟内存启用操作系统,我猜你会知道这一点。
答案 1 :(得分:1)
我知道两种方法:
当发生中断/异常时,MMU自动禁用。因此,必须将故障处理程序(数据中止处理程序)放置在已知的物理地址上,并且毫无疑问会出现虚假的MMU故障。处理程序负责从异常返回之前重新启用MMU或处理程序使用本身。在现实生活中,这种行为让驴子非常痛苦...
例如,“ Microblaze”拱门就是这样做的。
MMU不会自动禁用。诀窍是要有2套TLB表。 TLB1具有内核映射表,TLB0用于用户应用程序映射表。内核和用户应用程序应分别具有适当的链接,以排除彼此之间虚拟地址的重叠。
当用户应用执行sh **并导致MMU故障时,会发生异常。中止/故障处理程序位于内核内存空间中,因此将使用不同的TLB访问处理程序代码。您应该确定该内核TLB是正确的:)
如果内核异常处理程序本身生成异常,则存在伪数据和/或指令中止的可能性。
但是,实际上,例如,“ ARM-Ax” CPU会掩盖异常/中断。我认为不会发生虚假异常,但是我从未在实践中对其进行过测试。
硬件看门狗可能会帮您一个忙...