📄 linux 2.6 内核的精彩世界.doc
字号:
系统的设计上有着许多和对应单处理器系统类似的局限性。其中最大的设计局限之一就是系统中只有唯一的一块内存区,所有的处理器对它都平等地对它进行访问。在多处理器系统里,这样会在同一条内存总线上的多处理器之间引起相当高的竞争,导致性能瓶颈。NUMA
服务器,通过引入了以下的理念解决了这个问题:对于某个特定的处理器,一些内存比其他一些的更为接近(close)。可以这样简单地设想(同时技术上也不会有严重错误),你的系统有许多包含了处理器、内存以及其他元件(比如
I/O 扩展卡)。系统中有很多这样的卡,它们可以相互通讯;显而易见,相对其他卡上的内存,每块卡上的处理器能更快的访问本地内存(自己的卡上内存)。从许多角度上看,NUMA
体系结构就是一个紧密耦合的集群特例。 <br>
<br>
为了给 NUMA 主机提供良好的支持,Linux 十分必要在许多方面进行调整,以使新模型更具效率。首先,建立了一个内部拓扑 API,以使内核知道处理器和内存以及其他
IO 设备间的相互关系。有了内部拓扑 API 的支持,Linux 的进程调度器可以理解这些关系,并且会尝试优化任务以达到最佳的本地资源使用。此外,许多
NUMA 主机在各个节点(nodes)的线性内存区域之间存在空洞(holes)。新内核已经能够合理的处理这种不连续情况。内核还有许多其他使得
Linux 可以支持高端(high-end)主机的变化,这也是内核发展的一个明确方向。再过一年,我们可以期待 Linux 在高端机型上效率以及其他方面的进步。
<br>
<br>
深入 Linux <br>
除了横向支持越来越多的硬件,Linux 2.6 还在已支持的平台上根据硬件的性能提升进行了改进。这些针对特定 CPU 的优化包括:Transmeta 的
Crusoe 系列,Intel's Pentium 4 Xeon、Pentium 3-M、Pentium 4-M 和 AMD 移动处理器。新版本
Linux 还解决了某些 Athlon 处理器自身的 bug 导致的问题。 Linux 2.6 还解决了在某些多于 16 个处理器的系统启动时偶尔会挂起的问题,尽管这个
bug 不会影响大多数用户的正常使用。 <br>
<br>
超线程 <br>
<br>
在 Linux 2.6中不算新鲜,内核在 2.4.17 发布中就已经开始包含对 Intel P4 处理器的超线程(Hyperthreading)的支持(在这里提及它,一是因为它并没有包含在
2.4 最初的发布中,二是自那以后内核又有了很大的改变)。超线程使得单个的处理器可以伪装成操作系统看来二个或更多的多个处理器。最令人激动的是,Linux
是第一个把超线程特性引入市场的操作系统,尽管早在一年前 Intel 就发布了兼容的处理器。有传闻说,微软在对支持超线程的 CPU 按一个 CPU 还是按两个
CPU 收取授权费(license)的问题上拿不定主意。Linux 的开放模型(以及没有基于 cpu 的授权)使得 Linux 操作系统第一个支持这个新特性。显然,一个处理器就算扮作两个处理器工作,它还是一个处理器,性能并不能因此增加很多。2.5
中调度器和其他一些部分在有了新的优化,使得处理器的超线程可以真正的发挥作用。如果是在 2.4 下加入超线程支持,结果就不一定了,有时性能还会下降。 <br>
<br>
容量 -- 可扩展性的进展 <br>
<br>
除了对 NUMA 的支持,Linux 2.6 在处于食物链顶端的 Intel 服务器方面,也有一些变动。最重要的就是对 Intel 的物理地址扩展(PAE)的完全支持,使得较新的
32 位的 x86 系统可以访问高达 64 GB 的内存,但仅仅限于页面映射模式。另外,通过加强对高级可编程中断控制器(APIC)的支持,多处理器系统之上的
IRQ 均衡(balancing)大大提升。 <br>
<br>
在许多其他方面,内部限制在可能的地方都有所放松。Linux 系统上用户和用户组的数目从 65000 越升到了超过 40 亿(实际就是 16 位到 32
位的变化)。这使得 Linux 在之前可能超越限制的大型文件和认证服务器上更加实用。类似的,进程标识号(PID)的数目也从 32000 升到 10 亿。这个改变,与其他
PID 子系统优化一起,将提高在十分繁忙或是长期工作的系统上的应用程序的启动性能。尽管同时打开的文件最大数目并没有增加,但是 Linux 2.6 不会再要求你预先设定限制值;限制值会随着系统的运行自动调整。最后,Linux
2.6 包含了改进的 64 位的块设备支持(当然块设备本身应当支持 64 位模式),即使是在 i386 这样的 32 位平台。这样一来,文件系统的存储上限可达
2 TB。 <br>
<br>
内核互动性以及响应性 <br>
<br>
Linux 2.6 中一个受关注的焦点就是使得系统对于桌面用户以及其他一些需要对事件进行高度人为控制的应用具有更具响应性(responsitive)。这其中各个不同的目标系统具有很不同的挑战,但内核中包含了很多改变,使得它们同时受益。
<br>
<br>
2.6 中一个必须理解的主要内部改变是现在内核自身是可抢占的。在所有之前的 Linux 版本中,当系统运行内核的相关事务时,它不能被打断(在多处理器系统中,基于各
cpu 的角度这也是成立的)。Linux 2.6 中,内核现在允许自身在执行任务时被打断,这样用户任务可以继续运行即使内核正在做一些复杂的事情。(为了避免明显这可能带来的竞争情况,内核中含有一些具有锁的代码段,运行于这样的代码段的时候,内核不能被打断。)这个改变的主要好处是系统的可交互性(比如,对于桌面用户)大大提升,系统对于用户输入这样的事件感觉起来快多了。
<br>
<br>
其他使得 Linux 成为一个更加具有响应性系统的改变是并入对新的 "futexes"("Fast User-Space
Mutexes")的支持,这项支持发挥作用需要用户程序的支持(使用 futex 实现互斥)。Futexes 是一种序列化(serialize)事件使得它们不会相互冲突的机制。与传统的多数的线程库锁支持的
mutex 操作不同,这是部分基于内核的(partially kernel based),同时它也支持设置优先级使得高优先级的应用或线程优先获得竞争的资源。通过使用一个程序去指定一个等待的任务比其他的更重要,它带来了可能是一个应用的时序--关键区域更佳的响应性。
<br>
<br>
Linux 的 I/O 子系统也经历的很大的修改,使得它在各种工作负荷下都更具响应性。这个变化包括 I/O 调度子系统--决定何时、哪一进程去读一个设备的内核代码的完全重写。重写的
I/O 层现在可以更好地保证没有进程过长时间地停留在 I/O 等待上,同时不排斥以前的优化工作使得读等请求以最有效的次序操作硬件的优化工作。 <br>
<br>
尽管实时操作系统(RTOS)的开发者可以从这些改变中受益,Linux 2.6 将不会成为一个实时内核。然而,这些以及其他相关的背景工作使得将
Linux 转变为 RTOS 成为可能。为用户或开发者提供这样的支持的外部 patch(尚未合并到官方的内核版本)已经出现了。 <br>
<br>
模块子系统 - 设备驱动程序 <br>
<br>
在 Linux 2.6 的开发历程中,模块子系统是另一有重大改进的部分。许多代码被重写,以提高稳定性,并使系统更加透明。除了这些明显的表层的变化之外,还有更多背后的内核如何看待以及使用模块的改变。
<br>
<br>
首先,Linux 2.6 中内核驱动程序最显而易见的(虽然并没有太大作用)的变化是文件扩展名改变了。".ko"(kernel
object,内核目标文件)取代了 ".o"(这是一目标文件的常见扩展名,通常在程序编译期间,链接生成可执行应用程序之前创建)。与其说这使得模块并不是真正的中间文件这一点更为清楚,还不如说这仅仅是一个装饰性(cosmetic)的改动。
<br>
<br>
完完全全实质性的改进在于消除存在于很多内核版本中的竞态的多方面工作。问题的关键在于,如果卸载发生在模块检查并确认没有其它的设备正在使用它之后,使用一个正在被卸载的模块来启动设备是有可能的。新的内核模块代码应使得这一条件更难被触发。更进一步,现在简单地完全禁止模块卸载也是有可能的。
<br>
<br>
更加透明是新的模块子系统另一特性。在此之前,几乎所有的 Linux 版本中,模块是足够智能的,它们可以通过扫描总线寻找它识别(recognized)的设备ID号,检测到它所能够支持的设备(比如
PCI,ISA PnP 以及 PC 卡)。 Linux 2.6 标准化了这种支持,使之对内核来说外部化,外部程序以及模块加载器判断一个特定的模块可以支持哪些设备将更为容易。这将允许各种硬件管理程序(比如
Redhat 的 kudzu)对硬件作出智能化的判断,即使他们本身对自己所处理的硬件设备并不熟悉。如果你的知识超越了当前版本的驱动程序,你可以(通过新的
sys 文件系统中的一个接口)强制一个驱动程序工作于某一特定的设备,即使驱动程序并不知道自己可以支持该设备。 <br>
<br>
其他改进 <br>
<br>
除了上述的许多改变之外,还有很多其他可以提升系统性能的普遍性的改变。这其中包括更多的去除了 "Big kernel Lock"(早期
Linux 用于支持 SMP 系统时所采用的非细粒度锁),以及针对文件系统预读、回写和小文件操作的优化等。 <br>
<br>
Linux 2.6还解决了一个更为深刻的稳定性问题:内核将不会分配多于系统中 RAM(加 swap)数量的内存。此前, Linux 在一些即使系统内存耗尽的情况下,仍然允许
malloc 操作分配内存成功。过量分配(overcommitment)逻辑得到修改,使得这种情况现在不再可能出现。(当然,如果你耗尽了系统的RAM,即使没有超越最大可用数量--你需要担心更更严重的问题。)
<br>
<br>
Linux 总是一个开放标准的支持者。内核内部的大改变之一就是 Linux 的线程框架被重写,以使 NPTL(Native POSIX Thread
Library)可以运行于其上。对于运行负荷繁重的线程应用的 Pentium Pro 以及更先进的处理器而言,这是一个主要的性能提升;它也是企业级应用中的很多高端系统一直以来所期待的。(实际上,RedHat
已经将它向后移植到了 Linux 2.4,从 RedHat 9.0 中开始包含)线程框架的改变包含 Linux 线程空间中的许多新的概念,包括线程组、线程各自的本地存储区、POSIX
风格信号以及其他改变。主要的缺点之一是依赖于老式的 Linux -isms 而没有遵循 POSIX 标准的应用程序(比如 Sun Java)将不能运行在支持新式线程的系统之上。鉴于使用新的线程模型利远大于弊,很明显,新的内核发布不久,最为重要的那些应用都将会支持这个改变。
<br>
<br>
最后,2.6 可以支持编译时关闭内核对存储交换(swap)的支持,尽管对于绝大多数 Linux 之上的应用而言,没有直接的益处。这使得 Linux 可以在相对小的内存足迹(footprint)内运行,对于不大可能使用交换设备的嵌入式系统可能也是有益的。
<br>
<br>
统一设备模型 <br>
作为操作系统中的一个相对独立的组件,设备模型对于那些被设计运行于用于多种硬件之上的操作系统而言是至关重要的。简单地说,设备模型是内核中的基础设施,用于检测和决定系统中所有可选模块的资源使用。所有的操作系统(包括各版本的
Linux )都固有一些设备的概念。老版本的 Linux (2.2 或更早)仅使用一种直接的方法操作设备。系统为不同种类的硬件总线提供驱动程序,各式各样的设备驱动程序知道如何探测它们所支持的设备总线以寻找对应的硬件设备。这种系统非常分散,各种各样的总线提供许多互不兼容的
API,用于处理各种不同的操作。 Linux 2.4 通过使用一组通用接口将 PCI,PC卡以及 ISA PnP 整合到一个单一的设备结构中,完成了构建统一设备模型的第一步。
Linux 2.6 更进一步地推进了这方面的努力,力求在整个系统的范围内,内核以一种新的统一的视角看待它所依赖的硬件。 <br>
<br>
内核对象抽象 <br>
<br>
新设备模型基础的核心是一个所有底层设备类型都需使用的新的面向对象的接口。这个内核设备对象结构(称为 "kobject")包含用于引用计数和操作子设备的所有接口。底层设备(例如系统总线)利用这一公共接口层,向内核以及用户空间提供统一的系统视图。现在,所有这些都被放在了中心位置,这使得
Linux 可以使用这些信息作许多有用的事。 <br>
<br>
在内核中完整地保存这些新的信息,使得 Linux 可以更好的支持那些需要有深入的硬件知识的系统。一个明显的例子就是电源管理。近几年新出现的电源管理标准是
ACPI。ACPI,即高级电源配置管理界面,最早是在 Linux 2.4 中有支持。不同于 APM(高级电源管理),拥有这种接口的系统在改变电源状态时需要分别通知每一个兼容的设备。新的内核系统允许子系统跟踪需要进行电源状态转换的设备。另一个例子是支持热插拔的总线。机器启动后依然可以添加设备的能力在现在看来显得很普通,但
Linux 直到 2.2 版本才提供相关支持。到了 Linux 2.4,这种支持得到进一步的加强,范围也扩大到可热插拔的PCI、PC卡、USB 以及
Firewire 设备。通过从根本上消除热插拔设备和传统设备的差异,新内核的集中化设备系统扩展了这一支持。当你启动计算机的时候,设备检测例程将"插入"系统中的设备。无论在系统启动时,或是启动以后,系统发现系统中的某个设备时,都会相应创建一个相同的内核对象,这就使得处理可插拔设备的底层结构简单化了。
<br>
<br>
sys 文件系统 <br>
<br>
最明显的用户可见的改变可能是新的 sysfs 文件系统的出现,它集成了下面 3 种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的
devfs 文件系统以及针对伪终端的 devpts 文件系统。该文件系统(安装在 /sys 目录)是核心看到的设备树的一个直观反映。核心通过紧密合作的核心对象(kernel
object)子系统来建立这个信息:当一个核心对象被创建的时候,对应的文件和目录也被创建。(必要的话,也有可能一个核心对象被创建的时候并不在
sysfs 文件系统中有记录。) <br>
<br>
既然每个设备(或者说内核对象)在sysfs中都有唯一对应的目录结构,那么下一步可以把设备的属性(设备名,电源模式,中断处理等)信息输出到这个目录树中以供系统管理员读写。相应的,很多跟设备相关的/proc/sys的用法已经或者将要移到/sys目录下。
<br>
<br>
核心硬件支持 <br>
随着 Linux 的这些年的发展并逐步进入主流行列,从内核所支持的设备类型来看,每一次的内核发布,都像是一次跳跃:支持新兴的技术(2.4 的 USB),支持古老一些的传统技术(2.2
的 MCA)。发展到 Linux 2.6,不被 Linux 支持的设备已经相当少了。PC 机上的主流硬件没被支持的很少。正是由于这个原因,多数(显然不是所有)关于硬件支持方面的改进(包括上面所说的设备模型)围绕对已有支持的加强。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -