LKD 3rd 读书笔记——第1章/Linux Versus Classic Unix Kernels

Linux Versus Classic Unic Kernels

由于具有共同的祖先和相同的API,现代的Unix内核有很多共同的设计特点。没有任何意外,Unix通常是一个完整的、静态的二进制文件(聚内核)。这是指,它是一个运行在单个地址空间的单独的大的可执行镜像文件。Unix系统通过需要可分页的内存管理单元(MMU),这个硬件帮助系统加强内存保护并向每个进程提供单独虚拟地址空间。Linux历史上也需要MMU,但特殊的版本也可以运行在没有MMU的硬件环境上。这是一个巧妙的特性,允许Linux运行在没有MMU的小巧的嵌入式设备上,当然这是一个偏学术而不太实用的特性——因为在今天即使是简单的嵌入式系统也通常拥有高级的特性例如MMU。在本书里,我们聚焦在基于MMU的系统上。

聚内核与微内核
可以把内核分为主要的两个类别:聚内核与微内核(还有第三类,外核,主要存在于研究领域)。聚内核比其它两类的设计更简单,在1980之前所有内核都采用聚内核的方式。聚内核被实现为运行在单一的地址空间里的单一的进程。因此,这种内核通常以一个静态的二进制文件保存在磁盘中。所以内核的服务都存在并执行于一个大的内核地址空间里。在内核的内部进行通信显得直接了当,因为所有运行在内核态的代码都在相同的地址空间里:内核可以直接调用函数,就像用户空间的应用程序一样。这个模型的支持者们以聚内核的简洁和性能为理由。多大数Unix系统都采用聚内核的设计方法。

微内核则不是实现为单个的大的进程。而是把内核的功能分解成不同的进程,通常把这些进程称为服务。理想情况,只有在必要的时候服务才运行在特权模式下。其他服务都运行在用户空间里。所有这些服务,都被分解到不同的地址空间里,因此,像聚内核那样的直接的函数调用不再可能(指在多个服务间进行通信时)。替代地,微内核的通信通过消息传递:一套进程间通信(IPC)的机制被内嵌到系统中,各种服务通过在IPC之上发送消息来相互调用彼此的服务。把各种服务的分离可以防止一个服务的失败引起其他服务的失败。同样的,这种模块化的系统允许一个服务替换掉另一个服务。

由于IPC的机制会导致比平常的函数调用更多一些的开销,此外,它还包含在内核空间与用户空间之间进行上下文切换的开销,同时消息传递也会有一些延迟,所以微内核的吞吐量似乎不如采用简洁函数调用的聚内核。因此,所有实用的基于微内核的系统,现在都把大多数或所有服务放在内核空间,以避免频繁的上下文切换带来的开销,并潜在的支持直接的函数调用。Windows NT内核(被用于Windows XP,Vista,7)和Mach(被用于部分Mac OS X)就是微内核的例子。最新版的Windows NT和Mac OS X都不会在用户空间运行微内核的服务,它们都背离了微内核的设计初衷。

Linux属于聚内核,也就是说,整个Linux内核运行在内核态的单一的地址空间里。然而,Linux也从微内核中借鉴了很多好的想法:Linux推崇模块化的设计、可以抢点它自己(称为抢占式内核)、支持内核线程、可以动态加载二进制文件(内核模块)到内核镜像中。因此,Linux没有任何一个微内核设计带来的性能损耗:内核的代码都运行在内核态、直接的函数调用、没有消息传递的通信模式。虽然如此,Linux是模块化的、线程的、并且它自己是可调度的。实用主义再一次胜利。

 

随着Linus和其它开发者贡献到Linux内核,他们考虑如何更好的发展Linux而又不会疏忽掉它的Unix特性(更重要的是,Unix API)。因此,由于Linux不基于任何Unix变种,Linus和其他公司可以选择最好的解决方案来处理Unix面对的问题——或偶尔,发明新的解决方案。少量显著的差异存在于Linux和传统的Unix系统中:

1、Linux支持动态加载Linux模块。尽管Linux是聚内核,它可以按需动态地加载或卸载模块。
2、Linux支持对称多处理器(SMP)。尽管大多数商业版的Unix变种已经支持SMP,大多数传统的Unix实现是不支持的。
3、Linux内核是抢占式的。与传统Unix变种不一样,Linux内核可以抢占一个任务,即使这个任务正在执行。在其他的商业版Unix实现中,Solaris和IRIX是抢占式,其他大多数都不是。
4、Linux采用了有趣的方式支持线程:它并不区分线程和普通进程。对Linux内核而言,线程和进程都一样的——线程只是共享资源的进程。
5、Linux提供面向对象的设备模型。包括:设备类别、热插拨的事件、以及一个用户空间的设备系统(sysfs)。
6、Linux忽略某些通用的内核开发者们认为不良设计的Unix特性。例如STREAMS,或无法简洁地实现的标准。
7、Linux在任何意义上都是免费的。这个特性使Linux的实现成为Linux开放开发模型的自由运动的必然结果。如果一个特性没有价值或没有考虑透彻,Linux开发者们没有义务去实现它。相反地,Linux在面对变化时,采用一种先进的理念:修改必须解决一个特定的现实问题、来源于一个简洁的设计,并且有稳健的实现。因此,在其他现代Unix变种中,某些只是为了制造销售的噱头或是针对某个单一的需求而开发的一些特性,如可分页的内核内存,Linux是不会考虑的。

 

尽管有这些差异,Linux还是保持了很强的Unix特质。

展开阅读全文

没有更多推荐了,返回首页