我们知道,系统不可能给所有进程3G的地址空间,但是每个进程看到的都是3G的地址空间,其实进程所看到的进程空间是虚拟的,而维持虚拟空间到实际物理空间的映射是通过页表来实现的,下面来讲解一下页表的结构。
目前内核内存管理总是假定系统使用的是四级的页表。
1、首先,看看内存地址在也表中是如何分解的:
看看其中几个重要的常量
- PMD_SHIFT 指定了页内偏移量和最后一级页表项所需的比特位的总数,该值表明了中间也表层管理的地址空间的大小,即是2^PMD_SHIFT字节
- PUD_SHIFT,是PMD_SHIFT机上中间层也表索引所需的长度,它对应全局也目录一项中能寻址的地址长度
以下是一些常量,就不多说了
- #define PMD_SHIFT PUD_SHIFT
- #define PTRS_PER_PMD 1
- #define PMD_SIZE (1UL << PMD_SHIFT)
- #define PMD_MASK (~(PMD_SIZE-1))
- #define SHARED_KERNEL_PMD 0
- #define PAGETABLE_LEVELS 4
- /*
- * PGDIR_SHIFT determines what a top-level page table entry can map
- */
- #define PGDIR_SHIFT 39
- #define PTRS_PER_PGD 512
- /*
- * 3rd level page
- */
- #define PUD_SHIFT 30
- #define PTRS_PER_PUD 512
- /*
- * PMD_SHIFT determines the size of the area a middle-level
- * page table can map
- */
- #define PMD_SHIFT 21
- #define PTRS_PER_PMD 512
- /*
- * entries per page directory level
- */
- #define PTRS_PER_PTE 512
2、再看看也表的结构
pgd_t用于全局页目录项
pud_t用于上层目录项
pmd_t用于中间页目录项
pte_t用于直接页目录项
- typedef unsigned long pteval_t;
- typedef unsigned long pmdval_t;
- typedef unsigned long pudval_t;
- typedef unsigned long pgdval_t;
- typedef struct { pgdval_t pgd; } pgd_t;
- typedef struct { pudval_t pud; } pud_t;
- typedef struct { pmdval_t pmd; } pmd_t;
- typedef union {
- pteval_t pte;
- pteval_t pte_low;
- } pte_t;
由以上代码可知,这些页页目录和页表项的类型都是unsigned long的,最后的pte_t是用一个union来定义的。
阅读(5344) | 评论(0) | 转发(0) |