Linux内核印象

来源:互联网 发布:为什么4g网络很慢 编辑:程序博客网 时间:2024/05/16 08:53

第一次写了个Linux 内核模块。感觉Linux内核的设计确实是高度模块化,非常精巧的东东。现在写写对它的初步印象。

   模块化程度极高。整个内核就像一个巨大的linker(链接器),当它碰到模块没有被解释的符号的时候,居然能像链接器那样尝试解释它。这个特点极大的方便了程序员编写代码。因为你不需要链接任何的库文件(.lib)。相比Windows的WDM来说,这是一个非常大的优势。WDM你必须知道你要链接哪些库文件。甚至,你不需要有头文件。你假如知道函数签名是什么,你直接就可以使用这个函数。当然,也有少许坏处,就是假如内核没办法解释你的符号的时候,你的模块就不能使用了。

    方便的Build系统。这简直没得说,除了Qt的build系统还是我用过最人性化的build系统外,就数这个内核的Build系统了。三行不到就能描述完你对该模块的build需求,实在简洁。相比下,WDM需要内容比较多,而且还要留神库文件,实在难用。

   合理的设计。在Linux内核模块具有初始化和结束两个函数,这两个函数是必须的。相似的,WDM也有这两个函数,是驱动被读入内核和被unload的时候用的,不过unload的函数貌似需要显式的在读入函数(记得是Driver_Load指出,一不小心忘了这驱动就能导致资源泄漏,试问那个真正的内核程序不需要在unload的时候释放资源的?

   还有,WDM最匪夷所思的地方在于把控制设备的函数付给Driver对象。我越想越觉得微软那帮家伙摔到了……这么不符合面向对象的做法你怎么弄出来的??控制Device的函数就只应该赋给Device对象嘛!有哪个设计方案,哪种面向对象的语言,哪种约定是把和一个对象有关的函数赋给别的对象的?这种做法也不符合人的思维习惯。WDM这个设计实在是败笔。

    相反,Linux的确是把与某个设备有关的函数赋予设备对象的。比如char dev的初始化函数cdev_init。这里面的另一个好处就是可以方便的替换对设备的文件操作,比如在open一个设备的时候,你发现它是用于控制 设备的文件,而不是用于读写 设备的文件。你可以马上把设备的文件操作由初始化时候赋予的读写操作改为控制操作。这里面有什么好处呢?像WDM那样,就必须每次在IOControl这个Routine里面检查设备是用于读写还是用于控制,这就可能导致较低的性能。

  内存管理。这个方面我还没有深入的了解。但是由kmalloc函数签名看来,Linux分配给内核的内存似乎都是未分页的(None-Paged)。因为它没有考虑过中断的问题,貌似在哪个IRQL里面都使用它分配回来的内存。假如内存是可以分页的,那么必须考虑中断问题。因为在很高的IRQL下面,操作系统的分页机制是无效的,在这时候假如发现内存处于页出状态,哈哈,恭喜,蓝屏马上伺候你来啦。假如没有别的方法分配内存(我相信应该没有,因为我浏览了那么多源代码都是kmalloc或者vmalloc的,而vmalloc又调用kmalloc,以GFP_KERNEL为flag),那么Linux内核分配的内存应该都是未分页的。这和Windows比,对程序员来说,那是很方便的。因为程序员不需要考虑IRQL。但是对于操作系统来说,这可能会导致差劲的内核内存管理。因为内核分配的内存都不能页出(pageout)的话,会导致某些不常用的设备长期占用真正的内存,导致系统能利用的内存减少。实际Linux使用内存的情况如何呢?呃……用过的人都知道,开机的时候才用200多M,上升缓慢,1G的内存需要打开无数个firefox网页才能用耗尽。而Windows呢?呵呵,这就不敢恭维了。我觉得一方面这是由于Linux总体上的内存管理出色,所谓小瑕不能掩大瑜;另一方面,这是由于Linux的高度模块化。长期不用的模块可以从内核中去除所致。内存管理方面我还是没有透彻的理解,等我学到家再来看看今天说的话对了几成。

    至于编程的风格,大部分代码可以说是面向对象的(呃……别以为c语言不是一门面向对象的语言就没办法面向对象了);但是,还是有许多代码是直接修改数据的,这样做确实很不好,因为要程序员记熟内核的数据,确实很高难度。WDM这方面的代码就少一些。

    今天就说到这里吧。这只是初步的印象,透彻的理解陆续有来。

原创粉丝点击