【进程空间】通过页表寻址的过程

文章目录

  • 前言
  • 介绍页表、页框、页目录的概念
    • 页框
    • 页表
    • 页目录
    • 页表和页目录的分配
  • 一级页表和二级页表
    • 一级页表
      • 寻址过程
    • 二级页表
      • 寻址过程
    • 一级页表和二级页表的对比

前言

我们知道每个进程都有属于自己的虚拟地址空间,且每个进程的虚拟地址都是统一的。要想通过虚拟地址访问物理地址,我们就需要借助页表来建立映射关系。下面对于如何借助页表来寻址展开详细解释(以32位操作系统为例)。

介绍页表、页框、页目录的概念

页框

页框(Page Frame)是物理内存中的固定大小的块,通常为4KB。在物理内存中,页框是用于存储实际数据的最小单元。假设内存大小为4GB,也就能划分出1024*1024个页框。当进程通过页表来访问物理地址时,其本质就是找到页框的地址。

在这里插入图片描述
于是,操作系统对内存的管理,就可以看成是对页框即块的管理。那内核中又是如何描述一个页框的呢?
在Linux内核中,使用struct page结构来描述内存中的每一页框。这个结构体定义在内核头文件include/linux/mm_types.h中。该结构体通常有以下字段:

  • flags:标志位,表示页面的各种状态
  • mapping:指向该页框所属的地址空间
  • index:该页框在地址空间中的偏移量
  • _maocount:记录该页框到页表条目数
  • _refcount:页面引用计数。表示有多少用户正在使用该页框

页表

页表是用于存储物理内存与虚拟内存地址之间的映射关系的结构。每个进程都有属于自己的页表。页表中的每一个表项,都对应着一个页框的物理地址。一个页表项(PTE)通常包括以下几个字段:

  • 页框基地址:页框的第一个字节的地址
  • 控制位:包括存在位(P)、读/写位(R/W)、超级用户位(U/S)等。

给出32位页表项的控制位示例:
在这里插入图片描述
(上图来自知乎)

再给出内核中描述页表项的结构体代码,该结构体其实是一个位段,所有变量加起来一共32个bite位,即4字节:

// 页表项(PTE)的定义
typedef struct {
    uint32_t present    : 1;  // 存在位
    uint32_t rw         : 1;  // 读/写位
    uint32_t us         : 1;  // 用户/超级用户位
    uint32_t pwt        : 1;  // 页级写穿透位
    uint32_t pcd        : 1;  // 页级缓存禁用位
    uint32_t accessed   : 1;  // 访问位
    uint32_t dirty      : 1;  // 脏位
    uint32_t pat        : 1;  // 页属性表位
    uint32_t global     : 1;  // 全局位
    uint32_t available  : 3;  // 可用位
    uint32_t page_frame_base : 20; // 页框基地址
} __attribute__((packed)) page_table_entry_t;

页表其本质就是这种结构体数组

页目录

页目录是用来管理页表的结构。页目录中每一表项都指着一张页表的物理地址。一个页目录项(PDE)通常包括以下几个字段:

  • 页表基地址:页表的首地址(物理)
  • 控制位:包括存在位(P)、读/写位(R/W)、超级用户位(U/S)等。

给出32位页目录项的控制位示例:
在这里插入图片描述
(上图来着知乎)
同样,给出内核中描述页目录项的代码:

// 页目录项(PDE)的定义
typedef struct {
    uint32_t present    : 1;  // 存在位
    uint32_t rw         : 1;  // 读/写位
    uint32_t us         : 1;  // 用户/超级用户位
    uint32_t pwt        : 1;  // 页级写穿透位
    uint32_t pcd        : 1;  // 页级缓存禁用位
    uint32_t accessed   : 1;  // 访问位
    uint32_t reserved   : 1;  // 保留位
    uint32_t ps         : 1;  // 页大小(通常为4KB页)
    uint32_t ignored    : 1;  // 忽略位
    uint32_t available  : 3;  // 可用位
    uint32_t page_table_base : 20; // 页表基地址
} __attribute__((packed)) page_directory_entry_t;

综上,我们知道了页框、页表、页目录的概念,以及彼此之间的联系。那么在一个进程建立的时候, 页表和页目录的内容是固定的吗? 答案是否定的。

页表和页目录的分配

在Linux内核中,新进程的页目录表的内容是动态增加的。这意味着页目录表和页表的分配更新会根据实际情况动态进行,而不是在创建进程时一次初始化所有的页表项。
大致步骤如下:

  1. 进程创建建立并初始化新页目录表。该表大部分内容为空,有部分指向共享内核。
  2. 访问虚拟地址,如果该地址对应的页表项不存在,触发页故障。内核捕捉这个故障,然后给进程分配对于的页表,并更新页目录表页页表

一级页表和二级页表

在操作系统中,分页机制可以采用单级页表和多级页表进行地址映射。linux采用的就是多级页表。不同的分页机制会导致寻址的空间成本不同(页表本身也占空间)。下面以一级页表和二级页表为例,分析各自的空间成本。
单级页表:只有一张大的页表来映射虚拟空间和物理空间。结构较为简单,直接映射。
多级页表:分层次的管理地址空间,且一般都有一张页目录表。结构较为复杂,需要多次转换地址。

一级页表

总共就一张表。

  • 页表项大小:通常每一个页表项都是4个字节,即32个比特位。
  • 页表项数目:因为4GB内存一共有1024*1024个页框,要想映射所有页框。也就需要1024*1024个页表项。

一级页表的总大小:4bite10241024=4MB

当我们采用一级页表。给出一个虚拟地址(32位),如何找到目标的物理地址(某一字节)呢?

寻址过程

将虚拟地址分解为两个部分:

  1. 页表索引:高20位。因为一张页表的总项数为1024*1024=2^20(页框数),虚拟地址的高20位用来表示页表项的位置。
  2. 页内偏移量:低12位。通过高20位能找到一个唯一的页表项,即页框的物理地址。一个页框占4096个字节,用12位比特位恰好能表示4096个不同的位置。于是通过低12位比特位的组合,我们就能找到页框内的唯一一个字节。

假设现在有一个虚拟地址为:0x0000 1005取出高20位的十进制值为1,低12位的十进制值为5.于是在页表中找到下标为1的页表项,通过这个页表项我们能找到一个唯一的页框。再在该页框中从找到第5个字节的地址。该地址就是0x0000 1005对应的物理地址。
在这里插入图片描述

二级页表

在二级页表中,最外层的页表我们当成一个页目录。页目录中的每一项都指向一张页表。一共有1024个页目录项,即一共有1024张页表,每一张页表有1024个页表项,刚好对应1024*1024个页框。
1.页目录大小计算:

  • 页目录项大小:4字节。
  • 页目录数量:1024.

页目录总大小:4byte*1024=4KB

2.每个页表的大小计算:

  • 页表项大小:4字节
  • 页表项数量:每一个页表都有1024个页表项

每个页表的大小:10244byte=4KB
页表的总大小:1024
4KB=4MB
二级页表的总大小:4MB+4KB约等于4MB

寻址过程

将虚拟地址分为三个部分:

  1. 页目录索引:高10位用来索引页目录项,10个二进制位最多表示1024个位置。
  2. 页表索引:中间10位索引页表项
  3. 页内偏移量:低12位用于表示页内偏移量,12个二进制位最多表示4096个位置,刚好对应页框内每个字节的相对位置。

当我们拿到一个虚拟地址,取出高10位的二进制表示的值,作为页目录的下标找到目标页表。再取出中间10位二进制表示的值,用来作为目标页表的下标,来找到目标页框。最后取出低12位,在目标页框中找到唯一一个字节地址。

假设现在有一个虚拟地址0x00001005,得到页目录索引为0,页表索引为1,页内偏移量为5.所以我们就去下标为0的页目录项种去找到页表,并在该页表下标为1的页表项中找到页框,最后在该页框中找到第5个字节的地址。
在这里插入图片描述

一级页表和二级页表的对比

尽管从理论上看,一级页表和二级页表的总空间成本差不多。但是二级页表的使用效率会更高。
如果采用一级页表,每个进程都需要分配整个页表的内存,也就意味着每个进程都需要有4MB的空间来存放页表,且页表项很多都是空的。这对大多数应用来说都是一种浪费。

如果采用二级页表或者三级页表。每个进程拥有一张页目录页表的数量会根据实际情况来进行分配,因此实际内存小于4MB。这样一来,避免了为进程分配大量未使用的页表,从而节省了内存
从时间效率上来看,虽然一级页表直接可以找到页框的地址,而多级页表需要经过多次索引,但是多级页表带来空间上的节省是值得多消耗一些索引时间的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654977.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JS逆向之企名科技

文章目录 初步分析定位js编写完整代码参考文献初步分析 目标网址:企名科技 抓包分析,发现是post请求 请求代码如下: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import requestsheaders = {Connection:

【主流分布式算法总结】

文章目录 分布式常见的问题常见的分布式算法Raft算法概念Raft的实现 ZAB算法Paxos算法 分布式常见的问题 分布式场景下困扰我们的3个核心问题(CAP):一致性、可用性、分区容错性。 1、一致性(Consistency):…

玄机平台应急响应—webshell查杀

1、前言 这篇文章说一下应急响应的内容,webshell查杀呢是应急响应的一部分。那么什么是应急响应呢,所谓的应急响应指的是,当网站突然出现异常情况或者漏洞时,能够马上根据实际问题进行分析,然后及时解决问题。 2、应…

内网安全-隧道搭建穿透上线内网穿透-nps自定义上线内网渗透-Linux上线-cs上线Linux主机

目录 内网安全-隧道搭建&穿透上线内网穿透-nps-自定义-上线NPS工具介绍搭建过程 nps原理介绍MSF上线CS上线 内网渗透-Linux上线-cs上线Linux主机1.下载插件2.导入插件模块3.配置监听器4.服务端配置5.配置C2监听器并生成木马6.执行木马 内网安全-隧道搭建&穿透上线 内网…

做抖店如何避免被同行内卷?这5点建议,可以解决这个问题

我是王路飞。 都说2024年的抖店不赚钱了,商家太多了,太内卷了,一点都不好做~ 那为什么依然有很多商家在坚持做呢?为什么依然有很多新手入局呢? 无非是抖店确实能带来可观的利润回报罢了。 那如何避免被同行内卷呢&…

idea中git检出失败

之前clone好好的,今天突然就拉取不下来了。很多时候是用户凭证的信息没更新的问题。由于window对同一个地址都存储了会话。如果是新的会话,必须要更新window下的凭证。 然后根据你的仓库找到你对应的账户,更新信息即可。

【前端】从手动部署到自动部署:前端项目进化之路

从手动部署到自动部署:前端项目进化之路 在前端开发的领域内,部署是一个不可忽视的环节。随着项目复杂度的增加和线上更新频率的提升,手动部署逐渐暴露出它的弊端。本文将带你从手动部署过渡到自动部署,完成前端项目进化的重要一…

Round-Robin 调度逻辑算法

Round-Robin 调度逻辑算法 1 Intro1.1 固定优先级1.2 Round-Robin算法 之前上学还是工作,都接触过调度算法:Round-Robin和weight-Round Robin算法,但只知道它的功能和目的是什么,没有具体了解如何实现的; 现在是工作上…

移动云服务器选购指南(图文教程详解)

目录 一、前言 二、基本概念 2.1 定义 2.2 部署形式 2.3 用处 三、主流平台 四、主流产品推荐 4.1 云电脑 4.2 云主机ECS 4.3 弹性公网 IP 五、选购指南 5.1 明确场景 5.2 明确需求 5.3 明确身份 新用户 老用户 5.4 明确时间 5.5 明确教程 六、总结 一、前言…

【多态】(超级详细!)

【多态】(超级详细!) 前言一、 多态的概念二、重写1. 方法重写的规则2. 重写和重载的区别 三、多态实现的条件四、 向上转型五、动态绑定 前言 面向对象的三大特征:封装性、继承性、多态性。 extends继承或者implements实现&…

短视频商城全套源码:开启电商新纪元

随着数字媒体的快速发展,短视频平台已经成为人们获取信息、娱乐和社交的重要渠道。在这样一个大背景下,短视频商城的兴起,无疑为电商行业带来了新的机遇和挑战。本文将探讨短视频商城全套源码的重要性,以及它如何助力商家和开发者…

详解Spring MVC

目录 1.什么是Spring Web MVC MVC定义 2.学习Spring MVC 建立连接 RequestMapping 注解介绍及使用 获取单个参数 获取多个参数 获取普通对象 获取JSON对象 获取基础URL参数 获取上传文件 获取Header 获取Cookie 获取Session 总结 1.什么是Spring Web MVC 官⽅对于…

生成式AI模型大PK——GPT-4、Claude 2.1和Claude 3.0 Opus

RAG(检索增强生成)系统的新评估似乎每天都在发布,其中许多都集中在有关框架的检索阶段。然而,生成方面——模型如何合成和表达这些检索到的信息,在实践中可能具有同等甚至更大的意义。许多实际应用中的案例证明,系统不仅仅要求从上…

《征服数据结构》目录

我们知道要想学好算法,必须熟练掌握数据结构,数据结构常见的有 8 大类,分别是数组,链表,队列,栈,散列表,树,堆,图。但如果细分的话就比较多了,比如…

华为WLAN实验继续-2,多个AP如何部署

----------------------------------------如果添加新的AP,如何实现多AP的服务----------- 新增加一个AP2启动之后发现无法获得IP地址 在AP2上查看其MAC地址,并与将其加入到AC中去 打开AC,将AP2的MAC加入到AC中 sys Enter system view, re…

手写电纸书天花板,阅读办公新体验 | 汉王手写电纸本 N10 2024 版使用评测

手写电纸书天花板,阅读办公新体验 | 汉王手写电纸本 N10 2024 版使用评测 请问如果说到电纸书,你的认知还只是Kindle吗?然而遗憾的是,Kindle亦是过去,智能才是未来。 哈喽小伙伴们好,我是Stark-C~&#x…

【机器学习】【深度学习】批量归一化(Batch Normalization)

概念简介 归一化指的是将数据缩放到一个固定范围内,通常是 [0, 1],而标准化是使得数据符合标准正态分布。归一化的作用是使不同特征具有相同的尺度,从而使模型训练更加稳定和快速,尤其是对于使用梯度下降法的算法。而标准化的作用…

Python自动化办公Excel数据处理实战指南

目录 一、引言 二、需求分析 三、技术选型 四、实战操作 数据读取 数据清洗 数据分析 数据输出 五、学习资源推荐: 六、结语 一、引言 在现代办公环境中,Excel数据处理是一项不可或缺的技能。然而,当数据量庞大、处理流程复杂时&a…

Nocobase快速上手 -第一个collection

本文记录Nocobase中如何创建collection,以及如何将collection展示到页面中,并且配置CRUD相应的操作. Collection 在NocoBase中,collection(集合)是用来组织和存储各种数据的容器,如订单、产品、用户、评论…

【算法】位运算算法——判断字符是否唯一

题解:判断字符是否唯一(位运算算法) 目录 1.题目2.题解3.位图参考代码4.细节5.总结 1.题目 题目链接:LINK 2.题解 题解有两种方法, 一是做一个哈希数组,去查重; 二是直接用一个变量每一位来对应表示是否有这个字母…