Linux系统模型
Linux 内核非常庞大,代码非常得多。想要全面地了解整个内核是十分困难的一件事,但是“天下难事必做于易,天下大事必作于细”,对于Linux内核这个让我们无从下手的巨无霸,应该从小处做起,整体分解,逐步求精。
操作系统是面向用户的,计算机用户可以使用计算机操作系统来工作,聊天,玩游戏,我们使用的这些东西都是应用软件,内核的一个比较重要的工作,就是管理应用,为应用程序准备好运行内存,管理应用程序的执行,让应用程序通行无阻,让计算机发挥出最大的功能和效率。除了管理应用以外,操作系统内核还需要管理硬件设备,内核下面有非常多的设备驱动代码,内核跟CPU和硬件设备关系非常密切,在整个操作系统中的地位,具有承上启下的作用,因此可知内核的核心功能就是:管理硬件设备,供应用程序使用。
Linux内核是Linux操作系统一部分。对下,它管理系统的所有硬件设备;对上,它通过系统调用,向C库或者其它应用程序提供接口。
Linux内核实现了操作系统的三⼤核⼼功能:即进程管理、内存管理和⽂件系统,来达到管理计算机硬件和外设的功能。
1.进程管理是Linux内核中最重要的一个子系统,它主要提供对CPU的访问控制。因为在计算机中,CPU资源是有限的,而众多的应用程序都要使用CPU资源,所以需要“进程调度子系统”对CPU进行调度管理。
2.内存管理是计算机运行时内存的分配和使用,以便让各个进程可以安全地共享机器的内存资源。另外,内存管理会提供虚拟内存的机制,该机制可以让进程使用多于系统可用Memory的内存,不用的内存会通过文件系统保存在外部非易失存储器中,需要使用的时候,再取回到内存中。
3.文件系统就是数据的存储结构,硬盘中存的只是0010101101100,文件系统就是将其组织、分类、解析的。同时Linux内核将不同功能的外部设备抽象为可以通过统一的文件操作接口来访问,这就是Linux系统“一切皆是文件”的体现。
Linux有两把宝剑来高效地做到以上的功能:中断上下文、进程上下文。应用程序通过系统调用与内核通信,让内核代其完成不同的任务。
由上所述一个精简的Linux系统概念模型可以得出,这个模型拥有三个基本功能:进程管理、内存管理、文件管理。内核通过系统调用为用户进程提供各种服务,中断机制为硬件正常高效工作提供服务。
进程管理:
Linux中的一个任务(task)就是一个进程(process)。每一个进程都具有一定的功能和权限,它们都运行在各自独立的虚拟地址空间。Linux中每一个进程由一个task_struct数据结构 来描述(进程控制块PCB)。
CPU在每个系统滴答(Tick)中断产生的时候检查就绪队列里面的进程(遍历链表中的进程结构体),如有符合调度算法的新进程需要切换,保存当前运行的进程的信息(包括栈信息等)后挂起当前进程,选择新的进程运行,这就是进程调度。
进程的优先级差异是CPU调度的基本依据,调度的终极目标是让高优先级的活动能够即时得到CPU的计算资源(即时响应),低优先级的任务也能公平分配到CPU资源。因为需要保存进程运行的上下文(process context)等,进程的切换本身是有成本的,调度算法在进程切换频率上也需要考虑效率。
内存管理:
内存管理同样是Linux内核中重要的组成部分,它主要提供对内存资源的访问控制。Linux系统会在硬件物理内存和进程所使用的内存(称作虚拟内存)之间建立一种映射关系,这种映射是以进程为单位,因而不同的进程可以使用相同的虚拟内存,而这些相同的虚拟内存,可以映射到不同的物理内存上。
内存区域通过指针寻址,CPU的字节长度(32bit机器,64bit机器)决定了最大的可寻址地址空间。在32位机器上最大的寻址空间是4GBtyes。在64位机器上理论上有2^64Bytes。
Linux将虚拟地址空间分为内核空间和用户空间。每个用户进程的虚拟空间范围从0到TASK_SIZE。从TASK_SIZE到2^32或2^64的区域保留给内核,不能被用户进程访问。
在内核中,实现设备驱动时,外设(外部设备)的输入和输出区域可以被映射到虚拟地址空间,读写这些空间会被系统重定向到设备,从而对设备进行操作,极大地简化了驱动的实现。
虚拟文件系统:
Everything is a file.
系统几乎所有的资源都可以看成是文件。为了支持不同的本地文件系统,内核在用户进程和文件系统实现间包含了一层虚拟文件系统(Virtual File System)。大多数的内核提供的函数都能通过VFS(Virtual File System)定义的文件接口访问。
中断机制:
中断机制在计算机系统中发挥着关键作⽤,在没有中断机制之前,计算机只能批处理,而无法多个程序并发⼯作。中断机制的出现,让宏观时间上的程序并发得到了实现,当CPU监听到⼀个中断信号发⽣时,CPU就把当前正在执⾏的进程的CS:RIP寄存器和RSP寄存器等都压栈到内核堆栈,做保存现场的⼯作,把CS:RIP指向⼀个中断向量(中断处理程序的入口),然后去执⾏其他进程,等中断处理结束时再恢复现场,即恢复CS:RIP寄存器和RSP寄存器等到CPU上继续执⾏原进程。
中断使得硬件设备得以与处理器进行通信,不同的设备对应的中断不同,而每个中断都通过一个唯一的数字标识,它让硬件在需要的时候再向内核发出信号。
一个小例子:
简述:
用户进程X正在正常运行。
进程X请求某个系统调用。
中断机制介入,保存现场,将中断服务程序入口加载到CS:EIP,完成中断上下文切换,进入内核态。
根据系统调用号,调用相应的libc函数来处理。
中断处理程序结束,若发送进程调度,则当前状态暂时保存在内核堆栈,发送中断,转去执行另一进程,下次进程调度到该进程时再恢复现场。
若不发生进程调度,则恢复中断现场,回到用户态。
这个小例子在上述的精简的Linux系统概念模型逻辑上是正常运作的。
课程心得体会:
通过这门课程我学到了很多新知识,从宏观上Linux内核的基本模型到Linux内核源码。同时也让我明白了一个道理,“天下难事必做于易,天下大事必作于细”,先构建一个整体框架,在逐步求精的方法在学习方面是十分高效的。