简介
Linux内核的作用是将应用层序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址。Linux进程采用层次结构,每个进程都依赖于一个父进程。内核启动 init 程序作为第一个进程。该进程负责进一步的系统初始化操作。init 进程是进程树的根,所有的进程都直接或者间接起源于该进程。
- 从技术层面讲,内核是硬件与软件之间的一个中间层。作用是将应用程序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址。
- 从应用程序的层面讲,应用程序与硬件没有联系,只与内核有联系,内核是应用程序知道的层次中的最底层。在实际工作中内核抽象了相关细节。
- 内核是一个资源管理程序。负责将可用的共享资源(CPU时间、磁盘空间、网络连接等)分配得到各个系统进程。
- 内核就像一个库,提供了一组面向系统的命令。系统调用对于应用程序来说,就像调用普通函数一样。
Linux内核的核心功能
1、进程管理
内核负责创建和销毁进程,并处理它们与外部世界的联系(输入和输出)。 不同进程间通讯(通过信号,管道,或者进程间通讯原语)对整个系统功能来说是基本的,也由内核处理。 另外,调度器,控制进程如何共享 CPU, 是进程管理的一部分。 更通常地,内核的进程管理活动实现了多个进程在一个单个或者几个 CPU 之上的抽象。
2、内存管理
计算机的内存是主要的资源,处理它所用的策略对系统性能是至关重要的。 内核为所有进程的每一个都在有限的可用资源上建立了一个虚拟地址空间。 内核的不同部分与内存管理子系统通过一套函数调用交互,从简单的 malloc/free 对到更多更复杂的功能。
3、文件系统
Unix 在很大程度上基于文件系统的概念; 几乎 Unix 中的任何东西都可看作一个文件。 内核在非结构化的硬件之上建立了一个结构化的文件系统,结果是文件的抽象非常多地在整个系统中应用。 另外, Linux 支持多个文件系统类型,就是说,物理介质上不同的数据组织方式。 例如,磁盘可被格式化成标准 Linux 的 ext3 文件系统,普遍使用的 FAT 文件系统,或者其他几个文件系统。
4、设备控制
几乎每个系统操作最终都映射到一个物理设备上。 除了处理器,内存和非常少的别的实体之外,全部中的任何设备控制操作都由特定于要寻址的设备相关的代码来进行。 这些代码称为设备驱动。 内核中必须嵌入系统中出现的每个外设的驱动,从硬盘驱动到键盘和磁带驱动器。 内核功能的这个方面是本书中的我们主要感兴趣的地方。
5、网络
网络必须由操作系统来管理,因为大部分网络操作不是特定于某一个进程: 进入系统的报文是异步事件。 报文在某一个进程接手之前必须被收集、识别、分发。 系统负责在程序和网络接口之间递送数据报文,它必须根据程序的网络活动来控制程序的执行。 另外,所有的路由和地址解析问题都在内核中实现。
内核整体架构
根据内核的核心功能,Linux内核提出了5个子系统,分别为:
Process Scheduler(进程管理)、Memory Manager(内存管理)、VFS(Virtual File System 虚拟文件系统)、Network(网络子系统)、IPC(Inter-Process Communication 进程间通信)
进程管理(Process Scheduler)
进程管理是Linux内核中最重要的子系统,它主要提供对CPU的访问控制。因为在计算机中,CPU资源是有限的,而众多的应用程序都要使用CPU资源,所以需要“进程调度子系统”对CPU进行调度管理。进程调度子系统包括4个子模块:
- Scheduling Policy,实现进程调度的策略,它决定哪个(或哪几个)进程将拥有CPU。
- Architecture-specific Schedulers,体系结构相关的部分,用于将对不同CPU的控制,抽象为统一的接口。这些控制主要在suspend和resume进程时使用,牵涉到CPU的寄存器访问、汇编指令操作等。
- Architecture-independent Scheduler,体系结构无关的部分。它会和“Scheduling Policy模块”沟通,决定接下来要执行哪个进程,然后通过“Architecture-specific Schedulers模块”resume指定的进程。
- System Call Interface,系统调用接口。进程调度子系统通过系统调用接口,将需要提供给用户空间的接口开放出去,同时屏蔽掉不需要用户空间程序关心的细节。
内存管理(Memory Manager)
内存管理同样是Linux内核中最重要的子系统,它主要提供对内存资源的访问控制。Linux系统会在硬件物理内存和进程所使用的内存(称作虚拟内存)之间建立一种映射关系,这种映射是以进程为单位,因而不同的进程可以使用相同的虚拟内存,而这些相同的虚拟内存,可以映射到不同的物理内存上。内存管理子系统包括3个子模块:
- Architecture Specific Managers,体系结构相关部分。提供用于访问硬件Memory的虚拟接口。
- Architecture Independent Manager,体系结构无关部分。提供所有的内存管理机制,包括:以进程为单位的memory mapping;虚拟内存的Swapping。
- System Call Interface,系统调用接口。通过该接口,向用户空间程序应用程序提供内存的分配、释放,文件的map等功能。
虚拟文件系统(Virtual File System)
传统意义上的文件系统是一种存储和组织计算机数据的方法。它用易懂、人性化的方法(文件和目录结构),抽象计算机磁盘、硬盘等设备上冰冷的数据块,从而使对它们的查找和访问变得容易。因而文件系统的实质就是“存储和组织数据的方法”,文件系统的表现形式就是“从某个设备中读取数据 和 向某个设备写入数据”。
随着计算机技术的进步,存储和组织数据的方法也是在不断进步的,从而导致有多种类型的文件系统,例如FAT、FAT32、NTFS、EXT2、EXT3等等。而为了兼容,操作系统或者内核,要以相同的表现形式,同时支持多种类型的文件系统,这就延伸出了虚拟文件系统(VFS)的概念。VFS的功能就是管理各种各样的文件系统,屏蔽它们的差异,以统一的方式,为用户程序提供访问文件的接口。
我们可以从磁盘、硬盘、NAND Flash等设备中读取或写入数据,因而最初的文件系统都是构建在这些设备之上的。这个概念也可以推广到其它的硬件设备,例如内存、显示器(LCD)、键盘、串口等等。我们对硬件设备的访问控制,也可以归纳为读取或者写入数据,因而可以用统一的文件操作接口访问。Linux内核就是这样做的,除了传统的磁盘文件系统之外,它还抽象出了设备文件系统、内存文件系统等等。这些逻辑,都是由VFS子系统实现。VFS子系统包括6个子模块:
- Device Drivers,设备驱动,用于控制所有的外部设备及控制器。由于存在大量不能相互兼容的硬件设备(特别是嵌入式产品),所以也有非常多的设备驱动。因此,Linux内核中将近一半的Source Code都是设备驱动,大多数的Linux底层工程师(特别是国内的企业)都是在编写或者维护设备驱动,而无暇估计其它内容(它们恰恰是Linux内核的精髓所在)。
- Device Independent Interface, 该模块定义了描述硬件设备的统一方式(统一设备模型),所有的设备驱动都遵守这个定义,可以降低开发的难度。同时可以用一致的形势向上提供接口。
- Logical Systems,每一种文件系统,都会对应一个Logical System(逻辑文件系统),它会实现具体的文件系统逻辑。
- System Independent Interface,该模块负责以统一的接口(快设备和字符设备)表示硬件设备和逻辑文件系统,这样上层软件就不再关心具体的硬件形态了。
- System Call Interface,系统调用接口,向用户空间提供访问文件系统和硬件设备的统一的接口。
网络子系统(Network)
网络子系统在Linux内核中主要负责管理各种网络设备,并实现各种网络协议栈,最终实现通过网络连接其它系统的功能。在Linux内核中,网络子系统几乎是自成体系,它包括5个子模块:
- Network Device Drivers,网络设备的驱动,和VFS子系统中的设备驱动是一样的。
- Device Independent Interface,和VFS子系统中的是一样的。
- Network Protocols,实现各种网络传输协议,例如IP, TCP, UDP等等。
- Protocol Independent Interface,屏蔽不同的硬件设备和网络协议,以相同的格式提供接口(socket)。
- System Call interface,系统调用接口,向用户空间提供访问网络设备的统一的接口。