操作系统-受限直接执行(Limited Direct Execution, LDE)

概述

虚拟化 CPU的概念:操作系统需要以某种方式让许多任务共享物理CPU,让它们看起来像是同时运行。

在本节需要解决的关键问题是:如何高效可控地虚拟化 CPU?

解决方法:采用受限直接执行(Limited Direct Execution, LDE)机制

直接执行的概念

直接执行:直接在CPU上运行程序即可。使用正常的调用(call)跳转到用户程序的main(),用户程序结束后返回内核。

image-20210824004926563

直接执行存在的问题

优点:快速。该程序直接在硬件 CPU 上运行,因此执行速度与预期的 一样快。

存在的问题:不可控(对用户程序没有限制,且不能切换进程(时分共享))

  1. 对用户程序没有限制(用户程序可能做出危害行为)
  2. 不能切换进程(即没有完成时分共享的目标)

问题1: 受限制的操作

硬件通过提供不同的执行模式来协助操作系统。

  • 用户模式(user mode)。在用户模式下运行的代码会受到限制,应用程序不能完全访问硬件资源。例如,I/O请求等。
  • 内核模式(kernel mode):操作系统(或内核)就以这种模式运行。 在此模式下,运行的代码可以做它喜欢的事,包括特权操作,如发出 I/O 请求和执行所有类 型的受限指令。

系统调用:即用户程序向内核请求服务,比如读一个文件(read)、创建新进程(fork),加载新程序(execve)等。通过系统调用可以实现用户程序受限制的操作。

如果一个进程正在用户态中运行一个用户程序,并且需要一个系统服务,比如从一个文件读数据,那么它就必须执行一个陷阱或系统调用指令,将控制转移到操作系统。(即从用户模式切换到内核模式)操作系统接着通过参数检查,找出所需要的调用进程。然后,它执行系统调用,并把控制返回给在系统调用后面跟随着的指令。(即从内核模式切换到用户模式)

系统调用通过如下指令进行模式切换:

  • 陷入(trap):用户模式->内核模式

  • 从陷阱返回(return-from-trap):内核模式->用户模式

这两条指令类似于过程调用中的call,ret,但又有所不同:

  1. 系统调用切换到内核态。而过程调用指令并不改变模式。
  2. 过程调用给定过程所在的相对或绝对地址,TRAP指令不能跳转到任意地址上。根据机器的体系结构,或者跳转到一个单固定地址上,或者指令中有一8位长的字段,它给定了内存中一张表格的索引(陷阱表),这张表格中含有跳转地址。
image-20210824151142326

问题2: 进程切换

协作模式

协作(cooperative)模式:操作系统相信系统的进程会合理运行。OS 通过等待系统调用(显式的 yield 系统调用),或某种非法操作发生,从而重新获得 CPU 的控制权。

代表:早期版本的 Macintosh 操作系统或旧的 Xerox Alto 系统。

缺点:过于被动

非协作模式

时钟中断(timer interrupt):时钟设备可以编程为每隔几毫秒产生一次中断。产生中断时,当前正在运行的进程停止,操作系统中预先配置的中断处理程序(interrupt handler)会运行。此时,操作系统重新获得 CPU 的控制权,通过运行调度程序来做出是否切换进程。

image-20210824153451972

一些小问题

保存和恢复上下文

为了保存当前正在运行的进程的上下文,操作系统会执行一些底层汇编代码,来保存通用寄存器、程序计数器,以及当前正在运行的进程的内核栈指针,然后恢复寄存器、程序计数器,并切换内核栈,供即将运行的进程使用。

# void swtch(struct context **old, struct context *new); 2#
# Save current register context in old
# and then load register context from new.
.globl swtch
swtch:
# Save old registers
movl 4(%esp), %eax # put old ptr into eax popl 0(%eax) # save the old IP
movl %esp, 4(%eax) # and stack
movl %ebx, 8(%eax) # and other registers movl %ecx, 12(%eax)
movl %edx, 16(%eax)
movl %esi, 20(%eax)
movl %edi, 24(%eax)
movl %ebp, 28(%eax)
# Load new registers
movl 4(%esp), %eax # put new ptr into eax
movl 28(%eax), %ebp # restore other registers
movl 24(%eax), %edi
movl 20(%eax), %esi
movl 16(%eax), %edx
movl 12(%eax), %ecx
movl 8(%eax), %ebx
movl 4(%eax), %esp # stack is switched here
pushl 0(%eax) # return addr put in place
ret # finally return into new ctxt

并发

在中断或陷阱处理过程发生另一个中断?

简单的解决办法:关中断,即在中断处理期间禁止中断。

reference

[1]操作系统导论(ostep)

[2]现代操作系统

[3]深入理解计算机系统(csapp)

posted @ 2021-08-24 15:46  zju_cxl  阅读(293)  评论(0编辑  收藏  举报