虚拟地址线性地址物理地址映射关系(虚拟内存物理内存)(在Linux系统上,虚拟地址和线性地址是相等的)
Posted Dontla
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚拟地址线性地址物理地址映射关系(虚拟内存物理内存)(在Linux系统上,虚拟地址和线性地址是相等的)相关的知识,希望对你有一定的参考价值。
这篇文章可以让你了解进程的虚拟地址是如何映射物理地址的,在刚开始接触虚拟地址的概念时,真的是一头雾水,不知道它到底是个什么东西,一直有这个疑惑,为什么要用虚拟地址,虚拟地址的作用是什么?
经过这么多年做过的项目,积攒经验后,我可以略知一些虚拟地址的作用:
-
代码的移植性变得更加的好,在不同的平台进行编译后,就可以直接运行,因为代码和虚拟地址打交道,到别的系统上,都会将你的虚拟地址转换为物理地址,如果不用虚拟地址,用物理地址,那么到了别的平台,就得考虑代码当前使用的物理地址,是否被别人使用了。
-
不需要考虑内存分配的问题,也不需要担心内存不足,两个程序抢同一块内存导致崩溃的情况。
-
还有一个好处就是,虚拟地址映射的不一定是物理地址,还可能是硬盘上的某一块地方,比如,把暂时不用的数据放到硬盘的虚拟内存上。
既然,虚拟内存是虚拟的,那么必然有一块实际的内存与它做映射才可以使用,那么,虚拟地址和物理地址是如何做映射的呢,下面,就给大家讲讲。
提到虚拟地址和物理地址的映射,不得不说一下在它俩之间其实还有一个线性地址的存在,那么进程想要访问真正的物理地址,首先要将虚拟地址转换为线性地址,然后经过MMU就可以将线性地址转换为真正的物理地址。
虚拟地址到物理地址转换的逻辑图
下面一步一步来进行讲解,先讲讲虚拟地址和线性地址是如何进行转换的吧:
转换过程中,就需要一个寄存器,那就是段寄存器,段寄存器中存储的是描述符表的索引,你可以把描述符表看成是一个数组,那么段寄存器中的索引,你可以当成是数组的下标,这下你明白了吧。
上面说的描述符表你可能有点懵,它是啥东西,那么,我来告诉你,描述符表里面存放的是描述符,而描述符中就存放了线性的地址的基地址,我讲到这里,大家终于看到了线性地址的身影,
描述符中既然存放了基地址,那么就可通过基地址加上虚拟地址这个偏移量来算出线性地址了。
虚拟地址到线性地址的转换关系图
现在,我更想告诉大家一个结果,那就是虽然虚拟地址和线性地址是有转换关系的,但是在LINUX系统上,段描述符中的线性地址的基地址都是从0开始的,所以,会推算出,虚拟地址和线性地址是相等的,这回明白了吧,讲了半天虚拟地址和线性地址的转换,到头来原来虚拟地址和线性地址是相等的。
接下来,就讲讲线性地址是如何映射物理内存的,只需要一张图,就能看明白:
虚拟地址到物理地址转换的整体架构图
依据以下步骤进行转换:
-
从CR3寄存器中取出页目录的地址。
-
根据线性地址中的前10位,找到页目录的索引。
-
根据页目录项的值与中间10位相加后得到页表中的索引。
-
将页的起始地址与最后的12位相加后得到最终的物理地址。
结论:
在Linux系统上,虚拟地址和线性地址是相等的。
通过线性地址可以找到页目录中的页表,然后找到页表中的页表项,最终通过页表项和线性地址中的偏移,来找到最终的物理地址。
参考文章:一篇就让你了解进程的虚拟地址与物理地址是如何进行映射的
以上是关于虚拟地址线性地址物理地址映射关系(虚拟内存物理内存)(在Linux系统上,虚拟地址和线性地址是相等的)的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核 内存管理内存映射原理 ① ( 物理地址空间 | 外围设备寄存器 | 外围设备寄存器的物理地址 映射到 虚拟地址空间 )