如果你一开始就读linux 内核,那么你的思路会变得非常开阔,如果你读过unix 内核,那么你会惊叹于linux 内核的巧妙,如果你连NT 的内核也了解,那么你会发现linux 内核真是个另类,本文从内核栈的角度来简要说明linux 为何另类。
了解操作系统原理和计算机体系结构的都知道在应用程序陷入内核的时候要将用户栈切换到内核栈,而引起陷入的有三种方式:1. 系统调用;2. 硬件中断;3. 异常。但是如果执行续本来就在内核而发生了中断,那么怎么办呢?unix ,nt ,linux 的处理是不同的:
1.unix 的方式:
unix 中的进程的内核上下文有静态部分和动态部分,其中静态部分就是区表,进程表项和U 区,本文我们不考虑,动态部分最重要的就是内核栈,unix 按照 系统支持的中断级别种类将进程的内核栈分为多个层,每个中断级别对应一个层,这个中断级别的概念和nt 的irql 有些类似,其实它们的作用还真的一样,用 来屏蔽同优先级或下优先级的中断,由此来保证多层的中断栈不会使上下文乱掉,栈的层次是单向提高或者降低的。具体过程就是:用户空间的进程进行系统调用或 者被中断,那么系统切换到第0 层内核栈,开始执行处理程序代码,此时有一个更高级别的中断发生,那么系统切换到第1 层内核栈,.... 系统切换到第n 层内 核栈,如果采用硬件屏蔽中断的方式,那么第n 层以及第n 层以下对应级别的中断根本就不会发生了,如果不是硬件屏蔽,那么可能还会发生,只不过不会执行中断 处理代码,而只是将低优先级的中断pending ,等到以后中断级别降低后再延迟执行,和linux 软中断类似,只不过unix 对待中断的方式更加统一 了,每个中断级别对应一个栈;
2.NT 的方式:
在NT 内核,系统定义了irql 的概念,和unix 的类似,只是没有分层的内核栈,中断完全借用当前线程的内核栈,因此nt 的中断都是在任意上下文执行 的,unix 是同步的,意思是说虽然用了中断级别的概念,但是也就对“ 真正” 的中断有用,而nt 将很多可能的操作都往irql 框架填,以“ 假” 中断-- 软 中断的方式执行。某种意义上,nt 也是和unix 一样以一种统一的方式处理中断,不同的是unix 对待当前进程和中断的方式更加仁慈,多层内核栈保证了一 切,nt 就不那么仁慈了,直接借用了当前进程的内核栈,造成中断和当前进程鱼龙混杂的局面;
3.Linux 的方式:
Linux 的方式对于高手是轻松的,对于思维僵化的人是沉重的,它的实现相当灵活,毅然抛弃了硬件都建议的中断优先级的概念,从而也就抛弃了处理器中断级 别的概念,所有中断一视同仁,完全可嵌套;另外linux 没有那么多所谓的“ 层次” ,效率绝对有优势,对于中断上下文,和nt 一样,借用当前进程上下文, 采用硬件中断发布软中断的方式,这个也和nt 一样,但是却没有出现混乱,linux 内核尽量减少硬件中断处理时间,而且也不过分执行软中断,过多的软中断 在ksoftirqd 的进程上下文执行,它有自己的内核栈。你不能说linux 没有内核栈是它的弱点,linux 内核是高度可配置的,linux 内核也可 以配置独立的内核中断栈,反正不管你怎么说,linux 都是可以做到unix 或nt 能做到的事情,linux 内核是典型的“ 两面三刀” ,呵呵,不过我喜 欢。
谈完上面的三点,我想linux 为何另类的原因就不用多说了,linux 没有规则,没有规则就是灵活,而且总是毫不留情的抛弃硬件的建议,按照自己的方式 进行处理,其强大的内核机制保证不会发生混乱,而强大的内核机制竟然出自一个个小巧的数据结构,其一眼望去不是那么华丽,但是却是深不可测,毫无定法。
说linux 不规则,仅仅从系统结构的角度来说,它处理问题的方式却比unix 和windows 更规则,比如对于陷入内核的进程,和没有陷入的一样接受同 样的调度,linux 只是简单的区分交互进程来使得睡眠过久的进程提升优先级而不会像unix 的sysyem v 那样将唤醒优先级和睡眠原因硬性联系起来也不会像nt 那样规定不允许这也不允许那。
综上,如果你仅读过linux ,那么你会想当然认为所有内核都那样,有这种想法的原因就在于linux 内核设计原则就是按照现实世界的原则设计的,它的开 发人员极端复杂,本来就是三教九流,就难怪内核的两面三刀了。别的内核可能就不是那么“ 现实” 了,它们都是为了开发“ 内核” 而开发内核的,和现实的联系没 有linux 内核那么大,开发过程很规则,要经过总体构思和设计。这个世界,只要经过组织全盘设计过的东西,十有八九没有独侠的东西更具杀伤力,看过金庸 的小说吗?里面那个武林高手是属于军队的!?招无定法才是武林至尊,不要看外表多华丽,不要看内在多合逻辑,那还看什么,什么也不要看,只要默默品味就可 以了。