虚拟内存对我来说是一个相当复杂的话题。我试图理解它。这是我对 32 位系统的理解。示例 RAM 仅为 2GB。我试过阅读很多链接,目前我没有信心。我希望你们帮助我理清我的概念。请承认我的观点,并请回答您认为不对的地方。我的观点中也有一个令人困惑的部分。所以,这里开始总结。
这个 MMU 是 CPU 的一部分 - 一个硬件。
混淆点。
或者如果是MMU,MMU是如何生成地址的——是不是Segment+12位移位->页帧号,然后加上偏移量(位-1到10)->给出一个物理地址。
这是否意味着对于 32 位架构,我心中有这个计算。我可以从虚拟地址确定物理地址。
最佳答案
- Does Page table is maintained in Kernel? This VM area struct has a page table ?
是的。不完全是:每个进程都有一个 mm_struct,其中包含一个列表
vm_area_struct
's(代表抽象的、独立于处理器的内存区域,又名映射),以及一个名为 pgd
的字段,它是指向特定于处理器的页表的指针(其中包含每个页的当前状态:有效、可读、可写、脏等)。页表不需要是完整的,操作系统可以从 VMA 生成它的每一部分。
- How MMU cannot find the address in physical RAM. Let's say it translates to some wrong address in RAM. Still the code will execute, but it will be a bad address. How MMU ensures that it is reading a right data? Does it consult Kernel VM area everytime?
翻译失败,例如因为页面被标记为无效,或者尝试对只读页面进行写访问。
- Is the Mapping table - virtual to physical is inside a MMU. I have read it that is maintained by an individual process. If it is inside a process, why I can't see it. Or if it is MMU, how MMU generates the address - is it that Segment + 12-bit shift -> Page frame number, and then the addition of offset (bits -1 to 10) -> gives a physical address. Does it mean that for a 32-bit architecture, with this calculation in my mind. I can determine the physical address from a virtual address.
有两种常用的 MMU。其中一个只有一个TLB(Translation Lookaside Buffer),它是页表的缓存。当 TLB 没有尝试访问的翻译时,会生成 TLB 未命中,操作系统执行页表遍历,并将翻译放入 TLB。
另一种 MMU 在硬件中执行页表遍历。
在任何情况下,操作系统都会为每个进程维护一个页表,这将虚拟页号映射到物理帧号。这种映射可以随时更改,当页面被调入时,它映射到的物理帧取决于可用内存的可用性。
- cat /proc/pid_value/maps. This shows me the current mapping of the vmarea. Basically, it reads the Vmarea struct and prints it. That means that this is important. I am not able to fit this piece in the complete picture. When the program is executed does the vmarea struct is generated. Is VMAREA comes only into the picture when the MMU cannnot translate the address i.e. Page fault? When I print the vmarea it displays the address range , permission and mapped to file descriptor, and offset. I am sure this file descriptor is the one in the hard-disk and the offset is for that file.
初步估计,是的。除此之外,内核可能会决定摆弄进程的内存的原因有很多,例如:如果存在内存压力,它可能会决定从某个随机进程中分出一些很少使用的页面。用户空间也可以通过
mmap()
操作映射, execve()
和其他系统调用。
- The high-mem concept is that kernel cannot directly access the Memory region greater than 1 GB(approx). Thus, it needs a page table to indirectly map it. Thus, it will temporarily load some page table to map the address. Does HIGH MEM will come into the picture everytime. Because Userspace can directly translate the address via MMU. On what scenario, does kernel really want to access the High MEM. I believe the kernel drivers will mostly be using kmalloc. This is a direct memory + offset address. In this case no mapping is really required. So, the question is on what scenario a kernel needs to access the High Mem.
与其他问题完全无关。总之,高内存是一种能够在有限地址空间的计算机中访问大量内存的技巧。
基本上,内核为其保留了有限的地址空间(在 x86 上,典型的用户/内核拆分为 3Gb/1Gb [进程可以在用户空间或内核空间中运行。当调用系统调用时,进程在内核空间中运行。到避免在每次上下文切换时切换页表,在 x86 上通常地址空间在用户空间和内核空间之间分割])。因此内核可以直接访问高达 ~1Gb 的内存。为了访问更多的物理内存,涉及到一些间接,这就是高内存的全部意义所在。
- Does the processor specifically comes with the MMU support. Those who doesn't have MMU support cannot run Linux?
笔记本电脑/台式机处理器带有 MMU。 x86 从 386 开始支持分页。
Linux,特别是称为 µCLinux 的变体,支持没有 MMU (!MMU) 的处理器。许多嵌入式系统(ADSL 路由器,...)使用没有 MMU 的处理器。有一些重要的限制,其中包括:
fork()
. mmap()
When a program is loaded first the kernel will setup a kernel VM-Area for that process is it? This Kernel VM Area actually holds where the program sections are there in the memory/HDD. Then the entire story of updating CR3 register, and page walkthrough or TLB comes into the picture right? So, whenever there is a pagefault - Kernel will update the page table by looking at Kernel virtual memory area is it? But they say Kernel VM area keeps updating. How this is possible, since cat /proc/pid_value/map will keep updating.The map won't be constant from start to end. SO, the real information is available in the Kernel VM area struct is it? This is the acutal information where the section of program lies, it could be HDD or physical memory -- RAM? So, this is filled during process loading is it, the first job? Kernel does the page in page out on page fault, and will update the Kernel VM area is it? So, it should also know the entire program location on the HDD for page-in / page out right? Please correct me here. This is in continuation to my first question of the previous comment.
当内核加载程序时,它会根据可执行文件中的段(在 ELF 文件中可以使用
readelf --segments
看到)设置多个 VMA(映射),这些段将是文本/代码段、数据段等...在程序的生命周期中,动态/运行时链接器、内存分配器( malloc()
,也可以通过 brk()
扩展数据段)或直接由程序通过mmap()
, shm_open()
, 等等..VMA 包含生成页表所需的信息,例如它们告诉该内存是由文件支持还是由交换(匿名内存)支持。所以,是的,内核将通过查看 VMA 来更新页表。内核将在内存中分页以响应页面错误,并在内存压力时将内存调出。
以 x86 无 PAE 为例:
在没有 PAE 的 x86 上,线性地址可以分为 3 部分:前 10 位指向页目录中的一个条目,中间 10 位指向上述页目录条目所指向的页表中的一个条目。页表条目可能包含一个有效的物理帧号:物理地址的前 22 位。虚拟地址的底部 12 位是页面中的偏移量,该偏移量未转换为物理地址。
每次内核调度不同的进程时,都会向 CR3 寄存器写入一个指向当前进程页目录的指针。然后,每次进行内存访问时,MMU 都会尝试查找缓存在 TLB 中的翻译,如果没有找到,它会查找一个从 CR3 开始执行页表遍历的翻译。如果仍然没有找到,就会引发 GPF 故障,CPU 切换到 Ring 0(内核模式),内核尝试在 VMA 中找到一个。
Also, I believe this reading from CR, page directory->page-table->Page frame number-memory address this all done by MMU. Am I correct?
在 x86 上,是的,MMU 执行页表遍历。在其他系统(例如:MIPS)上,MMU 仅比 TLB 多一点,在 TLB 未命中异常时,内核通过软件执行页表遍历。
关于c - 是否只有在出现页面错误时才会出现虚拟内存区域结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20041212/