第一部分、内务子系统
操作系统内核的管理功能以及执行最终也要归于cpu的执行流,因此最简单的设计就是将内核的内务也设计成进程,但是对于一些特别的内务这个办法就不适用了,因为这些内务的特殊性恰恰在于它们是依赖cpu的,或者说是和cpu进行接口的。如果我们把计算机视为一台人类发明的智能的机器,那么很自然的,类似上帝造人那样,我们会把计算机设计成人的模样,计算机应该有心跳和反射。
到底什么是内核的内务 呢?其实举个例子就明白了。餐厅是顾客吃饭的地方,然而餐厅服务员也是人,也要吃饭,他们的吃饭问题就是内务问题,另外,餐厅需要及时打扫保持卫生,餐厅打扫卫生的阿姨的工作也属于内务问题。重要的问题是内务事务应该怎样执行。餐厅工作人员吃饭是直接付费还是免费还是从薪水中扣除...
内务子系统包括操作系统所有的子系统(进程、文件、内存...)加上中断等内容
一、时钟
1、时钟是最底层也是最基本的驱动器。
时 钟提供了基本的脉搏。
正 如动物的心跳一样,时钟提供了一切的节拍。
整 个机器依靠时钟的驱动运行。cpu芯片被精确设计,在周期性的时钟边缘触发事件中推进执行逻辑的值,比如EIP寄存器。然而cpu认为系统只有一个进程,一个执行流,这是冯.诺依曼机器模型决定的。
操 作系统必须获取这个事件,然后执行操作系统相关的操作,比如进程调度等等。
2、中断处理
如 果再次和动物心跳进行类比,那么中断就类似于反射(条件反射和非条件反射),当人被从背后拍打肩膀时,人会本能的扭头,或者膝跳反射,这些都是明显的例子。
操 作系统设置了中断处理程序,当cpu检测到中断事件发生时,将执行流自动路由到时钟中断处理程序。设置中断处理程序正如条件反射的学习过程一样。
3、时钟和中断的关系
对 于会思考的动物,心跳和反射无疑在其生理和心理行为中扮演了两大重要的角色,可以想象,没有心跳和瞬时反射的植物虽然也是生物,然而却几乎只能进行细胞分裂而无法进行丰富的生理和心理活动。
对 于计算机而言,心跳和反射依然重要,然而不同于动物,计算机的心跳是反射的一部分,对于动物来讲,心跳是心脏完成的,而反射是神经系统完成的。
时 钟中断也是一种中断,心跳和反射统一于中断。时钟也是由一个中断提供的。注意计算机和动物的区别,是否这一点导致了计算机不可能实现智能化?
神 经系统和心脏的分工是好的,心脏仅仅提供节拍和能量,而神经系统只提供行为。然而问题真的如此简单吗?
4、时钟中断处理-Linux
更 新当前进程的时间统计值
检 查是否需要进行进程调度
如 果需要调度的话,进行进程调度。使更需要运行的进程运行。
再 次重申,具体实现不重要,代码不重要,因此此部分内容很少,看代码就好...
二、软中断机制
1、硬件中断机制
外 设有事件的时候,会发起硬件中断,硬件中断处理程序需要做的工作量很不统一。
硬 件中断处理程序必须需要很快完成。中断是一种异常执行流,它不应该过分的影响正常执行流。比如一家人其乐融融,突然被一个不速之客(比如送快递的或者送牛奶的)打断了快乐,此时,不速之客最好的办法就是办完事赶快离开,或者在不能快速干完事的情况下,告知主人重要事宜后离开,主人待到快乐过后自行处理...
Linux在硬件中断处理程序中触发一种称为softirq的软中断。
2、软中断
耗 时比较久的中断处理事务
三、内核线程和工作队列
Linux将内核的一些事务交给内核线程来做。
任 何驱动程序或者内核子系统在任何时候都可以提交一些任务让内核来执行,这些任务全部交给工作队列是合理的。
2.6 内核中引入了工作队列,实际上工作队列也是一种内核线程。在经过了多次瘦身之后,2.6.36之后将工作队列进行了彻底的改进,用户(内核子系统或者驱动等)仅仅提交任务,具体如何调度这些任务全部由内核来完成,剥夺了任务提交者的很多权力,比如驱动只能提交任务,而不能创建过多的内核线程。
第二部分、内务子系统和Linux各子系统的协调
四、Linux进程的执行
1、被fork,创建一个task_struct
2、exec一个新的磁盘映像,填充进程地址空间
一 般的,Linux的可执行映像是ELF文件,该文件的内容被载入新进程的地址空间
3、执行系统调用,比如read。
该 步骤使用了操作系统内核中的VFS子系统,如果保证进程永远不使用文件,那么VFS完全可以从内核中移除。
4、被中断
L inux进程在执行过程中会经常被外设中断,即使没有任何外设,也会有时钟中断。被中断之后,执行中断策略,见前述。
5、执行期间需要大量内存
调 用mmap在进程地址空间申请虚拟内存,使用时通过alloc_pages申请物理页面。
如 果系统再也没有足够的可用物理页面了,将调用相关内核线程来释放一些物理页面,将之分配给当前需要页面的进程。
Linux的内务子系统采用“尽量满足”的策略,因为Linux的内务子系统的首要任务是为了解决有限的系统资源和潜在的、未知的、无限的进程需求之间的矛盾,因此内核决不能使用“怕堵车就不让人买车”的策略,既然linux内务子系统是“服务性”的,它就要尽量满足进程的需求,只有在实在满足不了的情况下,才会返回一个错误,告知用户没有可以使用的内存了,这是合理的,起码,内务子系统没有什么私心。
Linux的OOM-Killer存在很大的问题,问题就出在策略上,内核不能简单的将占用内存最多的进程kill掉,比如说一个重要的服务占据可300M的内存,够大了,然而一个恶意的程序仅占3M的内存,可是它fork出1000个子进程...接下来咋办?Linux内存子系统应该想办法探测到这个事情吗?如果这么做了,势必引起设计恶化的恶化,因为策略和机制耦合了,按道理来讲,机制应该不理解策略的...
6、执行完毕,调用exit系统调用退出。