• 64位内核开发第十讲,IRQL中断级别了解


    中断级别IROL了解

    一丶IRQL

    1.了解什么是中断

    中断就是产生的一个电信号.比如键盘.当按下就会产生电信号发送给CPU
    而CPU就会停止当前处理.去执行电信号.他是根据IRQL中断级别来进行处理的.
    如下图:

    中断说白了就是个电信号.打断CPU执行的代码. 去调用中断处理函数.
    此时CPU就处于硬件上下文.

    2.IROL中断级别.

    因为会产生很多CPU电信号.所有硬件同是发送中断处理级别怎么办.所以需要为这些级别分一个优先级. CPU会先执行优先级高的.会把优先级低的给屏蔽掉.

    当CPU处于中断上下文的时候. CPU不能是阻塞的/阻塞. 没有进程可以调度.

    了解CPU的上下文.至少脑海需要有印象

    上下文 说明
    中断上下文 CPU代替硬件做某些事情.
    进程上下文 CPU代替进程做某些事情.

    中断级别了解
    如下图:

    软件中只会处理下面三种级别.
    DISPATCH_LEVEL最高
    APC_LEVEL 其次
    PASSIVE_LEVEL最低

    3.遵守IROL编程规范的方式

    1.查询MSDN.MSDN最下面有IRQL级别的说明.

    运行在DISPATHCH_LEVEL级别的上下文.如何调用PASSIVE_LEVEL级别的函数.
    如我们有一个需求.
    当键盘按下的时候. 键盘的优先级最高. 会运行在DISPATCH_LEVEL级别.但是此时
    按照我们Ring3编程的想法.你可能会调用ZwCreateFile这个函数进行将按键写入到文件中.
    但是此时我们如果查询MSDN之后就会发现.其实ZwCreateFile是不能运行在DISPATCH级别的. 此时解决方法 就是创建一个 工作线程. 工作线程中完成
    我们想要操作的事情.

    3.在PASSIVE级别下.我们可以使用任何内存没有限制.

    首先了解下如下表格.

    函数 运行级别
    DriverEntry Passive级别.
    各种派遣函数 Passive级别
    完成函数 Dispatch级别
    各种NDIS回调函数 Dispatch级别

    PASSIVE级别是可以使用任何函数和内存
    DISPATCH级别只能访问能运行在DISPATCH级别内存.

    非分页内存
    NONPAGEPOOL 内存是可以在任何级别使用的.

    相关申请内存函数为:

    ExAllocatePoolWithTag

    PAGEDPOOL 分页内存
    只能在PASSIVE级别或者APC级别使用.
    我们可以加入一个宏.来判断当前的中断级别.有没有高于APC
    产生一个断言.如果当前级别大于APC级别就会报错.

    断言宏的意思就是 我决定当前的事就是某事. 如果你不是我指定的.
    那么对不起.报错.

    使用PAGE_CODE这个宏即可.
    其实很简单.宏站看看一下.

    #define PAGED_CODE() PAGED_ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
    
    
    #if (NTDDI_VERSION >= NTDDI_VISTA)
    #define PAGED_ASSERT( exp ) NT_ASSERT( exp )
    #else
    #define PAGED_ASSERT( exp ) ASSERT( exp )
    #endif
    
    往下跟很多.....
    
    直到最终
    
    #define NT_ASSERT_ACTION(_exp) 
        ((!(_exp)) ? 
            (__annotation(L"Debug", L"AssertFail", L#_exp), 
             DbgRaiseAssertionFailure(), FALSE) : 
            TRUE)
    
    

    其实很简单. 首先调用 KeGetCurrentIrql() 这个函数来判断是否小于等于 APC级别.
    然后当参数传递给 PAGED_ASSERT(exp)宏. 里面就调用函数进行断言

    断言宏只会在Debug版本中有效.让我们尽快发现问题.
    把 PAGE_CODE 放到我们代码块中即可.

  • 相关阅读:
    删库了一定要跑路吗?爱情 36 技之记忆重生!
    程序员和他的朋友们!
    聊起 BigTable,让你不再胆怯
    [Ant Design] Warning: Instance created by `useForm` is not connected to any Form element. Forget to pass `form` prop?
    Git 常用命令
    Git 名词解释
    js中void 0和undefined的区别
    js运算符优先级
    搭建React项目(低配版)
    mac常用shell指令笔记
  • 原文地址:https://www.cnblogs.com/iBinary/p/10990689.html
Copyright © 2020-2023  润新知