在x86上,启用分页是否会导致"无条件跳转"(因为EIP现在是虚拟地址)?

Ale*_*x D 5 cpu paging x86

通过将CR0中的分页位设置为1来启用分页时,所有指针(包括EIP)现在都被解释为虚拟地址而不是物理地址.除非CPU当前正在执行的内存区域是"身份映射"(虚拟地址映射到相同的物理地址),否则这似乎会导致CPU执行相当于"无条件跳转"的操作 - 它应该开始从不同的(物理)地址执行代码.

这实际发生了吗?看起来让操作系统启动代码可靠地运行这种行为是非常棘手的.或者所有保护模式操作系统身份映射他们自己的内核代码?

小智 3

是与否

是的,在非正式意义上,因为现在 MMU 执行从虚拟地址到线性地址的转换,并且 CPU 获取虚拟地址。如果我们在执行地址 处的指令时打开分页4000h,假设下一条指令位于 处4003h,则 4003h 可能会被翻译为8003hso 实际上从跳转4000h8003h。所以我们必须将当前正在执行的页面映射到,否则我们将不知道CPU将从哪里执行代码。

,从技术意义上来说,这不是跳转,因为 CPU 没有看到任何跳转指令及其所有副作用(例如丢弃 OoO 指令),而且 CPU 仅在整个缓存层次结构丢失后才访问内存,这意味着您仍然可以4003h即使页面被映射到不同的地址,也会执行指令。

那么,我们是否需要身份映射?

是的,我们需要它。不是完整的恒等映射,例如,我通常只(恒等)映射第 7 页和第 8 页(对应于线性范围 7000h-8fffh)。

将启用分页与启用保护模式进行比较,您可以看到它们有多么不同。分页立即生效,因此您需要在激活它之前创建所有页表,并且至少需要一个标识页来处理当前正在运行的代码而不依赖于缓存。
相反,启用保护模式更“简单”,您甚至可以在进入保护模式CS创建 GDT 条目,并且可以通过更改段寄存器(通常使用跳转)来控制何时首次使用它。

实际上,如果您知道自己在做什么(例如通过复制代码或使用某些硬件内存别名),那么您并不严格需要身份页面,但在一般情况下,这是非常特定于上下文的,它只会使事情变得无用的复杂化。

  • @AlexD 当我想尝试硬件(CPU 新功能、系统组件)时,我通常会编写一个小的引导程序。我不仅仅是开发整个操作系统(这是一项艰巨的任务),我还编写操作系统的一小部分来巩固理论、发现或只是为了好玩:) (2认同)
  • @AlexD 哈哈,当 GitHub 不存在并且我只有 56Kbps PSTN 连接时(从而将每周访问互联网的时间限制为几个小时),我就开始了。我在高清硬盘上有很多文件/项目,几乎没有注释和奇怪的名称:)然后我被用来用我的注释编写一个文本(并且只有文本)文件,我会给你所有的,但我把所有的东西都写在意大利语 (2认同)