当前位置:   article > 正文

【笔记】图说Linux下的虚拟内存寻址、页表_页表 虚拟地址

页表 虚拟地址

前言

很多地方都需要了解虚拟内存、内存寻址、页表、页表项这些概念,今天集中总结一下:

我们以一台32位计算机,4G内存来讲:

首先要了解这些

虚拟地址空间、虚拟内存技术

现代处理器采用的是虚拟地址寻址的方式,也就是平时访问的内存地址其实都是虚拟地址,需要由操作系统和CPU硬件翻译成物理地址,才能访问该地址的值;

采用这种方式的原因:

  • 如果应用程序可以直接访问物理内存,寻址物理内存的每一个细节,容易破坏操作系统;

  • 再者,如果要运行多个进程,理想状态下是各个进程所占物理内存互不干扰,但谁也无法保证程序没有BUG,如果误操作到其他进程,就会导致程序出现运行问题;

    当然也是有解决方案的,比如限定进程的内存访问界限,但这样会带来额外的寻址开销,这里不展开;

  • 且不管进程间的内存干扰,每个进程都占据一部分内存,就会导致内存不足;

    这里同样也有一些解决方案,比如手动覆盖技术、自动交换技术等,当然也同样存在各自的缺陷,这里也不细究;

那么为了解决上述问题,就有了虚拟内存技术,也成为了现代处理器内存寻址的解决方案;

虚拟内存地址空间被分成多个块,每块都有连续的地址空间,可以被分给应用程序;物理空间也同时被分成很多快,这些块大小和虚拟地址空间的块大小一致;系统会自动将虚拟地址空间映射到物理地址空间;进程只需要请求和操作虚拟内存,从每个进程的角度来看,内存中只存在操作系统内核以及本进程,自己独占了整个内存。我们先不管图里的内存分区。

在这里插入图片描述

虚拟内存技术拥有自动覆盖技术和自动交换技术,使得能够运行比当前空闲内存空间还要大的程序,并借助外存获得更多的空闲内存空间;这里不细究

虚拟内存技术下CPU是如何寻址的

本文以32位处理器,4GB内存来说;

先了解这么一些术语/概念,我尽量全文保持一致:

寻址空间/寻址能力

寻址空间指的是CPU对于内存寻址的能力,寻址空间大小也就是能用到多少内存,对于32位处理器,可以理解成可访问内存地址是2进制的32位,那么我们能访问的地址写成十六进制就有:0x0000 00000x0000 00010x0000 00020xffff ffff,一共232个地址,而每个地址对应的数据是一个字节(1B),那么能用到的内存一共就是232*1B也就是4GB,即寻址空间大小为4GB;

在这里插入图片描述

页表及相关概念

注:本文以一级页表为例,理解了一级页表也就好理解多级页表了

由于应用程序使用的内存地址是虚拟地址,为了能够将其与实际的物理内存达成一个映射,就需要一个表将虚拟地址映射到实际的物理内存地址,这个表就叫做页表,是存储在主存(RAM)里的。页表中的元素就叫做页表项,即虚拟地址与物理地址的映射,具体一点,我们直接看图,以区分开页表、页表项、虚拟地址与物理地址:

在这里插入图片描述

虚拟地址:也就是应用看到的内存地址,在本文就是一个4B(32bit)的地址,分为索引值VPN(Virtual Page Number)和页面偏移量,页面偏移量位数由页大小(page size)决定,Linux默认页大小为4KB,我理解这里的页大小也指的是这页地址所指向的总内存大小,也就是说,一页有4K个内存地址(映射),即212,这样的话,同一页的内存只有后面12位是变化的,前面20位是固定的,如图所示;

物理地址:也就是实际的物理内存地址,和虚拟地址的划分一致,分为PFN(Page Frame Number)和页面偏移量,页面偏移量同样由页大小决定,在默认的4KB页大小下,同样是12位的偏移量和20位的PFN;

所以说,页表其实就是要VPN到PFN的映射;

页表:页表存储着的其实是VPN到PFN的映射,是以array的形式连续存储的,所以VPN作为索引值是隐含在其中的,无需存储在页表中,只需要知道页表的基地址即可,这点类似数组和其下标的关系。系统根据虚拟地址的VPN和页表基地址,即可查到对应的PFN,而虚拟地址的page offset就是对应物理地址的offset,PFN+offset,就得到了虚拟地址对应的物理地址。

页表项:即页表中存储的元素,带有VPN、PFN之间的映射关系以及其他信息(是否缺页标志位、保护位、修改位、访问位和高速缓存禁止位…);由于page size变化会导致VPN和PFN的位数发生变化,所以表项大小其实是不确定的,具体情况具体对待;

注:有些资料中提到页表项大小至少要3B,实际要4B,实际上是在默认的4KB的page size下讲的,因为页大小为4KB时,VPN和PFN就是20bit,也就至少需要3B的内存来存储,但为了方便页表查询,会让一个页表项多占一个字节,也就是一个页表项占4B内存;这样一来,假设一个程序占用2GB的内存,在4KB的page size下,一共需要划分2GB / 4KB = 512K这么多的页表项,而在这个例子中每个页表项占4B内存,整个页表也就占:512K * 4B = 2MB;

计算过程也写一下:

2GB / 4KB = 2 * 2 ^ 30 B / 4 * 2 ^ 10 B = 2 ^ 19 = 2 ^ 9 * 2 ^ 10 = 512 K

512K * 4B = 2 ^ 11 KB = 2 MB

之前我就是被这个例子整晕的……

多级页表

以上我们说的都是一级页表,此外还有二级、三级页表,能够解决一些一级页表的缺陷,这里就不深究了;懒

结语

学习笔记,有错误或补充请指出;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/163362
推荐阅读
相关标签
  

闽ICP备14008679号