对于Windows操作系统的编程一般来说已经涉及到了较深的领域,针对该问题提出几家之言,均为转载:

一、

为了防止用户程序访问并篡改操作系统的关键部分,Windows使用了2种处理器存取模式(事实上Windows运行的处理器可以支持4种模式):用户模式和内核模式。用户程序运行在用户模式而操作系统代码(如系统服务和设备驱动程序)则运行在内核模式。在内核模式下程序可以访问所有的内存和硬件,并使用所有的处理器指令。操作系统程序比用户程序有更高的权限,使得系统设计者可以确保用户程序不会意外的破坏系统的稳定性。

虽然Windows进程有自己的运行空间,但是内核模式的操作系统代码和设备驱动程序代码则运行在同一个虚拟地址空间。虚拟内存中的每一页都标明了他可由处理器以哪种方式访问。系统空间中的也只能在内核模式下访问,而用户空间中的也在任何模式下都可以访问。而只读页(如可执行代码)在任何模式下都不能被写入。

Windows对运行在内核模式组件的空间并不提供读/写保护,这意味着在内核模式下,操作系统和驱动程序代码可以进入系统空间,并绕过系统的安全机制而访问对象。因为Windows的大部分运行在内核模式,因此在设计内核程序时要特别的谨慎,防止他们破坏系统的安全。

以上问题也说明在用第三方的驱动程序时也要很小心,因为一旦驱动程序运行在内核模式他就可访问系统的所有数据。这也是在Windows中进入驱动程序签证的一个原因,即当用户使用未注册的第三方软件时系统会给出警告。一个叫做驱动检测(Driver Verifier)的机制可以帮助驱动开发者发现bug(如缓存溢出和内存泄漏)。

用户程序在调用一个系统服务时会转入内核模式,比如Windows的ReadFile函数最终会调用内部的一个例程,后者实际执行了读文件,因为他要访问系统数据,因此它必须允许在内核模式。从用户模式向内核模式的转换是由一个特殊的指令完成的。操作系统捕获了这个指令,通知系统要请求一个服务,并将线程的参数传递给系统函数从而执行内部的函数功能。在将控制权将给线程之前,处理器会转回到用户模式,这样操作系统可以防止它的数据被误读或误写。

注意,从用户模式向内核模式的转换并不会影响线程的调度,事实上,模式的转换并不意味着运行环境的改变。

因此一个用户线程事实上一部分时间在用户模式下运行,另一部分时间在内核模式下运行。由于图画和窗口系统也在内核模式下,因此画图较多的程序在内核模式下的运行时间回比用户模式下更多。比如你可以允许一个Windows的图画本,或者弹球游戏,并观察他们分别在用户模式和内核模式下的时间。

可以用Windows自带的性能工具察看。通过开始-程序-管理工具-性能打开,或者在控制面板里面打开,管理工具-性能。

二、

从Intel80386开始,出于安全性和稳定性的考虑,该系列的CPU可以运行于ring0~ring3从高到低四个不同的权限级,对数据也提供相应的四个保护级别。运行于较低级别的代码不能随意调用高级别的代码和访问较高级别的数据,而且也只有运行在ring0层的代码可以直接对物理硬件进行访问。由于WindowsNT是一个支持多平台的操作系统,为了与其他平台兼容,它只利用了CPU的两个运行级别。一个被称为内核模式,对应80x86的ring0层,是操作系统的核心部分,设备驱动程序就是运行在该模式下;另一个被称为用户模式,对应80x86的ring3层,操作系统的用户接口部分(就是我们通常所说的win32 API)以及所有的用户应用程序都运行在该级别。操作系统对运行在内核模式下的代码是不设防的,所以不管是建设还是破坏内核模式下的编程都是值得去研究的。

如下图所示为Windows操作系统驱动程序模型:

Windows驱动程序既可以运行在用户态也可以运行在核心模态。

用户态与核心态驱动程序的区别

用户态的驱动程序运行在非特权处理机模式(nonprivileged processor mode)上,其他一些被保护的子系统代码也运行在该模式上。用户态的驱动程序不能获得系统数据的存取权,除非调用Win32 API或者系统服务。

核心态驱动程序作为操作系统的一个组成部分被执行——支持一个或多个受保护的子系统的操作系统底层组件。

用户态和核心态驱动程序有不同的结构,不同的入口点和不同的系统接口。一个设备是需要一个用户态驱动程序还是需要一个核心态驱动程序依赖于该设备的类型和操作系统对它提供的支持。

一些设备驱动程序可以完全地或部分地运行在用户态。用户态驱动程序没有堆栈空间的限制,可以访问Win32 API,并且容易调试。

大多设备驱动程序运行在核心态。核心态驱动程序可以完成某些受保护的操作,并且可以访问用户态驱动程序不能访问的系统结构体(system sturcture)。然而,访问权限的提高当然也要付出相应的代价——调试的艰难,系统随时面临毁坏的危险。当代码运行在有特权的核心态环境中时,操作系统对代码所请求的数据的完整性和有效性的检查将大大减少。

为了方便,应该用高级语言(high-level language)来编写驱动程序,通常,C适合用来编写核心态驱动程序,C或C++则适合用于编写用户态驱动程序。

用户模式与内核模式是如何交互的呢

当用户模式程序需要读取设备数据时,它就调用Win32 API函数,如ReadFile。Win32子系统模块(如KERNEL32.DLL)通过调用平台相关的系统服务接口实现该API,而平台相关的系统服务将调用内核模式支持例程。在ReadFile调用中,调用首先到达系统DLL(NTDLL.DLL)中的一个入口点,NtReadFile函数。然后这个用户模式的NtReadFile函数接着调用系统服务接口,最后由系统服务接口调用内核模式中的服务例程,该例程同样名为NtReadFile。

系统中还有许多与NtReadFile相似的服务例程,它们同样运行在内核模式中,为应用程序请求提供服务,并以某种方式与设备交互。它们首先检查传递给它们的参数以保护系统安全或防止用户模式程序非法存取数据,然后创建一个称为“I/O请求包(IRP)”的数据结构,并把这个数据结构送到某个驱动程序的入口点。在刚才的ReadFile调用中,NtReadFile将创建一个主功能代码为IRP_MJ_READ(DDK头文件中的一个常量)的IRP。实际的处理细节可能会有不同,但对于NtReadFile例程,可能的结果是,用户模式调用者得到一个返回值,表明该IRP代表的操作还没有完成。用户模式程序也许会继续其它工作然后等待操作完成,或者立即进入等待状态。不论哪种方式,设备驱动程序对该IRP的处理都与应用程序无关。

驱动程序完成一个I/O操作后,通过调用一个特殊的内核模式服务例程来完成该IRP。完成操作是处理IRP的最后动作,它使等待的应用程序恢复运行。

Windows用户态和内核态原理讲解相关推荐

  1. IO操作底层调用过程 | 用户态切换内核态原理 | 中断概念

    IO操作底层调用过程|内核|中断| 做后端的程序员都知道我们编写的程序主要分方法程序和IO操作程序. 有什么不一样呢? 方法程序就不多说了.IO程序有什么不同呢?IO操作指的是对硬件设备操作,比如键盘 ...

  2. 【java并发编程】底层原理——用户态和内核态的区别

    一.背景--线程状态切换的代价 java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统介入,需要在户态与核心态之间切换,这种切换会消耗大量的系统资源,因为用户态与内核态都 ...

  3. 系统调用原理与用户态以及内核态相互切换过程,以linux系统为主

    1. 讲系统调用前需要清楚的几个基本概念 1.1 内核态与用户态 内核态:当CPU执行内核的代码(CPU堆栈指针指向内核堆栈)时,我们就称此时处于内核态,内核态的代码可以使用特权指令,这些指令可以控制 ...

  4. 操作系统基础知识用户态和内核态的区别

    这节课给你带来了一道非常经典的面试题目:用户态线程和内核态线程有什么区别? 这是一个组合型的问题,由很多小问题组装而成,比如: 用户态和内核态是什么? 用户级线程和内核级线程是一个怎样的对应关系? 内 ...

  5. 用户态和内核态:用户态线程和内核态线程有什么区别?

    转载 文章来源于 拉钩教育 重学操作系统 林䭽 用户态和内核态:用户态线程和内核态线程有什么区别? 什么是用户态和内核态 Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有 ...

  6. Java程序员需要掌握的计算机底层知识(二):操作系统、内核、用户态与内核态、系统调用的执行过程

    操作系统 启动过程 通电 -> bios uefi 工作 -> 自检 -> 到硬盘固定位置加载bootloader -> 读取可配置信息 -> CMOS CMOS 用来存 ...

  7. 操作系统 | 用户态和内核态的切换(中断、系统调用与过程(库函数)调用)

    文章目录 中断 过程调用 系统调用 过程调用和系统调用的区别 中断 用户态.内核态之间的切换是怎么实现的? 用户态→内核态 是通过中断实现的.并且 中断是唯一途径 . 核心态→用户态 的切换是通过执行 ...

  8. Linux 用户态与内核态的交互——netlink 篇

    [size=4]Linux 用户态与内核态的交互 --netlink 篇[/size] 作者:Kendo 2006-9-3 这是一篇学习笔记,主要是对<Linux 系统内核空间与用户空间通信的实 ...

  9. Linux用户态与内核态通信的几种方式(待完善)

    文章目录 1. 内核启动参数 2.模块参数与sysfs 3.sysctl 4.系统调用 5.netlink 6. procfs(/proc) 7.seq_file 8.debugfs 9.relayf ...

  10. 计算机是如何识别内核态和用户态,用户态和内核态区分(二十七)

    用户态和内核态 Linux的架构中,很重要的一个能力就是操纵系统资源的能力.但是,系统资源是有限的,如果不加限制的允许任何程序以任何方式去操纵系统资源,必然会造成资源的浪费,发生资源不足等情况.为了减 ...

最新文章

  1. 指针运算(自己做个笔记)
  2. python开发安卓程序-用python开发android应用(1)
  3. WinForm 窗体之间交互的一些方法-兼托管事件
  4. eclipse error pages打红X的解决方法
  5. win10 linux安卓模拟器,genymotion安卓模拟器在Window10中使用的问题
  6. 云图说|初识云数据库GaussDB(for Redis)
  7. Linux驱动开发快速参考
  8. 曾经以为20岁很遥远_曾经以为30岁很遥远,却发现18岁是很久之前的事了。
  9. ​最高要价 8888元,小米 11 邀请函现身闲鱼;荣耀与微软签署全球 PC 合作协议;Xfce 4.16 发布|极客头条...
  10. 《战争论》第四篇《战斗》的主要内容
  11. 11 、图解2个node环境下replica shard是如何分配的
  12. 【数据集】BDD、KITTI、Cityscapes和Foggy Cityscapes百度云链接
  13. Spring 一二事(1)
  14. BT5的 U盘启动 制作
  15. YuxuanSys WMS412无线流媒体网关在会议场景中的应用一
  16. 用python计算内部收益率
  17. 关于Mifare Classic Tool (MTC)工具的秘钥包
  18. 阿里云,腾讯云,景安等谁家的备案流程比较简单?
  19. 引用pdf插件在线预览的问题
  20. 赋值具有的非单一 rhs 维度多于非单一下标数怎么办

热门文章

  1. SONY无线PS2遥控手柄与stm32单片机通信
  2. 数据库空间存储已满,如何清理释放空间
  3. windows 编程的学习次序
  4. 秒杀活动总结(秒杀之一)
  5. 学习笔记(109):R语言入门基础-text函数
  6. SSL/TLS 受诫礼攻击漏洞的问题的解决记录
  7. 算法注册机编写扫盲---第二课
  8. [C#]LambdaTest
  9. o2o、c2c、b2c、b2b、b2b2c都是什么?
  10. html5梯形图形代码,CSS秘密花园:梯形标签