【内核模式与用户模式】
操作系统为进程提供两个抽象:处理器抽象与内存抽象,使得应用程序进程仿佛拥有全部的处理器时间,和一个私有地址空间。
处理器需要提供一种机制,限制一个应用可以执行的指令以及可以访问的地址空间。
处理器通过一个控制寄存器的模式位来控制当前执行进程的指令执行权限。
设置了模式位:进程处于内核模式,可以执行处理器指令集的全部指令以及访问任何一个内存位置。
未设置模式位:进程处于用户模式,用户模式只能执行处理器指令集中的部分指令,即不允许执行特权指令:
停止处理器(关机)、改变模式位、发出一个IO操作。
同时也不允许访问其它进程地址空间的内容,不允许修改只读的数据段、代码段。
从用户模式切换到内核模式的方式:
- 应用程序执行系统调用。
- 应用程序被中断打断。
【上下文切换】
操作系统内核基于context_switch上下文切换的方式来完成控制的转移,从而实现多任务并发。
并发:一个任务的执行流在时间上与另一个任务发生重叠,多个任务按照一定的顺序执行。
内核为每一个进程维护一个task_struct结构,其中包含的信息即进程的上下文。一个典型的Linux进程上下文包括:
- 进程使用的寄存器组
- 程序计数器
- 用户堆栈
- 进程虚拟地址空间的页表
- 进程打开的文件描述符
- .....
进程在执行过程中,Linux内核基于CFS调度器来完成进程切换,内核选定一个新的进程调入运行,上下文切换的过程:
- 保存当前进程的上下文
- 恢复先前被抢占进程的上下文
- 控制转移到这个新恢复的进程
上下文切换由内核来完成,其基于一定的调度策略以充分发挥处理器的作用。
以系统调用read为例:
- 进程A发出系统调用read,陷入内核,进程A被挂起(让出CPU时间)
- 内核根据系统跳转表,跳转到异常处理程序(向磁盘控制器发出复制数据到内存指令DMA方式)
- 内核不空闲等待,而是执行调度器,调度进程B进行执行,控制转移给进程B
- 磁盘控制器发出硬件中断信号,表明数据传送到内存完成,跳转到内核中断处理程序
- 内核执行上下文切换,控制返回到进程A 进程A获得read的返回