seacover 2013-01-15
Linux 0.11的内存管理总结。。。许多其它内容参见“地址翻译”部分
1、分页相关的页目录表和页表
Linux 0.11中的内存管理是分页式的内存管理。程序中的逻辑地址,在经过地址翻译后会被转成线性地址。内存管理部分所接触的地址,基本上都以线性地址为主。
在分页式的内存管理中,将物理内存看成是一个个的连续的页组成。在Linux 0.11中,这个页的大小是4KB。因此,每个页的起始地址是4KB对齐的,也就是说在进行寻址内存页时,物理地址的低12位是没有帮助的。所以,这地址的低12位被用于其它特殊的作用。
页目录表中存放着页表所在页的物理起始地址,页表中存放着物理页的起始地址。简单来说,就是线性地址通过高10位,在页目录表中找到页表地址。然后使用页表和中间10位找到页的地址。最后使用页的地址和低12位找到字节地址。
页目录表在Linux 0.11中只有一个,它在物理地址为0的内存页上。所以,要计算页目录表中某一个项的地址就很容易,用这个项在页目录表中的索引乘以4即可。页目录项在页目录表中的索引由线性地址的高10位可以得到。如果这里有线性地址addr,那么计算这个线性地址在页目录表中的项的索引为addr>>22。最后,计算这个项的地址为(addr>>22)*4,也就是addr>>20。(在Linux 0.11中所有的进程共用一个页目录表,因为各个进程的线性地址之间没有重复)。
2、相关的变量数据
在memory.c中定义了与内存管理相关的变量和常量。
#define LOW_MEM 0x100000 进程可用的物理内存的最低地址,0x100000=1M。低于1M的物理地址,供系统使用
#define PAGING_MEMORY (15*1024*1024) 分页的内存大小,共15M
#define PAGING_PAGES (PAGING_MEMORY>>12) ,PAGING_PAGES内存分页之后全部的页数,总大小15M/每页大小4K
#define MAP_NR(addr) (((addr)-LOW_MEM)>>12) 物理地址addr对应的内存页的编号。物理地址addr与分页编号nr之间的关系为addr=LOW_MEM+nr*4K
static unsigned char mem_map [ PAGING_PAGES ] = {0,}; mem_map数组用来标识内存页的使用情况。对于编号为nr的内存页,如果mem_map[nr]为0,则表示这个内存页未被占用。如果mem_map[nr]大于0,则表示这个内存页被占用,并且mem_map[nr]的值为这个内存页被引用的次数
static long HIGH_MEMORY = 0; HIGH_MEMORY表示可用物理内存地址的最大值