Files

697 lines
26 KiB
Markdown
Raw Permalink Normal View History

2026-06-13 23:46:22 +08:00
# 第1.5章 系统运行机制
> [!abstract] 学习目标
> 1. 理解多进程并发运行的场景及其对硬件支持的需求
> 2. 掌握中断机制的工作原理,理解时钟中断对操作系统的核心作用
> 3. 理解 MMU存储管理部件如何实现进程隔离与地址转换
> 4. 掌握 CPU 双模式工作原理(内核模式 vs 用户模式)及特权指令的划分
> 5. 理解系统调用的完整流程(从用户程序到内核服务)
> 6. 理解广义中断的分类(外部中断、异常)
> 7. 能够综合运用上述机制,解释操作系统如何实现多任务并发执行
> [!info] 前置知识
> - 计算机组成原理CPU、内存、寄存器的基本概念
> - 二进制与地址的基本概念
> - 进程的基本概念(参见 [[06_进程控制]]
---
## 一、为什么需要系统运行机制?
### 1.1 多进程并发运行场景
在现代操作系统中,多个进程需要**并发**(交替)执行。考虑两个进程 A 和 B
```
进程 A 的代码: 进程 B 的代码:
A:1 B:1
A:2 B:2
A:3 B:3
A:4 B:4
A:5 B:5
```
实际在 CPU 上的执行顺序可能是:
```
时间线 → A:1 B:1 A:2 B:2 A:3 B:3 B:4 A:4 A:5 B:5
```
> [!question] 核心问题
> 这种交替执行不会自然发生CPU 只是一个顺序执行指令的"傻瓜机器",它不会自动在 A 和 B 之间切换。要实现多进程并发运行,**必须有硬件和操作系统的支持**。
实现多进程并发运行需要以下关键机制:
| 机制 | 作用 |
|------|------|
| [[#二、中断机制]] | 让 CPU 能够响应外部事件,实现进程切换的"触发器" |
| [[#三、MMU 存储管理部件]] | 实现进程间的地址隔离,防止互相干扰 |
| [[#四、CPU 工作模式]] | 区分特权操作,保护操作系统内核不被用户程序破坏 |
| [[#五、系统调用机制]] | 为用户程序提供受控的内核服务访问途径 |
---
## 二、中断机制
### 2.1 什么是中断?
**中断**Interrupt是指 CPU 在执行程序的过程中,收到来自外部设备或内部异常的信号,暂停当前程序的执行,转而去处理该事件,处理完毕后再返回原程序继续执行的过程。
> [!tip] 生活类比
> 中断就像你在看书时手机响了(外部中断),你先记住看到哪一页(保存断点),然后去接电话(处理中断),接完电话后回到那一页继续看(恢复执行)。
### 2.2 中断处理流程
CPU 处理一次中断的完整流程如下:
```mermaid
flowchart TD
A["CPU 正在执行用户程序"] --> B{"收到中断请求?"}
B -- "否" --> A
B -- "是" --> C["关中断(防止嵌套中断)"]
C --> D["保存断点<br>PC、PSW 压入内核栈)"]
D --> E["保存通用寄存器<br>(保存进程现场)"]
E --> F["识别中断源<br>(查询中断向量表)"]
F --> G["跳转到中断服务程序<br>PC ← 中断向量地址)"]
G --> H["执行中断服务程序<br>(处理具体的中断事件)"]
H --> I["恢复通用寄存器<br>(恢复进程现场)"]
I --> J["恢复断点<br>PC、PSW 出栈)"]
J --> K["开中断"]
K --> L["继续执行用户程序"]
style A fill:#e1f5fe
style C fill:#ffcdd2
style D fill:#ffcdd2
style G fill:#fff3e0
style H fill:#fff3e0
style J fill:#e1f5fe
```
**关键步骤详解**
1. **关中断**CPU 响应中断后立即关闭中断信号接收,防止在处理一个中断时又被另一个中断打断(中断嵌套)
2. **保存断点**将程序计数器PC和程序状态字PSW压入内核栈记录"回来后从哪里继续执行"
3. **保存现场**:将通用寄存器的内容保存到进程的 PCB进程控制块
4. **识别中断源**通过中断向量表Interrupt Vector Table确定是哪个设备发出的中断
5. **执行中断服务程序**:跳转到对应的中断处理函数,完成实际的处理工作
6. **恢复现场和断点**:从 PCB 恢复寄存器,从栈中弹出 PC 和 PSW
7. **开中断**:重新允许 CPU 接收中断信号
### 2.3 时钟中断 — 操作系统的"心跳"
> [!important] 时钟中断的核心地位
> **时钟中断**Timer Interrupt是由实时时钟RTCReal-Time Clock硬件周期性产生的中断是操作系统实现进程管理的最关键机制。
时钟中断的工作原理:
```mermaid
sequenceDiagram
participant RTC as 实时时钟 (RTC)
participant CPU
participant OS as 操作系统
participant PA as 进程 A
participant PB as 进程 B
PA->>CPU: 正在执行进程 A
RTC->>CPU: 时钟中断(每 10ms
CPU->>OS: 保存 A 的现场,进入内核
OS->>OS: 检查A 的时间片用完了吗?
OS->>CPU: 切换到进程 B
CPU->>PB: 恢复 B 的现场,执行进程 B
RTC->>CPU: 时钟中断(每 10ms
CPU->>OS: 保存 B 的现场,进入内核
OS->>CPU: 切换到进程 A
CPU->>PA: 恢复 A 的现场,执行进程 A
```
**时钟中断频率**:通常为 **10ms 一次**(即每秒 100 次),也称为 **时钟滴答**Clock Tick
> [!warning] 没有时钟中断会怎样?
> 如果没有时钟中断CPU 一旦开始执行某个进程,就永远不会主动让出 CPU。操作系统将无法实现"分时",也就无法让多个进程看起来在"同时"运行。时钟中断是操作系统实现**抢占式调度**的基础。
### 2.4 中断对操作系统的意义
中断机制对操作系统具有根本性的意义:
1. **实现进程并发执行**:时钟中断迫使 CPU 周期性地将控制权交还给操作系统,操作系统可以决定切换到哪个进程
2. **实现 I/O 管理**:设备完成 I/O 操作后通过中断通知 CPUCPU 可以将等待该 I/O 的进程唤醒
3. **实现系统调用**:用户程序通过软中断指令(如 `int $0x80`)请求内核服务
4. **异常处理**CPU 内部发生的异常(如除零、缺页)通过中断机制通知操作系统处理
---
## 三、MMU存储管理部件
### 3.1 为什么需要 MMU
> [!question] 核心问题
> 如果没有地址隔离,进程 A 可以直接读写进程 B 的内存空间,甚至可以修改操作系统内核的代码!这是绝对不允许的。
**没有 MMU 时**:程序中使用的地址 = 物理地址
```
进程 A: MOV [0x1000], 1 → 直接写物理地址 0x1000
进程 B: MOV [0x1000], 2 → 也写物理地址 0x1000 !冲突!
```
**有 MMU 时**:程序中使用的地址是**逻辑地址**(虚拟地址),经过 MMU 转换后才是**物理地址**
```
进程 A: MOV [0x1000], 1 → MMU 转换 → 物理地址 0x5000
进程 B: MOV [0x1000], 2 → MMU 转换 → 物理地址 0x8000 ✓ 不冲突
```
### 3.2 MMU 地址转换原理
MMU 通过**地址变换函数**将不同进程的逻辑地址映射到不同的物理地址区域:
```mermaid
flowchart LR
subgraph 进程A["进程 A"]
LA["逻辑地址空间<br>0x0000 ~ 0xFFFF"]
end
subgraph MMU_Block["MMU存储管理部件"]
TR1["地址变换函数 tr1()"]
end
subgraph PA_Phys["物理内存"]
PA_M["区域 1<br>物理地址 0x5000 ~ 0x14FFF"]
end
LA -->|"逻辑地址 0x1000"| TR1
TR1 -->|"物理地址 0x6000"| PA_M
style LA fill:#e1f5fe
style TR1 fill:#fff3e0
style PA_M fill:#e8f5e9
```
```mermaid
flowchart LR
subgraph 进程B["进程 B"]
LB["逻辑地址空间<br>0x0000 ~ 0xFFFF"]
end
subgraph MMU_Block2["MMU存储管理部件"]
TR2["地址变换函数 tr2()"]
end
subgraph PB_Phys["物理内存"]
PB_M["区域 2<br>物理地址 0x8000 ~ 0x17FFF"]
end
LB -->|"逻辑地址 0x1000"| TR2
TR2 -->|"物理地址 0x9000"| PB_M
style LB fill:#e1f5fe
style TR2 fill:#fff3e0
style PB_M fill:#e8f5e9
```
**关键概念**
| 术语 | 含义 |
|------|------|
| **逻辑地址**(虚拟地址) | 程序中使用的地址,每个进程从 0 开始编址 |
| **物理地址** | 实际内存硬件上的地址,全局唯一 |
| **地址变换函数** | MMU 中的映射规则,每个进程有独立的变换函数 |
> [!tip] 进程隔离的本质
> 每个进程都有自己独立的**逻辑地址空间**,通过 MMU 映射到物理内存中互不重叠的区域。进程 A 无法访问进程 B 的物理内存区域,从而实现了**进程隔离**。
### 3.3 页表与 MMU 保护机制
在现代操作系统中MMU 通常通过**页表**Page Table实现地址转换。页表中除了地址映射信息外还包含保护位
**页表项中的 U/S 位**
| U/S 位值 | 含义 | 访问权限 |
|----------|------|----------|
| 0 | Supervisor内核页 | 仅内核模式可访问 |
| 1 | User用户页 | 内核模式和用户模式均可访问 |
**CPU 标志寄存器中的 IOPL 位**
- `IOPL = 0``1`:用户模式(受限)
- `IOPL = 3`:内核模式(拥有全部 I/O 权限)
**保护机制的工作方式**
```mermaid
flowchart TD
A["CPU 执行指令,访问逻辑地址"] --> B["MMU 查页表"]
B --> C{"当前 CPU 模式?"}
C -- "用户模式" --> D{"页表 U/S 位?"}
D -- "U/S = 1用户页" --> E["允许访问 ✓"]
D -- "U/S = 0内核页" --> F["触发保护异常 ✗<br>终止进程"]
C -- "内核模式" --> G["允许访问所有页面 ✓"]
style E fill:#c8e6c9
style F fill:#ffcdd2
style G fill:#c8e6c9
```
### 3.4 Linux 地址空间划分
操作系统将每个进程的逻辑地址空间划分为**用户空间**和**内核空间**
| 操作系统 | 用户空间 | 内核空间 |
|----------|----------|----------|
| **32 位 Linux** | 低 3GB0x00000000 ~ 0xBFFFFFFF | 高 1GB0xC0000000 ~ 0xFFFFFFFF |
| **32 位 Windows** | 低 2GB0x00000000 ~ 0x7FFFFFFF | 高 2GB0x80000000 ~ 0xFFFFFFFF |
> [!info] 为什么内核空间在高地址?
> 将内核空间放在高地址是一种约定。在 Linux 中,所有进程共享同一个内核空间映射(内核只有一份),但每个进程的用户空间是独立的。当 CPU 处于用户模式时,访问内核空间会触发保护异常。
> [!tip] 相关链接
> 关于存储管理的更多内容,参见 [[13_存储管理基础]] 和 [[14_分页存储管理]]。
---
## 四、CPU 工作模式
### 4.1 双模式设计
现代 CPU 设计了两种工作模式,用于区分"谁可以执行什么指令"
| 模式 | 别名 | 权限 | 使用者 |
|------|------|------|--------|
| **内核模式** | 系统态、核心态、管态 | 可执行所有指令,访问所有内存 | 操作系统内核 |
| **用户模式** | 用户态、目态 | 只能执行非特权指令,不能访问内核空间 | 用户程序 |
> [!warning] 为什么需要两种模式?
> 如果所有程序都运行在内核模式,任何一个用户程序都可以:修改操作系统代码、直接操作硬件、访问其他进程的内存。这将导致系统完全不安全。双模式设计是操作系统**自我保护**的基础。
### 4.2 特权指令 vs 非特权指令
| 分类 | 特点 | 示例 |
|------|------|------|
| **特权指令** | 只能在内核模式下执行 | I/O 指令、停机指令HLT、特殊寄存器访问如修改页表基址寄存器 |
| **非特权指令** | 在任何模式下均可执行 | 算术逻辑运算ADD、SUB、寄存器操作MOV、内存访问普通读写 |
> [!warning] 用户模式执行特权指令会怎样?
> 如果 CPU 处于用户模式时执行了特权指令CPU 会立即触发一个**保护异常**Protection Exception操作系统会终止该进程通常表现为 "Segmentation Fault")。
### 4.3 不同架构的模式标识
CPU 通过标志寄存器中的特定位来标识当前工作模式:
**x86 架构**:使用 FLAGS 寄存器中的 **IOPL**I/O Privilege Level字段
```
FLAGS 寄存器:
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ ... │ IOPL│ IOPL│ ... │ IF │ ... │ ZF │ CF │
│ │ (13)│ (12)│ │ (9) │ │ (6) │ (0) │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
├───IOPL───┤
00 = Ring 0内核模式
11 = Ring 3用户模式
```
**ARM 架构**:使用 CPSRCurrent Program Status Register中的 **M[4:0]**
```
CPSR 寄存器:
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ ... │ M4 │ M3 │ M2 │ M1 │ M0 │ ... │ │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
├─── M[4:0] ───┤
10000 = User用户模式
10011 = Supervisor内核模式
10111 = Abort
11011 = Undefined
10010 = IRQ
10001 = FIQ
```
### 4.4 CPU 模式切换
CPU 模式切换发生在以下场景:
```mermaid
flowchart TD
subgraph 用户模式区["用户模式User Mode"]
A["执行用户程序"]
B["执行非特权指令"]
end
subgraph 内核模式区["内核模式Kernel Mode"]
C["处理中断/异常"]
D["执行系统调用"]
E["执行特权指令"]
end
A -->|"中断/异常发生<br>时钟中断、I/O中断、缺页等"| C
A -->|"系统调用<br>int $0x80 / SWI"| D
C -->|"中断返回<br>IRET"| A
D -->|"系统调用返回<br>IRET"| A
E -->|"设置 IOPL/M[4:0]"| A
style A fill:#e1f5fe
style B fill:#e1f5fe
style C fill:#fff3e0
style D fill:#fff3e0
style E fill:#fff3e0
```
**用户模式 → 内核模式**(两种途径):
1. **中断/异常**:硬件自动切换
- 时钟中断、I/O 中断
- 缺页异常、除零异常
- 系统调用(软中断)
2. **系统调用**:用户程序主动发起
- x86执行 `int $0x80` 指令
- ARM执行 `SWI` 指令
**内核模式 → 用户模式**
- 执行中断返回指令x86: `IRET`),恢复用户模式的状态
---
## 五、系统调用机制
### 5.1 什么是系统调用?
**系统调用**System Call是操作系统提供给用户程序的**唯一合法途径**,用于请求内核提供的服务。
> [!tip] 生活类比
> 系统调用就像银行柜台:你(用户程序)不能自己进入金库(内核空间)取钱,但你可以通过柜台窗口(系统调用接口)告诉工作人员(内核)你要做什么,工作人员帮你完成后再把结果交给你。
### 5.2 系统调用的必要性
用户程序**不能直接调用**内核函数,原因:
1. **地址隔离**:内核函数位于内核空间,用户模式无法访问
2. **权限保护**:内核函数可能执行特权操作(如 I/O用户模式无权执行
3. **安全控制**:内核需要验证参数的合法性,防止恶意调用
### 5.3 系统调用的完整流程
`printf("Hello")` 为例,完整调用链如下:
```mermaid
flowchart TD
A["用户程序<br>printf(#quot;Hello#quot;)"] --> B["C 库函数<br>write(1, #quot;Hello#quot;, 5)"]
B --> C["系统调用包装函数<br>将参数写入寄存器<br>EAX=4 (sys_write 号)<br>EBX=1 (文件描述符)<br>ECX=缓冲区地址<br>EDX=5 (长度)"]
C --> D["软中断指令<br>int $0x80"]
D --> E["CPU 模式切换<br>用户模式 → 内核模式<br>保存断点和现场"]
E --> F["查询系统调用表<br>根据 EAX=4 找到<br>sys_write 函数地址"]
F --> G["执行内核函数<br>sys_write()<br>实际完成屏幕输出"]
G --> H["系统调用返回<br>恢复现场<br>内核模式 → 用户模式"]
H --> I["返回用户程序<br>继续执行"]
style A fill:#e1f5fe
style B fill:#e1f5fe
style C fill:#e1f5fe
style D fill:#ffcdd2
style E fill:#fff3e0
style F fill:#fff3e0
style G fill:#fff3e0
style H fill:#ffcdd2
style I fill:#e1f5fe
```
### 5.4 系统调用的参数传递方式
用户程序通过**寄存器**将参数传递给内核:
**x86 架构的系统调用参数寄存器**
| 寄存器 | 用途 |
|--------|------|
| **EAX** | 系统调用号(标识调用哪个内核函数) |
| **EBX** | 第 1 个参数 |
| **ECX** | 第 2 个参数 |
| **EDX** | 第 3 个参数 |
| **ESI** | 第 4 个参数 |
| **EDI** | 第 5 个参数 |
| **EBP** | 第 6 个参数 |
> [!info] `int $0x80` 指令的作用
> `int $0x80` 是 x86 的**软中断指令**Software Interrupt。执行该指令时CPU 会:
> 1. 自动将 FLAGS、CS、IP 压入内核栈(保存断点)
> 2. 将 CPU 模式切换为内核模式
> 3. 从中断向量表的第 0x80 号表项取出中断服务程序入口地址
> 4. 跳转到该地址开始执行(即系统调用处理函数 `system_call`
### 5.5 系统调用的底层实现
```asm
; x86 Linux 系统调用的底层实现示意
; 用户程序部分C 库包装)
mov eax, 4 ; 系统调用号 = 4 (sys_write)
mov ebx, 1 ; 文件描述符 = 1 (stdout)
mov ecx, msg ; 缓冲区地址
mov edx, 5 ; 字节数
int 0x80 ; 触发软中断,进入内核
; 内核部分system_call
system_call:
; 1. 保存所有寄存器到内核栈
push eax
push ebx
push ecx
push edx
; ...
; 2. 根据 EAX 的值查系统调用表
call [sys_call_table + eax*4]
; 3. 返回值放在 EAX 中
mov [esp + 恢复位置], eax
; 4. 恢复寄存器,返回用户模式
pop edx
pop ecx
pop ebx
pop eax
iret
```
### 5.6 常见的系统调用
| 系统调用号 | 函数名 | 功能 |
|-----------|--------|------|
| 1 | `sys_exit` | 终止进程 |
| 2 | `sys_fork` | 创建子进程 |
| 3 | `sys_read` | 读文件 |
| 4 | `sys_write` | 写文件 |
| 5 | `sys_open` | 打开文件 |
| 6 | `sys_close` | 关闭文件 |
---
## 六、异常(广义中断)
### 6.1 广义中断的分类
在操作系统中,**广义的中断**包括两大类:
```mermaid
flowchart TD
A["广义中断"] --> B["外部中断<br>(硬件中断)"]
A --> C["异常<br>(内部中断)"]
B --> B1["I/O 中断<br>键盘、鼠标、网卡等设备发出"]
B --> B2["时钟中断<br>RTC 周期性发出"]
C --> C1["系统调用<br>用户执行 int $0x80 / SWI"]
C --> C2["缺页异常<br>访问的页面不在内存中"]
C --> C3["断点指令<br>调试器设置的断点"]
C --> C4["算术溢出<br>除零错误等"]
style A fill:#fff3e0
style B fill:#e1f5fe
style C fill:#ffcdd2
```
### 6.2 外部中断 vs 异常
| 特征 | 外部中断 | 异常 |
|------|----------|------|
| **来源** | CPU 外部设备 | CPU 内部执行指令时产生 |
| **发生时机** | 与当前指令无关,随机发生 | 与当前指令直接相关 |
| **是否可屏蔽** | 可屏蔽中断INTR可被 IF 位屏蔽 | 不可屏蔽 |
| **典型例子** | I/O 中断、时钟中断 | 缺页、除零、系统调用 |
### 6.3 常见异常类型
| 异常类型 | 触发条件 | 处理方式 |
|----------|----------|----------|
| **系统调用** | 执行 `int $0x80``SWI` | 查系统调用表,执行对应内核函数 |
| **缺页异常** | 访问的虚拟页面不在物理内存中 | 从磁盘调入页面(参见 [[14_分页存储管理]] |
| **断点指令** | 调试器在代码中设置断点 | 暂停程序,将控制权交给调试器 |
| **算术溢出** | 除零、溢出等运算错误 | 终止进程或通知进程处理 |
| **保护异常** | 用户模式执行特权指令或访问内核空间 | 终止进程Segmentation Fault |
---
## 七、多任务并发执行的综合场景
### 7.1 操作系统如何实现多任务并发
操作系统通过**中断驱动**的方式实现多任务并发执行。以下是几种典型的触发场景:
```mermaid
flowchart TD
A["CPU 正在执行进程 P1"] --> B{"发生了什么?"}
B -->|"时钟中断(每 10ms"| C["进入内核<br>调度器决定是否切换进程"]
B -->|"系统调用"| D["进入内核<br>执行内核函数"]
B -->|"I/O 请求"| E["进程 P1 等待 I/O<br>CPU 分配给其他进程"]
B -->|"进程结束"| F["进程 P1 终止<br>CPU 分配给其他进程"]
C --> G{"调度器决策"}
G -->|"继续执行 P1"| A
G -->|"切换到 P2"| H["保存 P1 现场<br>恢复 P2 现场<br>执行进程 P2"]
D --> I{"系统调用是否阻塞?"}
I -->|"不阻塞"| A
I -->|"需要等待"| E
E --> J["P1 进入等待队列<br>CPU 执行进程 P2"]
F --> K["回收 P1 资源<br>CPU 执行就绪队列中的进程"]
style A fill:#e1f5fe
style C fill:#fff3e0
style D fill:#fff3e0
style E fill:#ffcdd2
style F fill:#ffcdd2
```
### 7.2 四种典型场景详解
**场景一:时钟中断触发进程切换**
```
时间线:
P1 执行 → [时钟中断] → OS 调度 → P2 执行 → [时钟中断] → OS 调度 → P1 执行
↑ 10ms ↑ 10ms
```
**场景二:系统调用触发内核执行**
```
P1 执行 printf → [int $0x80] → 内核执行 sys_write → [iret] → P1 继续执行
```
**场景三I/O 等待导致 CPU 重分配**
```
P1 请求读磁盘 → P1 进入等待队列 → CPU 执行 P2 → 磁盘中断 → P1 就绪 → P1 继续执行
```
**场景四:进程结束释放 CPU**
```
P1 执行 exit() → P1 终止 → OS 回收资源 → CPU 执行就绪队列中的 P2
```
> [!important] 中断是操作系统的"发动机"
> 可以说,**没有中断就没有操作系统**。中断机制是操作系统实现进程管理、I/O 管理、内存管理等所有核心功能的基础。时钟中断让 OS 能够"定期检查"系统状态I/O 中断让 OS 能够响应设备事件,系统调用让 OS 能够为用户程序提供服务。
---
## 八、机制之间的关系
理解了各个机制后,需要看到它们之间的协同关系:
```mermaid
flowchart TD
subgraph 硬件支持
CLK["时钟中断<br>RTC 硬件)"]
MMU_HW["MMU 硬件<br>(地址转换)"]
CPU_MODE["CPU 双模式<br>IOPL/M[4:0]"]
INT_HW["中断控制器<br>PIC/APIC"]
end
subgraph OS核心功能
PROC["进程管理<br>(调度、切换)"]
MEM["内存管理<br>(地址隔离)"]
PROT["系统保护<br>(内核安全)"]
IO["I/O 管理<br>(设备驱动)"]
end
CLK -->|"触发进程切换"| PROC
MMU_HW -->|"地址转换 + 保护"| MEM
CPU_MODE -->|"特权级隔离"| PROT
INT_HW -->|"设备事件通知"| IO
PROC -->|"选择下一个进程"| MEM
MEM -->|"提供地址空间"| PROC
PROT -->|"限制用户操作"| PROC
style CLK fill:#ffcdd2
style MMU_HW fill:#ffcdd2
style CPU_MODE fill:#ffcdd2
style INT_HW fill:#ffcdd2
style PROC fill:#e1f5fe
style MEM fill:#e1f5fe
style PROT fill:#e1f5fe
style IO fill:#e1f5fe
```
> [!tip] 核心要点
> 操作系统的四大运行机制中断、MMU、CPU 模式、系统调用)不是孤立的,而是相互配合:
> - **中断**提供了"进入内核"的途径
> - **CPU 模式**确保了"谁能做什么"
> - **MMU** 保证了"谁的内存谁用"
> - **系统调用**提供了"受控的内核访问"
---
## 思考与练习
以下是 PPT 中给出的复习思考题:
1. **什么是逻辑地址、物理地址?什么是内核空间、用户空间?**
- 提示:逻辑地址是程序中使用的地址,物理地址是内存硬件的实际地址;内核空间是操作系统运行的区域,用户空间是应用程序运行的区域
2. **MMU 的功能是什么,如何实现进程隔离?**
- 提示MMU 负责逻辑地址到物理地址的转换;每个进程有独立的地址变换函数,映射到不同的物理区域
3. **特权指令与非特权指令的特点?**
- 提示:特权指令只能在内核模式执行(如 I/O 指令、停机指令),非特权指令在任何模式都可执行(如算术运算)
4. **两种 CPU 工作模式的特点?**
- 提示:内核模式可执行所有指令、访问所有内存;用户模式只能执行非特权指令、不能访问内核空间
5. **如何利用 MMU 与工作模式防止用户程序破坏 OS**
- 提示MMU 通过页表 U/S 位将内核页标记为仅内核模式可访问CPU 在用户模式执行特权指令会触发保护异常
6. **CPU 模式切换方法?**
- 提示:用户→内核:中断/异常/系统调用(硬件自动切换);内核→用户:执行 IRET 指令
7. **系统调用的作用、原理和实现过程?**
- 提示:作用是让安全地访问内核服务;原理是通过软中断指令触发模式切换;实现过程是参数通过寄存器传递,查系统调用表找到对应函数执行
8. **时钟中断对操作系统的作用?**
- 提示:时钟中断是操作系统实现进程并发执行的基础,它迫使 CPU 周期性地将控制权交还给 OS使 OS 能够进行进程调度
9. **中断对操作系统的意义?**
- 提示:中断是操作系统的"发动机"是实现进程管理、I/O 管理、系统调用等所有核心功能的基础
---
## 相关笔记
- [[02_Linux基础]] — Linux 系统的基本使用
- [[06_进程控制]] — 进程的创建、终止与管理
- [[11_处理机调度]] — 进程调度算法(时钟中断的实际应用)
- [[13_存储管理基础]] — 存储管理的基本概念
- [[14_分页存储管理]] — 分页存储与 MMU 的详细实现
---
## 参考资料
- 《操作系统概念》Operating System Concepts第1章、第2章
- 《深入理解计算机系统》CSAPP第1章、第9章
- 《现代操作系统》Modern Operating Systems第2章