关于mmu使用多级页表为什么省空间的分析

Q: 为什么使用多级页表能省内存?

A: 

首先考虑一级页表的情况。

内存虚拟空间是0~4G

按4K一页的方式分页。

那么需要总共1024 * 1024个页表项, 即1M个页表项

其中每个页表项为32位整数。

为什么??

想想里面需要存放什么???

最主要的其实就是映射的页表基地址。

假设0x12345678的虚拟地址, 映射的物理地址是0x56789678。

那我们页表项主要记录的就是0x56789这个基地址!!

最后12位是页表的偏移地址/序列号。


所以页表项就至少需要20位的空间了...所以用32位也就好理解了...


ok, cpu寻址0x1234 5678这个虚拟地址, 首先找到 mmu页表的基地址,  这个在cp15协处理器寄存器中保存着。(当前进程 + 内核的页表)

由于有1024*1024 1M个32位页表项,

所以页表空间需要4M,

假设起始地址是0xC100 0000,

最大范围就是, 0xC140 0000,

所以我们基地址就是0xC1.....

ok,  我们取出了mmu页表基地址0xC1, 

具体偏移呢?? 根据前20位, 即0x12345寻址。

找到页表项位置, 0xC10 8D14            (页表项4字节对齐, 所以最后两位是0)

假设寻找虚拟地址 0xFFF0 FFF0这个地址, 需要找第0xFFF0 F页表项。

0xFFF0 F * 4 = 0x3FFC3C (页表项最后两位为0, 即4字节对齐, 需左移两位, 也即乘以4)

则需要找到           0xC13F FC3C 这一页表项。

ok,  然后里面存放这物理地址页的基地址, 也即0x56789, 然后组合上页偏移地址,  就可以了。

最后寻址 0x56789678成功。

 


ok, 回归正题, 为什么二级页表比一级页表省内存?

从以上可以, 4k分页方式, 一级页表每一个页表项为4byte, 总共需要1M个页表项。

共需要内存4M。这样才能将0~4G的虚拟内存空间全部覆盖到。

否则 cpu 寻址未覆盖的 区域, 直接就寻址出错。 (像data abort和pre-fetch abort至少是寻址ok的,  取指出错)

比如汇编指令 ldr r0 0x12345678,  直接寻址就出错了...这个貌似不在arm的几种异常里面....


ok, 一级页表4M空间。

假设用段1M, 页4K的方式制作二级寻址页表。

首先为了0~4G空间全覆盖, 1024个段空间是不能省的。

而具体每个段对应的二级页表是否需要??

这个就不一定了....

通常我们写代码编译完 代码段 + 数据段也就是几百K 到几十M的范围。

假设我们写了段程序, 代码段 + 数据段 也就4M以内。

由于代码和数据的连续性,

所以我们可能也就只需要4个段就够了。。。

如此,  我们只需要将四个段的映射做好就可以了。

1个段对应256个页表。

所以我们4个段也就用1024个页表就够了。

最终,  这个进程使用的页表内存大小, 就为1024 * 4 + 1024 * 4,

即4K + 4K = 8K 就够了。


和一级页表比较下?

 

是否节省了很多内存??


是的,  奥妙就在这里^^

 

* 如果和我们书本写目录那样.... 那么 目录级别越多, 写得字肯定越多啦^^

因为书本每级目录都是全映射的...

 

你可能感兴趣的:(ARM,Linux)