软件运行机制和内存管理

内存的特殊地位

操作系统的核心职能是软件治理,而软件治理的一个很重要的部分是让多个软件可以共同合理使用计算机的资源不至于出现争抢的局面。

CPU可以直接访问的存储资源非常少,只有:寄存器、内存(RAM)、主板上的 ROM。寄存器的访问速度非常快但数量很少,大部分程序员不和他直接打交道,直接与他打交道的是编程语言的编译器,编译器会自动选择寄存器来优化程序的运行性能。主板上的 ROM 是非易失的只读存储,适合存放计算机的启动程序 BIOS。

所以,内存是唯一的 CPU 内置支持且和程序员直接打交道的基础资源。内存存储我们程序的输入输出数据以及程序本身。

计算机的运行过程

对于 CPU 来说,“计算”过程从计算机加电启动,执行 BIOS 程序的第一条指令开始到最后关机,整个就是一个完整的“计算”过程,这个过程有多少个“子计算过程”他并不关心。从操作系统的角度,计算机从开机到关机,整个“计算”过程,由很多软件,也就是“子计算过程”共同完成。计算机完整的计算过程如下:BIOS——>引导区引导程序——>OS 引导程序——>OS Shell 程序——>软件

内存管理

CPU 的实模式和保护模式

这两个模式CPU对内存的操作方式完全不同,在实模式下,CPU直接通过物理地址访问内存;在保护模式下,CPU通过一个地址映射表把虚拟的内存地址转为物理的内存地址,然后再去读取数据。

实模式下的内存管理

在实模式的操作系统下,所有的软件包括操作系统本身都在同一个物理地址空间下。在CPU看来,他们是同一个程序。操作系统有两种方式去分配内存:

一、把操作系统内存管理相关的函数地址放到一个大家公认的地方,每个软件想要申请内存就在这个地方取得内存管理函数并调用他

二、把内存管理功能设计为一个中断请求。内存的全局中有一个中断向量表,本质上就是在一个大家公认的地方放了一堆函数地址。例如键盘按了一个键会触发9号中断,在CPU收到中断请求时他会先停下手头的活来响应中断请求,完成之后再回去干原来的活。

内存在运行外置存储上的软件时会把软件完整地从外置存储读入到内存然后执行它。

实模式有两个比较显著的问题:安全性,软件之间可以随意修改对方的数据和程序指令;支持的软件复杂性低,可同时运行的软件数量少

保护模式下的内存管理

保护模式内存访问不再是直接通过物理内存,而是基于虚拟内存。虚拟内存模式,整个内存空间被分成很多个连续的内存页,每个内存页的大小是固定的,比如64K。每次 CPU 访问某个虚拟内存地址中的数据,他都会计算出这是要访问哪个内存页,然后CPU再通过一个地址映射表,把虚拟的内存地址转为物理的内存地址然后这个物理内存地址再去读取数据。地址映射表是一个数组,下标是内存页页号,值是该内存页对应的物理内存首地址。

某个内存页对应的物理内存地址可能不存在,这种情况叫缺页,没法读取数据,这时CPU会发起一个中断请求。这个缺页的中断请求会被操作系统接管,发生缺页时,操作系统会为这个内存页分配物理的内存,并回复这个内存页的数据。如果没有空闲的物理内存可以分配,他就会选择一个最久没有被访问的内存页进行淘汰。淘汰前会把内存页的数据保存起来,下次CPU访问被淘汰的内存页时一样会发生缺页中断请求,操作系统会恢复该内存页的数据。

通过这个虚拟内存机制,操作系统并不需要一上来就把整个软件装进内存中,而是通过缺页中断按需加载对应的程序代码片段。多个软件同时运行的问题也解决了,内存不够用的时候就把最久远的没用过的内存页淘汰掉腾出物理内存出来。

中断:中断的设计初衷是CPU响应硬件设备的一个机制。当某个输入输出设备发生一件需要CPU来处理的事情,他就会触发一个中断;但是CPU也提供了指令允许软件触发一个软中断。大部分情况,操作系统的能力通过软中断向我们写的软件开放,为此还专门引入了一个术语“叫系统调用”