From f6a18d86480698f174659e11139ac1bb454dd58e Mon Sep 17 00:00:00 2001 From: wyfcyx Date: Tue, 15 Oct 2024 16:15:25 +0000 Subject: [PATCH] deploy: ea80a825ac8af60a7157a72cb9d90d0211f9d832 --- _sources/chapter4/2address-space.rst.txt | 2 +- chapter4/2address-space.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_sources/chapter4/2address-space.rst.txt b/_sources/chapter4/2address-space.rst.txt index d3223b58f..a62dd184f 100644 --- a/_sources/chapter4/2address-space.rst.txt +++ b/_sources/chapter4/2address-space.rst.txt @@ -24,7 +24,7 @@ 地址虚拟化出现之前 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -我们之前介绍过,在远古计算机时代,整硬件资源只用来执行单个裸机应用的时候,并不存在真正意义上的操作系统,而只能算是一种应用函数库。那个时候,物理内存的一部分用来保存函数库的代码和数据,余下的部分都交给应用来使用。从功能上可以将应用占据的内存分成几个段:代码段、全局数据段、堆和栈等。当然,由于就只有这一个应用,它想如何调整布局都是它自己的事情。从内存使用的角度来看,批处理系统和裸机应用很相似:批处理系统的每个应用也都是独占内核之外的全部内存空间,只不过当一个应用出错或退出之后,它所占据的内存区域会被清空,而应用序列中的下一个应用将自己的代码和数据放置进来。这个时期,内核提供给应用的访存视角是一致的,因为它们确实会在运行过程中始终独占一块固定的内存区域,每个应用开发者都基于这一认知来规划程序的内存布局。 +我们之前介绍过,在远古计算机时代,整个硬件资源只用来执行单个裸机应用的时候,并不存在真正意义上的操作系统,而只能算是一种应用函数库。那个时候,物理内存的一部分用来保存函数库的代码和数据,余下的部分都交给应用来使用。从功能上可以将应用占据的内存分成几个段:代码段、全局数据段、堆和栈等。当然,由于就只有这一个应用,它想如何调整布局都是它自己的事情。从内存使用的角度来看,批处理系统和裸机应用很相似:批处理系统的每个应用也都是独占内核之外的全部内存空间,只不过当一个应用出错或退出之后,它所占据的内存区域会被清空,而应用序列中的下一个应用将自己的代码和数据放置进来。这个时期,内核提供给应用的访存视角是一致的,因为它们确实会在运行过程中始终独占一块固定的内存区域,每个应用开发者都基于这一认知来规划程序的内存布局。 后来,为了降低等待 I/O 带来的无意义的 CPU 资源损耗,多道程序出现了。而为了提升用户的交互式体验,提高生产力,分时多任务系统诞生了。它们的特点在于:应用开始多出了一种“暂停”状态,这可能来源于它主动 yield 交出 CPU 资源,或是在执行了足够长时间之后被内核强制性放弃处理器。当应用处于暂停状态的时候,它驻留在内存中的代码、数据该何去何从呢?曾经有一种省内存的做法是每个应用仍然和在批处理系统中一样独占内核之外的整块内存,当暂停的时候,内核负责将它的代码、数据保存在外存(如硬盘)中,然后把即将换入的应用在外存上的代码、数据恢复到内存,这些都做完之后才能开始执行新的应用。 diff --git a/chapter4/2address-space.html b/chapter4/2address-space.html index 891f47b7a..45eab3543 100644 --- a/chapter4/2address-space.html +++ b/chapter4/2address-space.html @@ -398,7 +398,7 @@

本节导读

虚拟地址与地址空间#

地址虚拟化出现之前#

-

我们之前介绍过,在远古计算机时代,整硬件资源只用来执行单个裸机应用的时候,并不存在真正意义上的操作系统,而只能算是一种应用函数库。那个时候,物理内存的一部分用来保存函数库的代码和数据,余下的部分都交给应用来使用。从功能上可以将应用占据的内存分成几个段:代码段、全局数据段、堆和栈等。当然,由于就只有这一个应用,它想如何调整布局都是它自己的事情。从内存使用的角度来看,批处理系统和裸机应用很相似:批处理系统的每个应用也都是独占内核之外的全部内存空间,只不过当一个应用出错或退出之后,它所占据的内存区域会被清空,而应用序列中的下一个应用将自己的代码和数据放置进来。这个时期,内核提供给应用的访存视角是一致的,因为它们确实会在运行过程中始终独占一块固定的内存区域,每个应用开发者都基于这一认知来规划程序的内存布局。

+

我们之前介绍过,在远古计算机时代,整个硬件资源只用来执行单个裸机应用的时候,并不存在真正意义上的操作系统,而只能算是一种应用函数库。那个时候,物理内存的一部分用来保存函数库的代码和数据,余下的部分都交给应用来使用。从功能上可以将应用占据的内存分成几个段:代码段、全局数据段、堆和栈等。当然,由于就只有这一个应用,它想如何调整布局都是它自己的事情。从内存使用的角度来看,批处理系统和裸机应用很相似:批处理系统的每个应用也都是独占内核之外的全部内存空间,只不过当一个应用出错或退出之后,它所占据的内存区域会被清空,而应用序列中的下一个应用将自己的代码和数据放置进来。这个时期,内核提供给应用的访存视角是一致的,因为它们确实会在运行过程中始终独占一块固定的内存区域,每个应用开发者都基于这一认知来规划程序的内存布局。

后来,为了降低等待 I/O 带来的无意义的 CPU 资源损耗,多道程序出现了。而为了提升用户的交互式体验,提高生产力,分时多任务系统诞生了。它们的特点在于:应用开始多出了一种“暂停”状态,这可能来源于它主动 yield 交出 CPU 资源,或是在执行了足够长时间之后被内核强制性放弃处理器。当应用处于暂停状态的时候,它驻留在内存中的代码、数据该何去何从呢?曾经有一种省内存的做法是每个应用仍然和在批处理系统中一样独占内核之外的整块内存,当暂停的时候,内核负责将它的代码、数据保存在外存(如硬盘)中,然后把即将换入的应用在外存上的代码、数据恢复到内存,这些都做完之后才能开始执行新的应用。

不过,由于这种做法需要大量读写外部存储设备,而它们的速度都比 CPU 慢上几个数量级,这导致任务切换的开销过大,甚至完全不能接受。既然如此,就只能像我们在第三章中的做法一样,限制每个应用的最大可用内存空间小于物理内存的容量,这样就可以同时把多个应用的数据驻留在内存中。在任务切换的时候只需完成任务上下文保存与恢复即可,这只是在内存的帮助下保存、恢复少量通用寄存器,甚至无需访问外存,这从很大程度上降低了任务切换的开销。

在本章的引言中介绍过第三章中操作系统的做法对应用程序开发带了一定的困难。从应用开发的角度看,需要应用程序决定自己会被加载到哪个物理地址运行,需要直接访问真实的物理内存。这就要求应用开发者对于硬件的特性和使用方法有更多了解,产生额外的学习成本,也会为应用的开发和调试带来不便。从内核的角度来看,将直接访问物理内存的权力下放到应用会使得它难以对应用程序的访存行为进行有效管理,已有的特权级机制亦无法阻止很多来自应用程序的恶意行为。