LINUX内核架构

内核

内核是硬件与软件之间的一个中间层。其作用是将应用程序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址

从应用程序的角度来看,内核是应用程序所知道的层次结构中的最底层

内核负责将可用共享资源(包括CPU时间、磁盘空间、网络连接等)分配到各个系统进程,同时还需要保证系统的完整性

将内核视为库,其提供了一组面向系统的命令。通常,系统调用用于向计算机发送请求。借助于C标准库,系统调用对于应用程序就像是普通函数一样,其调用方式与其他函数相同。

常用操作系统内核:
宏内核:内核的全部代码,包括所有子系统(如内存管理、文件系统、设备驱动程序)都打包到一个文件中。内核中的每个函数都可以访问内核中所有其他部分。

进程

传统上,UNIX操作系统下运行的应用程序、服务器以及其他程序都称为进程

进程切换的问题:
1.通过撤销进程的CPU资源之前保存进程所有与状态相关的要素,并将进程置于空闲状态。在重新激活进程时,则将保存的状态原装恢复。进程之间的切换称之为进程切换
2.重要进程得到的CPU时间多一点,次要进程得到的少一点。确定哪个进程运行多长时间的过程称为调度

Linux对进程采用了一种层次系统,每个进程都依赖于一个父进程。内核启动init程序作为第一个进程,负责进一步的系统初始化操作。
fork可以创建当前进程的一个副本,父进程和子进程只有PID(进程ID)不同,父进程内存的内容将被复制

为了使操作更高校,linux将内存复制操作延迟到父进程或子进程向某内存页面写入数据之前

exec将一个新程序加载到当前进程的内存中并执行,旧程序的内存页将刷出,其内容将替换为新的数据,然后开始执行程序。

线程

线程也可称为轻量级进程。本质上一个进程可能有若干线程组成,这些线程共享同样的数据和资源,但可能执行程序种不同的代码路径。
由于线程和主程序共享同样的地址空间,主程序自动就可以访问接收到的数据。因此除了为防止线程访问同一内存区而采取的互斥机制外,就不需要什么线程通信了。

linux用clone方法创建线程。其工作方式类似于fork,但启用了精确的检查,以确认哪些资源与父进程共享、哪些资源为线程独立创建。

地址空间

CPU的字长决定了所能管理的地址空间的最大长度。

地址空间的最大长度与实际可用的物理内存数量无关,因此被称为虚拟地址空间

虚拟地址空间的一个解释是:从系统中每个进程的角度来看,地址空间中只有自身一个进程,而无法感知到其他进程的存在,也无需关注其他程序的存在。

linux将虚拟地址空间划分为内核空间用户空间。用户进程不能访问内核空间。
这种划分与可用的内存数量无关。各个系统进程的用户空间是完全彼此分离的,而虚拟地址空间顶部的内核空间总是同样的。

特权级别

linux只使用两种不同的状态:核心态用户态。两种状态的关键差别在于:用户状态禁止访问内核空间,用户进程不能操作或读取内核空间中的数据,也无法执行内核空间中的代码。这种机制可防止进程无意间修改彼此的数据造成相互干扰。

从用户态到核心态的切换通过系统调用的特定转换手段完成, 且系统调用的执行因具体系统而不同。内核还可以由异步硬件中断激活,然后在中断上下文中运行。中断与系统调用的主要区别是:
在这里插入图片描述
因为中断可能随时发生,而中断发生时可能是任意用户进程处于活动状态,由于该进程基本上与终端的原因无关,因此内核无权访问当前用户空间的内容。

虚拟和物理地址空间

大多数情况下,虚拟地址空间,就算是每个进程自身的虚拟地址空间,也比系统中可用的物理内存要大。因此内核和CPU必须考虑如何将实际可用的物理内存映射到虚拟地址空间的区域。

可取的方法是用页表来为物理地址分配虚拟地址。虚拟地址关系到进程的用户空间和内核空间,而物理地址则用来寻址实际可用的内存。
在这里插入图片描述
并非虚拟地址空间的所有页都映射到具体某个页帧,可能是因为页没有被使用,或者是数据尚不需要被使用而没有载入内存中。

内存映射可以将任意来源的数据传输到进程的虚拟地址空间中,可以像普通内存一样用通常的方法访问该地址空间,修改该地址空间的数据也会自动修改源数据。
内核在实现设备驱动程序时直接使用了内存映射,外设的输入/输出可以映射到虚拟地址空间的区域中,对相关内存区域的读写会由系统重定向到设备。

猜你喜欢

转载自blog.csdn.net/jieyannn/article/details/105186832