什么是 Linux 内核?

2025年3月17日 | 阅读11分钟

Linux 内核简介

Linux 内核是一个开源、免费、多任务、模块化、单体式、类 Unix 的操作系统内核。最初由 Linus Torvalds 于 1991 年为他的 i386 架构 PC 开始开发,后来被选作 GNU 操作系统的内核,旨在作为 Unix 的自由(免费)替代品。

Linux 根据 GNU 通用公共许可证 v2 发布,但包含其他兼容许可证下的文件。自 20 世纪 90 年代末以来,它已成为多个操作系统发行版的一部分,其中许多发行版也通常被称为 Linux。

  • Linux 被广泛应用于各种计算系统,包括超级计算机、大型机、服务器、个人电脑、移动设备和嵌入式设备。
  • 通过一系列简单的命令,它可以针对许多使用场景和架构进行定制;特权用户甚至可以在运行时微调内核参数。
  • Linux 内核的几乎所有代码都是使用 GCC GNU 扩展的 C 编程语言编写的。
  • 它生成高度优化的可执行文件 vmlinux,以最大限度地利用任务执行时间和内存空间。
  • 日常的开发讨论都在 LKML(Linux 内核邮件列表)上进行。
  • 修改是通过 Git 版本控制系统进行的跟踪,该系统最初由 Torvalds 为 BitKeeper 开发,作为自由软件的替代品。

Linux 内核的特性与架构

Linux 是一个单体式内核,设计标准,支持以前仅存在于闭源非自由操作系统内核中的几乎所有功能。以下各节和列表概述了 Linux 架构设计及其一些重要方面。

  • 在 NUMA 和 SMP 架构上实现并发计算和多个进程的同时真正并行执行。
  • 配置和选择多个内核驱动程序和功能,在引导前修改内核参数,以及在运行时微调内核行为。
  • 配置和运行时更改任务调度程序的策略,以实现抢占式多任务处理;自 2007 年以来,CFS(完全公平调度程序)一直是 Linux 的默认调度程序,它使用红黑树,可以在 O(log n) 的时间复杂度内查找、插入和删除进程信息,其中 n 是可运行任务的数量。
  • 同步机制和进程间通信。
  • 使用分页式虚拟内存的高级内存管理。
  • 在多种具体文件系统(FAT32、JFS、XFS、Btrfs、ext4 等)之上构建的虚拟文件系统。
  • 可配置的输入/输出调度程序,ioctl(2) 系统调用可用于操作唯一文件的基本设备参数,支持异步输入/输出。
  • 操作系统级虚拟化、硬件辅助虚拟化和半虚拟化。Linux 内核支持创建可在 Xen hypervisor 上作为 Dom0 运行的 Linux 发行版。
  • 通过 SR-IOV 和 VFIO 进行 I/O 虚拟化。VFIO(虚拟函数 I/O)在安全内存保护的环境中公开直接设备访问。VM Guest 可以直接访问 VM Host Server 上的硬件设备。与半虚拟化和全虚拟化相比,此方法可提高性能。
  • 用于强制访问控制和自主访问控制的安全机制(POSIX ACLs、AppArmor、SELinux 等)。
  • 通过 RPMsg 子系统实现非对称多处理。
  • 各种分层通信协议(如互联网协议套件)。

大部分内核扩展和设备驱动程序在内核空间中运行,并具有对硬件的完全访问权限。少数例外在用户空间中运行。此外,还有 WaylandX Window System,这是几乎所有人与 Linux 一起使用的显示服务器协议和窗口系统。

设备驱动程序配置为模块,可以在系统运行时加载和卸载,并且在某些情况下可以被抢占,以正确管理硬件中断并更好地支持对称多处理,这与标准单体式内核不同。Linux 使用虚拟内存和内存保护,并且还可以管理非统一内存访问。

What is the Linux Kernel?

接口

Linux 是 Unix 的一个副本,专注于对 Single UNIX 和 POSIX 规范的兼容性。此外,内核提供 Linux 特定的系统调用和多个接口。代码必须满足一组许可规则才能被添加到官方内核中。

用户空间和内核之间的 Linux ABI(应用程序二进制接口)具有四个稳定性级别(已移除、已废弃、测试中、稳定)。尽管如此,系统调用应该永远不会改变,以免破坏依赖它们的用户空间程序。

可加载内核模块(LKMs)本质上不能依赖稳定的 ABI。因此,每当系统中有新的内核可执行文件时,它们都应该重新编译。在内核中的驱动程序,配置为 vmlinux(内核可执行文件)的集成部分,在构建过程中被静态链接。

线程和进程

Linux 使用较新的 clone3 (2) 和 clone (2) 系统调用来创建进程。新实体可以共享调用者的部分或全部资源,具体取决于提供的参数。这些系统调用可以创建从新独立进程到调用进程中的新执行线程的各种新实体。

如果可执行文件与共享库动态链接,则动态链接器会查找并加载所需的对象,为程序执行进行准备,然后执行它。一种非常特殊的线程类别是内核线程。它们不应与上面提到的用户进程的执行线程混淆。内核线程仅存在于内核空间,其目的是并发运行内核操作。

抢占与调度

Linux 调度程序很标准,因为它支持不同的调度策略和类。调度程序类可以定义为可插入的调度程序算法,这些算法可以注册到基础调度程序代码中。所有类都会调度多个进程。核心调度程序代码按优先级顺序遍历所有类,并选择包含已准备好执行的调度实体 (sched_entity) 的最高优先级调度程序。

实体可以是线程组、线程,甚至是一个特定用户的每个进程。Linux 同时提供完全内核抢占和用户抢占。抢占减少了延迟,提高了响应速度,并使 Linux 更兼容实时和桌面应用程序。

同步与并发

内核存在多种并发原因(例如,对称多处理、内核抢占和用户任务、软中断和中断)。为了保护由硬件异步修改的关键区域和内存区域,Linux 提供了一组工具。

它们由原子类型、无锁算法、互斥锁、信号量和自旋锁组成。几乎所有无锁算法都建立在内存屏障之上,以强制执行内存顺序并避免由于编译器优化而产生的意外副作用。

中断管理

中断管理分为两个不同的部分。然而,它也可以被视为一个整体任务。由于时间限制和同步需求不同,它被分成了两部分。第一部分由称为 top half 的中断服务例程组成,而第二部分由 bottom halves 执行。Linux 中断的服务例程可以嵌套。

内存管理

在 Linux 中,内存管理是一个复杂的话题。内核不可分页。内核中没有内存保护;因此,内存违规会导致系统崩溃和不稳定。Linux 使用 4 级和 5 级页表操作虚拟内存。用户内存空间是可分页的。它管理着 RAM 中所有页面帧的信息,这些信息在重启后立即填充,并一直保留到关机,无论是否与虚拟页面相关。

支持的架构

如今,Linux 是移植性最强的操作系统内核之一,运行在从 ARM 架构到 IBM z/Architecture 大型机等各种系统上,而最初并非为可移植性而设计。最初的移植是在 Motorola 68000 平台上实现的。

内核的改动如此之大,以至于 Torvalds 将 Motorola 版本视为一个“类 Linux 操作系统”和一个分支。然而,这促使 Torvalds 领导了一次重大的代码重构,以支持移植到多种计算架构。此外,Linux 也被移植到许多手持设备上,如苹果的 iPod 和 iPhone 3G。

支持的设备

LKDDb 项目于 2007 年启动,旨在创建一个 Linux 内核已知的协议和硬件的综合数据库。该数据库通过对内核源代码进行静态分析自动构建。Linux 硬件项目于 2014 年晚些时候宣布,旨在从许多 Linux 发行版的用户那里自动收集所有经过测试的硬件配置的数据库。

在线补丁

通过在线补丁,甚至可以使用 kGraft、kpatch 和 ksplice 等在线补丁方法对内核进行无需重启的更新。对于在线内核修补,极简化的基础已集成到 2015 年 4 月 12 日发布的 4.0 版本 Linux 内核主线中。

安全性

内核中的错误会带来安全问题。例如,它们可能导致权限提升或成为拒绝服务攻击的向量。多年来,已检测并修复了许多影响系统安全的错误。新功能会频繁实现,以提高内核的安全性。

Linux 内核的开发

What is the Linux Kernel?

开发者社区

Linux 内核的开发者社区大约由 5000 到 6000 名成员组成。排名前 30 的开发者贡献了略多于 16% 的代码。与许多开源应用程序项目一样,开发者需要遵守贡献者公约。贡献者公约是一份行为准则,旨在规范对少数贡献者的骚扰。为避免使用包容性术语,请使用授权的源代码。

源代码管理

Linux 开发社区使用 Git 来管理源代码。Git 的用户可以通过 git-clone(1) 命令克隆 Torvalds 的最新发布树,并通过 git-pull(1) 命令保持更新。

向内核提交代码

希望修改 Linux 内核的开发者首先测试和开发该修改。根据修改的重要性以及它改变的子系统数量,它将作为单个补丁或两个或多个源代码补丁提交。

如果一个子系统由一个维护者管理,则将补丁作为电子邮件发送到该子系统的维护者,并将正确的邮件列表抄送。邮件列表的阅读者和维护者将检查补丁并提供反馈。一旦完成了这个审查过程,子系统维护者就会将补丁合并到相关的 Git 内核树中。

编码风格与编程语言

Linux 操作系统是用独特的 C 语言编写的。该语言得到了 GCC 的支持,GCC 是一个可以以多种方式扩展 C 标准的编译器。自 2002 年以来,所有代码都必须遵守 Linux Kernel Coding Style 中包含的 21 条规则。

GNU 工具链

GNU cc 或 GCC(GNU Compiler Collection)是 Linux 源代码的默认编译器,并且需要一个名为 make 的实用程序。GNU Assembler 通过 GCC 生成的汇编代码生成目标文件。GNU Linker 生成一个名为 vmlinux 的静态链接的可执行内核文件。ld 和 as 都是 GNU Binary Utilities 的一部分。上面提到的工具统称为 GNU 工具。

编译器兼容性

长期以来,GCC 是唯一能够正确构建 Linux 的编译器。2004 年,Intel 可能修改了内核,使其 C 编译器能够编译它。自 2010 年以来,一直致力于使用 Clang(C 语言的替代编译器)来构建 Linux。Clang 所属的 LLVM 编译器基础设施的项目被称为 LLVMLinux。

内核调试

影响 Linux 内核的病毒可能难以排查。这是因为内核与硬件和用户空间之间的交互,以及它们可能由比用户程序更多样化的原因引起。一些潜在原因的例子包括不正确的硬件管理、同步原语的误用以及代码中的语义错误。在内核中,非致命的错误报告被称为 “oops”;这种偏离正确 Linux 内核行为的情况可能允许系统在可接受的可靠性下稳定运行。

开发模式

Linux 内核以滚动方式接收新代码。检入项目的软件必须能够编译并无误运行。所有内核子系统都有一个分配的维护者,该维护者负责根据内核代码标准审查补丁,并维护一个可以在几周的合并窗口中与 Linus Torvalds 共享的补丁队列。这些补丁由 Torvalds 与 Linux 内核前一个稳定版本的源代码合并。

主线 Linux

Linus Torvalds 的 Git 树被称为主线 Linux,它包含了 Linux 内核。所有稳定的内核版本都来自主线树,该树会频繁发布在 kernel.org 上。主线 Linux 支持运行 Linux 操作系统的少量设备。非主线支持由 Linaro 和 Yocto 等独立项目提供,但在许多情况下,需要从设备供应商处获取内核。供应商内核通常需要一个板级支持包。事实证明,在主线 Linux 之外管理内核树非常困难。

类 Linux 内核

稳定分支维护者 Greg Kroah-Hartman 使用“类 Linux”一词来描述供应商的下游内核分支,这些分支包含许多要合并到主线内核中的代码行。Google 表示,他们希望在 Android 操作系统中使用主线 Linux 内核,以减少内核分叉(2019 年)。此外,“类 Linux”一词也用于 可嵌入 Linux 内核子集,该子集不包含完整的 Linux 主线内核,而是包含一个经过修改的微小代码子集。

内核类型

内核通常有三种类型,列出并解释如下:

What is the Linux Kernel?

单体式内核

它是操作系统广泛使用的内核。在单体式架构中,内核由可以动态加载和卸载的多个模块组成。这种架构可以增强操作系统的功能,并允许轻松扩展内核。使用单体式架构可以方便地进行内核维护,因为它允许在需要修复特定模块的错误时加载和卸载相关模块。

微内核

微内核是作为单体式内核的替代品而出现的,旨在解决内核代码尺寸不断增长的问题,而单体式内核在这方面做得不够好。它允许一些基本服务,如文件系统、设备驱动程序管理、协议栈等,在用户空间中执行。它可以提高操作系统的功能,增强安全性和最小化代码,并确保稳定性。

它通过使系统的其余部分正常运行而不中断来减少受影响区域的损害。操作系统中的每个基本服务都通过 IPC(进程间通信)提供给程序。在微内核架构中。它允许硬件和设备驱动程序之间直接交互。

混合内核

它可以决定在超级用户模式和用户模式下执行什么。例如,在混合内核环境中,设备驱动程序的文件系统 I/O 会在用户模式下执行,而 IPC 和服务器调用则驻留在超级用户模式下。

用户空间和内核空间

在 Linux 操作系统中,系统内存被分为两个区域:用户空间和内核空间。让我们描述所有内存区域并理解其功能。

用户空间

用户界面或用户空间是运行在操作系统内核平台之外的代码。它被定义为操作系统用于与内核链接的多个程序、应用程序或库。由于内存使用的复杂过程,恶意功能只能限制在用户系统中。

内核空间

它处于正式状态,提供对硬件设备的完全访问权限并保护内存空间。这种用户空间和内存空间合称为内核空间。在内核空间环境中,核心访问系统硬件和服务被维护并作为服务提供给系统的其余部分。


下一个主题Crontab Linux