1,内核实际上是一台增强的计算机,将计算机抽象到一个高层次平台,内核是应用程序所知的结构层次中的最底层,CPU是个例外,但并不是所有指令都对程序可用。
2,内核分为微内核和宏内核两种,前者只有最基本的功能,其他功能全部委托给独立的进程,后者包括了所有子系统,Linux基于宏内核范型实现,模块可以在系统运行时插入到内核代码中,热插拔和动态装载得以实现。
3,Unix系统中运行的所有程序,服务器都称为进程,每个进程在CPU虚拟内存中分配地址空间,每个地址空间相互独立,要想进行彼此通信,就要使用特殊的内核机制。
4,Linux系统中,真正正在运行的进程树木不会超过CPU数目,内核按照短的时间间隔在不同进程只见切换,造成同时处理多进程的假象,在撤销进程的CPU资源前,保存进程所有状态相关的要素,再激活进程时,只需要恢复原样就可以。内核确定进程运行时间长短的过程,称为调度。
5,linux对进程采用一种层次结构,每个进程都依赖一个父进程,init作为第一个进程,负责初始化,所有进程都直接或间接源自该进程。
6,Unix有两种创建新进程的机制,fork和exec。fork创建当前进程的一个副本,父子进程只有PID不同,父进程的内存内容被复制,采用时写复制技术,主要原理是将内存复制操作延迟到父进程或子进程向某内存页写入数据之前,只读情况下,父子进程共用同一内存页。
7,exec将一个新程序加载到当前进程的内存中并执行,内存页刷出,替换为新的数据,开始执行新的程序。
8,线程,进程并不是内核支持的唯一程序执行形式,除了重量级进程,还有一种轻量级进程——线程。本质上一个进程可以由若干线程组成,线程共享数据和资源,线程的概念已经集成到许多编程语言之中。进程可以看作一个正在执行的程序,线程则是与主程序并行的程序函数或者例程。
9,Linux使用clone方法创建线程,与fork类似,但是启用了精确检查,确定了与父进程共享哪些资源,扩展了线程的概念,一定程度上允许线程与进程之间连续转换。
10,命名空间,在Linux初期,命名空间被集成到许多子系统,使不同进程可以看到不同的系统视图,每个进程都有唯一的标识符,启用命名空间后,全局资源具有不同的分组,每个空间都有特定的PID集合,某个命名空间中挂载的卷不会传播到其他命名空间。
11,虚拟机供应商通过容器的命名空间来建立系统的多个视图,从容器内部看是一个完整的Linux系统,而且与其他容器没有交互,彼此分离,更像一台运行的Linux计算机,
与完全的虚拟化解决方案相比,计算机只需要一个内核管理若有容器。
12,由于内存区域通过指针寻址,因此CPU的字长决定了所能管理的地址空间的最大长度。32位系统是2的32次方B,等于4GB,64位系统,可以管理2的64次方B。
13,地址空间的最大长度与实际可用的物理内存数量无关,因此被称为虚拟地址空间。从系统的每个进程角度看,地址空间只有自身一个进程,无法感知到其他京城的存在。
14,Linux将虚拟地址空间划分为内核空间和用户空间。
15,系统中每个进程都有自身的虚拟地址范围,系统中的每个用户进程都有自身的虚拟地址范围,从0到TASK_SIZE,用户空间之上的区域留给内核专用,用户进程不能访问。
16,TASK_SIZE是一个特定于计算机体系结构中的常数,按比例把地址空间划分为两个部分。地址空间中的实际可寻址部分小于理论长度,但大于实际可能的内存数量,因此完全够用。这样可以节省CPU的工作量,但是虚拟地址空间中含有一些不可寻址的洞。
17,英特尔处理器区分四种进程特权级别,从0到3,数字越小,可以访问的功能更多,但是Linux只有两种不同状态,核心态和用户态。两种状态差别在于对TASK_SIZE的内存区域的访问,用户进程径直访问内核空间,也不能读取内核空间的数据,无法执行内核空间的代码。
18,从用户态到核心态的切换通过系统调用的特定转换手段完成,普通进程要执行任何影响整个系统的操作,需要借助系统调用向内核发出请求,内核检查进程是否允许执行想要的操作,然后代表进程执行所需的操作,接下来返回到用户态。
19,内核还可以由异步硬件中段激活,然后在中断上下文中运行,与进程上下文运行的主要区别是,中断上下文中运行不能访问虚拟地址中用户空间部分。因为中断可能随时发生,发生是可能任一进程处于活动状态,由于该进程基本上与中断的原因无关,因此内核无权访问当前用户空间的内容。
20,除了普通进程,系统中还有内核线程运行,内核线程不与任何特定用户空间进程关联,因此无权处理用户空间。
21,CPU大多数时间都在执行用户空间中的代码,当执行系统调用时,切换到核心态,内核完成请求,在此期间可以访问虚拟地址空间用户部分,完成调用之后切换为用户态,硬件中段也会使CPU切换到核心态,这种情况下不能访问用户空间。
22,ps fax命令的输出中可以很容易识别内核线程,其名称都在方括号内。从内核线程名称后的斜线和CPU编号可以看到线程指定运行的CPU。
23,多数情况下,单个虚拟地址空间就比系统中可用的屋里内存要大。
24,内核和CPU通过页表来为物理地址分配虚拟地址,虚拟地址关系到进程的用户空间和内核空间,而物理地址则用来寻址实际可用的内存。
25,进程的虚拟地址空间被内核划分为很多等长的页,物理内存页划分为同样大小的页,物理内存的页通常成为页帧,而页专指虚拟地址空间中的页。
26,用来将虚拟地址空间映射到物理地址空间的数据结构称为页表。实现两个地址空间的关联最容易的方法是使用数组,对虚拟地址空间中的每一页,都分配一个数组项,该数组项指向与之关联的页帧。
27,但由于虚拟空间大部分区域都是没有使用的,因此也没有关联到页帧,那就可以使用功能相同但内存量使用更少的模型:多级分页。
28,大多数系统使用三级页表,而Linux采用四级页表。
29,虚拟地址的第一部分称为全局页目录——PGD,用于索引进程中的一个数组,GPD的数组项指向另一些数组的起始地址,这些数组称为中间页目录。——PMD
30,PMD的数组项也是指针,指向下一级数组,称为页表或页目录。第三个部分称为页表数组——PTE,用作页表的索引。页表的数组项指向页帧。
31,虚拟地址的最后一个部分称为偏移量,指定了页内部的一个字节位置,归根结底,每个地址都都指向地址空间中唯一定义的某个字节。
32,多级页表节省了大量内存,但是也有一个问题,就是每次必须逐级访问多个数组才能将虚拟地址转换为屋里地址。CPU使用两种方法加速——CPU中有一个专门的部分叫MMU——内存管理单元,用于优化内存访问操作;地址转换中出现最频繁的地址被保存到地址转换后备缓冲器——TLB,无需从内存中访问页表,即可直接获得地址数据,从而加速地址转换。
网友评论