Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56212
  • 博文数量: 47
  • 博客积分: 2095
  • 博客等级: 大尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-01 18:42
文章分类

全部博文(47)

文章存档

2011年(1)

2008年(46)

我的朋友

分类: LINUX

2008-04-08 23:54:58

The Linear Address Fields

The following macros simplify Page Table handling:

PAGE_SHIFT

Specifies the length in bits of the Offset field; when applied to 80x86 processors, it yields the value 12. Because all the addresses in a page must fit in the Offset field, the size of a page on 80x86 systems is 212 or the familiar 4,096 bytes; the PAGE_SHIFT of 12 can thus be considered the logarithm base 2 of the total page size. This macro is used by PAGE_SIZE to return the size of the page. Finally, the PAGE_MASK macro yields the value 0xfffff000 and is used to mask all the bits of the Offset field.

PAGE_SHIFT

指明了offset字段的长度;在x86处理器上,这个值是12。因为一个页面的所有地址都必须适宜offset字段,x86系统上一个页面的大小时2^12,也就是4096byte;取值12PAGE_SHIFT因此是页总大小对2取对数值。PAGE_SIZE使用这个宏返回页大小。最后宏PAGE_MASK取值0xfffff000,用来获得offset字段的所有bit

让我们看看代码里怎样表示的:(linux2.6.24.4

include/asm-x86/page_32.h (大概从2.6.24以后,i386x86_64这两个架构合并成x86)

/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT    12
#define PAGE_SIZE    (1UL << PAGE_SHIFT)
#define PAGE_MASK    (~(PAGE_SIZE-1))

#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1))
#define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)

PMD_SHIFT

The total length in bits of the Offset and Table fields of a linear address; in other words, the logarithm of the size of the area a Page Middle Directory entry can map. The PMD_SIZE macro computes the size of the area mapped by a single entry of the Page Middle Directory that is, of a Page Table. The PMD_MASK macro is used to mask all the bits of the Offset and Table fields.

When PAE is disabled, PMD_SHIFT yields the value 22 (12 from Offset plus 10 from Table), PMD_SIZE yields 222 or 4 MB, and PMD_MASK yields 0xffc00000. Conversely, when PAE is enabled, PMD_SHIFT yields the value 21 (12 from Offset plus 9 from Table), PMD_SIZE yields 221 or 2 MB, and PMD_MASK yields 0xffe00000.

Large pages do not make use of the last level of page tables, thus LARGE_PAGE_SIZE, which yields the size of a large page, is equal to PMD_SIZE (2PMD_SHIFT) while LARGE_PAGE_MASK, which is used to mask all the bits of the Offset and Table fields in a large page address, is equal to PMD_MASK.

PMD_SHIFT

表示线性地址中offset字段和PT字段的总长度;也就是一个PMD项能映射地址范围的对数。宏PMD_SIZE表示一个PMD项映射区域的大小,也就是一个PT的大小。PMD_MASK用来获得offsetPT字段的所有bit

当没有启用PAE时,PMD_SHIFT取值2212offset字段bit加上10PT字段bit),PMD_SIZE等于2^224MB,PMD_MASK等于0xffc00000:

include/asm-x86/pgtable-2level-defs.h

#ifndef _I386_PGTABLE_2LEVEL_DEFS_H
#define _I386_PGTABLE_2LEVEL_DEFS_H

#define SHARED_KERNEL_PMD    0

/*
 * traditional i386 two-level paging structure:
 */


#define PGDIR_SHIFT    22
#define PTRS_PER_PGD    1024

/*
 * the i386 is two-level, so we don't really have any
 * PMD directory physically.
 */


#define PTRS_PER_PTE    1024

#endif /* _I386_PGTABLE_2LEVEL_DEFS_H */

注意到上面并没有定义PMD_SHIFT,因为2层结构并不需要PMD和PUD,他们定义在两个通用的头文件里:

include/asm-generic/pgtable-nopud.h

#define PUD_SHIFT    PGDIR_SHIFT
#define PTRS_PER_PUD    1
#define PUD_SIZE     (1UL << PUD_SHIFT)
#define PUD_MASK     (~(PUD_SIZE-1))

include/asm-generic/pgtable-nopmd.h:

#define PMD_SHIFT    PUD_SHIFT
#define PTRS_PER_PMD    1
#define PMD_SIZE     (1UL << PMD_SHIFT)
#define PMD_MASK     (~(PMD_SIZE-1))


当启用PAE时,PMD_SHIFT取值2112offset字段bit加上9PT字段bit),PMD_SIZE等于2^212MB,PMD_MASK等于0xffe00000:

include/asm-x86/pgtable-3level-defs.h

#ifndef _I386_PGTABLE_3LEVEL_DEFS_H
#define _I386_PGTABLE_3LEVEL_DEFS_H

#ifdef CONFIG_PARAVIRT
#define SHARED_KERNEL_PMD    (pv_info.shared_kernel_pmd)
#else
#define SHARED_KERNEL_PMD    1
#endif

/*
 * PGDIR_SHIFT determines what a top-level page table entry can map
 */

#define PGDIR_SHIFT    30
#define PTRS_PER_PGD    4

/*
 * 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

#endif /* _I386_PGTABLE_3LEVEL_DEFS_H */

大页面没有使用最后一层页表结构。因此LARGE_PAGE_SIZE取值为一个大页面的大小,也就是等于PMD_SIZE2^PMD_SHIFT,LARGE_PAGE_MASK用于获得offsetPT字段的所有bit,等于PMD_MASK。

PUD_SHIFT

Determines the logarithm of the size of the area a Page Upper Directory entry can map. The PUD_SIZE macro computes the size of the area mapped by a single entry of the Page Global Directory. The PUD_MASK macro is used to mask all the bits of the Offset, Table, Middle Air, and Upper Air fields.

On the 80 x 86 processors, PUD_SHIFT is always equal to PMD_SHIFT and PUD_SIZE is equal to 4 MB or 2 MB.

决定一个PUD项能映射区域大小的对数。PUD_SIZE计算一个PUD项所能映射区域的大小.(这里应该是笔误!)

x86处理器上,PUD_SHIFT总是等于PMD_SHIFT,PUD_SIZE等于4MB或2MB

PGDIR_SHIFT

Determines the logarithm of the size of the area that a Page Global Directory entry can map. The PGDIR_SIZE macro computes the size of the area mapped by a single entry of the Page Global Directory. The PGDIR_MASK macro is used to mask all the bits of the Offset, Table, Middle Air, and Upper Air fields.

When PAE is disabled, PGDIR_SHIFT yields the value 22 (the same value yielded by PMD_SHIFT and by PUD_SHIFT), PGDIR_SIZE yields 222 or 4 MB, and PGDIR_MASK yields 0xffc00000. Conversely, when PAE is enabled, PGDIR_SHIFT yields the value 30 (12 from Offset plus 9 from Table plus 9 from Middle Air), PGDIR_SIZE yields 230 or 1 GB, and PGDIR_MASK yields 0xc0000000.

一个PGD项能映射范围的对数。PGDIR_SIZE计算一个PGD项能映射范围的大小。

没有启用PAE时,PGDIR_SHIFT取值22,PGDIR_SIZE取值2^22=4MB;启用PAE时,PGDIR_SHIFT取值30,PGDIR_SIZE取值2^30=1GB。

PTRS_PER_PTE, PTRS_PER_PMD, PTRS_PER_PUD, and PTRS_PER_PGD

Compute the number of entries in the Page Table, Page Middle Directory, Page Upper Directory, and Page Global Directory. They yield the values 1,024, 1, 1, and 1,024, respectively, when PAE is disabled; and the values 512, 512, 1, and 4, respectively, when PAE is enabled.

分别表示一个PT表、PMDPUDPGD的元素数目。没有启用PAE时,分别取值1024111024;而启用PAE时,则分别取值51251214

阅读(352) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~