首页UC › 分页机制

分页机制

段机制实现虚拟地址到线性地址的转换,然而,linux有意的将linux的所有段基址设为0,所以在linux中,线性地址与虚拟地址是相同的,我们以后讨论中,也不对虚拟地址和线性地址进行区分。我们着重学习分页机制,分页机制实现线性地址到物理地址的转换。

分页机制管理对象是特定大小的空间块,称之为“页”。这里所说“空间”包括物理空间和线性地址空间(虚拟地址空间),分页机制把这两种空间看成是由 页组成,线性地址空间的任一页可映射到物理空间任一页,如下图所示。通常把物理空间中的一页叫做一个页面或页框(page frame)。
20130830094910

图中每一小方块就是一页。

IA32架构中,二级分页模型就可满足系统需求;而IA32 中开启PAE(物理地址扩展,用于物理内存大于4G的情况)模式后,Linux使用三级分页模型;如果是64位系统,Linux使用四级分页模型,也就是 说x86架构的分页模型可能是二级、三级或四级,我们只讨论IA32的普通情况。

所以IA32架构中,linux采用了一种三级分页机制,即页全局目录(Page Global Directory)、页中间目录(Page Middle Directory)和页表(Page Table)。

普通情况下,linux忽略PMD,所以实质上是2级分页机制,相应的,32位线性地址被分为3部分索引:
20130830104139

Linux分别采用pgd_t、pte_t这种数据结构来表示页全局目录项和页表项。
这些结构定义如下:在http://lxr.linux.no/#linux-bk+v2.6.11.5/include/asm-i386/page.h#L58
typedef struct { unsigned long pte_low; } pte_t;
typedef struct { unsigned long pgd; } pgd_t;

这些类型实质是32位无符号长整型,其中20位存着页框基址,剩余12位存着各种属性。例如页目录的每一项是pgd_t类型数据,这个数据的中的20位是页表的基址。

20130830104218

另外,页目录表及页表在定义如下:在 http://lxr.linux.no/#linux-bk+v2.6.11.5/include/asm-i386/pgtable.h#L34
extern pgd_t swapper_pg_dir[1024];
……
extern unsigned long pg0[1024];

其中swapper_pg_dir 为页目录,pg0 为一临时页表,后面会详细介绍。

线性地址到物理地址的转换过程如下:
1、从CR3寄存器读取PGD的基址(即PGD所在物理页面的基址),与32位线性地址的第一部分索引相加,得到页目录项的物理地址。
2、第一次访问内存,读取该物理地址,得到pgd_t结构,其中的20位是页表的物理基址。
3、将页表基址与线性第二部分索引相加,得到页表项的物理地址。
4、第二次访问内存,读取该物理地址,得到pte_t结构,其中的20为是页框的物理基址
5、将页框基址与线性地址第三部分索引相加,得到最终的物理地址
6、第三次访问内存,读取该地址。

了解了分页机制,接下来看看:内核空间简单介绍

发表评论