对我来说,虚拟内存是一个非常复杂的话题。我想了解它。这是我对32位系统的理解。示例RAM仅为2GB。我尝试阅读许多链接,但目前我还没有信心。我希望你们能帮助我阐明我的概念。请承认我的观点,也请回答您认为错误的地方。我的观点中也有一个困惑的部分。因此,这里开始摘要。

  • 每个进程都认为它仅在运行。它可以访问4GB的内存-虚拟地址空间。
  • 当进程访问虚拟地址时,它将通过MMU转换为物理地址。
    该MMU是CPU的一部分-硬件。
  • 当MMU无法将地址转换为物理地址时,它将引发页面错误。
  • 页面错误时,将通知内核。内核检查VM区域结构。如果可以找到它-可能在磁盘上。它将进行一些页内/页外的操作。并将此内存放在RAM中。
  • 现在,MMU将再次尝试,这次将成功。
  • 如果内核找不到地址,它将发出一个信号。例如,无效访问将引发SIGSEGV。

  • 混淆点。
  • Page表是否在内核中维护?这个VM区域结构有一个页表?
  • MMU如何无法在物理RAM中找到地址。假设它转换为RAM中的某个错误地址。仍然可以执行代码,但这将是错误的地址。 MMU如何确保它正在读取正确的数据?是否每次都引用内核VM区域?
  • 是映射表-虚拟到物理位于MMU中。我已阅读了由单个过程维护的文档。如果它在流程中,为什么我看不到它。
    或者,如果是MMU,则MMU如何生成地址-是段+ 12位移位->页面帧号,然后加上偏移量(-1至10位)->给出一个物理地址。
    在我心中,对于32位体系结构,这是否意味着这种计算。我可以从虚拟地址中确定物理地址。
  • cat/proc/pid_value/maps。这显示了vmarea的当前映射。基本上,它会读取Vmarea结构并进行打印。这意味着这很重要。我无法在完整图片中显示此部分。执行程序时,会生成vmarea结构。仅当MMU无法转换地址(即页面错误)时,VMAREA才会出现在图片中吗?当我打印vmarea时,它将显示地址范围,权限并映射到文件描述符和偏移量。我确定此文件描述符是硬盘中的文件描述符,并且偏移量是针对该文件的。
  • 高内存概念是内核无法直接访问大于1 GB(大约)的内存区域。因此,它需要一个页表来间接映射它。因此,它将临时加载一些页面表以映射地址。 HIGH MEM是否会每次进入画面。因为用户空间可以通过MMU直接转换地址。在哪种情况下,内核确实要访问High MEM。我相信内核驱动程序将主要使用kmalloc。这是直接存储器+偏移地址。在这种情况下,实际上不需要映射。因此,问题在于内核在哪种情况下需要访问High Mem。
  • 处理器是否特别附带MMU支持。那些没有MMU支持的人不能运行LInux?
  • 最佳答案



    是的。不完全正确:每个进程都有一个mm_struct,其中包含vm_area_struct的列表(代表抽象的,与处理器无关的内存区域,又名映射),以及一个称为pgd的字段,该字段是指向特定于处理器的页表的指针(其中包含每个页面的当前状态:有效,可读,可写,脏,...)。

    页表不需要完整,操作系统可以从VMA生成页表的每个部分。



    翻译失败,例如因为该页面被标记为无效,或者试图对只读页面进行写访问。



    常用的MMU有两种。其中之一只有一个TLB(转换后备缓冲区),它是页表的缓存。当TLB没有尝试访问的转换时,将生成TLB未命中,OS进行页表遍历,并将转换放入TLB中。

    另一种MMU在硬件中执行页表。

    在任何情况下,操作系统都会为每个进程维护一个页表,这会将虚拟页号映射到物理帧号。当页面被调入页面时,此映射可以随时更改,其映射到的物理帧取决于可用内存的可用性。



    第一次近似,是的。除此之外,内核还有很多原因可以决定摆弄进程的内存,例如:如果存在内存压力,它可能决定从某个随机进程中调出一些很少使用的页面。用户空间还可以通过mmap()execve()和其他系统调用来操纵映射。



    完全与其他问题无关。总之,高内存是一种能够在有限的地址空间计算机中访问大量内存的技术。

    基本上,内核保留有一个有限的地址空间(在x86上,典型的用户/内核拆分为3Gb/1Gb [进程可以在用户空间或内核空间中运行。当调用syscall时,进程在内核空间中运行。避免必须在每个上下文切换上切换页面表,通常在x86上,地址空间在用户空间和内核空间之间进行划分]。因此内核可以直接访问约1Gb的内存。要访问更多的物理内存,需要使用一些间接方法,这就是高级内存的全部含义。



    笔记本电脑/台式机处理器随附MMU。从386开始,x86支持分页。

    Linux,特别是称为µCLinux的变体,支持不带MMU(!MMU)的处理器。许多嵌入式系统(ADSL路由器等)使用不带MMU的处理器。有一些重要的限制,其中包括:

  • 某些系统调用根本不起作用:例如fork()
  • 一些系统调用具有限制和不符合POSIX的行为:例如mmap()
  • 可执行文件格式不同:例如bFLT或ELF-FDPIC而不是ELF。
  • 堆栈无法增长,必须在链接时设置其大小。



  • 当内核加载程序时,它将根据可执行文件中的段(在ELF文件中您可以通过readelf --segments看到)设置多个VMA(映射),这些段将是文本/代码段,数据段等。在程序的生命周期内,动态/运行时链接程序,内存分配器(malloc(),也可以通过brk()扩展数据段)或直接由程序通过mmap()shm_open()等创建其他映射。 。

    VMA包含生成页表所需的信息,例如他们告诉该内存是由文件支持还是由交换支持(匿名内存)。因此,是的,内核将通过查看VMA来更新页表。内核将响应页面错误而在内存中进行页面调度,并响应于存储器压力而将内存进行页面调度。

    以x86 no PAE为例:

    在没有PAE的x86上,线性地址可以分为3部分:前10位指向页面目录中的条目,中间10位指向页面表中由上述页面目录条目指向的条目。页表条目可能包含有效的物理帧号:物理地址的前22位。虚拟地址的低12位是页面的偏移量,该偏移量未转换为物理地址。

    每次内核调度一个不同的进程时,将使用指向当前进程的页面目录的指针写入CR3寄存器。然后,每次进行内存访问时,MMU都会尝试查找缓存在TLB中的转换,如果找不到,则从CR3开始查找进行页表遍历的转换。如果仍然找不到一个,则会引发GPF故障,CPU切换到Ring 0(内核模式),内核会尝试在VMA中找到一个。



    在x86上,是的,MMU执行页表遍历。在其他系统(例如:MIPS)上,MMU仅比TLB多一点,而在TLB未命中的情况下,内核会通过软件进行页表遍历。

    09-28 07:02