酷睿双核t9300还够用吗:处理器模式

来源:百度文库 编辑:中财网 时间:2024/07/08 06:21:31

2.4.1 处理器模式

2010-11-29 16:11 潘爱民 电子工业出版社 我要评论(0) 字号:T | T

综合评级:

想读()   在读()   已读()    品书斋鉴()    已有人发表书评

《Windows内核原理与实现》第2章Windows 系统总述,本章将简要地介绍WRK(Windows Research Kernel),这是Microsoft 提供的一套可以编译和运行的Windows 内核源代码,本书后面章节的绝大多数讲解都将参考WRK 中的源代码。本节为大家介绍处理器模式。

AD:


    2.4 Windows 内核的基本概念

    Windows 内核中的各个组件并非单纯的独立模块,相反地,组件之间不可避免地包含着复杂的依赖关系,甚至存在交叉调用。这对于讲述和学习这些组件的原理多少造成了不便。例如,在介绍线程调度算法时,需要理解基本的同步语义;而在介绍同步机制时,又需要明白线程是如何被调度的。为了使读者在阅读后面的章节时思路更加顺畅,这一节将简要地介绍Windows 内核中的一些基本概念,从而使读者对于Windows 内核中的核心机制首先有概念上的初步认识。在本节的正文描述中,这些概念将以粗黑字体的形式突出标示,并尽可能地注明中英文,以便于理解。

    2.4.1 处理器模式

    我们先来看处理器在运行程序时所处的状态。在Intel x86 处理器上,段描述符有一个2 位长度的特权级:0 表示最高特权级,3 表示最低特权级。Windows 只使用0 和3 两种特权级(在有些资料上分别称为0 环和3 环),通常特权级0 表示CPU 处于内核模式(kernelmode),3 表示用户模式(user mdoe)。在任何时刻,处理器总是位于这两种模式之一。在本章前面介绍Windows 体系结构时我们已经看到过内核模式和用户模式的划分。

    处理器有许多指令只有在特权级0 的模式下才可以使用,例如I/O 指令、操纵内部寄存器(如GDT、IDT、MSR)的指令等。当处理器位于用户模式时,它处于一种相对隔离的状态:能够执行的指令是受限制的,能够访问的内存也是受限制的。一旦越过这些限制,就会引发处理器异常,因而操作系统可以捕获到这些异常,并决定处理器是否继续执行。因此,操作系统可以有足够的能力来保护自己免受用户模式代码的影响。然而,当处理器位于内核模式时,这一层保护不复存在,任何一个未被捕捉和处理的指令错误都会引起系统崩溃。

    在Windows 中,当处理器位于不同模式下时,它可以访问的内存地址空间也是不一样的。在用户模式下,处理器只能访问当前进程的地址空间(有时也称为用户地址空间);而在内核模式下,处理器不仅可以访问当前进程的地址空间,还可以访问系统地址空间。因此,正如图2.2 所示,内核模式下的代码和数据都是共享的,所有的进程一旦其指令流进入到内核模式下,则系统地址空间中的代码和数据都是相同的(有个别例外将在第4章中指出)。

    一个指令流(即线程)在执行时,在以下情况下会发生模式切换:用户模式代码触发了异常,则控制流进入到内核模式,内核中的异常处理函数可以决定该控制流是否继续执行;用户模式代码在执行时,被一个中断打断(软中断或硬中断),则控制流进入特权模式,等中断处理例程完成以后,它若调用iret/iretd 指令,则控制流恢复到用户模式下;执行特殊的模式切换指令,例如Intel x86 的sysenter 指令,从用户模式切换到内核模式。而为了从内核模式切换到用户模式,通常简单地使用sysexit、iret/iretd 这样的指令即可。

    由于系统空间是所有进程共享的,所以,任何一个进程在执行内核模式的代码时,实际上是在使用操作系统的服务。在Windows 体系结构中,内核模式向上有一个执行体API(见图2.3),尽管它并非文档化的API,但对于应用程序而言,这便是系统服务。Windows将这些系统服务组织成了一张表,称为SDT(Service Descriptor Table,服务描述符表)。第8 章将介绍用户模式与内核模式之间的切换原理,以及系统服务分发过程。

    2.4.2 内存管理

    Intel x86 体系结构既支持段式内存管理,也支持页式内存管理,然而,Windows 没有使用段式内存管理方案,而只是简单地将32 位虚拟内存空间按照0~4 GB 的线性地址空间来看待。任何一个进程都定义了它自己的完整4 GB 地址空间,但是,其2 GB~4 GB 之间的部分是所有进程共享的,称为系统地址空间;而0~2 GB 的部分才是它自己私有的,称为进程地址空间。对于某些特殊的应用程序,例如数据库程序,它们总是希望其私有空间越大越好。在这种情况下,利用Windows 的“/3GB”引导选项,这样的进程可以获得3 GB 进程地址空间,而系统地址空间只占用1 GB。本书不讨论这样的情形。

    为了有效地管理2 GB 系统地址空间,Windows 在初始化时将这2 GB 划分成了一些固定的区域,各个区域有专门的用途。而且,Windows 内核使用了一组全局变量来记录每个区域的边界,所以,系统地址空间的初始化实际上是对这些全局变量的初始化,并相应地初始化每个区域。Windows 的一些引导选项以及系统配置(位于注册表)可能会影响到某些区域的位置和大小。系统空间中的主要区域包括:内核模块映像、PFN 数据库、换页内存池、非换页内存池、会话空间、系统缓存区、系统PTE 区域、系统视图以及页表等。

    Windows 使用Intel x86 的二级或多级页表机制来访问虚拟内存。处理器在执行内存访问指令时,将虚拟地址翻译成物理地址,翻译过程涉及查询页目录和页表,一旦页表项指示一个页面未在物理内存中,则触发页面错误(page fault)异常。虚拟内存管理器通过页面错误异常将已被换出到磁盘上的数据或代码重新带入物理内存,供当前活跃的程序访问。另一方面,当物理内存紧张时,它会将不常用的页面换出到磁盘上。Windows 利用Intel x86 的页表机制,实现了灵活的页面交换算法,可以支持一个或多个页面交换文件;同时也实现了内存页面的写时复制(copy-on-write)特性。

    在系统地址空间中,不同的区域使用并不完全相同的内存页面管理算法,较为典型的有以下三种:

    非换页内存池。这部分内存区域在初始化时已经被映射到物理页面,所以,Windows利用空闲链表的做法,按照不同的粒度(1、2、3、≥4 个页面大小),将空闲页面链接起来。空闲页面本身即链表中的节点,因而这些链表无须额外的内存空间(除了头节点)。申请和释放页面的操作实际上是针对空闲链表来进行的。

    换页内存池。在换页内存池区域,空闲的页面并没有被映射好物理页面,Windows使用位图来管理页面的分配。分配连续的多个页面,即从位图中找到连续的零位。

    系统PTE 区域。这部分内存区域存放的并非PTE,而只是表示这部分地址范围是以PTE 的形式来管理的,即把PTE 当做资源来管理。当内核需要一段虚拟地址来映射物理页面时,它可以使用系统PTE 区域中的地址。

    以上这些内存区域按照页面粒度来管理其分配情况,Windows 执行体在这些系统内存区域管理的基础上,还提供了一组更小粒度(8 B 的倍数,最小为8 B)的内存池管理,包括执行体换页内存池和执行体非换页内存池。这些内存池通过空闲链表记录下每个已申请页面中的空闲内存块;当释放内存时,自动与相邻的空闲内存块合并以构成更大的空闲内存块。内核其他组件或驱动程序通过执行体暴露的API 函数(例如ExAllocatePoolWithTag和ExFreePoolWithTag)来使用这些内存池。

    进程地址空间是随进程一起被创建的,每个进程有它自己的页目录页面,其中有一半页目录项(PDE)是共享的,即系统地址空间部分,余下一半初始化为零。随着进程中的映像文件(包括.exe 文件和各个DLL 文件)被加载进来,以及各个模块的初始化代码被执行,进程地址空间将被建立起来。

    进程地址空间按照其虚拟地址是否被分配或保留来进行管理,用户模式代码通过Windows API 函数VirtualAlloc(Ex)和VirtualFree(Ex)来申请或释放地址范围,而内核中的虚拟内存管理器则通过一棵平衡二叉搜索树来管理进程地址空间被使用的情况。树中的每个节点为VAD(虚拟地址描述符,Virtual Address Descriptor),描述了一段连续的地址范围;但是在整个地址空间中,被使用或保留的地址范围往往是不连续的。之所以选择平衡二叉搜索树,是因为这样可使查找、插入和删除VAD 节点都可以快速地完成。

    在VAD 树中,有一种重要的节点类型为内存区对象(section object),它是Windows平台上两个或多个进程之间共享内存的一种常用方式。内存区对象可以被映射到系统的页面文件、可执行映像文件或者其他的数据文件中,也可能被映射到物理内存中,总之,内存区对象代表了一种物理存储资源。

    除了对系统地址空间和进程地址空间的管理,内存管理器另一个重要的任务是管理有限的物理内存。在Windows 的系统地址空间中,专门保留了一个称为PFN 数据库(PageFrame Number Database,页帧编号数据库)的区域。每一个物理页面都对应于PFN 数据库中的一项,此PFN 项描述了该页面的状态。Windows 支持八种状态:活动、备用(standby)、已修改、已修改但不写出、转移、空闲、零化和坏状态。这里活动状态是指正在被某个进程或系统空间所使用,有一个对应的PTE 指向该页面。坏状态说明一个物理页面已被检测到硬件错误。其他的状态说明了一个物理页面已经不再被原来的PTE所指,但是其内容可能还有效,或者需要被写到磁盘上,或者内容已经不再需要了,或者页面内容已被零化等多种可能。内存管理器利用PFN 数据库,按照页面的状态来管理物理内存,并且负责页面的状态转移。

    那么,当系统中的进程需要使用大量内存时,内存管理器如何将有限的物理页面分配给那些需要使用内存的进程呢?这是Windows 工作集管理器要解决的任务。这里工作集(working set)是指一个进程当前正在使用的物理页面的集合。Windows 系统中除了进程工作集,还有系统工作集(即系统空间中动态映射的页面集合)和会话工作集(即会话空间中的代码和数据区)。

    每个进程都有一个工作集链表,其中的每一项不仅记录了物理页面的编号,还记录了其他的属性,包括它的年龄(2 位),因此,工作集管理器可以根据一些策略来选择要修剪的进程,然后,针对被选中要修剪的进程,选择哪些页面被换出到磁盘中,从而将物理页面腾出来。工作集管理器运行在一个称为平衡集管理器(balance set manager)的线程中,每隔1 s 被触发一次,当可用内存太低时也会被触发。平衡集管理器除了触发工作集管理器以外,也定期触发进程/栈交换器(process/stack swapper)。进程/栈交换器是另一个单独的线程,一旦被唤醒,就会将满足特定条件的进程和栈换入内存或换出内存。

    Windows 的内存管理综合运用了多种数据结构和算法,较为复杂。关于以上每一个概念的详细描述,请参考第4 章中的相关章节。