小林coding阅读笔记:操作系统篇之内核设计
Posted adventure.Li
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小林coding阅读笔记:操作系统篇之内核设计相关的知识,希望对你有一定的参考价值。
前言
- 参考/导流:
小林coding - 内核设计 - 学习意义
- 了解Linux和Windows主要OS的发展历程(背景)
- 了解相关的设计架构、理念以及底层的基本工作原理
- 相关说明
该篇博文是个人阅读的重要梳理,仅做简单参考,详细请阅读小林coding的原文!
一、现有操作系统背景
- Windows (闭源、商业化,个人PC)
- Linux(开源,自由,服务器)
Windows 和 Linux 可以说是我们比较常见的两款操作系统的。
Windows 基本占领了电脑时代的市场,商业上取得了很大成就,但是它并不开源,所以要想接触源码得加入 Windows 的开发团队中。
对于服务器使用的操作系统基本上都是 Linux,而且内核源码也是开源的,任何人都可以下载,并增加自己的改动或功能,Linux 最大的魅力在于,全世界有非常多的技术大佬为它贡献代码。
二、OS内核的概念
对于计算机来说,实际上是CPU、内存等硬件协同工作。要想进行软件应用控制硬件就需要遵循不同的串口协议,通信协议。对应应用程序较少来说,基本上可以应对,但当应用越来越丰富,管理起来则十分麻烦,此时 则需要 抽象 通用部分来提升 复用 。于是,操作系统的内核 则作为该 中间层 去管理起来,应用只需要 和 它打交道即可,屏蔽了 差异性。
基础能力
作为中间层,它 需要对硬件进行统一管理,并抽象 接口API 供上层应用调用,它所具有的功能如下(对于现代操作系统):
- 管理进程、线程【CPU的使用能力抽象】,决定哪个进程、线程使用 CPU,也就是进程调度的能力;
- 管理内存,决定内存的分配、回收、越界处理、地址映射等,也就是内存管理的能力;
- 管理硬件设备【磁盘存储器(文件系统的抽象)、显示屏、键盘等外设】,为进程与硬件设备之间**提供通信【指令、控制,联系】**能力,也就是硬件通信能力;
- 提供系统调用【对于上层用户来说的抽象】,如果应用程序要运行更高权限运行的服务,那么就需要有系统调用,它是用户程序与操作系统之间的接口。
如何工作
随着OS的普及,用户群体的变化,考虑用户并非像以前那样是专业的人士。因此设计出来 用户态 + 内核态,来保证 用户的 安全、可靠地 使用 计算机。
对于内核来说具有很高的权限,可以控制 cpu、内存、硬盘等硬件,而应用程序具有的权限很小,因此大多数操作系统,把内存分成了两个区域【通过 内存空间的划分 来区别,因为程序最终写入内存,CPU再从内存进行读数据 控制执行】:
- 内核空间,这个内存空间只有内核程序可以访问;
- 用户空间,这个内存空间专门给应用程序使用;
用户空间的代码只能访问一个局部的内存空间,而内核空间的代码可以访问所有内存空间。因此,当程序使用用户空间时,我们常说该程序在用户态执行,而当程序使内核空间时,程序则在内核态执行。
应用程序如果需要进入内核空间,就需要通过系统调用,下面来看看系统调用的过程:
内核程序执行在内核态,用户程序执行在用户态。
当应用程序使用系统调用时,会产生一个中断。发生中断后, CPU 会中断当前在执行的用户程序,转而跳转到中断处理程序,也就是开始执行内核程序。内核处理完后,主动触发中断,把 CPU 执行权限交回给用户程序,回到用户态继续工作。
三、Linux的内核设计
Linux 内核设计的理念主要有这几个点:
- MultiTask,多任务(单道→批处理 → 多任务
- SMP,对称多处理
- ELF,可执行文件链接格式
- Monolithic Kernel,宏内核
MultiTask
多任务意味着可以有多个任务同时执行,这里的「同时」可以是并发或并行:
- 对于单核 CPU 时,可以让每个任务执行一小段时间,时间到就切换另外一个任务,从宏观角度看,一段时间内执行了多个任务,这被称为并发。
- 对于多核 CPU 时,多个任务可以同时被不同核心的 CPU 同时执行,这被称为并行。
SMP
SMP 的意思是对称多处理,代表着每个 CPU 的地位是相等的【防止饥饿,对比负载均衡策略,选举策略的设计理念】,对资源的使用权限也是相同的,多个 CPU 共享同一个内存,每个 CPU 都可以访问完整的内存和硬件资源。
这个特点决定了 Linux 操作系统不会有某个 CPU 单独服务应用程序或内核程序,而是每个程序都可以被分配到任意一个 CPU 上被执行。
ELF
ELF 的意思是可执行文件链接格式,它是 Linux 操作系统中可执行文件的存储格式。
组成结构
ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table);
//ELF Header
#define EI_NIDENT 16
typedef struct
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;// 程序地址入口
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
Elf32_Ehdr;
// Program Header
typedef struct
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;//虚拟地址
Elf32_Addr p_paddr;//物理地址
Elf32_Wordp_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
Elf32_Phdr;
ELF 文件有两种索引,Program header table 中记录了「运行时」所需的段,而 Section header table 记录了二进制文件中各个「段的首地址」。
我们编写的代码,首先通过「编译器」编译成汇编代码,接着通过「汇编器」变成目标代码,也就是目标文件,最后通过「链接器」把多个目标文件以及调用的各种函数库链接起来,形成一个可执行文件,也就是 ELF 文件。执行 ELF 文件的时候,会通过「装载器」把 ELF 文件装载到内存里,CPU 读取内存中的指令和数据,于是程序就被执行起来了
Monolithic Kernel
Monolithic Kernel 的意思是宏内核,Linux 内核架构就是宏内核,意味着 Linux 的内核是一个完整的可执行程序,且拥有最高的权限。
宏内核的特征是系统内核的所有模块,比如进程调度、内存管理、文件系统、设备驱动等,都运行在内核态。
不过,Linux 也实现了动态加载内核模块的功能,例如大部分设备驱动是以可加载模块的形式存在的,与内核其他模块解耦,让驱动开发和驱动加载更为方便、灵活。
- 微内核:内核功能少,,稳定性高,可移植性高,性能消耗大
- 宏内核:-
与宏内核相反的是微内核,微内核架构的内核只保留最基本的能力,比如进程调度、虚拟机内存、中断等,把一些应用放到了用户空间,比如驱动程序、文件系统等。这样服务与服务之间是隔离的,单个服务出现故障或者完全攻击,也不会导致整个操作系统挂掉,提高了操作系统的稳定性和可靠性。
微内核内核功能少,可移植性高,相比宏内核有一点不好的地方在于,由于驱动程序不在内核中,而且驱动程序一般会频繁调用底层能力的,于是驱动和硬件设备交互就需要频繁切换到内核态,这样会带来性能损耗。华为的鸿蒙操作系统的内核架构就是微内核。
还有一种内核叫混合类型内核,它的架构有点像微内核,内核里面会有一个最小版本的内核,然后其他模块会在这个基础上搭建,然后实现的时候会跟宏内核类似,也就是把整个内核做成一个完整的程序,大部分服务都在内核中,这就像是宏内核的方式包裹着一个微内核。
Windows 设计
当今 Windows 7、Windows 10 使用的内核叫 Windows NT,NT 全称叫 New Technology。
下图是 Windows NT 的结构图片:
Windows 的可执行文件的格式与 Linux 也不同,所以这两个系统的可执行文件是不可以在对方上运行的。
Windows 的可执行文件格式叫 PE,称为可移植执行文件,扩展名通常是.exe
、.dll
、.sys
等。
以上是关于小林coding阅读笔记:操作系统篇之内核设计的主要内容,如果未能解决你的问题,请参考以下文章