首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于80x86的Linux的分段和分页机制(3)

基于80x86的Linux的分段和分页机制(3)

页全局目录包含若干页上级目录的地址,页上级目录又依次包含若干页中间目录的地址,而页中间目录又包含若干页表的地址。每一个页表项指向一个页框。线性地址因此被分成五个部分。图中没有显示位数,因为每一部分的大小与具体的计算机体系结构有关。

对于没有启用物理地址扩展的32位系统,两级页表已经足够了。从本质上说Linux通过使“页上级目录”位和“页中间目录”位全为0,彻底取消了页上级目录和页中间目录字段。不过,页上级目录和页中间目录在指针序列中的位置被保留,以便同样的代码在32位系统和64位系统下都能使用。内核为页上级目录和页中间目录保留了一个位置,这是通过把它们的页目录项数设置为1,并把这两个目录项映射到页全局目录的一个合适的目录项而实现的。

启用了物理地址扩展的32 位系统使用了三级页表。Linux 的页全局目录对应80x86的页目录指针表(PDPT),取消了页上级目录,页中间目录对应80x86的页目录,Linux的页表对应80x86的页表。

最终,64位系统使用三级还是四级分页取决于硬件对线性地址的位的划分。

那么,为什么Linux是如此地热衷使用分页技术而对分段机制表现得那么地冷淡呢,因为Linux的进程处理很大程度上依赖于分页。事实上,线性地址到物理地址的自动转换使下面的设计目标变得可行:
• 给每一个进程分配一块不同的物理地址空间,这确保了可以有效地防止寻址错误。
•区别页(即一组数据)和页框(即主存中的物理地址)之不同。这就允许存放在某个页框中的一个页,然后保存到磁盘上,以后重新装入这同一页时又被装在不同的页框中。这就是虚拟内存机制的基本要素。

每一个进程有它自己的页全局目录和自己的页表集。当发生进程切换时,Linux把cr3控制寄存器的内容保存在前一个执行进程的描述符中,然后把下一个要执行进程的描述符的值装入cr3寄存器中。因此,当新进程重新开始在CPU上执行时,分页单元指向一组正确的页表。

把线性地址映射到物理地址虽然有点复杂,但现在已经成了一种机械式的任务。本章下面的几节中列举了一些比较单调乏味的函数和宏,它们检索内核为了查找地址和管理叶表所需的信息;其中大多数函数只有一两行。也许现在你就想跳过这部分,但是知道这些函数和宏的功能是非常有用的,因为在以后章节的讨论中你会经常看到它们。
2.4 线性地址字段处理
下列宏简化了页表处理:

PAGE_SHIFT

指定Offset字段的位数;当用于80x86处理器时,它返回的值为12。由于页内所有地址都必须放在Offset字段,因此80x86系统的页的大小是212 =4096字节。PAGE_MASK宏产生的值为0xfffff000,用以屏蔽Offset字段的所有位。

PMD_SHIFT

指定线性地址的Offset和Table字段的总位数;换句话说,是页中间目录项可以映射的区域大小的对数。PMD_SIZE宏用于计算由页中间目录的一个单独表项所映射的区域大小,也就是一个页表的大小。PMD_MASK宏用于屏蔽Offset字段与Table字段的所有位。当PAE被禁用时,PMD_SHIFT 产生的值为22(来自Offset 的12 位加上来自Table 的10 位),PMD_SIZE产生的值为222 或 4 MB,PMD_MASK产生的值为 0xffc00000。相反,当PAE被激活时,PMD_SHIFT 产生的值为21(来自Offset的12位加上来自Table的9位), PMD_SIZE 产生的值为221 或2MB以及PMD_MASK产生的值为 0xffe00000。大型页不使用最后一级页表,所以产生大型页尺寸的LARGE_PAGE_SIZE宏等于PMD_SIZE(2PMD_SHIFT),而在大型页地址中用于屏蔽Offset字段和Table字段的所有位的LARGE_PAGE_MASK宏,就等于PMD_MASK。

PUD_SHIFT
确定页上级目录项能映射的区域大小的对数。PUD_SIZE宏用于计算页全局目录中的一个单独表项所能映射的区域大小。PUD_MASK宏用于屏蔽Offset字段,Table字段,MiddleAir字段和UpperAir字段的所有位。在80x86处理器上,PUD_SHIFT总是等价于PMD_SHIFT,而PUD_SIZE则等于4MB或2MB。

PGDIR_SHIFT

确定页全局页目录项能映射的区域大小的对数。PGDIR_SIZE宏用于计算页全局目录中一个单独表项所能映射区域的大小。PGDIR_MASK宏用于屏蔽Offset,Table,Middle Air及Upper Air的所有位。当PAE 被禁止时,PGDIR_SHIFT产生的值为22(与PMD_SHIFT 和PUD_SHIFT 产生的值相同),PGDIR_SIZE 产生的值为 222或 4 MB,以及 PGDIR_MASK 产生的值为0xffc00000。相反,当PAE被激活时,PGDIR_SHIFT 产生的值为30 (12 位Offset 加 9 位Table再加9位 Middle Air), PGDIR_SIZE 产生的值为230 或 1GB以及PGDIR_MASK产生的值为0xc0000000。

PTRS_PER_PTE, PTRS_PER_PMD, PTRS_PER_PUD以及PTRS_PER_PGD

用于计算页表、页中间目录、页上级目录和页全局目录表中表项的个数。当PAE被禁止时,它们产生的值分别为1024,1,1和1024。当PAE被激活时,产生的值分别为512,512,1和4。
继承事业,薪火相传
返回列表