<2024年3月>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

文章分类

导航

订阅

戏说IRQL(1)

答应网友写一篇IRQL的文章,因琐事所累,迟迟未下笔,不觉已经数日,深感歉意。在这样个大家埋头读微信的时代,想学习IRQL这中晦涩概念的好学者是多么可贵啊,因此宁可少休息一个晚上,也要动笔了。

其实,谈论IRQL的文章已经非常多,随便谷歌,百度或者饼一下,都可以找到足够读上半天的内容。那为什么还要写呢?吹牛点说,当然是别人写的不好,虽然自己也未必能写好。

闲言少叙,先解释下题目吧,为啥叫戏说呢?冠冕堂皇些,有两个原因,一是希望这篇文能够通俗易懂,最好活泼有趣,二是戏说与细说谐音,希望这篇文能等把道理说通说透,要深挖到底,要掰开皮说馅,不要蜻蜓点水,把关键东西一掠而过,或者支支吾吾语焉不详。轻声说,还有一个原因,就是作者面前除了电脑屏幕外,还有一个电视屏幕,里面演的是笔者偏好的京剧,音配像之《将相和》正在上演,此时此刻,“将”府的正在酒馆里欺负“相”府的……写这样的文章时,看这样的戏正好,感谢CCTV 11。

可以进正题了,虽然不想按老学究的方式按部就班地讲,但还必须解释一下IRQL这个名字。字面的含义是中断请求级别,这个中文翻译与英文原意可以说是精确匹配,信达雅。但是看了这个名字还是让人一头雾水。这不怪大家,因为这个名字取的不好。甚至可以说有点毛病,不是中文翻译的毛病,是英文本来就有毛病。

简单来说,IRQL的本意是用来描述CPU正在做的事情的重要程度,简单说就是正在执行代码的优先级别。为什么定义优先级呢,两个目的: 一是为了防止低优先级的事情把高优先级的事情打断;而是防止因为CPU忙于低优先级的而忽略了高优先级的。举个例子来说,假如你在开会,如果此时手机响起,接听后,如果打电话的是你根本不感兴趣的推销先生,那么你一定因为被骚扰而生气,但如果电话是说请你到某公司做副总,那么你多半会认为这个电话还是该接的,比眼下的滥会重要。IRQL正是为这样的初衷而设计的,根本目的就是要制定一个规则,让CPU总是可以优先处理更重要的事情。更具体地说,可以分两个方面:

1) 当CPU在执行低优先级的垃圾代码时,CPU可以随时放弃执行,去处理更重要的大事。

2) 当CPU在处理大事时,可以专心处理,不要去理会低优先级的垃圾代码。

概括一下,就是让低优先级的代码可以随时被(高优先级的)打断,让高优先级的不被(低优先级的)打断。

如此看来,IRQL这个名字是从任务角度取的,比如如果把垃圾广告电话的IRQL定为-10,那么猎头公司的IRQL就应该高一些,比如定为-8。但问题是,当人们使用IRQL这个名字时,通常都是站在CPU这个角度的,甚至把它当成是CPU的属性,比如CPU如果在执行IRQL为28的任务,那么就说CPU的IRQL是28。就好比是你在接优先级为-10的垃圾电话,就说成你目前的IRQL是-10,如果有IRQL为-8的电话打过来,如果把旧的掐断,新的接起,那么你的IRQL就切换为-8了。

所以,如果就IRQL的本意来说,这个名字是可以的,描述的是一个任务的总要性,它请求CPU中断的级别。比如,时钟中断的IRQL是28,电源任务的IRQL是30,高两级,原因是虽然更新时间很重要,但还是没有供电重要,一掉电就全玩完了。但如果像大多数时候使用的,把IRQL直接用在CPU身上,那么这个名字就不对劲了,CPU是被中断的目标,别人请求它,所以对CPU来说,应该叫被请求级别之类的……

太挖字眼没意思,大家搞清楚其中的道理就够了。生活中有很多“词不达意”的名字,多一个就多一个了。

铺垫有了,接下来通过几个试验来理解几个重要的IRQL级别。启动虚拟机,运行我写的Imbuggy小程序,点击Load让其加载名叫RealBug.sys的驱动程序。

然后点击Loop at IRQL按钮,让CPU执行驱动程序中的RoamAtIRQL函数:

VOID RoamAtIRQL(ULONG ulIRQL)

{

         KIRQL OldIrql;

         KeRaiseIrql((KIRQL)ulIRQL, &OldIrql);

         while(1)

                   _asm{hlt};

 

         KeLowerIrql(OldIrql);

}

熟悉Windows驱动的看官,对这个函数中的两个DDI一定非常熟悉:KeRaiseIrql和KeLowerIrql,一个是提升IRQL,一个是降下来。但是大家对提升IRQL后做个死循环这样的代码一定是陌生的。因为整个DDK中散步了很多关于IRQL的警告,其中很重要的一条原则就是在高IRQL时要格外谨慎,不能做这个,不能干那个,充满了限制。

那么在高IRQL(26)漫步到底会怎么样呢?

点下按钮后,再尝试点别的地方,纹丝不动。为什么呢?因为CPU忙于执行高优先级的任务,没有机会执行IRQL最低的普通线程,所以界面就没有任何反应了。

【写文章总比空想要费事和慢的多,一部《将相和》结束了,可是只写了三分之一,而且时间已经不早了,未完待续】

posted on 2013年9月8日 22:20 由 Raymond

# re: 戏说IRQL(1) @ 2013年9月9日 16:30

持续关注。

kkindof

# re: 戏说IRQL(1) @ 2013年11月19日 14:09

1."而是防止因为CPU忙于低优先级的而忽略了高优先级的。", 应是"二是防止因为CPU..."

2."描述的是一个任务的总要性"应是"...的重要性"

Anyway,"太挖字眼没意思!", 只是非常喜欢Raymond的文章,所以就留言了.

merryzhao

Powered by Community Server Powered by CnForums.Net