Lesson 09 虚拟内存
在上一讲中,我们讨论了如何虚拟化处理器(线程)。这一讲,我们将讨论硬件抽象的内存虚拟化。
老师原本的思路是先讲分段的功能再介绍分页,但是从操作系统的角度上来看,我们先讲分页再讲分段会更好一些。
1. 虚拟内存与页表
虚拟内存的核心在于:程序不再直接访问物理内存,而是访问一个巨大的、虚构的虚拟地址空间。
- 页表:
- 理解:页表负责把个体看到的虚拟地址翻译成物理内存中真实的地址。
- 过程:CPU 将虚拟地址拆分为页号和页内偏移。通过查表:
虚拟页号 → 物理块号,再拼上偏移量,就找到了数据。
- 当 CPU 访问虚拟地址但在页表中找不到对应的物理映射时,会触发页错误。如果地址合法但数据在磁盘上,内核会透明地将数据换入内存并恢复程序执行。这种延迟绑定的技巧让我们可以运行规模远超物理内存的程序。
- 隔离:通过页表,两个进程可以使用完全相同的虚拟地址,但它们被映射到了不同的物理区域。
2. 内存分段(安全与功能)
有了页表的空间映射,我们还需要对这些空间进行精细化的管理,这就是分段的初衷。
- 核心思路:将内存划分为具有特定功能的“段”(代码段、数据段、栈段),每个段分配不同的权限。
- 硬件支持:CPU 增加了分段寄存器记录起始地址,并由内存管理器进行实时判断。
- 权限控制(R/W/X):这是安全性的飞跃。
- R(只读):保护常量不被修改。
- RX(只读执行):保护代码不被恶意覆盖。
- RW(读写):允许变量数据的变动。
- 收益:即使程序由于漏洞被注入了恶意代码,分段权限也能通过“禁止在数据段执行代码”来拦截攻击。
3. 内核与特权切换:受保护的“门”
为了管理这些页表和分段权限,系统必须有一个拥有最高权力的裁判,这就是内核。
- 双特权级设计:CPU 划分为内核态(最高权限,可修改页表/寄存器)和用户态(普通权限)。
- 进入内核之门(The Gate):用户程序不能直接进入内核,必须通过特定的“门”:
- 用户态 → 内核态:应用程序通过执行
SVC(系统调用指令)并传递一个Gate标识符。这个过程是原子性的,确保内核能安全、唯一地接管控制权。 - 内核态 → 用户态:内核处理完请求后,将 CPU 状态设回用户态并跳回原程序。
- 用户态 → 内核态:应用程序通过执行
- 内核的重要作用:它是系统中的可信中介,是唯一可以执行特权指令的程序。
4. 对照
Lesson 09 Virtual Memory
In the previous lesson, we discussed how to virtualize the processor (threads). In this lesson, we will explore Memory Virtualization, the next pillar of hardware abstraction.
While the teacher’s original approach was to introduce the functions of Segmentation before Paging, we will flip the order here as it provides a better perspective from an Operating Systems standpoint.
1. Virtual Memory and Page Tables
The core of Virtual Memory is that programs no longer access physical memory directly; instead, they access a vast, fictional Virtual Address Space.
- The Page Table:
- Understanding: The Page Table is responsible for translating the virtual addresses seen by an individual process into real addresses in physical RAM.
- The Process: The CPU splits the virtual address into a Page Number and an Offset. By looking up the table:
Virtual Page Number → Physical Block Number, and then appending the offset, the actual data is located.
- Page Faults: When the CPU accesses a virtual address but cannot find a corresponding physical mapping in the page table, it triggers a Page Fault. If the address is valid but the data resides on the disk, the kernel transparently swaps the data into memory and resumes execution. This Delayed Binding (Demand Paging) technique allows us to run programs that are significantly larger than the available physical memory.
- Isolation: Through page tables, two separate processes can use identical virtual addresses, yet they are mapped to entirely different physical regions, ensuring they never interfere with one another.
2. Memory Segmentation (Security and Functionality)
While page tables provide spatial mapping, we still need fine-grained management of these spaces—this is the primary purpose of Segmentation.
- Core Concept: Divide memory into functional “segments” (such as Code, Data, and Stack), assigning specific permissions to each.
- Hardware Support: The CPU includes Segment Registers to record the base address of each segment, while a Memory Manager performs real-time validation during every access.
- Permission Control (R/W/X): This represents a leap in system security.
- R (Read-Only): Protects constants from being modified.
- RX (Read/Execute): Protects code from being maliciously overwritten.
- RW (Read/Write): Allows for the dynamic changing of variable data.
- Benefits: Even if a program is injected with malicious code due to a vulnerability, segmentation permissions can intercept the attack by “disallowing the execution of code within the data segment.”
3. The Kernel and Privilege Switching: The Protected “Gate”
To manage these page tables and segmentation permissions, the system requires a referee with supreme authority: the Kernel.
- Dual Privilege Levels: The CPU is split into Kernel Mode (highest privilege, capable of modifying page tables and registers) and User Mode (restricted privilege for normal applications).
- Entering the Kernel (The Gate): User programs cannot enter the kernel arbitrarily; they must pass through a specific “Gate”:
- User Mode → Kernel Mode: An application executes an
SVC(Supervisor Call) instruction and passes aGateidentifier. This process is atomic, ensuring that the kernel takes control safely and uniquely. - Kernel Mode → User Mode: Once the kernel has processed the request, it sets the CPU back to User Mode and jumps back to the original program.
- User Mode → Kernel Mode: An application executes an
- The Crucial Role of the Kernel: It serves as the Trusted Intermediary of the system and is the only program permitted to execute privileged instructions.