1.Linux 的体系结构
User Space 是用户空间即应用程序执行的地方。Kernel Space 是内核空间,分为 3 层:① 最上层实系统调用接口,即内核向用户提供服务的接口,例如 io read 和 write。应用程序通过软件中断后,调用系统内核提供的功能。② 内核程序。③ 最下层是体系结构的代码,通常称为 BSP。
Linux 内核简介:
内核是操作系统最基本的部分,提供了安全访问计算机硬件的基本能力。这种访问是有限的,并且内核决定应用程序在什么时候对某部分硬件操作多长时间。内核负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
问题 1:内核的实质是什么?
答:内核的实质也是一种应用程序,只不过它是直接操作硬件的。内核直接面对硬件,调用硬件接口即硬件厂商提供的指令集。内核是直接面向硬件的,故可用资源权限很大,但内核是工作在有限地址空间内的,例如 Linux 的32位系统在线性地址空间中,内核只认为自己有 1G 的空间,剩下的 3G 给用户态的应用程序。
说明:编写内核级应用程序的时候,为了避免过于底层,因此内核可以动态编译后,重启加载该程序,例如驱动程序通过动态编译生成可执行文件,然后系统重启后加载该驱动就可以使用相应的设备。
问题 2:从动态角度如何分析 Linux 主机的运行状态
答:用户态的应用程序逻辑上是运行在内核,但实际是直接工作在硬件上的。简单来说,任意应用程序数据都在内存中,数据处理都是在 CPU,只是应用程序不能随意使用这些硬件资源,需要接受内核的管理。当用户态的应用程序需要访问硬件资源时,首先通过系统调用接口向 CPU 发起特权请求,一旦 CPU 收到特权请求就会唤醒内核,从而执行内核中的某段代码,然后将结果返回给应用程序。接着内核代码退出,内核程序暂停。
问题 3:CPU 占用与内核的关系
答:内核将 CPU 虚拟化提供给进程,使得内存中每一个进程都以为直接是独占 CPU。内核将 CPU 切成时间片,随着时间流逝完成了在进程之间分配计算能力,即内核把 CPU 以时间的方式提供了计算能力。
2.内核的整体架构与子系统
- Process Scheduler 进程管理:负责管理 CPU 资源,使得让各个进程以时间片的方式使用 CPU 资源
- Memory Manager 内存管理:负责管理 Memory(内存)资源,是的各个进程可以安全地共享机器的内存资源。另外,内存管理会提供虚拟内存的机制,可以让进程使用多于系统可用的 Memory,不用的内存会通过文件系统保存在外部非易失存储器中,需要使用的时候再取回到内存中。
- VFS(Virtual File System)虚拟文件系统:将不同功能的外部设备,例如 Disk 设备(硬盘、磁盘、NAND Flash、Nor Flash 等)、输入输出设备、显示设备等,抽象为可以通过统一的文件操作接口(open、close、read、write等)来访问。
- Network 网络系统:负责管理系统的网络设备,并实现多种多样的网络标准。
- IPC(Inter-Process Communication)进程间通信:不管理任何的硬件,主要负责 Linux 系统中进程之间的通信
2.1 Process Scheduler 进程管理
进程调度是 Linux 内核中最重要的子系统,主要提供对 CPU 的访问控制。进程调度子系统的 4 个模块,如下图所示。
- System Call Interface 系统调用接口:系统调用接口将需要提供给用户空间的接口开放出去,同时屏蔽掉不需要用户空间程序关心的细节。例如应用程序的主进程可以利用系统调用接口,创建、暂停和恢复子线程。
- Architecture-independent Scheduler 模块:体系结构无关的部分,即与 CPU、内存等硬件无关的模块。它与 Scheduling Policy 模块沟通决定接下来要执行哪个进程,最后通过 Architecture-specific Schedulers 模块 resume 指定的进程。
- Scheduling Policy 进程调度策略:决定哪个或哪几个的进程将拥有 CPU 切片时间。
- Architecture-specific Schedulers 模块:体系结构相关的部分,即与 CPU、内存等硬件相关联的模块。将对不同 CPU 的控制抽象为统一的接口,主要在 suspend 和 resume 进程时使用,牵涉到CPU的寄存器访问、汇编指令操作等。
2.2 Memory Manager 内存管理
内存管理也是 Linux 内核中最重要的子系统,主要提供对内存资源的访问控制。Linux 系统会在硬件物理内存和进程所使用的内存(虚拟内存)之间建立一种映射关系。这种映射是以进程为单位,不同的进程可以使用相同的虚拟内存,而这些相同的虚拟内存,可以映射到不同的物理内存上。内存管理子系统包括 3 个子模块,如下图所示。
- System Call Interface 系统调用接口:通过该接口向用户态的应用程序提供内存的分配、释放,文件的 map 等功能。
- Architecture-independent Scheduler 模块:提供所有的内存管理机制,包括以进程为单位的 memory mapping、虚拟内存的 Swapping 等。
- Architecture-specific Schedulers 模块:提供用于访问内存硬件的虚拟接口。
2.3 VFS 虚拟文件系统
虚拟文件系统 VFS 就是管理各种各样的文件系统,屏蔽其差异,以统一的方式为用户程序提供访问文件的。VFS 子系统包括 6 个子模块,如下图所示。
- System Independent Interface 模块:负责以统一的接口表示硬件设备和逻辑文件系统,包括快设备和字符设备。
- Logical Systems 模块:每一种文件系统都会对应一个 Logical System 逻辑文件系统,实现了具体的文件系统逻辑。
- Device Independent Interface 模块:定义了硬件设备的统一方式即统一设备模型,所有的设备驱动都遵守这个定义,可以降低开发的难度。
- Device Drivers 模块:设备驱动模块用于控制所有的外部设备及控制器。由于存在大量不能相互兼容的硬件设备,特别是嵌入式产品,所以也有非常多的设备驱动。因此,Linux 内核中将近一半的 Source Code 都是设备驱动。
2.4 Network 网络系统
网络子系统在 Linux 内核中主要负责管理各种网络设备,并实现各种网络协议栈,最终实现通过网络连接其它系统的功能,包括 5 个子模块,如下图所示。
- Protocol Independent Interface 模块:屏蔽不同的硬件设备和网络协议,以相同的格式提供接口即 Socket
- Network Protocols 模块:实现各种网络传输协议,例如 IP、TCP、UDP 等
- Device Independent Interface 模块:定义了硬件设备的统一方式即统一设备模型,所有的设备驱动都遵守这个定义,可以降低开发的难度。
- Network Device Drivers 模块:网络设备的驱动,类似 VFS 子系统中的设备驱动。
3.内核源代码的目录结构
Linux 内核源代码包括三个主要部分。
- 内核核心代码:上面所描述的各个子系统和子模块,以及其它的支撑子系统,例如电源管理、Linux初始化等
- 其它非核心代码:例如库文件(因为Linux内核是一个自包含的内核,即内核不依赖其它的任何软件,自己就可以编译通过)、固件集合、KVM(虚拟机技术)等
- 编译脚本、配置文件、帮助文档、版权说明等辅助性文件
include/ ---- 内核头文件,需要提供给外部模块(例如用户空间代码)使用。
kernel/ ---- Linux 内核的核心代码,包含了 2.1 小节所描述的进程调度子系统,以及和进程调度相关的模块
mm/ ---- 内存管理子系统 2.2 小节
fs/ ---- VFS 子系统 2.3 小节。
net/ ---- 不包括网络设备驱动的网络子系统 2.4 小节)。
ipc/ ---- IPC(进程间通信)子系统。
arch// ---- 体系结构相关的代码,例如arm, x86等等。
arch//mach- ---- 具体的machine/board相关的代码。
arch//include/asm ---- 体系结构相关的头文件。
arch//boot/dts ---- 设备树(Device Tree)文件。
init/ ---- Linux系统启动初始化相关的代码。
block/ ---- 提供块设备的层次。
sound/ ---- 音频相关的驱动及子系统,可以看作“音频子系统”。
drivers/ ---- 设备驱动(在Linux kernel 3.10中,设备驱动占了49.4的代码量)。
lib/ ---- 实现需要在内核中使用的库函数,例如CRC、FIFO、list、MD5等。
crypto/ ----- 加密、解密相关的库函数。
security/ ---- 提供安全特性(SELinux)。
virt/ ---- 提供虚拟机技术(KVM等)的支持。
usr/ ---- 用于生成initramfs的代码。
firmware/ ---- 保存用于驱动第三方设备的固件。
samples/ ---- 一些示例代码。
tools/ ---- 一些常用工具,如性能剖析、自测试等。
Kconfig, Kbuild, Makefile, scripts/ ---- 用于内核编译的配置文件、脚本等。
COPYING ---- 版权声明。
MAINTAINERS ----维护者名单。
CREDITS ---- Linux主要的贡献者名单。
REPORTING-BUGS ---- Bug上报的指南。
Documentation, README ---- 帮助、说明文档。