Linux内核的普及
Linux内核(英语:Linux kernel),是Linux操作系统的内核,以C语言写成,符合POSIX标准,以GNU通用公共许可证发布。Linux最早是由芬兰黑客林纳斯·托瓦兹为尝试在英特尔x86架构上提供自由免费的类Unix系统而开发的。该计划开始于1991年,林纳斯·托瓦兹当时在Usenet新闻组comp.os.minix登载帖子[7],这份著名的帖子标示着Linux计划的正式开始。
在计划的早期有一些Minix黑客提供了协助,而今天全球无数程序员正在为该计划无偿提供帮助。
技术上说Linux是一个内核。“内核”指的是一个提供硬件抽象层、磁盘及文件系统控制、多任务等功能的系统软件。一个内核不是一套完整的操作系统。一套基于Linux内核的完整操作系统叫作Linux操作系统,或是GNU/Linux。
Linux内核是在GNU通用公共许可证第2版之下发布的[4](加上一些固件与各种非自由许可证)。贡献者遍布世界各地,日常开发在Linux内核邮件列表。
许可证
原先托瓦兹将Linux置于一个禁止任何商业行为的条例之下,但之后改用GNU通用公共许可证第二版。该协议允许任何人对软件进行修改或发行,包括商业行为,只要其遵守该协议,所有基于Linux的软件也必须以该协议的形式发表,并提供源代码。
托瓦兹曾经公开声称将Linux置于GNU通用公共许可证之下是他一生中所做的“最好的决定”。
固件争议
许可证争议的一个重点是Linux使用固件二进制包以支持某些硬件设备。理察·马修·斯托曼认为这些东西让Linux某部份成为非自由软件,甚至以此散布Linux更会破坏GPL,因为GPL需要完全可获取的源代码[8]。
林纳斯·托瓦兹及Linux社区中的领导者,支持较宽松的许可证,不支持理察·马修·斯托曼的立场。社区中的Linux-libre提供完整的自由软件固件。
GPL第三版
目前Linux使用的版本为GPL 2,2007年,自由软件基金会发布了GPL 3。而目前存在一些争议,讨论如何让Linux较容易地转成使用后继版本的GPL,例如第三版(无论是否真的会这样做)[9]。
2006年1月16日,GPL 3许可证第一版草案发布。托瓦兹随后宣布不会让Linux内核转换到使用GPL 3许可证[10]。托瓦兹本人认为他自己写在版本2.4.0的代码仅使用版本2的GPL[11]。然而GPL这个词并没有明述到底它指的是哪个版本,任何版本都有可能,而艾伦·考克斯指出很多Linux包有特别指出它们使用哪种版本的GPL[12]。
加载式核心模块许可证
另一个争论点,就是加载式核心模块是否算是知识产权下的派生创作,意即LKM是否也受GPL约束?托瓦兹本人相信LKM仅用一部分“公开”的核心接口,因此不算派生创作,因此允许一些仅有二进制包裹的驱动程序或不以GPL声明的驱动程序用于核心。但也不是每个人都如此同意,且托瓦兹也同意很多LKM的确是纯粹的派生创作,也写下“基本上,核心模块是派生创作”这样的句子。另一方面托瓦兹也说过:
有时候一些驱动程序原先并非为 Linux 设计,而是为其他操作系统而作(意即并非为 Linux 作的派生创作),这是个灰色地带……这“的确”是个灰色地带,而我个人相信一些模块可视为非 Linux 派生创作,是针对 Linux 设计,也因此不会遵守 Linux 订下的行为准则。[13]
特别像绘图卡驱动程序就有非常大的争议,也许到最后得由立法机关给个答案。
SCO争议
在2003年3月,SCO Group对IBM提告,声称IBM将一些在SCO知识产权许可证保护下的Unix源代码植入Linux中,破坏了SCO给予IBM的源代码使用权限。另外SCO也发出一大堆存证函给许多公司,警告他们在没有SCO权限的情况下使用了Linux,此举可能导致侵犯知识产权,并且以起诉为手段对个别用户施压。SCO也同时对Novell、戴姆勒克莱斯勒(DaimlerChrysler)(在2004年7月被部份驳回)以及AutoZone提出告诉,且被Red Hat与其他反对SCO论点的公司反告。
技术特性
架构
Linux是一个宏内核,设备驱动程序可以完全访问硬件。Linux内的设备驱动程序可以方便地以模块化(modularize)的形式设置,并在系统运行期间可直接装载或卸载。
塔能鲍姆-林纳斯辩论
Linux不是微内核架构的事实曾经引起了林纳斯·托瓦兹与安德鲁·斯图尔特·塔能鲍姆之间一场著名的争论。1992年在Usenet讨论组群comp.os.minix[14]开始了一场网络论战,讨论的主题在于操作系统架构的选择。稍后一些著名的黑客也加入讨论,如大卫·米勒、曹子德。这场辩论影响了Linux核心的设计走向。塔能鲍姆认为Linux内核采用的宏内核已经过时了,应该采取比较先进的微内核架构,引起了林纳斯的反击。
在2006年5月9日,这个主题被重新审视[15],并且在2006年5月12日塔能鲍姆写了一份立场声明。
抢占式调度系统
每个任务赋予唯一的一个优先级(有些操作系统可以动态地改变任务的优先级);
假如有几个任务同时处于就绪状态,优先级最高的那个将被运行;
只要有一个优先级更高的任务就绪,它就可以中断当前优先级较低的任务的执行;
可移植性
尽管林纳斯·托瓦兹的初衷不是使Linux成为一个可移植的操作系统,今天的Linux却是全球被最广泛移植的操作系统内核。从移动电话到超级电脑,甚至于有人成功的将Linux内核在索尼出品的游戏机PS2及PS3和微软出品的游戏机Xbox上使用。Linux也是IBM超级计算机Blue Gene的操作系统。直至2011年11月,全球前五百大超级电脑(TOP500)有高达91.4%的比例采用Linux为它们的操作系统。一些为手机开发的操作系统,使用Linux内核的修改后的版本,其中包括谷歌Android、Firefox OS、HP WebOS和诺基亚Maemo。
内核错误
Linux中,内核错误(Kernel panic)是指操作系统在监测到内核系统内部无法恢复的错误,相对于在用户空间代码类似的错误。操作系统试图读写无效或不允许的内存地址是导致内核错误的一个常见原因。内核错误也有可能在遇到硬件错误或操作系统BUG时发生。在许多情况中,操作系统可以在内存访问违例发生时继续运行。然而,系统处于不稳定状态时,操作系统通常会停止工作以避免造成破坏安全和数据损坏的风险,并提供错误的诊断信息。
内核oops
在Linux上,oops即Linux内核的行为不正确,并产生了一份相关的错误日志。许多类型的oops会导致内核错误,即令系统立即停止工作,但部分oops也允许继续操作,作为与稳定性的妥协。这个概念只代表一个简单的错误。
当内核检测到问题时,它会打印一个oops信息然后杀死全部相关进程。oops信息可以帮助Linux内核工程师调试,检测oops出现的条件,并修复导致oops的程序错误。
Linux官方内核文档中提到的oops信息被放在内核源代码Documentation/oops-tracing.txt中[21]。通常klogd是用来将oops信息从内核缓存中提取出来的,然而,在某些系统上,例如最近的Debian发行版中,rsyslogd代替了klogd,因此,缺少klogd进程并不能说明log文件中缺少oops信息的原因。
若系统遇到了oops,一些内部资源可能不再可用。即使系统看起来工作正常,非预期的副作用可能导致活动进程被终止。内核oops常常导致内核错误,若系统试图使用被禁用的资源。
Kerneloops提到了一种用于收集和提交oops到 http://www.kerneloops.org/ 的软件[22] 。Kerneloops.org同时也提供oops的统计信息。
编写语言
Linux是用C语言中的GCC版(这种C语言有对标准C进行扩展)写的,还有几个用汇编语言(用的是GCC的”AT&T 风格”)写的目标构架短段。 因为要支持扩展的C语言,GCC在很长的时间里是唯一一个能正确编译Linux的编译器。在2004年,Intel主张通过修改内核,以便它的编译器能正确编译内核。[24]在2009年,有通过修改内核2.6.22版而成功编译的报告(并带来平均8-9%性能增长)。[25][26] 有许多其他的语言用在一些方面上,主要集中在内核构建过程中(这里指从源代码创建可启动镜像)。包括Perl,Python,和多种脚本语言。有一些驱动可能是用C++,Fortran,或其他语言写的,但是这样是强烈不建议的。 Linux的官方构建系统仅仅支持GCC作为其内核和驱动的编译器。
重新开发的估价
按照传统商业软件开发的方式,重新开发Linux 2.6.0内核的估计代价将是 6.12亿美元(€4.67亿欧元,£3.94亿英镑),以2004年的COCOMO人月估计模型.[27]在2006,欧盟资助的一项研究表明,重新开发Linux2.6.8以后的内核,代价是€8.82亿欧元( 6.12 亿 美 元 ( € 4.67 亿 欧 元 , £ 3.94 亿 英 镑 ) , 以 2004 年 的 C O C O M O 人 月 估 计 模 型 . [ 27 ] 在 2006 , 欧 盟 资 助 的 一 项 研 究 表 明 , 重 新 开 发 L i n u x 2.6.8 以 后 的 内 核 , 代 价 是 € 8.82 亿 欧 元 ( 11.4 亿美元, £7.44 亿英镑).[28]
截至2011年1月4日,使用当前的代码行(LOC)和大卫·惠勒的计算工资数,这将花费约30亿美元(约22亿欧元),才能够重新开发的Linux内核。
安全
计算机安全是一个非常公众化的主题,关系到Linux内核,因为大量在内核中的错误可能成为潜在的安全漏洞,是否允许提升权限漏洞或拒绝服务攻击源漏洞。[30]在过去的几年中,许多这样的缺陷被发现,并在Linux内核中被修补好。新的安全功能被继续实现,以解决在Linux内核中的电脑不安全问题。[31][32]
批评者指责内核开发人员,称他们掩盖(至少并未公布)安全漏洞。2008年,作为回应,Torvalds称:“个人认为,安全漏洞只是‘正常的漏洞’。这些漏洞我并不去掩盖,不过我不认为应当把它们特殊化,更不认为应该追踪并公示它们……我不理会整个安全团队,原因之一就是,我认为这些漏洞不仅美化还鼓励了错误的行为。这令安全人员成了‘英雄’,就犹如不修补正常漏洞的人就不值一提似的。而事实上,所有无聊的正常漏洞极为重要,仅仅因为它们实在太多了。我不认为该美化和关心那些严重的安全漏洞——它们并不及那些由死锁造成的随机严重崩溃来得更特殊。”[33][34]
如2012年五月,SYSRET指令被发现在AMD和英特尔处理器间在实现方面有差异,这个差异在Windows、FreeBSD、XenServer和Solaris这些主流操作系统会导致漏洞。2012年六月,Linux核心中该问题已被修复。
开发
开发模式
Linux内核目前的开发模式是Linus Torvalds制作的新版本的发布,也被称为“vanilla”或“mainline”的内核,这意味着它们包含了主要的,通用的开发分支。在托瓦尔兹进行初始一轮集成由所有其他程序员,几个回合的bug修正预发布版的主要变化之后,这个分支大约每3个月正式发布一个新的版本。
特性历史
1.0版本
有176,250字符串。[37]此版本的Linux内核只支持单处理器基于i386的计算机系统,可移植性成为一个问题。随后1.2版(310,950字符串)[38]支持多种计算机架构例如Alpha、SPARC、MIPS处理器。
3.0版本
托瓦兹宣布,大的变化是,“没有,绝对没有。”[39]2011年5月30日,托瓦兹宣布,“让我们确保我们真正的下一个版本不只是一个全新的闪亮的数字,而是有一个好的内核。”3.0的发布日接近Linux的20周年纪念日。
3.5版本
CoDel 队列管理算法
seccomp filters
沙盒机制
Android 风格的 自动休眠和唤醒锁机制
用户空间探测子系统 uprobes
TCP 连接修复
减少重复确认加快转发的 TCP Early Retransmit
连续性内存分配器
kcmp () 系统调用
ext4文件系统加入元数据校验和
改进 Btrfs
3.6版本
客户端TCP Fast Open实现
3.7版本
改进开源图形卡驱动程序,包括:Nvidia, Intel and Radeon.
通过 Xen hypervisor 实现对 ARM Cortex-A15 的硬件虚拟化支持
继续改进 BTRFS 文件系统
TCP Fast open
3.8版本
CPU热插拔支持;
改进ACPI电源管理;
改善XFS文件系统;
支持64位ARMv8/AArch64;
放弃支持旧的i386处理器,减少内耗复杂度;
Video 4 Linux 2驱动支持 DMA-BUF;
在某些工作负荷下减少物理内存占用;
支持微软Windows 8多重触摸协议;
音频驱动改进;
加密性能改进;
支持下一代IBM POWER8处理器(2013年发布)
XFS 文件系统的元数据完整性检查
提升了 NUMA 调度
核心内存使用审计和关联使用率限制
EXT4 文件系统的 inline data support
近乎完全支持 user namespace 等待
3.9版本
继续完善F2FS文件系统
省电功能改进
改善ARM处理器支持
音效、音频重大更新
Google Goldfish Android模拟器源代码
DRM显卡驱动改善
硬件支持改善
3.10版本
完整支持DynTicks(动态定时器),并成为内核级别的核心特性。
KVM虚拟化改进。
音频/声音驱动更新。
ARM架构支持改进,包括更好地支持64位架构。
大量的Linux加密子系统优化。
AMD电源管理改进。
分阶段驱动(Staging Drivers)改进与新举措。
BCache固态硬盘/机械硬盘缓存框架已经可用,使用两种硬盘的系统将会大大提速。
eCryptfs AES-NI性能改进,支持AES指令集的AMD/Intel x86处理器将会大大提速。
Btrfs文件系统支持skinny extent,quota也进行了一些重建。
F2FS闪存文件系统重大改进。
XFS额外保护。
DRM驱动多方面改进。
Radeon DRM驱动支持golden registers、UVD视频解码、RadeonSI tiling。
引入QXL KMS驱动。
3.11版本
支持LZ4压缩,LZ4压缩和解压缩速度快于LZO、Snappy和zlib,目前只支持ARM架构,在ARMv7 1.5GHz硬件上它的压缩速度能达到45.6MB/s,相比之下LZO 是25.2 MB/s
轻量级压缩交换缓存Zswap
例行的Btrfs和XFS文件系统bug修正和性能改进,F2FS修正了Linux 3.10中发现的一个性能退化bug,首次加入高性能并行分布式文件系统Lustre
动态电源管理支持从Radeon HD 2000到Radeon HD 7000系列的GPU
KVM和Xen虚拟化支持64位硬件(AArch64)
3.12版本
优化了CPU频率管理器,更有效的实现动态调频功能,间接提升了部分开源和闭源驱动的性能。
进一步改善了 Radeon 开源驱动的动态电源管理。
增加了逆向工程出来的 Snapdragon/Adreno 显卡驱动。
支持 AMD 首个异构计算的 Berlin 系列服务器 APU。
小幅改善了 F2FS、XFS 和 Btrfs 文件系统。
ext4文件系统加入两个新功能:支持主动 extent 缓存,减少主读工作负荷的存储器使用,改进异步 I/O。
改进英特尔 Haswell 图形性能。
支持 NVIDIA Optimus 显示技术的动态 GPU 电源管理,双显卡笔记本可以动态的关闭或激活第二个 GPU。
3.13版本
多队列块层允许I/O负载在多CPU核心中均衡,延展性更好,减少磁盘延迟,提供更好的磁盘性能。
支持英特尔 Broadwell 和 AMD Radeon R9 waii 的新驱动。
防火墙子系统/包过滤引擎 nftables 取代 iptables。
提供了一个更简单的核心 ABI,减少重复代码,更有效的支持过滤规则。
开源NVIDIA驱动加入新的电源管理代码。
改进 AMD HDMI 音频功能。
英特尔硬件支持立体/3D HDMI设备。
Btrfs和F2FS文件系统改进。
Linux功率限制框架和实时平均功率限制驱动程序将允许在超出定义临界值时限制某些组件的功耗。
3.14版本
开源NVIDIA驱动支持更多NVIDIA显卡。
英特尔 Broadwell 的显示芯片及音频系统获得更好的支持。
VMware SVGA2 显示驱动程序重大变更。
NVIDIA Tegra初步支持 PRIME。
开源AMD驱动部份设备支持改进。
经由新的驱动程序支持AMD加密协作处理器。
通用CPU加速。
F2FS及BTRFS文件系统改进。
新增Xen的PVH支持。
加入Deadline调度器。
支持MIPS最新的CPU核心支持。
加入TCP自动抑制功能。
3.15版本
支持EFI混合模式,可以在32位的UEFI上运行64位的核心。
激活异步线程来加快暂停及恢复的时间。
开源驱动对新一代的NVIDIA Maxwell显卡的初步支持,以及对近期的AMD显卡的VEC 2.0视频解码支持。
CPU前端的AVX-512及RDSEED扩充支持。
支持Sony DualShock 4 控制器。
LLVM近乎完全支持编译主线核心。
3.16版本
部份支持64位ARM架构的EFI。
Samsung的Exynos多平台核心支持。
改进ARM的Xen虚拟化支持。
支持Dell Latitude掉落感应器。
新的Synaptics触控版驱动程序。
改进对Sony DualShock 4的支持。
大量声卡驱动程序更新。
Btrfs及XFS文件系统的重大更新。
维护
其它Linux核心程序的维护者还包括:
罗伯特·拉姆:preemptible kernel, inotify
英格·蒙内: x86架构, scheduler, locking
大卫·米勒:网络、sparc架构
汉·彼德·艾文(Hans Peter Anvin):x86架构、内核加载器
版本命名
Linux内核有三个不同的命名方案。
早期版本:
第一个版本的内核是0.01。其次是0.02,0.03,0.10,0.11,0.12(第一GPL版本),0.95,0.96,0.97,0.98,0.99及1.0。[49]
从0.95版有许多的补丁发布于主要版本版本之间。
旧计划(1.0和2.6版之间),版本的格式为A.B.C,其中A,B,C代表:
A大幅度转变的内核。这是很少发生变化,只有当发生重大变化的代码和核心发生才会发生。在历史上曾改变两次的内核:1994年的1.0及1996年的2.0。
B是指一些重大修改的内核。
内核使用了传统的奇数次要版本号码的软件号码系统(用偶数的次要版本号码来表示稳定版本)。
C是指轻微修订的内核。这个数字当有安全补丁,bug修复,新的功能或驱动程序,内核便会有变化。
自2.6.0(2003年12月)发布后,人们认识到,更短的发布周期将是有益的。自那时起,版本的格式为A.B.C.D,其中A,B,C,D代表:
A和B是无关紧要的
C是内核的版本
D是安全补丁
自3.0(2011年7月)发布后,版本的格式为3.A.B,其中A,B代表:
A是内核的版本
B是安全补丁