Linux下逻辑地址-线性地址-物理地址图解

一、逻辑地址转线性地址

      机器语言指令中出现的内存地址,都是逻辑地址,需要转换成线性地址,再经过MMU(CPU中的内存管理单元)转换成物理地址才能够被访问到。

我们写个最简单的hello world程序,用gccs编译,再反编译后会看到以下指令:

mov    0x80495b0, %eax

这里的内存地址0x80495b0 就是一个逻辑地址,必须加上隐含的DS 数据段的基地址,才能构成线性地址。也就是说 0x80495b0 是当前任务的DS数据段内的偏移。

在x86保护模式下,段的信息(段基线性地址、长度、权限等)即段描述符占8个字节,段信息无法直接存放在段寄存器中(段寄存器只有2字节)。Intel的设计是段描述符集中存放在GDT或LDT中,而段寄存器存放的是段描述符在GDT或LDT内的索引值(index)。

Linux中逻辑地址等于线性地址。为什么这么说呢?因为Linux所有的段(用户代码段、用户数据段、内核代码段、内核数据段)的线性地址都是从 0x00000000 开始,长度4G,这样 线性地址=0x00000000+逻辑地址(偏移量),也就是说逻辑地址等于线性地址了。

二、线性地址转物理地址

       前面说了Linux中逻辑地址等于线性地址,那么线性地址怎么对应到物理地址呢?这个大家都知道,那就是通过分页机制,具体的说,就是通过页表查找来对应物理地址。

准确的说分页是CPU提供的一种机制,Linux只是根据这种机制的规则,利用它实现了内存管理。

在保护模式下,控制寄存器CR0的最高位PG位控制着分页管理机制是否生效,如果PG=1,分页机制生效,需通过页表查找才能把线性地址转换物理地址。如果PG=0,则分页机制无效,线性地址就直接做为物理地址。

分页的基本原理是把内存划分成大小固定的若干单元,每个单元称为一页(page),每页包含4k字节的地址空间(为简化分析,我们不考虑扩展分页的情况)。这样每一页的起始地址都是4k字节对齐的。为了能转换成物理地址,我们需要给CPU提供当前任务的线性地址转物理地址的查找表,即页表(page table)。注意,为了实现每个任务的平坦的虚拟内存,每个任务都有自己的页目录表和页表

为了节约页表占用的内存空间,x86将线性地址通过页目录表和页表两级查找转换成物理地址。

32位的线性地址被分成3个部分:

最高10位 Directory 页目录表偏移量,中间10位 Table是页表偏移量,最低12位Offset是物理页内的字节偏移量。

页目录表的大小为4k(刚好是一个页的大小),包含1024项,每个项4字节(32位),项目里存储的内容就是页表的物理地址。如果页目录表中的页表尚未分配,则物理地址填0。

页表的大小也是4k,同样包含1024项,每个项4字节,内容为最终物理页的物理内存起始地址。

每个活动的任务,必须要先分配给它一个页目录表,并把页目录表的物理地址存入cr3寄存器。页表可以提前分配好,也可以在用到的时候再分配

还是以 mov    0x80495b0, %eax 中的地址为例分析一下线性地址转物理地址的过程。

前面说到Linux中逻辑地址等于线性地址,那么我们要转换的线性地址就是0x80495b0。转换的过程是由CPU自动完成的,Linux所要做的就是准备好转换所需的页目录表和页表(假设已经准备好,给页目录表和页表分配物理内存的过程很复杂,后面再分析)。

内核先将当前任务的页目录表的物理地址填入cr3寄存器。

线性地址 0x80495b0 转换成二进制后是 0000 1000 0000 0100 1001 0101 1011 0000,最高10位0000 1000 00的十进制是32,CPU查看页目录表第32项,里面存放的是页表的物理地址。线性地址中间10位00 0100 1001 的十进制是73,页表的第73项存储的是最终物理页的物理起始地址。物理页基地址加上线性地址中最低12位的偏移量,CPU就找到了线性地址最终对应的物理内存单元。

我们知道Linux中用户进程线性地址能寻址的范围是0 - 3G,那么是不是需要提前先把这3G虚拟内存的页表都建立好呢?一般情况下,物理内存是远远小于3G的,加上同时有很多进程都在运行,根本无法给每个进程提前建立3G的线性地址页表。Linux利用CPU的一个机制解决了这个问题。进程创建后我们可以给页目录表的表项值都填0,CPU在查找页表时,如果表项的内容为0,则会引发一个缺页异常,进程暂停执行,Linux内核这时候可以通过一系列复杂的算法给分配一个物理页,并把物理页的地址填入表项中,进程再恢复执行。当然进程在这个过程中是被蒙蔽的,它自己的感觉还是正常访问到了物理内存。

   

 三. 页面结构分析:

  1.  分页转换功能由驻留在内存中的表来描述,该表称为页表(page table),存放在物理地址空间中。页表可以看作是简单的2^20 物理地址数组。线性地址到物理地址的映射功能可以简单地看作是进行数组查找。线性地址的高20bit 构成了这个数组的索引值,用于选择对应页面的物理(基)地址。线性地址的低12bit 给出了页面中的偏移量,加上页面的基地址最终形成对应的物理地址。由于页面基地址对齐在4K 边界上,因此页面基地址的低12 bit 肯定是0. 这意味着 高 20 bit的页面基地址 和 12 bit 偏移量连接组合在一起就能得到对应的物理地址。
  2. 页表中每个页表项大小为 32 bit。 由于只需要其中的20 bit来存放页面的物理基地址,因此剩下的12 bit 可以用于存储诸如页面是否存在等属性信息。如果线性地址索引的页表项被标注为存在的,则表示该项即有效,我们可以从中取得页面的物理地址。如果项中表明不存在,那么当访问对应物理页面时就会产生一个异常。

 四.两级页表结构:

  •  页表含有2^20 (1MB)个表项,而每项占用4byte 。如果作为一个表来存放的话,它们最多将占用4MB的内存。因此为了减少内存占用量,80X86 使用了两级表。由此,高20bit 线性地址到物理地址的转换也被分成两步来进行,每步使用(转换)其中10 个 bit。
  •  第一级表称为页目录(page directory)。它被存放在 1 页 4kb 页面中,具有2^10 (1kb) 个 4byte 长度的表项。这些表项指向对应的二级表。线性地址的最高10 bit (位 32~22)用作一级表(页目录)中的索引值来选择2^10个二级表之一。
  • 第二级表称为页表(page table),它的长度也是一个 Page,最多含有1kb 个 4 byte 的表项。每个 4byte 表项含有相关页面的20 bit 物理基地址。二级页表使用线性地址中间10bit (位21~12)作为表项索引值,以获取含有页面20 bit 物理基地址。该20bit 页面物理基地址和线性地址中的低12bit (页内偏移)组合在一起就得到了分页转换过程的输出值,即对应的最终物理地址。
  • 图4-17 所示出了二级表的查找过程。其中CR3 寄存器指定页目录表的基地址。线性地址的高10bit 用于索引这个页目录表,以获得指向相关第二级页表的指针。线性地址中间10bit  用于索引二级页表,以获得物理地址的高20 bit。线性地址的低 12 bit 直接作为物理地址低12 bit,从而组成一个完整的32 bit 物理地址。

   

 五.页表项格式:

  1.      页目录和页表的表项格式见图4-18所示。其中位 31~ 12 含有物理地址的高20 bit,用于定位物理地址空间中一个页面(页帧)的物理基地址。表项的低12 位含有页属性信息。这里简要说明其余属性的功能和用途。
  2. P: 位 0 是存在(present)标志,用于指明表项对地址转换是否有效。 P =1 表示有效;P =0 无效。在页转换过程中,如果说涉及的页目录或页表的表项无效,则会产生一个异常。如果 P =0,那么除表示表项无效外,其余比特位可供程序自由使用,见图4-18(b)所示。例如: 操作系统可以使用这些位来保存已存储在磁盘上的页面的序号。
  3. R/W : 位1 是读写标志(Read/Write)标志。如果 等于1,表示页面可以被读,写或执行。如果为0 表示页面只读或可执行。当处理器运行在超级用户特权级(R0,R1,R2),则R/W 位不起作用。页目录项中的R/W位对其所映射的所有页面起作用。
  4. U/S : 位2 是用户/超级用户(User/Supervisor) 标志。如果为1,那么运行在任何特权级上的程序都可以访问该页面。如果为0,那么页面只能被运行在超级用户特权级(R0~R2)上的程序访问。页目录项中的U/S位对其所映射的所有页面起作用。
  5. A : 位5是已访问(Accessed)标志。当处理器访问页表项映射的页面时,页表项的这个标志就会被置于1.当处理器访问页目录表项映射的任何页面时,页目录表项的这个标志就会被置于1.处理器值负责设置该标志,操作系统可通过定期地复位该标志来统计页面的使用情况。
  6. D : 位6 是页面已经被修改(Dirty)标志。当处理器对一个页面执行写操作时,就会设置对应页表项的D 标志。处理器并不会修改页目录项中的D标志。
  7. AVL : 该字段保留专供程序使用。处理器不会修改这几位,以后的升级处理器也不会使用。

转自:https://blog.csdn.net/wxzking/article/details/5905214

转自:https://blog.csdn.net/liutianshx2012/article/details/52398144

猜你喜欢

转载自blog.csdn.net/m0_37806112/article/details/81146400