Linux内核 ——内存寻址

一.概述

      平时我们在进行高级语言编程时,总会遇到地址这个概念,在32位程序中,其范围一般在0x00000000至0xffffffff之间,这就是虚拟地址,也称为线性地址。而当我们编写汇编程序时,会遇到段(如:代码段)与偏移的概念来指示一个地址,这种寻址方式称为逻辑地址。然而,内存芯片(如RAM随机存储器)并不认识这些地址,为此需将上述两种地址转化为物理地址以供内存芯片寻址。

     其总体寻址过程如下:通过逻辑地址(段+偏移)定位出所在的线性地址位置,之后将线性地址转化为物理地址。

 

二.逻辑地址转为线性地址

      通过读取段寄存器中的索引号,从而去全局描段述符描述符表或局部段描述符表中查找段描述符,再加上偏移量便得到了线性地址。

      

三.将线性地址转为物理地址(将页映射到物理页框)

      线性地址被分割为固定长度的页,RAM被分为固定长度的页框(亦称为物理页),每个页都可以对应到一个物理页。这个对应过程便是线性地址到物理地址的转化过程。

     比如有的系统中会将32位线性地址划分位多个域,第一级域为页目录索引,其记录了在页目录表的第几项去寻找页表(页表中的每个页表项都记录了一个线性地址所对应的物理页)。第二级域为页表索引,记录了第几个页表项存储了对应的物理页信息,最后一个域为偏移,即物理页中偏移多少才对应该线性地址。综上所述,线性地址到物理地址的转化是通过一个多级表实现的。

    Linux中使用了更多层域,这是因为这样可以避免内存的浪费,若只是用一张转化表,那么每一项都必须先分配内存,这样,若低12位为偏移,那么表项需要2^20次方个,每个项四字节,便须4M内存。若使用多级表,则无需立刻为每个页表都分配内存。

 

【问】:为何不使用分段的方法,将每个进程都分配到同一线性地址的不同段,而是采用分页的方式,将每个进程的线性地址空间映射到不同的物理空间?

【答】:因为这样各个进程便可共享同一组线性地址空间,内存管理变得更加方便,比如linux内核中,所有的段都是从0x00000000开始的,即linux下逻辑地址偏移字段的值与相应的线性地址的值总是相等的。

 

【猜测】:我们知道进程的地址空间是在进程创建之初确定的,那么为什么进程所占的内存大小会发生变化呢,这应该是因为并未一开始就为进程地址空间的所有线性地址都分配一个对应的物理页框,而是在真正需要时才进行这种映射,前面所说的多级转化表的优点其实也佐证了这一点。

 

你可能感兴趣的:(Linux内核)