Linux进程地址空间补充——页表内核设计

页表

​ 起始地址加偏移量是x86的特点;

​ 1.CPU中存在着CR3寄存器,保存着进程对于用户级页表的物理地址,可以快速找到页表;2.CPU中有寄存器将task_struct的地址保存下来,可以找到task_struct然后找到mm_struct,mm_struct里面有字段指向页表;

​ 内存中存放的数据里面有地址,但是这个地址是虚拟地址,CPU读到之后经过转化会变成物理地址,然后再去物理地址对应的内存空间访问数据;

​ 以32位机器为例,虚拟地址是32位的,可以分成10+10+12;页表也不是一整块的,而是经过了划分;如果不划分,每一个地址是4字节,一行映射虚拟加物理地址8字节,还有权限标志位和标识是否在内存的标志位,所以一行的空间大小设置为10字节,最后需要的10*4GB的空间,空间要求根本无法实现;

​ 页表是被这样划分的。32位被拆成2级,一级页表只有1024个条目,使用虚拟地址高位的前十位作为数组下标,来进行查找对应的二级页表,二级页表也是1024个条目,根据高位的次十位来进行索引,对应的位置是页框的起始地址;其中一级页表叫做页目录,其内容是页目录表项,二级页表的内容叫做页表表项;虚拟地址剩下的十二位表示在一个页框中距页表起始地址的偏移量;极端情况下总共需要1024*1024*4=4mb空间存放所有的二级页表,再加上一个4kb大小的页目录,之后就映射到了内存的页框中了;实际上二级页表很大的空间都不需要使用,并且内核空间只需要有一份,但是进程创建时,创建的资源仍旧是一个很重的活;存在页匡大小为4MB的大页式内核,这样空间就会更小;CPU内有32位寄存器和浮点数寄存器;CPU会根据类型转换成偏移量,然后进行内存的访问,如果类型过大会分批加载;
在这里插入图片描述
总结:通过页目录和二级页表使用虚拟地址的高20个bit位实现页框的映射,使用最后12位实现页框内具体地址的偏移量;即高20位就可以映射到物理内存;

​ CR3寄存器一般存放的是页目录,对于一个进程二级页表可以残缺甚至没有,但是页目录必须得有;

​ CR2寄存器保存的是越界、异常或者引起缺页中断的虚拟地址,然后进行构建映射或者是语法检查上层报错;

猜你喜欢

转载自blog.csdn.net/qq_33093885/article/details/136945737