OS:Limited Direct Execution

本文是自己在深入阅读Operating Systems Three Easy Pieces关于虚拟化CPU的知识点总结,后面会不断更新连续每一节,欢迎大家批评指正

0. overview

💡 为了能够虚拟化cpu,因此os需要实现一些机制来共享cpu→ time sharing,让一个程序运行一段时间,然后在切换到另外一个程序执行一段时间。存在一些挑战

  1. 性能需要控制好
  2. 需要保持对程序的控制,控制其运行时间和访问的数据 因此,在保持控制的同时获得高性能是构建操作系统的核心挑战之一。

1. Basic Technique: Limited Direct Execution

为了能够是程序像期望的一样执行,开发者提出了一种"有限直接执行:Limited Direct Execution"。

反过来"直接执行:Direct Execution" 指的是:直接将程序运行在cpu上

  1. 在进程链表中创建进程实体
  2. 为该进程分配内存
  3. 从disk将代码数据载入内存,并定位到函数执行入口(main),然后执行程序
  4. 执行完return后,返回到OS内核,并清除进程链表中的该进程

直接执行产生的问题

  1. 若直接运行程序,OS如何限制程序执行,保证程序会按预期正常执行?
  2. 程序运行时,OS如何停止程序执行,并切换到其他程序上去?从而实现Time sharing.

2 直接执行引发的问题1: 限制操作

直接执行程序速度显然比较快,但若进程想执行 I/O 和其他一些的受限操作(如系统调用这些) ,或访问系统的资源,但又不能让进程完全控制系统。操作系统和硬件如何协同工作来做到这一点?

通过引入一种的处理器模式状态。

  1. user mode : 用户模式\用户态,限制用户的程序只能运行在该状态,不能进入系统内核执行,如不能直接执行I/O操作。但想执行咋办?→通过系统调用
  2. kernel mode:内核模式\内核态,在这种模式下,运行的代码可以做它喜欢的事情,包括特权操作,例如发出I / O请求和执行所有类型的受限制指令。

所以用户程序想要执行系统内核的代码,则需要通过系统调用 ,系统调用允许内核小心地向用户程序公开某些关键功能,例如访问文件系统等。

为了执行系统调用,需要两种特殊的指令:

  1. trap instruction,陷入指令:该指令同时跳转到内核并将权限级别提升到内核模式;一旦进入内核,系统现在可以按形式执行所需的任何特权操作,如I/O操作(如果允许),从而为调用进程执行所需的工作。
  2. return-from-trap instruction,从陷入指令返回指令。完成后,操作系统调用一个特殊的从陷阱返回指令,该指令返回到调用用户程序中,同时将特权级别降低回用户模式。

硬件在执行陷入指令时需要注意,因为它必须确保保存调用者寄存器的内容,以便在操作系统发出从陷阱返回指令时能够正确返回。

另一个问题:当程序调用系统调用时,该如何知道在OS哪里运行该系统调用的代码

  1. 内核在启动的时候设置trap table 。当机器启动时,它以特权(内核)模式启动,因此可以根据需要自由配置机器硬件。因此,操作系统要做的第一件事就是告诉硬件在某些(trap指令时)异常事件发生时要运行什么代码
  2. OS会告诉硬件这些陷入指令处理的硬件位置(通常是一些指令)。一旦通知硬件,它就会记住这些处理程序的位置,直到机器下次重新启动,因此硬件知道当系统调用和其他异常事件发生时要做什么(即跳转到什么代码)
  3. 为了标识 指定确切的系统调用,会给每个系统调用分配一个系统调用号码。用于标识每个系统调用。用户模式下调用系统调用时,会负责将系统调用号码放到 指定的寄存器或者堆栈的某个位置。
  4. 由OS系统调用的处理器来检查该系统调用号码,判断是否有效或者合法。

3 直接执行的问题2: 进程间的切换

直接执行的下一个问题是实现进程之间的切换。操作系统应该决定停止一个进程并启动另一个进程。

具体来说,如果一个进程在CPU上运行,根据定义,**这意味着操作系统没有运行。**如果操作系统没有运行,它怎么能做任何事情呢?(提示:它不能)虽然这听起来几乎是哲学上的,但这是一个真正的问题:如果OS不在CPU上运行,操作系统显然没有办法采取行动

所以,操作系统如何重新获得对CPU的控制,以便它可以在进程之间切换?


3.1 A Cooperative Approach: Wait For System Calls

在协作调度系统中,操作系统通过等待程序系统调用某种非法操作的发生来重新获得对CPU的控制权。但是若有程序永远循环执行,且不调用系统调用,岂不是完蛋?

3.2 A Non-Cooperative Approach: The OS Takes Control

即使进程不合作,**操作系统如何获得对CPU的控制?**操作系统可以做些什么来确保流氓进程(无限执行)不会发生在机器上?→通过时间中断器

可以对定时器设备进行编程,使其每隔这么多毫秒就引发一次中断;当中断被引发时,当前运行的进程被暂停,并且操作系统中预先配置的中断处理程序运行 。此时,操作系统重新获得了对 CPU 的控制权,因此可以为所欲为:停止当前进程,并启动另一个进程。

一旦计时器开始,操作系统就可以感到安全,因为控制权最终将被归还给它,因此操作系统可以自由地运行用户程序。计时器也可以关闭(也是一种特权操作),稍后我们将在更详细地了解并发性时讨论

请注意,当中断发生时,硬件有一些责任,特别是保存中断发生时正在运行的程序的状态,以便后续的从陷阱返回指令将能够正确恢复正在运行的程序。这组操作与硬件在显式系统调用陷阱进入内核期间的行为非常相似,因此可以保存各种寄存器(例如,保存到内核堆栈上),从而通过从陷阱返回的指令轻松恢复。


3.3 保存和恢复上下文

上下文切换在概念上很简单:操作系统所要做的就是为当前正在执行的进程保存一些寄存器值(例如,到其内核堆栈上)并为即将执行的进程恢复一些值(从它的内核堆栈)。


3.4 并发执行,中断怎么办?

当你处理一个中断而另一个中断发生时会发生什么?这在内核中不是很难处理吗?

  1. 在处理中断程序时,关中断,这样做可确保在处理一个中断时,不会向 CPU 提供其他中断。若关中断太长则会导致失去一些程序的中断
  2. 操作系统还开发了许多复杂的锁方案,以保护对内部数据结构的并发访问。这使得多个活动可以同时在内核中进行,这在多处理器上特别有用。
    💡 因此,我们有了虚拟化CPU的基本机制。但是,一个主要问题尚未得到解答:我们应该在给定时间运行哪个进程?调度程序必须回答的正是这个问题,因此也是我们研究的下一个主题。
相关推荐
阑梦清川2 天前
linux操作系统课程学习02
操作系统
阑梦清川2 天前
linux操作系统课程学习01
操作系统
望获linux4 天前
【实时Linux实战系列】CPU 隔离与屏蔽技术
java·linux·运维·服务器·操作系统·开源软件·嵌入式软件
数据智能老司机5 天前
Linux内核编程——网络驱动程序
linux·架构·操作系统
数据智能老司机5 天前
Linux内核编程——字符设备驱动程序
linux·架构·操作系统
数据智能老司机5 天前
Linux内核编程——Linux设备模型
linux·架构·操作系统
望获linux5 天前
【Linux基础知识系列】第四十篇 - 定制彩色终端与 Prompt
linux·运维·前端·chrome·操作系统·开源软件·嵌入式软件
望获linux15 天前
【实时Linux实战系列】实时I/O操作与中断处理
linux·服务器·microsoft·操作系统·交互·rtos·嵌入式软件
redreamSo15 天前
世俗点,假如幸福能量化,公式是什么?
操作系统
智践行16 天前
ROS2 Jazzy:编写可组合节点(C++)
操作系统