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的基本机制。但是,一个主要问题尚未得到解答:我们应该在给定时间运行哪个进程?调度程序必须回答的正是这个问题,因此也是我们研究的下一个主题。
相关推荐
小小小小钰儿39 分钟前
2.1-Windows本地部署大模型
人工智能·windows·计算机·网络安全·操作系统·编程
流浪00116 小时前
Linux系统篇39——线程(四) pthread库的由来和线程的创建与等待
linux·操作系统·线程·pthread库
流浪0011 天前
Linux系统篇42——线程(七) pthread库管理线程的工作流,从创建到回收
linux·操作系统·线程·线程创建到销毁
云计算练习生1 天前
什么是 Linux?从 Unix 到开源生态的完整脉络
linux·开源·操作系统·unix
云计算练习生2 天前
什么是上下文切换?进程切换时 CPU 到底在保存什么
linux·服务器·操作系统·进程切换
CS创新实验室4 天前
为什么三台机器就能选出一个“带头大哥“?——Raft 一致性算法,一次讲透
分布式·操作系统
sweet丶4 天前
iOS 为什么没有内存交换分区(swap)
操作系统
我爱cope10 天前
【操作系统 | 计算机硬件:CPU、内存与 I/O 如何支撑操作系统?】
学习·操作系统
NineData10 天前
NineData 与统信服务器操作系统完成兼容认证
数据库·oracle·操作系统·软件·数据库管理工具·ninedata·统信
DataScience_201911 天前
系统|dup2:文件描述符复制的艺术
操作系统