我们都知道CPU寻址过程是:逻辑地址-(分段)->线性地址-(分页)->物理地址。
逻辑地址由段选择符和段偏移地址两部分组成;可以通过段选择符在段描述符表中找到段基地址,段基地址+段偏移地址=线性地址。
在32位CPU架构中,MMU使用的是平坦内存模型,即所有的段基地址都是0,所以逻辑地址可以很容易在分段过程中过渡到线性地址。
分页的主要作用就是将线性地址转化为物理地址。
在linux0.11内核中:
有1个页目录,共1024目录项(每项4Byte);
每1个目录项对应一个页表,共1024个页表项;
每1个页表项对应一页“物理页内存”,一页物理页4K。
刚好是32位CPU最大寻址空间1024*1024*4K=4G。
而linux0.11支持16M的物理=4(目录项)*1024(页表项)*4096K(/页) 。
分页可以看做是线性地址通往物理地址的一道门,门前的都是32位的线性地址,线性地址=目录项(前10位)+页表项(中间10位)+偏移地址(后12位)组成,
目录项(10位,对应1024目录项)
页表项(10位,对应1024页表项) “注意,页表项在系统初始化时是空的,当发生缺页操作时,才会填充页表项的值”
偏移地址(12位,对应4096byte的物理页偏移)
这样,在寻址时,通过线性地址的前10位定位到某一目录项,通过中间10位定位到此目录项的页表项(对应物理页),通过后12位定位到此页表项中具体物理地址。
分页主要用于虚拟化,即在某一时刻,虽然内存只被某一进程使用,但在人的感官中,所有进程共享了内存。就像图书馆(硬盘)里只有1本书(物理内存),但是有10个人(多进程)要看这本书,最好的处理办法就是每个人只能看1天(cycle),第1个人看完之后还回图书馆,第2个人再看,然后第3个人,10天之后,所有人都看了这本书,相对于这10天时间,这本书被所有人共享。分页机制就是利用这种方式将有限的物理内存最大利用化。
同时,分页很好的解决了内存碎片问题(相对于分段、粒度很小),支持了写时拷贝技术、内存和文件映射,有效的交换空间处理等。
注(图1来自google搜索,图2来自《Linux内核完全注释》)