操作系统概念_第八章_内存管理

本文详细介绍了操作系统的内存管理,包括基本硬件如CPU-高速缓存-内存和基地址-界限地址寄存器的作用,以及地址绑定的不同阶段。重点讲述了分页机制,包括页表结构、页表的硬件实现和内存保护。此外,还讨论了分段机制在Intel Pentium和Linux中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

第五章将CPU调度,CPU调度提高了CPU利用率和系统对用户的响应速度,而这一操作,是将非调度进程保存到内存中实现的,因此需要实现共享内存。

多进程保存到内存和实现共享内存之间有联系吗?上述话来自于课本,但没想明白有什么因果联系…

要管理内存,自然也需要很多策略,算法,本章将从硬件和软件两个层面描述内存的组织方法和管理方法。


基本硬件

基本硬件主要解决了访存速度的提高和用户进程的保护问题

CPU-高速缓存-内存

首先要知道的一个前提是,CPU只能从内存和处理器内的寄存器中读取指令或数据,如果数据不在内存或缓存中,那么CPU必须先通过指令将数据从外存中转移到内存中。

为了提高CPU访存速度,通常在CPU-内存之间增加高速缓存,即CPU-高速缓存-内存,这样就保证了CPU访问物理内存的相对速度,提高CPU的利用率。

基地址-界限地址寄存器

除了要保证CPU访存速度外,还需要保证操作系统不被用户进程访问以及一个用户进程不被其他用户进程访问,这种保护可以通过硬件来实现,一个简单的方案就是:使用基地址寄存器保存用户进程合法的最小物理地址,使用界限地址寄存器保存用户进程的地址的范围大小

这里写图片描述

通过这种方式,CPU硬件对用户进程产生的每一物理地址与寄存器地址进行比较来完成。这种方案允许操作系统修改寄存器的值,而不允许用户进程的修改。过程示意图如下:
这里写图片描述

因为操作系统在内核模式下,可以无限制的访问任意内存,所以操作系统能够完成将用户进程装入内存,在进程出错时输出进程,以及修改调用进程的参数等操作。

地址绑定

程序以二进制形式存放在硬盘上,进程执行时会装入内存,进程执行时,系统会访问内存中相关的指令和数据。最后,进程终止,相对于的地址空间会被释放。

而在进程装入内存时,指令和数据应该装入内存的哪一块地址,应该如何分配,也就是地址绑定(Address binding)的方式。

虽然计算机的地址空间从0开始,但进程的地址空间是可以放在任意位置,而不必从0开始。

源程序中的地址通常用符号表示(如count)(也就是变量的形式??),编译器通常将这些符号绑定在可重定位的地址。链接程序 / 加载程序则再将可重定位的地址绑定成绝对地址,每一次绑定都可以看成是一个地址空间到另一个地址空间的映射

地址绑定通常在以下几个阶段发生:

  • 编译时(compile time),如果编译时知道进程将要驻留在内存中的绝对地址,那么就可以生成绝对代码(absolute code),但这种方式一旦开始地址发生变化,就需要重新编译。
  • 加载时(load time),如果编译时不清楚绝对地址,那么编译器就必须生成可重定位代码(relocatable code),这样地址绑定就会延迟到加载时进行,这样开始地址如果变化,只需要在加载时引入改变值即可
  • 执行时(execution time),如果一个进程在执行时可以从一个内存段移动到另一个内存段,那么绑定就必须发生在执行时

执行时完成地址绑定是绝大多数通用计算机系统采用的方法。

逻辑地址空间和物理地址空间

逻辑地址(logical address):CPU生成的地址称为逻辑地址

物理地址(physical address):加载到内存地址寄存器中的地址称为物理地址。

逻辑地址空间(logical address space):由程序生成的所有逻辑地址的集合。

物理地址空间(physical address space):由这些逻辑地址所有相对应的物理地址的集合。

在《操作系统概念》一书中,对逻辑地址和虚拟地址(virtual address)不做区分,两者含义相同。

在编译、加载、执行时都会产生虚拟地址和物理地址,但编译和加载时会产生相同的虚拟地址和物理地址,而在执行时,根据绑定方案,则会产生不同的虚拟地址和物理地址。

理所当然的,执行时的虚拟地址空间和物理地址空间也是不同的。

内存管理单元:当虚拟地址和物理地址不同时,需要通过一个映射关系来完成两者的转换,完成这个操作的设备称为内存管理单元(memory-management unit,MMU)

为了完成这种映射,有很多种方式,一个简单的基于基地址寄存器的推广的方式是:所有用户进程生成的地址都要经过基地址寄存器,经过加操作后,生成物理地址。
这里写图片描述

这里将基地址寄存器称为重定位寄存器(relocation register),其他的映射方案将在 8.3-8.7 节讨论

动态加载

之前讨论的进程都是完整的放入内存中的,但进程大小受限于物理内存大小的限制,一个解决方案是采用动态加载(dynamic loading),这样一个子程序只有在执行时才加载,在这之前均会以重定位的形式存储在外存上。

当主程序执行时,当一个子程序调用另一个子程序时,先检查该子程序是否已加载,如果没有加载则动态加载。

动态加载的使用不到的子程序绝对不会被加载,节省了内存空间。

动态链接与共享库

操作系统或者用户本身会写一些库,用于复用,而链接(linking)就是将用户自己的程序和这些库链接起来,这样程序就能够通过这些库来实现自己想要的功能(类似于编程中的import)。

静态链接和动态链接中静态和动态的概念有些类似于是否使用动态加载

  • 静态链接(static linking):指在加载时将库与用户程序直接合并为一个二进制可执行程序。
  • 动态链接(dynamic linking):用户的程序中只保存一个存根(stub) / 引用,在使用到库的时候,通过这个引用来查找系统中相应的库装入内存。

两者各有优点,具体可以看一下百科中对静态链接和动态链接的比对

静态链接一个明显的缺点就是每一个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值