Memory management 当您丢失页面目录的虚拟地址时会发生什么情况?
我正在为我的内核(32位x86)编写一个内存管理器 在这个过程中。。。我面临着一个进退两难的局面 虚拟内存映射的描述:Memory management 当您丢失页面目录的虚拟地址时会发生什么情况?,memory-management,x86,kernel,paging,osdev,Memory Management,X86,Kernel,Paging,Osdev,我正在为我的内核(32位x86)编写一个内存管理器 在这个过程中。。。我面临着一个进退两难的局面 虚拟内存映射的描述: 前4MB的身份映射 虚拟地址0xC0000000映射到物理地址0x100000(也是一个4 Mb映射) 我的页面目录位于物理地址0x9c000。 我的页面表1位于物理地址0x9d000。 我的页面表2的物理地址为0x9e000 (我这里只需要两页表格:)。。。这些分别对应于标识映射和更高内存映射) 祝福身份映射。。。。我可以安全地访问我的页面目录和页面表,就好像根本没有启用
- 前4MB的身份映射
- 虚拟地址0xC0000000映射到物理地址0x100000(也是一个4 Mb映射)
我遗漏了什么吗?不要丢失您的虚拟页面目录地址!在已知物理地址和已知虚拟地址(它们不需要标识映射)至少需要页面目录的一小部分。不要丢失虚拟页面目录地址!在已知物理地址和已知虚拟地址(它们不需要标识映射)至少需要页面目录的一小部分。Um,不要丢失它!您几乎需要将一些内存块映射到已知的物理地址,或者是标识,或者是一些已知的映射(比如高2MiB映射到低2MiB的物理地址)。您可以创建一个全新的页面目录树并将其安装在CR3中,但前提是您在某个地方有一些已知的映射。您可以禁用分页,但至少可以说,在CS:EIP没有标识映射的情况下这样做可能是个问题。基本上就是不写错误的内核;丢失对关键数据的引用是不可恢复的,这不应该令人震惊。信息甚至不在CPU内部的某个地方。是的,这是真的,Intel可以提供一个特殊的存储指令,使用寄存器作为物理地址,而不是虚拟地址。但操作码空间非常有限,386必须支持解码一条额外的指令,仅用于极为罕见的用例,而这种用例最多只能使每数千条执行一对指令受益。如果盲目使用,可能会覆盖自己的代码或堆栈。操作系统必须知道物理地址才能编程DMA硬件,然后需要通过正常的虚拟地址高效读取数据……在64位中,将所有物理内存空间映射到高虚拟内存地址更容易。在32位系统上,您不能真正做到这一点。一些32位内核可能会映射一部分内存来处理分页结构,但有些人也知道使用递归页表技术(你可以用谷歌搜索)。它们更难理解,而且它们确实占用了一些虚拟地址空间(如果在保护模式下使用PAE,情况尤其糟糕),而且该解决方案不可移植到其他CPU架构。rescurive页表的一个复杂之处是,您无法轻松更改另一个进程的结构,它通常涉及一些临时页映射,但它是可行的,尽管有额外的复杂性。嗯,不要丢失它!您几乎需要将一些内存块映射到已知的物理地址,或者是标识,或者是一些已知的映射(比如高2MiB映射到低2MiB的物理地址)。您可以创建一个全新的页面目录树并将其安装在CR3中,但前提是您在某个地方有一些已知的映射。您可以禁用分页,但至少可以说,在CS:EIP没有标识映射的情况下这样做可能是个问题。基本上就是不写错误的内核;丢失对关键数据的引用是不可恢复的,这不应该令人震惊。信息甚至不在CPU内部的某个地方。是的,这是真的,Intel可以提供一个特殊的存储指令,使用寄存器作为物理地址,而不是虚拟地址。但操作码空间非常有限,386必须支持解码一条额外的指令,仅用于极为罕见的用例,而这种用例最多只能使每数千条执行一对指令受益。如果盲目使用,可能会覆盖自己的代码或堆栈。操作系统必须知道物理地址才能编程DMA硬件,然后需要通过正常的虚拟地址高效读取数据……在64位中,将所有物理内存空间映射到高虚拟内存地址更容易。在32位系统上,您不能真正做到这一点。一些32位内核可能会映射一部分内存来处理分页结构,但有些人也知道使用递归页表技术(你可以用谷歌搜索)。它们更难理解,而且