一、内核
什么是内核?
计算机是由各种外部硬件设备组成的,如内存、cpu、硬盘等。如果每个应用都要和这些硬件对接通信协议,就太麻烦了,所以这个工作就由内核来负责。内核作为软件连接硬件设备的桥梁,使应用开发者只需关心如何与内核交互,而不是与硬件交互。
内核的任务?
内核一般会具有以下能力:
- 执行流调度:管理进程、线程,决定哪个进程、线程占用CPU;
- 内存管理:决定内存资源的分配和回收;
- 设备驱动:为进程与硬件设备之间提供通信能力;
- 系统调用:如果应用程序要运行更高权限运行的服务,就需要系统调用,它是用户程序与操作系统之间交互的接口。
内核是怎么工作的?
内核具有最高的权限,可以控制各种硬件。而用户程序具有的权限很小,因此操作系统把内存分成了两个区域:内核空间和用户空间。
内核空间和用户空间
- 内核空间只有内核程序可以访问;
- 用户空间专门给应用程序使用,当然内核程序也可以使用。
用户程序只能访问局部的内存空间,而内核程序可以访问所有内存空间。
内核态和用户态
当程序使用用户空间时,我们常说该程序在用户态执行;当程序使内核空间时,程序则在以内核态执行。
应用程序如果需要进入内核空间,就需要通过系统调用,下面来看看系统调用的过程:(参考信号处理)
当程序使用系统调用时会产生中断,CPU 会中断当前在执行的程序,跳转到中断处理程序,也就是开始执行内核程序。内核处理完后,主动触发中断,把 CPU 执行权限交回给用户程序,回到用户态继续执行后面的代码。
二、Linux的设计
Linux 内核的设计理念主要有以下几点:
- MultiTask,多任务
- SMP,对称多处理
- ELF,可执行文件链接格式
- Monolithic Kernel,宏内核
MultiTask
MultiTask 的意思是多任务,Linux 是一个多任务的分时操作系统。多任务意味着可以有多个任务并行运行。
-
对于单核 CPU:可以基于时间片轮转,每个任务执行一小段时间后就切换另一个任务。从宏观角度看,一段时间内执行了多个任务,称为串行。
-
对于多核 CPU:多个任务可以同时被不同核心的 CPU 同时执行,这被称为并行。
SMP (Symmetric Multi-Processor)
对称多处理。表示每个 CPU 的地位和对资源的权限是相等的,多个 CPU 共享内存,每个 CPU 都可以访问完整的内存和硬件资源。
这个特点决定了 Linux 不会有某个 CPU 独占程序,每个程序都可以被分配到任意一个 CPU 上被执行。
ELF (Executable and Linkable Format)
可执行文件链接格式。它是 Linux 中可执行文件的存储格式,可以从下图看到它的结构:
ELF 把文件分成了一个个分段,每一个段都有自己的作用。
ELF 文件有两种索引,Program header table 中记录了「运行时」所需的段,而 Section header table 记录了二进制文件中各个「段的首地址」。
ELF文件是如何生成的?
代码首先经过编译器编译成汇编代码,然后通过汇编器变成目标代码,也就是目标文件,最后通过链接器把多个目标文件以及调用的各种函数库链接起来,形成可执行文件,也就是 ELF 文件。
ELF文件是如何被执行的?
执行 ELF 文件的时候,会通过装载器把 ELF 文件加载到内存,CPU 去读取内存中的指令和数据,程序就被执行起来了。
Monolithic Kernel
宏内核。Linux 内核架构就是宏内核,意味着 Linux 的内核是一个完整的可执行程序,且拥有最高的权限。宏内核的特征是内核的所有功能,比如进程调度等,都运行在内核态。
Linux 也实现了动态加载内核模块的功能,例如大部分设备驱动是以可加载模块的形式存在的,与内核其他模块解藕,让驱动的开发和加载更灵活。
与宏内核对应的是微内核。微内核架构的内核只保留最基本的能力,比如进程调度、虚拟机内存、中断等,把一些应用放到了用户空间,比如驱动程序、文件系统等。这样服务与服务之间是隔离的,单个服务出现故障或者完全攻击,也不会导致整个操作系统挂掉,提高了操作系统的稳定性和可靠性。
微内核内核功能少,可移植性高。但是相比宏内核的缺点是,由于驱动程序不在内核中,而驱动程序一般会频繁调用底层,于是驱动和硬件设备交互就需要频繁切换到内核态,这样会带来性能损耗。