Linux下逻辑地址-线性地址-物理地址详解( 二 )


还是以 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内核这时候可以通过一系列复杂的算法给分配一个物理页,并把物理页的地址填入表项中,进程再恢复执行 。当然进程在这个过程中是被蒙蔽的,它自己的感觉还是正常访问到了物理内存 。

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

文章插图
 




推荐阅读