回顾:
- 操作系统内核设计与硬件功能密切相关
- 寄存器提供CPU使用的数据
- MMU将逻辑地址转换为物理地址,抽象出内存硬件的细节
本章小结:
- Kernel and user space 内核和用户空间:内核模式代码比用户模式代码拥有更多的权限
- Interrupts 中断:中断改变了调用内核代码的正常执行流程
- System calls 系统调用:系统调用允许我们运行内核代码来访问操作系统的服务
- The C programming language - an operating systems perspective. C编程语言——操作系统的视角。
内核和用户空间

在内核模式下运行的代码通常被称为内核(kernel)。虽然这是操作系统的核心,但通常它们也会有用户界面、调度守护进程等用户进程。
中断
进入内核以响应事件

CPU不能有效地处于隔离状态。程序,也就是CPU,必须能够响应各种事件。例如:
- 连接的硬件设备可能需要通信
- 时间的流逝
- 糟糕的事情发生了——零除、硬件故障……
中断是处理此类事件的机制。抽象地说,中断是一种改变正常执行流程的机制。
- 可以异步发生(asynchronously),由CPU外部的不可预测因素触发,例如用户输入(有时术语interrupt是为这个类保留的);
- 也可以同步发生(synchronously),由CPU执行指令直接触发(有时这个类使用术语exception)
中断机制
- CPU正在做一些工作,例如运行一个用户进程进行一些计算
- 中断由硬件设备发出信号——例如,指示某些IO数据可用
-
CPU记录其当前状态的各个方面,切换到内核模式,并在处理程序中运行代码来为中断服务
-
一旦完成,CPU将返回处理其他任务
挑战
处理中断是操作系统实现中比较具有挑战性的任务之一:
中断可以在任何时候出现
- 理想情况下,处理中断的时间不应该太长
- 处理程序可以将工作拆分为立即处理的顶部组件和计划稍后处理的底部组件
中断可能被其他中断打断 - 必须可以嵌套中断处理程序
有时,关键代码不能被中断,必须暂时禁用
CPU利用率
阻塞IO (Blocking IO):幼稚的IO,浪费CPU周期等待缓慢的设备响应。
,
,
,
, 
,
,
, 
中断:当有工作要做时,中断“回调”支持更好的CPU使用率。
,
,
, 
,
,
, 
, 
系统调用
通过软件请求进入内核
系统调用是程序向操作系统请求服务的方式。典型的系统调用:
- 请求内存
- 访问文件
- 运行程序(进程)
- 访问并发特性
我们可以区分API和系统调用:
- API是一种编程接口——通常是在用户空间中运行的函数库,例如pthreads
- 为了提供所需的特性,API可能需要进行系统调用来访问所需的功能
- 这种关系不一定是一对一的——单个API函数可能调用零个、一个或多个系统调用
- 通常程序员使用不那么繁琐的术语,并简单地引用API作为系统调用
系统调用如何允许用户进程运行内核空间代码?——系统调用机制:
- 某些用户代码正在运行
- 系统调用是必需的,每个系统调用都有一个唯一的系统调用号
- 系统调用号码存储在指定的寄存器中
- 系统调用参数存储在指定的寄存器中
- 同步中断(异常)是由一个被称为陷阱(trap)的指令触发的
- 中断由内核模式代码处理,内核模式代码调用提供所需功能的系统调用服务例程
- 操作系统继续运行调用代码
系统调用服务例程实际上可能不会立即为请求提供服务——例如,它必须等待某些资源(如IO)
操作系统可能无法继续运行原始调用程序
系统调用是内核为了系统上运行的所有东西的利益而完成工作的大好机会
具体细节因操作系统而异
现代方法可能会避免基于中断的机制,并出于效率原因使用其他CPU支持
C编程语言
操作系统实现语言的标准
为什么我们要选择像C这样古老的语言来实现操作系统呢?

性能
作为通用软件,操作系统必须足够快,以满足尽可能多的用户。
- 一个慢的操作系统会减慢它运行的每个程序
- 移动硬件还必须考虑能源效率
- 对性能的偏好超过了简单、优雅和可维护性
- 不能牺牲正确性
可移植性
由于操作系统开发是困难的,重用是可取的。
- 必须直接在硬件上运行-没有直译式语言。
- 理想情况下,必须能够编译许多不同的硬件平台。
可预测性
对于用户程序,操作系统的行为必须是可预测的。
- 例子-游戏不能容忍不可预测的延迟,减慢帧速率和响应速度。
- 不可预测的行为(如垃圾回收:编程中的一种自动机制,用于释放不再使用的资源(如分配的内存))是不合适的。
1385

被折叠的 条评论
为什么被折叠?



