posts - 9, comments - 4, trackbacks - 0, articles - 9

windows内核初窥

Posted on 2008-05-19 20:44 xlz 阅读(122) 评论(0)  编辑 收藏 引用

[日期:2007-10-06]  来源:25175教育信息平台  作者:admin  阅读:241 次  [字体: ]

windows内核初窥(一)--体系结构

windows是一个非常优秀的OS,从今天开始,我要和大家共同分享windows给我们带来的快乐!本人只所以将自己的学习笔记与大家分享,一是让自己更深入的理解windows,再就是有什么疏漏之处,望大家指正!!来吧,开始我们的windows之旅! powered by 25175.net

一,windows2000体系结构
(1)系统模型
   在大多数多用户的OS中,用户程序和系统程序是分开的---系统程序是一个比较高的优先级上运行(核心态),而用户程序是在一个较低的等级上运行。系统程 序有对系统数据和硬件的操作权,而用户程序要想操作系统数据或者硬件就只能通过系统程序。系统程序在windows2000中是以服务的形式给出。当一个 用户程序要访问系统数据时,通过向相应的服务发出请求而实现,而此时CPU通过一个陷阱来陷入到核心态来运行。当所要求的服务完成返回时, windows2000负责恢复用户线程(windows2000中,CPU是以线程为单位来进行调度的)的寄存器状态等,从而使得用户线程得以继续运 行。windows2000中,内核和设备驱动都是运行在核心态,它们使用同一段内存空间,这意味着属于某个组成部分的数据有可能被其它的组成部分所修 改,有潜在的风险!各个组成部分之间又是可以相互协作的,为了完成一个任务,往往需要这些组成部分之间进行合作。有关系统模型在以后的日子我们会慢慢说
(2)可移植性
  windows2000被设计成能在多种硬件平台上运行,我们可能会感到很奇怪,它是怎么实现其移植性的呢?我们知道每个平台上的指令系统都不同,所以,不同平台上的代码肯定是不一样的,所以实现移植性的手段也不是很神秘的,主要是以下两点:
     1,windows2000是分层次的,底层部分是平台相关的,而上层部分是平台无关的。也就是说对于每个硬件平台底层部分都要有一个实现,而底层对上层 的接口是统一的,所以上层就不用关心底层到底是怎么样实现的,它关心的就是他们之间的接口。 在windows2000中,实现可移植性的两个重要部分是内核(kenel)和硬件抽象层(HAL),这两个部分我们以后会详细说
     2,windows2000的大部分是用C写的,也有一部分是用C++写的,汇编语言只用在直接跟硬件打交道的地方和对性能要求教高的地方。

     上面这个系统结构图在很多书上都有,它就是windows2000的结构图,下面我们就来详细说说各个部分的功能:

      从上图我们可以看出,在用户态,windows2000有三个子系统,分别为win32,posix,os/2.其中最重要的就是win32,它负责输入 输出管理,没有它,系统将无法工作,其它两个子系统需要配置才能启动。我们主要精力放在win32上,因为这是我们用的最广的。我们要特别注意以下三个关 键点:子系统进程,子系统动态链接库,用户进程。

   (1) 子系统进程:win32子系统在windows2000中是以一个进程的形式出现的(csrss.exe)。它负责所有win32用户进程,线程的创建与撤消,建立与撤消临时文件,以及控制台的管理。

   (2)子系统动态链接库:win32子系统用的动态链接库,里面有子系统所需要的大部分功能。

    (3)用户创建的运行于wn32子系统之上的应用程序。

   用户进程并不直接地调用系统服务,它们直接调用子系统动态链接库,当一个程序调用子系统动态链接库的一个功能时,可能会发生以下三中情形之一:

   (1)所要求的功能全部是由子系统动态链接库提供,也就是说程序完全运行于用户态。

   (2)需要调用一个或者多个运行于核心态的服务。

   (3)需要子系统进程的协助才能完成,这时,用户进程向子系统进程发送一C/S请求,具体工作由子系统进程来完成。

 特别说明,当用户进程调用系统服务时实际上是通过设置一个陷阱陷入到核心态来运行,将运行权交给系统服务调度程序来调度,并不用通过创建新的进程,线程来实现。

ntdll.dll

子系统下面是 ntdll.dll,它提供了一些子系统动态链接库所需要的功能。其实,NTDLL.DLL的最主要功能就是为它的下层---执行体提供一个文档化接口,使得它以上的各个模块可以调用执行体提供的服务。

执行体:

      这是令人激动的一层,因为从这层开始我们就进入了windows的核心态,虽然我们对核心态的具体含义不是太清楚,没有关系,随着我们研究的深入你就会慢慢发现这是最重要的一层,因为所有windows的主要功能都是在这里完成的,下面我们就一点一点剖开:

     这一层包含以下几种重要函数(服务):

(1)可以从用户态直接调用的函数,这些在NTDLL中文档化(前面已说过),这些中大多数都可以调用某个WIN32 API来启动所对应的服务。

(2)只能从核心态调用的函数,其中有一些在DDK中已文档化,编写windows上驱动程序的人员必须熟悉的

(3)没有文档化的函数,供执行体内部使用

执行体从总体上可以分为以下几个模块:

(1)配置管理器:负责管理注册表,我们以后会详解

(2)进程、线程管理器:负责创建和终止进程、线程。

(3)安全引用监视器:在本地计算机上执行安全策略,保护计算机的资源

(4)I/O管理器:实现I/O的设备无关性,并负责把I/O请求分配给相应的设备驱动程序以进一步处理

(5)即插即用管理器(PNP):确定设备应该由哪个驱动程序来支持并负责加载相应驱动。在启动时的枚举过程中,它收集每个设备所需要的硬件资源, 并根据设备的需要来分配合适的硬件资源如I/O端口,IRQ,DMA通道之类,当系统中的设备发生变化时它负责向系统和应用程序发送通知消息。

(6)电源管理:协调电源时间,通过合理的配置,使得CPU降低电源消耗

(7)缓冲管理器:将最近使用过的数据留在CACHE中来提高系统的整体性能

(8)虚拟内存管理:这是最为让人激动的地方,对于这个部分的理解会影响我们对整个系统结构的理解,我们会在以后详细解说

(9)WDM管理方法例程:可以让设备驱动程序发布性能和配置信息以及从用户态的WMI服务接受命令

         在WINDOWS平台上有过编程经历的人一定对句柄(handle)不陌生,句柄到底是什么样的东东呢??这往往给一些初学者带来一些迷惑。其实要真正理 解句柄就要从windows的设计理念上来解决这个问题,那就是wndows是面向对象的,它把系统的一些资源,进程,文件等都看成对象,用对象管理器对 这些对象统一管理。对于用户来说是通过句柄来操作响应对象的,可以看成是对象的一个引用。

内核:
     内核是执行体的下一个层次,它为执行体提供一些最基本的功能,简单的对象,而执行体就通过在这些简单对象上加上一些安全属性,控制属性等来完成更为复杂的功能。它重要提供以下四种函数:
(1)线程调度
(2)陷阱处理和异步调度
(3)中断处理和调度
(4)多处理器同步

   内核提供了一个低层次的系统原语和机制供执行体来调用以实现其功能。内核只是提供了底层的机制,而不做任何策略性的事务。但线程的调度和异常处理是在内核中实现的,内核永远都运行在核心态。
   一类对象叫做控制对象,包括APC,DPC对象以及I/O要用到的对象,如中断对象。
   一类对象叫做调度对象,用于线程调度。这些对象包括线程,互斥体,事件,内核事件对,信号量,定时器,可等待定时器。

   硬件支持:
   内核的另一主要功能是使得执行体和设备驱动独立于硬件,这个工作包含处理多个方面的差异:中断处理,异常处理,多处理器同步方式的差异

硬件抽象层(HAL):
   这是windows2000实现其可移植性最重要的组成部分,HAL是一个可加载的核心态模块(HAL.DLL),它提供了windows2000所运行 的硬件平台的底层接口,HAL隐藏了各种与硬件有关的细节,比如I/O接口、中断控制器、多处理通信机制等----这些都是平台相关的。当需要平台相关的 信息时,windows2000的内部模块或者用户程序通过HAL来实现。

设备驱动程序:
   
    设备驱动程序是核心态可加载模块(以.SYS为扩展名),它们是I/O管理器和相关硬件设备的接口。它们运行于以下三种环境之一:
    (1) 在一个初始化了I/O函数的用户线程环境中
    (2) 在内核模式的系统线程中
    (3) 中断发生后(不在任何进程和线程中运行,中断发生时哪一个进程或者线程正在运行)
    如前所述,windows2000的设备驱动程序并不直接操作硬件,而是调用HAL中的函数作为与硬件的接口。驱动程序通常用C语言写(有时用C++)。因此,设备驱动程序通过使用HAL可以实现平台无关性。
     有以下几中设备驱动程序:
    (1)硬件驱动程序:实现对物理硬件的读写(通过使用HAL)。
    (2)文件系统驱动程序:是面向文件I/O的驱动程序,它把这些请求转化成绑定到特定设备的I/O请求
    (3)文件过滤器驱动程序
    (4)网络重定向驱动程序
    (5)协议驱动程序
    (6)内核流过滤器驱动程序
  因为安装驱动程序是把用户编写的用户态代码添加到系统的唯一办法,因此,一些程序员通过编写设备驱动程序可以访问OS的内部函数或者内部数据结构。


    好,到此为止我们对windows2000的整体结构有了大概的了解,在接下来的日子里我们要对每个部分进行更为深入的研究,并且会举一些例子程序来辅助说明,因为我们学它的目的就是为了用,为了改变!


 


windows内核初窥(二)-系统机制

系统机制:
windows2000为执行体、内核、设备驱动程序等核心态部分提供了一些基础机制。先让我们看看都有哪些:
powered by 25175.net
    (1)陷阱调度:包括中断、延迟过程调用(DPC)、异步过程调用(APC)、异常处理、系统服务调度。
    (2)执行体对象管理
    (3)同步机制:自旋锁、内核调度对象以及等待是如何实现的
    (4)系统线程
    (5)多种系统机制如windows2000全局标志
    (6)本地过程调用
下面我们就来逐个分析:
 
陷阱调度:
 
中断和异常的实质是使CPU不按照正常的步骤来工作,硬件和软件都能够察觉到它们。陷阱是当异常或者中断发生时能够 保存当前线程状态并转向相应处理的一种系统机制。在windows2000中,处理器将控制交给陷阱处理程序--一些专门来处理中断、异常的程序。下图给 出了一些激活陷阱处理程序的示例:

中  断
中断处理过程
陷阱处理程序
请求系统服务
中断处理过程
软、硬件异常
异常调度程序
异常
处理
虚拟地址异常
虚拟地址管理
 
 
 
内核通过以下方式来分辨中断和异常:中断是一个异步事件(可以在任何时间产生),不管处理器在执行什么程序。中断典 型地由I/O设备、时钟、定时器产生,必要时我们可以屏蔽中断。而异常是一个同步事件,它是由正在执行的特定代码产生的,重新执行相同的代码会重复产生特 定的异常。比如访问非法内存、除数为0等。系统把系统服务也作为异常来处理。
无论是硬件或者是软件都能产生中断和异常,比如说,一个总线异常是由硬件引起的,而除数为0显然是软件中的BUG导致的;同样,I/O设备可以产生中断,内核本身也能产生软中断(APC,DPC)。
当一个硬件中断或者异常发生时,处理器收集足够的状态信息以保证当异常或中断处理完毕后可以正确返回到当前执行点。 处理器通过在当前线程的内核栈区建立一个陷阱框架(用来保存现场)来实现。陷阱框架通常时线程整个上下文环境的一部分。而把软中断当成硬中断的一部分来处 理,或者是调用内核中相应的处理程序。
在大多数情况下,当有陷阱发生时内核负责寻找相应的处理程序并且在处理程序返回时负责恢复中断线程的继续执行。
中断调度:
硬件中断是由I/O设备产生以求获得CPU服务的,这种中断机制使得CPU的利用率提高很多。软件也能够产生中断, 比如说,内核可以发起一个中断来进行线程调度。内核在必要的时候可以关中断,这样CPU就可以屏蔽掉任何中断-----这在有些时候是必要的,比如线程对 于临界区的访问,异常处理等。
 硬件中断处理:
 在X86家族里,外部中断在中断控制器里进行排队,控制器依次中断CPU的运行。当CPU被中断时,它要求中断控 制器提交中断请求,中断控制器将中断请求翻译为中断请求号,并且把这个号码当成索引来查询中断调度表(IDT),并且将控制权交给相应的中断处理程序。中 断调度表(IDT)在系统启动的时候就已经初始化了,里面包括中断号和相应处理程序的对应。
 中断请求登等级IRQL:
 中断是有等级的,这对于软、硬中断都是适用。内核将中断为0---31共32个等级,等级高的权限高。内核负责将软中断对应到相应的等级上,HAL负责将硬件中断对应到相应的等级上。如下图所示:
中断处理是按等级来运行的,并且是抢占式的,高等级的可以阻塞低等级的运行。当运行中断处理程序时,CPU把自己的IRQL设置为要执行的中断的IRQL,然后运行.
那么系统是如何把硬件中断映射到相应的IRQL的呢?答案是HAL,在WINDOWS2000中,总线驱动能够得知 所有连接到总线上的设备,以及每个设备能发出何种中断,紧接着总线驱动把所得到的情况汇报给PNP(即插即用管理器),它做出抉择。最后调用HAL函数 HalpGetSystemInterruptVector来实现映射。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理