windows是一个非常优秀的OS,从今天开始,我要和大家共同分享windows给我们带来的快乐!本人只所以将自己的学习笔记与大家分享,一是让自己更深入的理解windows,再就是有什么疏漏之处,望大家指正!!来吧,开始我们的windows之旅!
一,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的整体结构有了大概的了解,在接下来的日子里我们要对每个部分进行更为深入的研究,并且会举一些例子程序来辅助说明,因为我们学它的目的就是为了用,为了改变!