当前位置:C++技术网 > 精选软件 > Windows核心编程入门:4 轻松理解用户态和内核态

Windows核心编程入门:4 轻松理解用户态和内核态

更新时间:2016-05-12 22:53:58浏览次数:1+次

    在写完《Windows核心编程入门2:操作系统内核有哪些类型以及特色》后,到现在已经是相隔一个月了。在这个过程中,我仔细研究了用户态和内核态。一直迟迟没有更新,一是因为要仔细揣摩,以免理解的不够。当然,我现在还没有接触系统内核代码,自然理解还是不够的。这个过程我也是加深理解学习,写之前也是查阅了很多资料书籍,然后自己消化,再用自己的思想整理表达出来,更加完整更加通俗易懂的表达出来,让更多人能够轻松理解。时隔一个月,还因为工作的忙碌、出差、放假旅游,都把节奏打乱了。这才恢复过来。继续把这个系列写完,再更新其他东西。至于工作上的事情,留给白天去忙碌吧。晚上做点自己的事情,放松一下,总结写文章提高一下自己的水平。
    对于什么是Windows都不知道的人来说,你可以多查查资料了解,然后也是可以看我们这些文章的。我们C++技术网的教程或者系列文章,至少是我主笔的,都基本做到了小白都能看得懂的通俗程度。也因此就显得有些啰嗦了。所以,只有委屈有基础的人咯。
    我们买了电脑,只是买了一个硬件。要让硬件发挥作用,这是计算机操作系统考虑的问题。现在的计算机都是大规模集成电路形式的,拆开电脑,你看到一个主板,上面各种元件,还有其他各个部件,都是各种电路板支持的。作为一个男生,我也比较喜欢拿个扳手去修各种家电,修改一个家电,成就感杠杠的。有一次爷爷说机顶盒坏了,我想试着去修一下,结果拆开了,发现就是一块电路板,其他什么也没有。这让我深受打击。这么一块电路板,让我不知所措。是的,各种各样的硬件都有这样的电路板,很多集成度很高,一块板里基本是各种各样的元件,也有的比较简单。外表光鲜的硬件,拆开后都是一块块电路板,不禁让人感觉硬件内部是如此的空虚呀。
    从另一个角度想想,我们无法直接用扳手修理,很多基本也无法用按钮去操作了。集成度越高,越没有办法在硬件上直接操作了。那么这些硬件如何去操作的呢?集成度非常高的典型代表就是计算机了。基本上,硬件本身无法直接操作。我们要操作硬件,让这些电路板发挥作用,就得通过软件了。在现在设备越来越智能的时代,很多设备都可以称为一台微型电脑了,内部有专用的指令,外部设备只要给它发送这些指令就可以操作这些设备了。电脑自然也是这样。
    而这些指令不可能通过手指摩擦发送,也不能动动嘴巴就能发送。所以,这才有了软件。能够完整接纳硬件,然后在软件上提供界面操作硬件的,都可以叫做操作系统。在计算机上的操作系统叫做计算机操作系统,在收音机上运行的系统叫做收音机操作系统。大家不要局限于计算机操作系统。现在非常流行的不就有手机操作系统嘛。
    现在的设备基本都有一个操作系统来管理,人类不直接操作硬件了,也没法直接操作,不然你怎么让一个电路板运行呀,难道你眼睛放电让电路板执行指令么?操作系统也就理所当然完全霸占了硬件。如果你买一个电脑没有安装操作系统,你是不是很焦虑,即使电脑配置再牛逼,不就是一堆硬件嘛,玩不起来呀。
    我们的计算机操作系统是非常成熟的了。操作系统就是用来操作管理硬件的,对于操作系统来说,它可以任意操作计算机的硬件,包括内存、磁盘、显卡、屏幕、键盘鼠标等等各种硬件设备。它说要访问哪个硬件就可以访问哪个硬件。计算机的世界里,操作系统就是老大,所有的硬件资源都是操作系统管辖的。一个操作系统就如同一个国家,操作系统内核程序,就如同国家核心领导层,这就是我们前面说的操作系统内核。我们通常叫做内核程序执行的状态叫做内核态或者核心态。当然,因为操作系统是接管硬件的,在硬件上有绝对的管理能力,它知道哪些可以操作,哪些不能被操作,哪些已经被分配出去了,操作系统内核扮演的就是一个不折不扣的管理层角色,因此也叫内核态为管态(管理层态)。如果按照权利大小来看,自然内核是核心管理层,自然也是会给自己赋予绝对特权的,这样方便管理各种硬件,提供完整的控制。在自己的地盘里,自己当然是最大的,自然是特权级的。所以,内核态也叫作特权态。那么特权态自然相对于非特权态了,只有比较才有意义,如果大家都是可以自由访问,也没有必要分特权态了。特权态访问的东西,自然不能被一般权利的程序访问了。这个很好理解,比如国家领导人出席的国家机密场所,不是普通人能够去的。就是等级低了,也是不能去的。大家经常听过什么ring0-ring3这些名词,我解释一下。ring0是CPU的一个特权级别。ring0,ring1,ring2,ring3。Windows只使用其中的两个级别ring0和ring3,ring0只给操作系统内核用,ring3普通应用程序都能用。如果普通应用程序企图执行ring0指令,则Windows会显示“非法指令”错误信息。
    ring是戒指、环状的意思。描述的是一个权利适用的范围。0级最高,也就是操作系统内核使用的,可以对硬件随意访问。3级最低,也就是广大程序使用的,级别3自然很多地方都有约束条件,不能随意访问硬件。如果在3级下,很多事情做不了。所以很多病毒都会想着提升自己的特权,如果能够达到ring0,自然也就无所不能了。很多人以为自己知道ring0这个一个东西就觉得好了不起一样的,其实这些名词并不能说明什么,学了点核心编程的,也就慢慢知道这些名词了。关键是要理解这些名词背后的思想含义。
    相对于操作系统的那些状态称呼(核心态、内核态、管态、特权态)来说,普通的应用程序也是有状态的,不过因为应用程序权利太普通了,称呼也少些。我们叫非内核态为用户态或者目态。目态就好比很多地方你只能看,却去不了的,只有有特权的领导才能去的。如果将计算机世界类比为人类社会,系统内核程序就是核心管理层了,系统其它系统组件,就是地方的管理层了,普通的应用程序就是最普通的广大民众了。
    我想解释到这里,你不理解内核态和用户态都难了吧。好吧,再多扩展一点,让你理解更加深入一点。我们这些文章,看似浅显,实际却是将内部的原理都通俗化了。当你再深入学习的时候,也就很好懂了。我们这里绝非是聊聊历史那样的。所以对于这些描述文字还是需要用心理解吸收的哦。
    那么核心态和用户态真实的应用场景到底是哪样的呢?我们前面类比了人类社会,不免还是有点模糊,虽然理解了,但是还是不能具体化到实际场景。我们来看看这不同的状态到底是怎么回事。
    操作系统的目标是很好的管理硬件,没有操作系统,我们没法使用硬件。但不是随便有一个可以操作硬件的系统就可以了的。我们需要系统稳定的运行。假如系统在你转账,写论文,做各种事情做到一半的时候突然崩溃了,是不是会让你产生很大损失呢!必须损失很大啦。稳定是评价一个操作系统的好坏的关键因素。不稳定的系统谁也不敢使用,谁知道什么时候挂了。当硬件发生不可修复的错误时,系统就会崩溃蓝屏。操作系统不仅要让用户可以很好的使用硬件,还要保证系统稳定,保护硬件不被恶意或者非恶意的操作,以免让系统造成崩溃。这也是系统为什么要设置不同的运行状态的原因。
    设置运行状态,也只有操作系统内核才能完全访问硬件,应用程序都是委托内核程序操作硬件。这样一来,硬件的操作都是内核程序执行的。这样硬件的所有操作都是在操作系统控制范围之内的,这样就大大提高了系统的稳定性。
    用户态的程序也就是我们平时写的程序,和内核程序其实没有什么不同,都是执行指令,都是完成逻辑的执行而已。区别就在于程序关联的权限级别了。权限不同,能够执行的指令类别也就不同。ring0权利的程序也就是内核程序,可以执行计算机中所有指令,这些指令包括普通指令和特权指令。如果ring3的程序试图执行特权指令,会被驳回,无法执行。只因为拥有的权限不同,能做的事情就不一样。就好比国家核心领导人身份地位高,权利高,很多国家决策可以决定,然而他们也是一个普通人。但是他有做决定的权限,所以可以做决策。我们普通民众,没有那些权限,自然也无法做影响国家运作的决策。
    你可能发现ring1和ring2并没有提及,因为目前系统用0和3级别就可以了。因为系统只需要区别内核态和用户态就可以满足管理需求了,所以没有必要使用ring1和ring2。当然如果以后有特别需要,ring1和ring2也会用上的。
    内核态和用户态还有一个区别,不过这个区别可能让你感觉身体不适哦。或者会让你觉得挺受打击的。所有的程序(内核态程序和用户态程序),都是在CPU上执行的,因为CPU是共享的,所有程序都是在CPU上执行,因此有竞争关系了。如果内核态程序和用户态程序打架,抢CPU,你猜谁会赢呢?这还用猜嘛,自然内核态赢啦。一个有特权的和一个普通的,根本没有竞争的可能。用户态程序在CPU上执行,会按照一定的策略轮流的执行,这样可以保证大家都可以执行。这样保证公平性。然而对于特权态和用户态来讲,真会公平吗?不会的。系统自然有优先级机制,特权态的程序自然优先级很高。即使用户态程序刚执行,如果内核态程序需要执行,用户态也只有退出来咯。而用户态某一个程序十万火急,内核态程序没有执行好,那也只有等咯。也就是说,内核态是不会被打断的,而用户态是可以打断的哦。这是一个很现实的问题哦。这个和人类社会太像了。所以不要苦恼了,不要抱怨了,计算机世界里,其实也是人生百态呀。程序也有程序的烦恼呀。
    对于硬件访问的限制,我们接触最多的就是内存了。物理内存的访问,不只是应用程序不能直接操作内存,甚至一部分内存应用程序根本就见不着。应用程序使用的是虚拟内存地址空间,最终只能转换到一段内存中。我们看似应用程序可以访问4G内存(32位程序),实际上只是虚拟的哦。而且程序也不是直接操作内存,所有操作都是通过地址转换,将虚拟地址转为实际的物理内存地址,这样才能操作。如此一来,内存的操作也是在内核程序的处理下完成的。因此内核可以控制程序访问内存,避免应用程序随意操作内存。操作系统本身所在的内存和应用程序使用的内存是隔离开的,所以应用程序不能修改操作系统内核所在的内存数据的。这样是防止恶意程序破坏操作系统,或者防止正常程序无意破坏了操作系统哦。
    至于对于用户态的其他硬件访问的限制,我就不再举例说明了。相信说了这么多,你可以非常了解用户态和内核态了吧。如果还有什么疑问,可以在文章底下留言。