内核组成
简介
内核的任务
如内核寻址硬盘时,一系列操作都是内核完成,与程序不相干。
共享资源 包括CPU时间、磁盘空间、网络连接等
实现策略
微内核
最基本的功能直接由中央内核实现,
宏内核
内核组成 部分
内核空间
核心内核 调用设备驱动程序
用户空间
应用程序 c库 系统调用内核 核心内核
进程 以及切换 、调度
进程
传统上 UNIX操作系统下运行的应用程序、服务器以及其他应用程序统称为进程。每个进程都在CPU的虚拟内存中分配地址空间。每个进程的地址空间是完全独立的、因此进程不会意识到彼此的存在。
如果彼此需要通信,必须使用特定的内核机制
切换
由于linux是多任务系统,支持并发执行的若干进程。系统中真正运行的进程数据不能超过cpu数目,因此内核会按照短的时间间隔在不同的进程之间切换
调度
Unix进程
UNIX操作系统有两种创建新进程的机制分别是fork和exec
Fork
Fork可以创建当前进程的一个副本,父进程和子进程共享一个PID(进程id不同)
为了提高fork效率,使用copy on write
Exec
将一个新程序加载到当前进程的内存中并执行,旧程序的内存也将刷出,内容替换为新的数据
线程
Linux采用clone方法创建线程,启用精确检查,确认哪些资源与父进程共享,哪些资源为线程独立创建
命名空间
每个命名空间可以包含一个特定的PID集合,或可以提供文件系统的不同视图,在某个命名空间中挂载的卷不会传播到其他命名空间中。
地址空间与特权级别
容量单位
KIB 2^10
MIB 2^20
GIB 2^30
32位操作系统,2^32 也就是4GIB
64位
虚拟地址划分
地址空间的最大长度与实际可用的物理内存数量无关,因此被称为虚拟内存地址。
LINUX将虚拟地址划分为内核空间和用户空间。
每个用户进程都有自身的虚拟地址范围,从0到TASK_SIZE,
用户空间之上的区域,从TASK_SIZE到2^32或2^62保留给内核专用,用户进程不能访问。
特权级别
CPU特权级别 比如IA-32 体系用4中特权级别构成系统,各级别可以看做是环,内环可以访问更多的功能,外环更少。
lINUX只有两种不同的状态:核心态和用户状态
两种状态的关键差别在于对于高于TASK_SIZE 内存区域的访问。
简而言之,在用户状态禁止访问内核空间。
用户进程不能操作或读取内核空间中的数据,也无法执行内核空间中的代码。这是内核专用领域,这种机制可以防止进程无意间修改彼此的数据而造成相互干扰。
从用户状态到核心状态的转换通过系统调用特定的转换手段完成,
如果普通进程想要执行任何影响整个系统的操作,只能借助于系统调用内核发出请求。
除了代表用户程序执行代码之外,内核还可以由异步硬件中断激活,然后在中断上下文中进行。
虚拟和物理地址空间
页
虚拟地址空间被内核划分为很多等长的部分,这部分称之为页。物理内存也划分为同样大小的页。
页帧
物理内存页经常称作页帧,页则专指虚拟地址空间中的页。
虚拟地址空间和物理内存之间的映射使得进程之间的隔离有一点松动。
内核负责将虚拟地址空间映射到物理地址空间,因此可以决定哪些内存区域在进程之间共享,哪些不共享。
用户空间 用户层
称呼用户运行的应用程序时,有两个等价的名词可用,其中之一是用户层,
另一种说法是某个应用程序在用户空间运行。
用户层这个名词总是指应用程序本身,而用户空间则不仅可以表示应用程序,还指代了应用程序所运行的虚拟地址空间的一部分,与内核空间相对。
页表
定义
用来将虚拟地址空间映射到物理地址空间的数据结构称为页表。
因为虚拟地址空间的大部分区域都没有使用,因而就没有关联到页帧,那么就可以使用功能相同的内存用量少得多的模型,多级分页。
多级分页
全局页表 PGD
虚拟地址的第一部分称为全局页目录,PGD Page global directory。PGD用于索引进程中的一个数组(每个进程有且仅有一个),该数组就是所谓的全局页目录或PGD,PGD的数组项指向另一些数组的起始地址,这些数组称为中间页目录PMD
中间页表 PMD
在通过PGD数组项找到对应的PMD之后,则使用PMD来索引,PMD的数组项也是指针,指向下一级数组,称为页表或页目录
页表 PTE
虚拟地址的第三部分称为PTE,用作页表的索引,虚拟内存页的映射和页帧的映射就此完成,因为页表的数组项是指向页帧的。
页表的特色在于,对虚拟地址中不需要的区域,不必创建中间页目录或页表,多级页表节省了大量内存。
页帧 Offset
虚拟地址最后一部分称为偏移量,指定了页内部的一个字节位置、
物理内存的分配
内存分配时,必须记录页帧的已分配或空间状态,以免两个进程使用同样的内存区域。内核可以分配完整的页帧,具体的内存更小部分可以交给用户空间中的标准库。
伙伴系统
很多时候需要分配连续页,内核采用古老的技术 伙伴系统
系统中的内存都是两两分组,每组中的两个内存块称作伙伴
slab缓存
内核本身需要比完整页帧小得多的内存块。
一般性缓存 slab缓存
如kmalloc 和 free
页面交换和页面回收
页面交换
通过利用磁盘空间作为扩展内存,从而增大了可用的内存,在内核需要使用更多内存时,不经常使用的页可以写入硬盘
页面回收
用于将内存映射被修改的内容与底层的块设备同步,为此有时也简称为数据回写。