linux之页表详解
页表的详解
标签:虚拟地址,物理地址,地址,详解,页表,linux,进程,权限,千字 From: https://blog.51cto.com/u_15835985/9211594在进程地址空间与物理内存之间,就是通过页表来进行映射关联的!
==而页表的功能也不仅仅是简简单单的映射!如下图!==
例如:是否命中,进程关于这个内存的读写权限,是用户的还是内核的!等等
这样子我们就能理解
char * str = "hello world"; *str = 'H';
这个代码会在==运行的时候==就会报错!——在知道页表之前我们一般都会解释说是因为这个字符串常量放在了常量区所以不能修改!
==但是现在有了页表我们就能解释了!凭什么在常量区,就不能写入修改呢?==
因为当我们进行解引用的时候其实就是要去找到它的起始地址,然后进行修改!
而要修改就要有虚拟地址和物理地址的转换!当转换的时候,会去查页表,然后去查看其RWX权限,然后发现只有R权限!但是我们是要进行写操作的!所以此时地址转换单元(MMU)就会将当前的访问行为终止——通过向硬件报错的方式,然后操作系统就会通过发送信号的方式,发送给进程!进程收到喜欢之后就要在而合适的时候去捕抓信号,因为信号的默认行为一般是终止,所以进程就被终止了!
页表还分为内核级页表和用户级页表!——通过U/K权限来进行区分!U权限就是用户级(User)页表,K权限就是内核级(Kernel)页表
==我们该如何的去看待资源和页表呢?==
地址空间是进程能看到的资源窗口——诸如:栈区,堆区,内核区,初始化,未初始化数据都是在进程地址空间看到的!所以才说是一个资源窗口!
页表决定,进程真正拥有资源的情况!——因为进程自己认为自己拥有的是整个操作系统的所有资源!但是其实不是!
合理的对地址空间和页表进行资源划分,我们就可以一个进程所有的资源进行分类
==页表是如何将虚拟地址转化为物理地址的呢?==
页表是通过将虚拟地址和物理地址映射,然后查表来完成的!那么它是如何进行查表的呢
首先我们要明白一一页表到底有多大!
虚似地址空间(32位下)一共有2^32个地址!
如果真的是有2^32^个地址!一那么虚拟地址空间也应该有 2^32^个条目!因为我们的每一个地址都要有个条目来映射而且每一个条目都要有很多的属性
我们假设每一个条目有6字节(物理地址+WRX权限+U/K权限+是否命中)
这样的话光是页表就有24GB的空间!——==这是不太可能的!==
==所以我们必须意识到页表不止有一张!==
红色的1—4就是虚拟地址转化为物理地址的全部流程!
通过前10个地址去页目录里面找对应的页表!然后通过第二个10位的地址,找页表里面存的页框的真实的物理地址的起始地址!!
最后通过虚拟地址的最后12位作为偏移量!——找到了这个物理地址!
我们将地址拆分成10,10,12位单位后!有可能我们一个进程运行的时 候,只使用了一个页目录和几个页表!剩下的不使用就不用加载到内存里面!只有需要的时候才要进行创建,而且哪怕把全部的地址加载进来,也不会很大!因为我们页表只索引到了页框的起始地址!整个页表的条目个数也就是4GB/4KB = 2^20^个目录,后面的12位只是作为偏移量没有创建映射关系,这样子总共就是2^20个(这样子计算下来按照一个地址一个字节来计算,总的也就1m的大小!加上各种属性,也就几mb!)
==这样子大大的减少页表占用过大的内存空间,导致了内存空间不足的问题了!==