`
totoxian
  • 浏览: 1062752 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

通过IRQL看NT内核

 
阅读更多

linux强调的是进程自主性,windows则是对象自主性,其中线程本身也是一个对象,进程也是,所以一个进程可以操作另外一个进程的地址空间也就不足为奇了,windows的通信实际上是对象间通信,而linux因为一切围着进程转,最新的内核中断也被线程化了,因此通信就是进程间通信,linux 中进程作为超级容器的意义要比windows的更大些,windows中进程是一个容器,也是一个对象,某种意义上它作为容器的意义是容纳别的对象。 windows的模块化思想更加鲜明。

windows中将缺页,调度等概念从线程,进程中分离,专门安排一个irql级别来处理之,而linux下相应的概念则永远和进程相绑定,看看缺页中断的处理代码,考虑的一直都是进程的概念,在windows中,考虑的就是对象的概念了,比如文件对象等等,但是缺页本质上真的是和进程相关的,所以在 windows中没有进程/线程上下文的的执行绪当然就不能缺页了,那么谁没有进程/线程上下文呢(也就是ms说的“任意上下文”)?答案是 dispatch_level之上(包括dispatch)的没有进程/线程上下文,所以,相应级别的执行中就不能访问分页内存(可能被换出而导致缺页的内存)了。windows下进程/线程是和其他对象并列的概念,没有什么特殊之处,但是在linux(unix)中,它们却是终极重要的概念,贯穿整个系 统。windows为了实现完全异步和为了配合可移植性,将一切抽象成了“中断”,所以我们没有必要特别说什么上下文的概念,上下文只是一个进程/线程的 容器,没有又如何,代码照样执行,之所以强调什么时候要有上下文什么时候没有必要完全是为了配合进程/线程的,为了使进程/线程好管理。

我比较喜欢将一大堆的结果归结为一个原因,就像一切宏观运动都是牛顿定律的结果,一切微观运动都是量子力学的结果,一切宇观运动都是相对论的结果一样,从这一点上看,研究windows是一个好的选择。

我们看一下两个操作系统的缺页,先说linux。

在linux中,发生缺页后执行缺页中断处理,当时的上下文还是引起缺页的进程线程上下文,除非当前在中断或软中断中,然后内核挂起当前线程,执行磁盘 io,将页面取回或者分配一个匿名页面,实际上这里挂起当前线程的意思是执行的缺页中断处理并不属于当前线程和在磁盘io或分配匿名页面的过程中可能要等 待,等待意味着线程切换,一直到线程实际切换,上下文一直是当前线程上下文。 在前面说的中断或软中断中出现缺页的话就不能随便进行线程挂起了,因为此时是linux唯一可能在任意上下文的情况,即使在内核发生缺页也没有关系,缺页 处理只认上下文,不管在什么态(因为内核数据结构常常在中断中被访问,所以,一般还是别在内核用分页内存了,所以linux又规定,内核数据结构从 slab或类似的连续区分配分配,并且常驻内存,你完全可以修改内核,在内核分配一个页面,映射到内核空间或用户空间,然后修改缺页处理程序,使得可以处理映射到内核导致的缺页,最后保证你永远不在中断中访问这个地址,很麻烦,但可能!),所以linux硬性规定:中断不能引起缺页(原因仅仅一个,上下文不确定)。(附:本质意义上,内核空间并不属于任何进程的地址空间,只是一个所有进程和资源的管理空间,所以内核空间大家公用,所以linux很是巧妙的将物理内存线性映射到内核地址空间,内核数据结构大部分在此分配,一旦满足不了要求,可以从vmalloc区域分配,并且只更新0号进程页表,由缺页中断 来解决别的进程页表和0号进程页表同步问题,所以linux内核空间地址的中断并不需要真正分配内存页面,只需要修改个页表就行。linux内核空间地址不许缺页并没有实质性的规定,只是为了内核开发的方便,所以linux仅仅解决用户空间的缺页和内核vmalloc页表缺页。)回到前面正常情况,在有上 下文的情况下进行磁盘io或分配匿名页以及可能引起的当前线程睡眠切换有问题吗?一点问题也没有,因为linux/unix尽量使所有执行绪都有特定上下 文,不允许的操作作为稀有的特例已经被硬性明文禁止了,这样的弊端在于,留给程序员的只有好好把这个原理研究透或者把那些规定背熟了。在windows中 的情况呢?上下文没有那么特殊了,一切都是异步的中断,很多执行绪没有特定上下文,那么发生缺页后呢?可能缺页发生在用户线程,而用户线程运行在被动中断请求级别,这是没有任何问题的,所有别的级别的执行绪都可以中断它,最重要的,io开始例程在dispatch级别运行,缺页处理运行在 dispatch,调度也运行在dispatch。首先,为何调度在dispatch运行呢?因为在dispatch或之上的执行绪就是任意上下文环境 了,它们是不允许发生线程切换的,这怎么保证呢?如果在dirql级别的要切换,那么就要将irql提升到dispatch,因为当前dirql比 dispatch高,于是蓝乎,如果在dispatch的dpc要调度,那么它要提升irql到dispatch,因为它已经在了,于是亦蓝乎,这就是原 因,调度运行在dispatch实际上是为了保证没有上下文的执行绪不能发生线程切换(类比linux,linux中也是没有上下文的不能切换);那么 io开始为何也在dispatch呢?这是因为windows是异步的,一个线程发起一个io不一定在当前上下文就可以执行,可能在一个硬件中断发生后有 了执行的条件(考虑irp排队),然后此中断派发一个dpc开始io动作,中断没有确定上下文,它派发的dpc同样没有上下文,所以io开始只能在没有上 下文的dispatch执行;io分派例程比如read,write之类的必须在有上下文的被动级别运行,因为它们可能要睡眠,而且不能打扰io开始和完成例程;现在考虑缺页,看看它能在哪里执行,咱们从低irql到高考虑,我们假设被动irql也参与到中断模拟,如果缺页处理运行在最低的被动irql, 那么就完了,试想一个同样在被动irql的线程发生缺页,缺页运行前必先提升irql到被动级别,但是不巧,已经是被动级别了,出错,返回,蓝!但是事实上,被动级别并不参加中断模拟,这说明缺页处理运行在被动级别是可以的,但是考虑apc级别,它可使参与中断模拟了,apc比被动级别高,于是如果缺页处 理在被动级别,那么apc就不能缺页了,这说明apc不能用分页内存,这很影响大家伙的信心,windows怎么能这么限制程序员呢;那么我们就将缺页处理运行级别往上提高一级,到apc级别,还是不行,apc还是不能缺页,因为它就是在apc级别的,虚拟中断只能被irql比它高的中断掉;于是再往上 走,到dispatch吧,这下好了,apc可以使用分页内存了,但是提升到这个级别仅仅为了让apc使用分页内存,如果又引起别的问题,那么还是别让 apc使用分页内存了。考虑缺页需要哪些操作,无非就是分配内存页面,或者从磁盘读取页文件,考虑后者,肯定要开始一个磁盘io过程,而磁盘io就是在 dispatch进行的,这可以,考虑前者,分配页面可能导致线程睡眠,现在缺页正在dispatch运行,想挂起一个线程也没有问题,正好调度也是在这个级别运行,仍然没有问题,现在我们可以说缺页处理可以在这个级别了,但是,人是贪心的,一些限制总是使人能有所创新,只可惜,这次的创新在 windows完美主义下失败了,我们不甘心dispatch以及之上的内存不能使用分页内存,于是再往上提一级,提到哪级姑且不考虑,如果 dispatch这种没有上下文的级别产生缺页就有可能睡眠或请页,但是io开始和调度都是确定性的在下面的级别运行,于是不能再往上了,就这样了,缺页中断处理程序只能在dispatch级别运行。

这下有意思吧,windows的大框架已经定死,不需要硬性规定,一两条原则就可以决定这么多事情:1.中断虚拟化的irql机制使windows成为完全异步os内核;2.对象化模块化使windows不过分依赖于进程/线程的概念,使得1的实现简单化。网上很多人比如赫赫有名的毛德操教授说 windows的进程可以操作别的进程空间是windows不安全的原因之一,我认为这句话没错,但是毛教授似乎没有理解windows为何这么做,它不安全是因为细节没有把握好,而大的框架我很欣赏,也很坚信,没有错!linux的软中断和任务队列就是windows的借鉴,只可惜,linux是善变 的,发现工作队列后毅然抛弃了任务队列。

linux更像是一件艺术作品而windows更像一件工业产品。举个例子:一个高大的全钢架结构建筑矗立在广场,看似永远都没有完过工,巨大的钢架抬头 可见,耗资巨大,周围只有钢架,没有封顶,人在里面难免风吹雨淋,人们会在底楼租一间盖好的屋子,但难免还会被漏下来的建筑石料将屋顶砸破,头破血流,目前开发商大势已去,真不知能否完工,但是框架结构绝对一流,缺的不是技术,而是激情;在郊外的草地上,几个满怀激情的人在自己修建一座别墅,没有开发商, 没有人观望,只有他们自己,别墅异常豪华,没有什么框架,因为不需要,他们有技术,有激情,缺的是大家的支持。前者是windows,后者是linux, 而unix可能就是金字塔吧。

现在的硬件也在提供更多的功能,从而使一些软件策略更加容易实现,比如apic就实现了软中断功能,这就更加使得windows的irql如鱼得水了,我认为linux马上也将用最新的apic软中断功能来实现softirq,这一向是linux的作风:绝不落伍!

感叹:现在的硬件也在越来越快的发展了,快赶超软件发展速度了,看,什么都在封装,以前用引脚传递硬件信息,现在用消息了(看看pci和pcie吧),硬 件和软件都在两极分化,一帮人搞的东西越来越简单,越傻瓜,另一帮人却越来越高深,越深不见底!呜呼,我,何去何从?!

分享到:
评论

相关推荐

    WinNT内核的分析(Gloomy)

    ### WinNT内核的分析(Gloomy) #### INTRO (写给NT研究者) ...通过对Windows NT内核的深入分析,我们可以更全面地理解操作系统内部是如何组织和管理资源的。这对于开发高效、安全的应用程序来说至关重要。

    NT下读写端口

    1. IRQL(Interrupt Request Level):在Windows NT中,读写端口操作必须在合适的中断请求级别(IRQL)下进行,通常在被动级别(PASSIVE_LEVEL)或调度级别(DISPATCH_LEVEL)。 2. KeInsertQueueApc:这个系统调用...

    内核PELoader

    - `ntimage.h`可能包含与Windows NT内核相关的PE文件结构定义,提供头文件支持。 - `PeLoader.h`可能是自定义的头文件,包含了PELoader的相关函数原型和结构定义。 - `type.h`可能定义了与PELoader相关的数据类型...

    windows内核分析

    在深入探讨Windows NT内核之前,我们首先需要了解构成其核心的一些关键组件。Windows NT的操作系统架构是高度模块化的,旨在提高可扩展性和可靠性。 1. **Ntoskrnl.exe**:这是Windows NT的核心组件,包含了系统...

    nt式驱动程序架子

    这些驱动程序遵循Microsoft的Windows内核模式编程模型,适用于包括Windows NT、Windows 2000、Windows XP、Windows Server 2003、Windows Vista以及后续版本在内的系统。本篇将详细讲解NT式驱动程序的基础知识,特别...

    windows内核的分析 by gloomy

    本文通过对 Windows 内核的深入分析,详细介绍了 Windows 操作系统的核心组件及其功能,并解释了 Windows NT 操作系统内存布局的具体划分。通过对这些概念和技术的理解,读者可以更好地掌握 Windows 内核的工作原理...

    ReactOS-0.3.3源码

    它的设计借鉴了Windows NT内核的模型,如KPCR(Kernel Processor Control Region)和IRQL(Interrupt Request Level)等概念。 2. **设备驱动程序(Device Drivers)**:ReactOS包含了一系列的驱动程序,这些驱动...

    WDM开发指导

    此外,WDM驱动利用中断请求级别(IRQL)来管理同步和并发操作,确保系统稳定性。 四、开发流程 开发WDM驱动程序通常涉及以下步骤: 1. 设备枚举:操作系统识别并加载驱动程序。 2. 驱动注册:驱动程序注册到系统...

    windows device driver技術詳解源碼

    开发驱动程序需要熟悉内核编程,包括IRQL(Interrupt Request Level)、调度例程、I/O请求包(IRP)、设备对象和文件对象等概念。 5. **驱动程序源码分析** 源码可以帮助我们理解驱动如何初始化、响应I/O请求、...

    TDI2000驱动代码

    在Windows 2000中,TDI驱动程序通常基于NT内核,利用系统提供的服务来实现这些功能。它通过注册为系统的服务提供者,向上层的TCP/IP协议栈或其他网络协议提供服务。 TDI驱动的编写涉及到以下几个关键知识点: 1. *...

    驱动开发windwos入门

    在编写驱动程序时,开发者需要掌握Windows内核的工作原理,熟悉IRQL(Interrupt Request Level)、调度、中断处理、设备对象等核心概念。同时,内核调试技巧也是必不可少的,因为驱动程序的错误可能导致系统崩溃,...

    WDM驱动程序开发

    WDM驱动程序架构基于Windows NT的操作系统体系结构,该结构将驱动程序分为不同的层级,包括用户模式驱动程序和内核模式驱动程序。在内核模式驱动程序中,位于Ring0级别的代码可以访问硬件设备,而Ring3级别的代码...

    蓝屏部分代码 查询

    技术上,它表示在内核模式下,一个进程试图以高于其应有的内部请求级别(IRQL)访问它无权访问的内存地址。 - 解决方案:可以尝试前面提到的解决方案中的2、3、5、8、9步骤来排查问题,这可能包括更新或重新安装...

    键盘过滤驱动 获取键盘按键

    5. **系统调用和回调函数**:驱动程序通常会注册回调函数,以响应键盘事件,并通过系统调用来与内核或其他驱动通信。 6. **调试和测试**:由于驱动程序运行在核心层,错误可能导致系统崩溃,因此需要进行严格的调试...

    windows 驱动开发技术详解

    4. **IRQL(Interrupt Request Level)**:在内核模式驱动中,IRQL是一个关键概念,用于管理中断处理和同步。理解IRQL的层次和规则对于编写正确且高效的驱动至关重要。 5. **I/O管理**:驱动程序需要处理I/O请求,...

    Wdm1.rar_wdm1

    WDM驱动程序是一种混合驱动模型,它结合了VxD(虚拟设备驱动)和NT VDM(内核模式驱动)的优点,旨在提供更好的硬件兼容性和性能。WDM驱动程序运行在用户模式和内核模式下,使得它们能够高效地与硬件交互,同时确保...

    系统蓝屏表.蓝屏代码

    系统蓝屏代码表 0x0000000A:IRQL_NOT_LESS_OR_EQUAL ... 表明在内核模式中存在以太高的进程内部请求级别(IRQL)访问其没有权限访问的 内存地址. ◇解决方案:请用前面介绍的解决方案中的2、3、5、8、9方案尝试排除.

    Windows internals 5th

    - **Executive**:Executive是NT内核的一部分,负责管理内存、进程、线程等关键资源。 - **Kernel**:内核是操作系统的最核心部分,提供了对硬件的直接访问。 - **硬件抽象层 (HAL)**:HAL使得操作系统能够在不同的...

Global site tag (gtag.js) - Google Analytics