🌈 博客个人主页:Chris在Coding
🎥 本文所属专栏:[Linux内核]
❤️ 前置学习专栏:[Linux学习]从0到1
⏰ 我们仍在旅途
目录
前言--Linux内核简述
内核的任务
内核实现策略
内核在操作系统中的位置
如何获取Linux内核源码
下载Linux内核源码
文本编辑器--VsCode
Linux内核整体架构
Linux 内核子系统
Linux 内核子系统之间的关系
Linux目录结构详解
前言--Linux内核简述
Linux内核是由林纳斯·托瓦兹(Linus Torvalds)在1991年开始开发的。当时他为了得到一个可以运行UNIX操作系统的个人计算机,开始编写一个操作系统内核,并将其命名为Linux。随后,越来越多的开发者加入到项目中,共同完善和扩展Linux内核。如今,Linux已经成为最流行和广泛使用的开源操作系统内核之一,驱动着许多不同类型的设备和服务器。
内核的任务
在纯技术层面上,内核是硬件与软件之间的一个中间层。其作用是将应用程序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址。尽管如此,仍然可以从其他一些有趣的视角对内核进行研究。
- 从应用程序的视角来看,内核可以被认为是一台增强的计算机,将计算机抽象到一个高层次上。例如,在内核寻址硬盘时,它必须确定使用哪个路径来从磁盘向内存复制数据,数据的位置,经由哪个路径向磁盘发送哪一条命令,等等。
- 另一方面,应用程序只需发出传输数据的命令。实际的工作如何完成与应用程序是不相干的,因为内核抽象了相关的细节。应用程序与硬件本身没有联系,只与内核有联系,内核是应用程序所知道的层次结构中的最底层,因此内核是一台增强的计算机。
- 当若干程序在同一系统中并发运行时,也可以将内核视为资源管理程序。在这种情况下,内核负责将可用共享资源(包括CPU时间、磁盘空间、网络连接等)分配到各个系统进程,同时还需要保证系统的完整性。
- 另一种研究内核的视角是将内核视为库,其提供了一组面向系统的命令。通常,系统调用用于向计算机发送请求。借助于C标准库,系统调用对于应用程序就像是普通函数一样,其调用方式与其他函数相同。
内核实现策略
当前,在操作系统实现方面,有以下两种主要的范型。
微内核:
- 中央内核(微内核)只实现最基本的功能,如进程调度和内存管理。
- 其他功能(如文件系统、网络协议栈等)由独立的进程或服务器实现,通过明确定义的通信接口与微内核进行通信。
- 这种设计使得系统的各个部分清晰划分,鼓励使用清洁的程序设计技术,同时具有动态可扩展性和在运行时切换重要组件的优点。
- 但是,由于在组件之间通信需要额外的 CPU 时间,因此在实际应用中,微内核的性能往往比宏内核较低。
宏内核:
- 所有内核功能都打包到一个文件中,包括进程管理、内存管理、文件系统等。
- 内核中的每个函数都可以访问内核中的所有其他部分,因此容易导致代码复杂度较高。
- 宏内核在目前仍然是性能更好的选项,因此像 Linux 这样的操作系统采用了这种范型。
- 但是,为了弥补宏内核的一些缺陷,引入了模块化的设计,允许在运行时向内核动态添加功能,实现了模块的热插拔和动态装载。
内核在操作系统中的位置
为了更具象地理解内核,不妨将Linux计算机想象成有三层结构:
- 硬件部分:物理机(这是系统的底层结构或基础)是由内存(RAM)、处理器(或 CPU)以及输入/输出(I/O)设备(例如存储、网络和图形)组成的。其中,CPU 负责执行计算和内存的读写操作。
- 系统软件部分(Linux 内核):操作系统的核心。(没错,内核正处于核心的位置)它是驻留在内存中的软件,用于告诉 CPU 要执行哪些操作。
- 用户部分:这些是内核所管理的运行程序。用户进程共同构成了用户空间。用户进程有时也简称为进程。内核还允许这些进程和服务器彼此进行通信(称为进程间通信或 IPC)。
也就是说设计内核的目的:
- 对下:与硬件交互,管理所有的软硬件资源
- 对上:为用户程序(应用程序)提供一个良好的执行环境
- 在整个计算机软硬件架构中,内核的定位是:纯“搞管理”
如何获取Linux内核源码
下载Linux内核源码
我们首先进入Linux内核的官网www.kernel.org
我们跟着点击箭头所指向的链接后就可以选择我们想要下载的Linux内核版本,大家可以按照实际的需求选择(这里我选择5.x的版本,最后我下载5.6.18版本的内核源码)
其中就5.6.18而言,其中5代表的是主版本号,6代表的是次版本号,18就代表的是修改的次数,可以理解为小版本号
这里我们主要注意次版本号的选择
- 如果次版本号是偶数,通常表示这个版本是一个稳定版本,主要用于生产环境或者正式发布。
- 如果次版本号是奇数,可能表示这个版本是一个开发版本或者测试版本,其中可能包含了一些新功能的添加,但是可能相对不稳定。
文本编辑器--VsCode
Visual Stdio Code简称VS Code,是一款跨平台的、免费且开源的现代轻量级代码编辑器,支持几乎 主流开发语言的语法高亮、智能代码补全、自定义快捷键、括号匹配和颜色区分、代码片段提示、代码对比等特性,也拥有对git的开箱即用的支持。同时,它还支持插件扩展,通过丰富的插件,用户能获得更多高效的功能.
vsCode官网下载
下载安装后这里我推荐一些常用的插件:
- Chinese (Simplified)
- vscode-icons
- C/C++ Extension Pack
- GBKtoUTF8
现在我们就可以通过VsCode打开我们之前下载的内核文件来阅读源码
Linux内核整体架构
Linux 内核子系统
如上图所示,Linux内核有5大主要子系统
进程调度 (Process Scheduler):
- 控制进程对 CPU 的访问,决定哪个进程执行,采用进程优先级调度算法。
内存管理 (Memory Manager):
- 允许多个应用程序进程安全地访问内存。
- 分为硬件相关和硬件无关部分,硬件无关部分提供了内存映射和虚拟内存机制,硬件相关部分则负责管理真实的内存硬件。
虚拟文件系统 (Virtual File System):
- Linux内核将不同功能的外部设备,例如Disk设备(硬盘、磁盘、NAND Flash、Nor Flash等)、输入输出设备、显示设备等等,抽象为可以通过统一的文件操作接口(open、close、read、write等)来访问。虚拟文件系统为所有类型的设备和逻辑文件系统提供统一接口。
- 可以分为设备驱动程序和逻辑文件系统。
网络管理 (Network Manager):
- 提供对网络协议和网络硬件的支持。
- 包括网络协议栈和硬件驱动程序,网络协议栈负责与其他设备通信,而硬件驱动程序负责与本设备的网络硬件通信。
进程间通信 (Inter-Process Communication):
- 支持进程间的通信机制。
Linux 内核子系统之间的关系
-
进程调度与内存管理:
- 进程调度依赖于内存管理模块,因为进程调度需要考虑进程的内存使用情况。
- 内存管理依赖于进程调度模块,因为内存管理需要考虑到进程的执行情况,以便有效地分配和释放内存资源。
-
内存管理与虚拟文件系统:
- 内存管理与虚拟文件系统两个子系统相互依赖。
- 内存管理依赖于虚拟文件系统,因为虚拟文件系统可能会影响到内存的使用情况。
- 虚拟文件系统依赖于内存管理,因为虚拟文件系统可能需要操作内存来缓存文件或者进行文件的映射操作。
-
虚拟文件系统与网络管理:
- 虚拟文件系统与网络管理两个子系统相互依赖。
- 虚拟文件系统可能需要依赖网络管理来访问网络文件系统或者进行网络文件传输。
- 网络管理可能需要依赖虚拟文件系统来操作文件系统中的网络相关配置或者进行文件的读写操作。
-
进程调度与网络管理:
- 网络管理依赖于进程调度模块,因为网络管理可能需要考虑进程的执行情况,以便进行网络资源的分配和管理。
-
进程间通信与内存管理、进程调度:
- 进程间通信依赖于内存管理和进程调度两个子系统模块,因为进程通信涉及到进程的内存空间和调度执行。
进程调度 与 内存管理 这两个子系统之间 是相互依赖的
内存管理 与 虚拟文件系统 之间 相互依赖
Linux目录结构详解
Linux内核源代码包括三个主要部分:
内核核心代码:
- 包括各个子系统和子模块,如进程调度、内存管理、文件系统等,以及支撑子系统,如电源管理、系统初始化等。
- 这部分代码构成了 Linux 内核的主体,实现了操作系统的核心功能。
其他非核心代码:
- 包括库文件、固件集合、KVM 等。
- 这些代码可能不直接与内核功能相关,但是对于系统的完整性和功能扩展起到了重要的作用。
辅助性文件:
- 包括编译脚本、配置文件、帮助文档、版权说明等。
- 这些文件是为了方便开发者阅读、编译、配置和使用内核而提供的辅助工具和信息。
- arch/:体系结构相关的代码,包括不同体系结构的具体实现和头文件。
- block/:提供块设备的支持。
- certs/: 与认证签名相关的代码。
- crypto/:加密和解密相关的库函数。
- Documentation/: 描述模块功能和协议规范的代码。
- drivers/:设备驱动的代码。
- fs/:虚拟文件系统(VFS)子系统的代码。
- include/:包含内核头文件,提供给外部模块使用。
- init/:Linux 系统启动初始化相关的代码。
- ipc/:IPC(进程间通信)子系统的代码。
- kernel/:包含 Linux 内核的核心代码,包括进程调度子系统和相关模块。
- lib/:提供内核使用的库函数的实现。
- mm/:内存管理子系统的代码。
- net/:不包括网络设备驱动的网络子系统的代码。
- samples/:一些示例代码。
- scripts/:用于内核编译的配置文件和脚本。
- security/:提供安全特性(如 SELinux)的支持。
- sound/:音频相关的驱动和子系统代码。
- tools/:一些常用工具,如性能剖析和自测试工具。
- usr/:用于生成 initramfs 的代码。
- virt/:提供虚拟机技术(如 KVM)的支持。