<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(1)》(17)

本文主要是介绍<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(1)》(17),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Linux操作系统原理分析之linux存储管理(1)》(17)

  • 6 Linux 存储管理
    • 6.1 80x86 的分段机制
      • 6.1.1 80x86 的虚拟存储空间
      • 6.1.2 段描述符表
      • 6.1.3 逻辑地址向线形地址的转换

6 Linux 存储管理

6.1 80x86 的分段机制

Linux 最早在 intel80386 机器上开发,当前也主要运行在 intel 80386、80486 和 pentium 系列机器上。按照管理把该机器系列统称 80x86,也称 i386。

80x86 机器中用于控制和管理内存的硬件机制称为存储器管理单元 MMU(memory manage unit)。

在 MMU 控制下,80x86 具有两种存储管理模式

👉实地址模式:cpu 只能寻址 1MB 空间,MS-DOS 操作系统就工作在实地址模式下;
👉受保护的虚地址模式(保护模式):80x86 提供了虚拟存储的硬件机制,它是 OS
实现多任务存储管理以及提供存储保护的硬件基础。Linux 就是在该模式下实现其各种功能的。

6.1.1 80x86 的虚拟存储空间

1.物理地址和虚拟地址

物理地址:通常出现在地址总线上的地址称为物理地址。内存空间有物理地址确定,所以内存又称为物理地址空间。内存的最大容量由物理地址长度决定。80x86 机器的地址总线为 32 位,故有它确定的物理地址空间的范围可达 232B,即 4GB。

虚拟地址:用户作业的地址空间是由逻辑地址确定的,逻辑地址就是机器指令中使用的地址,故逻辑地址空间的最大容量由机器地址长度决定。80x86 指令地址字长度 48 位,其中 46 位用于寻址,因此80x86 的逻辑地址地址空间最大可达 64T。故 80x86 提供给程序人员使用的逻辑地址空间远远大于实际的物理地址空间,是一个虚拟的存储空间。所以逻辑地址就是虚拟地址。

为了支持多道进行并发执行以及实现存储保护,80x86 存储管理机制把 64T 的逻辑地址空间分成性质
不同的两部分:

👉全局地址空间:所有进程共享的空间,通常存放 os 的程序和数据。
👉局部地址空间:由系统分配给各个进程使用,用于存放进程各自的程序和数据。

2. 地址转换方式
80x86 在保护模式下提供了两种地址转换方式:

👉分段机制
👉分段+分页的两级地址转换方式。(本书只介绍这种转换方式)。

  1. 分段分页地址转换
    在系统运行时,逻辑地址必须转换成物理地址才能访问物理内存。80x86 中分段分页的地址转换机制中需要两级地址转换:

👉第一级:由分段机制完成逻辑地址向线性地址的转换 由分段机制完成逻辑地址向线性地址的转换。分段机制把逻辑地址空间分成若干个相互独立的地址空间,它称为线性地址空间。线性地址空间的地址称为线性地址。每个线性地址空间从 0 开始编址,80x86 中线性地址是 32 位的,因此每个线性地址空间最大 4G。在多道系统中,每个线性地址可以供一个用户进程使用,这就保证了每个进程都有自己独立的虚拟存储空间 这就保证了每个进程都有自己独立的虚拟存储空间。

地址类型说明
逻辑地址面向用户,是用户在程序设计时使用的地址空间,也就是用户程序中指令访问的地址空间;
线性地址面向进程,使进程使用的地址空间,对用户透明

👉第二级:由分页机制完成线性地址向物理地址的转换

说明:
1)在 80x86 中,虚拟地址空间的全局和局部地址空间都被划分成不同段。64T 的虚拟地址空间最多可以分 16K 个段。每个段的最大长度可达 4G;
在这里插入图片描述

2)全局地址空间和局部地址空间各自最多可以有 8K 段,分别称为全局段和局部段。
3)由于虚拟存储空间不是实际存在的,所以其中的段的数量,段的大小是不确定的,是根据需要随时建立的。当然不能超过上面提到的最大限制。

6.1.2 段描述符表

80x86 的段描述符表就是前面原理部分提到的段表。段描述符就是段表表项,每个段描述符的长度为8B。80x86 提供两种不同的段描述符:

👉全局描述符表 GDT(Global Descriptor Table):描述全局段,故系统中只有一个全局描述符表
👉局部描述符表 LDT(Local Descriptor Table):描述各个进程的各个局部段。故系统中有多少进程就有多少 LDT。

1.全局描述符表 GDT
1)80x86 中,全局描述符表 GDT 中一般包括 3 种不同种类的描述符:

👉系统内核代码段和数据段的描述符
👉进程状态段 TSS(Task State Segment)的描述符。系统中每个进程都有一个 TSS 段,用于保存该进程的上下文。所有进程的 TSS 段描述符都集中的保存在 GDT 中。
👉LDT 描述符:对各个进程的局部描述符表 LDT 进行描述的描述符,记录各个进程的局部描述符 LDT 在线性地址空间的位置和长度。每个进程 LDT 描述符在 GDT 中的位置,由系统记录在该进程 TSS 段的一个 16 位的位域中,该位域的值称为 LDT 选择符。

2)全局描述符表寄存器(GDTR):记录 GDT 在线性地址空间中的位置
在这里插入图片描述

其中:

表基址:指出 GDT 的起始地址;
表限:表限的值加 1 位 GDT 的长度。

说明:16 位的表限确定了 GDT 的最大地址空间为 64K,由于每个描述符长度为 8B,因此 GDT 最多可以拥有 8K 个描述符。每个描述符对应一个段,因此系统中最多可以有 8K 个全局段。

2.局部描述符表 LDT:描述进程各个局部段的。
3.定位 LDT
因为单处理机中某个时刻只能有一个进程处于运行状态,所以在某个时刻只有当前进程的 LDT 处于活动(使用)状态。系统需要能迅速定位活动的 LDT。

80x86 通过局部描述表寄存器 LDTR 和相应的 LDT 高速缓存来实现定位 LDT。

👉局部描述表寄存器 LDTR: 是一个 16 位寄存器,它的作用是指出当前进程的 LDT 描述符在GDT 中的位置,也就是前面提到的 LDT 选择符。在进程切换时,从进程的 TSS 中取出 LDT 选择 符,并将它放入 LDTR 中; 在地址映射时,首先从 LDTR 中得到 LDT 选择符;然后 GDT 中根据 LDT 选择符找到 LDT描述符(即得到 LDT 的位置等信息),接下来才能找到 LDT(即段表)。显然这样是会严重影响程序运行速度的。故引入了 LDT 高速缓存。
👉LDT 高速缓存: 保存从 GDT 中找到的 LDT 描述符。引入 LDT 高速缓存后,第一次仍需要完成上面提到的三个步骤,但是第一次完成时,将从GDT 中找到的该进程的 LDT 描述符保存在了 LDT 高速缓存中。这样以后地址映射时,可以直接从高速缓存中得到 LDT 的位置等信息。

LDT 高速缓存:
在这里插入图片描述
说明:

16 位的表限确定了 LDT 的最大地址空间为 64K,由于每个描述符长度为 8B,因此LDT 最多可以拥有 8K 个描述符。每个描述符对应一个段,因此系统中最多可以有 8K 个局部段。

6.1.3 逻辑地址向线形地址的转换

1.基本过程(参照原理部分)
在 80x86 中逻辑地址的格式如下所示:
在这里插入图片描述
在 80x86 中,程序执行中读取每一条指令时都需要访问代码段。这时系统把逻辑地址中的选段符装入寄存器 CS 中,把段内偏址装入指令计数器 EIP 中,然后经过硬件分段机制把逻辑地址转成指向代码段的32 位线性地址。

程序中执行读写数据的指令时,系统把指令中逻辑地址的选段符装入 DS 寄存器中,把段内偏址装入某个通用寄存器中,然后经过硬件分段机制把逻辑地址转成指向数据段的 32 位线性地址。

2.段描述符寄存器(参照原理部分,快表)
选段寄存器:上述中设计到的寄存器,因为包含了选择某个段的索引值,故又称其为选段寄存器。

80x86 中有 6 个段寄存器:CS、DS、SS、ES、FS 和 GS;

段描述符寄存器:根据程序的局部性原理,为了提高地址映射速度,减少访问内存的次数。80x86 分段机制在高速缓存中,为每个选段寄存器都配置了一个对应的段描述符寄存器,用于保存当前访问的那些段的段描述符。

这篇关于<Linux>(极简关键、省时省力)《Linux操作系统原理分析之linux存储管理(1)》(17)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/446015

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

Oracle数据库定时备份脚本方式(Linux)

《Oracle数据库定时备份脚本方式(Linux)》文章介绍Oracle数据库自动备份方案,包含主机备份传输与备机解压导入流程,强调需提前全量删除原库数据避免报错,并需配置无密传输、定时任务及验证脚本... 目录说明主机脚本备机上自动导库脚本整个自动备份oracle数据库的过程(建议全程用root用户)总结

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

Linux如何查看文件权限的命令

《Linux如何查看文件权限的命令》Linux中使用ls-R命令递归查看指定目录及子目录下所有文件和文件夹的权限信息,以列表形式展示权限位、所有者、组等详细内容... 目录linux China编程查看文件权限命令输出结果示例这里是查看tomcat文件夹总结Linux 查看文件权限命令ls -l 文件或文件夹

idea的终端(Terminal)cmd的命令换成linux的命令详解

《idea的终端(Terminal)cmd的命令换成linux的命令详解》本文介绍IDEA配置Git的步骤:安装Git、修改终端设置并重启IDEA,强调顺序,作为个人经验分享,希望提供参考并支持脚本之... 目录一编程、设置前二、前置条件三、android设置四、设置后总结一、php设置前二、前置条件

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

Linux系统之lvcreate命令使用解读

《Linux系统之lvcreate命令使用解读》lvcreate是LVM中创建逻辑卷的核心命令,支持线性、条带化、RAID、镜像、快照、瘦池和缓存池等多种类型,实现灵活存储资源管理,需注意空间分配、R... 目录lvcreate命令详解一、命令概述二、语法格式三、核心功能四、选项详解五、使用示例1. 创建逻