3951 字
20 分钟
1.3操作系统运行环境

1.3 操作系统的运行环境#

1.3.1 操作系统内核#

现代操作系统通常采用分层架构,将与硬件紧密相关的模块(如中断处理程序、设备驱动程序)、运行频率较高的模块(如时钟管理、进程调度),以及各模块共用的基础操作,集中置于紧靠硬件的层次并常驻内存。这部分核心组件被称为操作系统内核。这种设计有两个主要目的:一是保护核心模块免受应用程序破坏;二是提升操作系统的运行效率。不同操作系统的内核功能存在一定差异,但大多数都包含以下两类功能:

1. 支撑功能#

这类功能为操作系统其他模块提供基础支持,以保障系统稳定且高效地运行。

  1. 时钟管理。时钟是计算机系统的关键部件,其功能包括计时和产生定时中断。操作系统通过时钟管理向用户提供标准系统时间,并利用时钟中断实现任务调度。例如,在分时操作系统中通过时间片轮转进行进程切换,在实时操作系统中依据截止时间控制任务执行,在批处理系统中衡量作业运行进度。因此,系统的大量活动均依赖于时钟机制
  2. 中断机制中断是现代操作系统运行的基础,它允许CPU在I/O操作期间执行其他指令,从而提高资源利用率。中断来源广泛,包括键盘输入、鼠标事件、系统调用、设备驱动和文件访问等。当发生中断时,内核负责保存当前进程的现场,转移控制权至相应的处理程序,并在处理完成后恢复现场,有效提升了系统的并发处理能力。
  3. 原语。原语是由若干条指令组成的、用于完成特定功能的操作,具有原子性,即其执行过程不可被中断,必须一气呵成。原语通常运行在内核态,执行时间短、调用频繁,是保证系统安全性和一致性的重要机制。常见的原语包括进程切换、进程同步和资源分配等。为实现原子性,原语常通过关闭中断等手段确保执行不被干扰。

2. 系统资源管理功能#

操作系统通过一系列核心数据结构(如进程控制块、设备控制块、内存分配表、缓冲区等)对系统资源进行统一管理。为实现高效、安全的资源使用,内核需提供以下三类基本管理功能:

  1. 进程管理。负责进程的创建与撤销、状态转换、调度与分派,并维护进程控制块(PCB)等核心数据结构。
  2. 存储器管理。实现内存的分配与回收、地址映射、内存保护及页面置换等机制,确保多道程序安全、高效地共享主存资源。
  3. 设备管理。完成设备的分配与回收、缓冲区管理、I/O调度及设备驱动调用,屏蔽硬件差异,为用户提供统一的设备访问接口。

1.3.2 处理机的双重工作模式#

为确保操作系统正确运行,必须严格区分操作系统代码与用户程序的执行环境。绝大多数计算机系统通过硬件支持实现这一区分,即为处理机设置至少两种独立的运行模式:用户态(也称目态)和内核态(也称管态系统态)。硬件通过一个模式位标识当前运行模式(例如0表示内核态,1表示用户态),从而明确当前执行的是系统任务还是用户任务。

系统引导时,硬件从内核态开始工作,完成操作系统的加载后,切换到用户态执行用户程序。一旦发生中断或陷阱,硬件就会自动从用户态切换至内核态(模式位置0)。因此,操作系统一旦获得控制权,就处于内核态;而在将控制权交还用户程序前,将切换回用户态(模式位置1)。

这种双重模式机制通过指令分类提供保护:将可能危及系统安全的指令定义为特权指令仅允许在内核态下执行;其余指令定义为非特权指令可在任意模式下执行。具体如下。

  1. 特权指令。仅能在内核态执行,可访问全部地址空间(包括用户空间和系统空间),并执行关键操作,如启动外设、设置系统时钟、关闭中断、修改模式位或返回用户态等。
  2. 非特权指令。通常在用户态下执行,主要用于一般计算和数据处理,其内存访问被限制在用户地址空间,无法直接操作硬件或系统核心资源。

上述限制由硬件强制实施:若用户程序试图执行特权指令,则硬件将产生非法指令异常;操作系统捕获该异常后,会终止该程序并重新调度。

1.3.3 中断和异常的概念#

在引入内核态与用户态之后,操作系统必须解决两者之间的安全切换问题。内核运行在内核态,用户程序运行在用户态;用户程序虽不能直接执行内核功能,却必须通过受控方式使用这些服务。为此,系统在内核中设立若干称为“门”的受控入口,而用户程序进入内核态的唯一合法途径就是中断或异常。当CPU运行用户程序时,一旦发生中断(如I/O完成)或异常(如系统调用、除零错误),硬件会自动将处理器切换至内核态,并跳转至内核中对应的处理程序。这一机制由硬件强制保障,确保状态切换的安全性与原子性。

中断机制对现代操作系统至关重要。操作系统的演进本质上是不断提升资源利用率的过程:当某程序因等待I/O等事件而暂时无法继续执行时,系统需及时将其挂起,转而调度其他就绪程序运行。在抢占式多任务系统中,这一调度行为主要依赖中断(尤其是时钟中断)来触发。因此,中断机制是现代操作系统实现高效并发与资源共享的基础。

1. 中断和异常的定义#

中断(Interrupt)也称外中断,是指来自CPU执行指令外部的事件,通常用于信息输入/输出(见第5章),如设备发出的I/O结束中断,表示设备I/O操作已完成。时钟中断,表示一个固定的时间片已到,用于系统计时、进程调度或启动定时任务等。

异常(Exception)也称内中断,是指来自CPU执行指令内部的事件,如程序的非法操作码、地址越界、运算溢出、虚存系统的缺页及专门的陷入指令等引起的事件。异常一旦发生,就必须立即处理,不可被屏蔽。

2. 中断和异常的分类#

外中断可分为可屏蔽中断和不可屏蔽中断。可屏蔽中断是指通过INTR线发出的中断请求,通过改变屏蔽字可以实现多重中断,从而使得中断处理更加灵活。不可屏蔽中断是指通过NMI线发出的中断请求,通常是紧急的硬件故障,如电源掉电等。此外,异常也是不能被屏蔽的。

异常可分为故障、自陷和终止。故障(Fault)通常是由指令执行引起的异常,如非法操作码、缺页故障、除数为0、运算溢出等。自陷(Trap,也称陷入)是一种事先安排的“异常”事件,用于在用户态下调用操作系统内核程序,如条件陷阱指令、系统调用指令等。终止(Abort)是指出现了使得CPU无法继续执行的硬件故障,如控制器出错、存储器校验错等。故障和自陷异常属于软件中断(程序性异常),终止异常和外中断属于硬件中断

3. 中断和异常的处理过程#

中断和异常处理过程的大致描述如下:当CPU在执行用户程序的第 ii 条指令时,若该指令引发异常(如缺页、除零),或在指令执行结束后检测到中断请求信号,则CPU会打断当前程序,转入相应的中断或异常处理程序执行。若问题可被处理程序解决,则对于异常,通常在处理完成后返回第 ii 条指令重新执行(例如,缺页处理完成后重访原内存地址);而对于中断,则在处理完成后返回第 i+1i+1 条指令继续执行。若处理程序判定为不可恢复的致命错误,则终止该用户程序。通常情况下,中断和异常的具体处理由操作系统(及设备驱动程序)完成。

注意区分中断处理和子程序调用:

  1. 中断处理程序与被中断的程序相互独立,无固定关联;而子程序与主程序属于同一程序的主从关系。
  2. 中断的产生通常是随机的;而子程序调用由CALL指令显式触发,是程序员事先安排的。
  3. 子程序调用完全由软件实现;而中断处理需要硬件电路支持才能完成。
  4. 中断处理程序的入口地址由中断向量表直接提供;子程序的入口地址则由CALL指令中的地址码指定。
  5. 调用中断处理程序和子程序均需保护程序计数器(PC)的内容:前者由硬件在中断响应过程中自动保存,后者由CALL指令在执行时将当前PC压入栈中。
  6. 响应中断时,需对同时到达的多个中断请求进行优先级裁决;而子程序调用不存在此类操作。

1.3.4 系统调用#

系统调用是操作系统提供给应用程序(程序员)使用的接口,可视为一种特殊的公共子程序调用。系统中的各种共享资源均由操作系统统一管理,因此凡涉及共享资源的操作(如存储分配、I/O传输及文件管理等),都必须通过系统调用向操作系统提出服务请求,由操作系统代为完成,并将结果返回给应用程序。这样可以保证系统的稳定性和安全性,防止用户进行非法操作。通常,一个操作系统提供的系统调用有几十条乃至上百条,每个系统调用都有唯一的系统调用号。这些系统调用按功能大致可分为如下几类。

  • 设备管理。完成设备的请求或释放,以及设备启动等功能。
  • 文件管理。完成文件的读、写、创建及删除等功能。
  • 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
  • 进程通信。完成进程之间的消息传递或信号传递等功能。
  • 内存管理。完成内存的分配、回收,以及获取作业占用内存区的大小和起始地址等功能。

显然,系统调用涉及系统资源管理、进程管理等关键操作,对整个系统的影响非常大,因此必须由操作系统内核程序在内核态下完成。操作系统提供系统调用的核心目的,是让应用程序能够安全地间接调用内核功能。它本质上是一种特殊的过程调用,与普通过程调用存在显著差异。

  1. 运行状态不同。普通过程调用的调用者与被调用者运行在同一特权级;而系统调用的调用者运行在用户态,被调用者运行在内核态。
  2. 状态转换不同。普通过程调用无须特权级切换,可以直接跳转;系统调用则需要通过陷入指令(Trap)触发,先从用户态切换到内核态,再由内核分派至相应处理程序。
  3. 返回机制不同。系统调用执行完毕后,内核可能根据调度策略决定是否切换进程;而普通过程调用总是直接返回原调用点。
  4. 嵌套调用限制不同。系统调用的嵌套深度受到内核栈空间的限制;而普通过程调用的嵌套深度通常仅受用户栈大小约束。

系统调用的处理过程可分为4个阶段。

  1. 传递系统调用参数。用户程序将系统调用号及所需参数压入堆栈(或通过寄存器),为内核服务做准备。
  2. 执行陷入指令并切换至内核态。用户程序执行陷入指令,触发CPU从用户态切换至内核态。硬件与内核协同保存现场,将PC、PSW及通用寄存器内容压入内核堆栈。
  3. 定位并执行相应服务程序。内核根据系统调用号查询系统调用表,找到对应处理程序的入口地址,并执行具体的服务逻辑。
  4. 恢复现场并返回用户态。服务完成后,内核恢复被中断进程的CPU现场,将运行模式切换回用户态,并将控制权交还给用户程序,使其从断点继续执行。

用户程序通过执行陷入指令,主动将CPU控制权移交操作系统内核;内核完成请求后,再将控制权交还。这一机制确保了用户程序无法直接执行高危操作,必须通过受控接口请求操作系统代为执行,进而保障系统安全与稳定。由此,可概括操作系统的运行环境:用户程序运行在受限的用户态,通过系统调用(主动)或异常/中断(被动)两种受控途径进入内核态,请求内核提供资源管理与服务支持;内核处理完毕后,再安全返回用户态继续执行。这种用户态与内核态的隔离,构成了现代操作系统安全、高效运行的基础环境。

在操作系统层面,我们关注内核态与用户态的软件实现与切换机制;其硬件支持细节可结合“计算机组成原理”课程中关于中断与异常的内容深入理解。

常见的用户态转向内核态的情形包括:

  1. 用户程序请求操作系统服务(系统调用)。
  2. 发生外中断(如I/O完成、时钟信号)。
  3. 用户程序执行过程中产生异常(如除零、缺页)。
  4. 用户程序试图执行特权指令,从而触发异常。

从内核态返回用户态由内核通过特定的返回指令(如IRET)完成,该操作在内核态执行。

评论