Linux——补充点(页表映射及LWP)

目录

补充点1:进程地址空间堆区管理

补充点2:Linux内核进程上下文切换

补充点3:页表映射

补充点4:两级页表


补充点1:进程地址空间堆区管理

        Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息。该结构体存放在叫做任务列表的双向循环列表中!

所学习过的包含:

        进程标识符 - 进程优先级 - 进程状态 - 进程地址空间 - 文件描述符表 -  进程信号位图 - CPU寄存器的上下文数据 - 进程相关页表(内核级页表、用户级页表)

        在进程地址空间中,栈区,代码区等一部分区域,是被整体所使用的!而堆区具有更细粒度的划分,包括使用者等(参考文章:Glibc——堆利用机制[拓展]_IfYouHave的博客-CSDN博客),因此堆是使用一个vm_area_struct小的结构体进行区分,使用双链表的形式进行管理!

(参考文章:linux内核学习笔记-struct vm_area_struct_struct vm_area_struct source code_带着耳机去梦游的博客-CSDN博客)

        在进行堆区申请空间,上层调用malloc函数 - 底层调用brk系统调用,就会申请一个vm_area_struct,内有start表针虚拟地址起始,end表示虚拟地址结束,经过页表映射至内存。

        堆区典型特征:申请的空间连续!

OS是可以做到让进程进行资源细粒度划分的

补充点2:Linux内核进程上下文切换

        进程上下文是进程执行活动全过程的静态描述。我们把已执行过的进程指令和数据在相关寄存器与堆栈中的内容称为进程上文,把正在执行的指令和数据在寄存器与堆栈中的内容称为进程正文,把待执行的指令和数据在寄存器与堆栈中的内容称为进程下文。

        实际上linux内核中,进程上下文包括进程的虚拟地址空间和硬件上下文。

        进程硬件上下文包含了当前cpu的一组寄存器的集合,arm64中使用task_struct结构的thread成员的cpu_context成员来描述,包括x19-x28,sp, pc等。

        进程上下文切换主要涉及到两部分主要过程:进程地址空间切换和处理器状态切换。地址空间切换主要是针对用户进程而言,而处理器状态切换对应于所有的调度单位。

进程地址空间切换:

        进程地址空间内有进程运行的指令和数据,因此到调度器从其他进程重新切换到我的时候,为了保证当前进程访问的虚拟地址是自己的必须切换地址空间。

        进程pcb内mm_struct结构体将各个vma组织起来进行管理,其中有一个成员pgd至关重要,地址空间切换中最重要的是pgd的设置。pgd中保存的是进程的页全局目录的虚拟地址,那么pgd的值是何时被设置的呢?

        答案是fork的时候,如果是创建进程,需要分配设置mm_struct,其中会分配进程页全局目录所在的页,然后将首地址赋值给pgd,完成了这一步,也就完成了进程的地址空间切换,确切的说是进程的虚拟地址空间切换。

处理器状态(硬件上下文)切换:

        处理器状态切换就是将前一个进程的sp,pc等寄存器的值保存到一块内存上,然后将即将执行的进程的sp,pc等寄存器的值从另一块内存中恢复到相应寄存器中,恢复sp完成了进程内核栈的切换,恢复pc完成了指令执行流的切换。

        其中保存/恢复所用到的那块内存需要被进程所标识,这块内存这就是cpu_contex这个结构的位置(进程切换都是在内核空间完成)。

线程部分会学习:

        内核线程,不需要切换地址空间,只进行硬件上下文切换

        所有的进程线程之间进行切换都需要切换处理器状态。

        对于普通的用户进程之间进行切换需要切换地址空间

        同一个线程组中的线程之间切换不需要切换地址空间,因为他们共享相同的地址空间。
        内核线程在上下文切换的时候不需要切换地址空间,仅仅是借用上一个进程mm_struct结构。(参考文章:深入理解Linux内核进程上下文的切换 - 知乎 (zhihu.com))

补充点3:页表映射

        MMU(Memory Management Unit),即内存管理单元,是一个硬件,是现代CPU架构中不可或缺的一部分,MMU主要包含以下几个功能:

  • 虚实地址翻译
在用户访问内存时,将用户访问的虚拟地址翻译为实际的物理地址,以便CPU对实际的物理地址进行访问。
  • 访问权限控制
可以对一些虚拟地址进行访问权限控制,以便于对用户程序的访问权限和范围进行管理,如代码段一般设置为只读,如果有用户程序对代码段进行写操作,系统会触发异常。
  • 引申的物理内存管理
对系统的物理内存资源进行管理,为用户程序提供物理内存的申请、释放等操作接口。

使用MMU带来的好处或者优势:

  • 提升物理内存的利用率
物理内存按需申请,如代码段的内存在执行时进行映射和转换,进程fork后,t通过写时复制(Copy-On-Write)进行真正的物理内存分配。解决内存管理碎片化的问题,即在系统运行一段时间后,频繁的内存申请和释放会导致内存碎片化,无法申请到一块足够大的地址连续的内存。
  • 对内存地址的访问进行控制
如上述代码段只读权限控制,多线程的栈内存之间的空洞页隔离可以防止栈溢出后改写其他线程的栈内存,不同进程之间的地址隔离等等。
  • 将进程的地址空间隔离
不同进程之间可以使用相同的虚拟内存地址空间,而进程间的物理内存又可以做到隔离,这保证了进程的独立性同时,又简化了地址的访问方式,如在早期32位CPU上,为了支持4G以上的物理内存,一般物理地址有36-bit(如PowerPC-604系列),但是用户的虚地址仍然使用32-bit,做法就是将用户的不同进程的32-bit虚地址在MMU转换时,转换为36-bit的物理地址,这样每个进程仍然能访问0-3G虚地址范围,将多个进程的3G空间映射到36-bit的物理内存空间中去。

上述参考文档(MMU原理 - page)

如何从虚拟地址映射到物理内存?

  1. .exe就是一个文件
  2. 我们的可执行程序本来就是按照地址空间方式进行编译的(编译形成二进制文件的格式 - ELF格式)
  3. 可执行程序,其实按照区域也已经以4KB为单位进行了划分
  4. 物理内存也早就按照4KB为单位划分成一个个page(操作系统进行IO的基本单位就是4KB)
  5. 因为被划分,操作系统就需要管理划分后每一块物理内存的属性等,先描述,在组织,page。因此4G的物理内存,便会形成100w+个块,假设一个结构体为20字节,100w+个page会使用20MB的内存空间

        

磁盘内文件以4KB为单位划分的块成为页帧,物理内存划分块称为页框

IO基本单位是4KB,就是将页帧内容 -> 页框

补充点4:两级页表

        页表在进行映射时,会通过虚拟地址,访问物理内存,页表中含有其他字段,表征磁盘数据是否被加载到内存,没有,变会进行申请内存page,通过文件系统加载内存,最后填充在页表右侧,这种行为为缺页中断!(用户零感知)

        4.1 单级页表存在的问题:

        若计算机系统按字节寻址,支持32位逻辑地址,采用分页存储管理,页面大小为4KB,页表项长度为4B。4KB = 2^12B,因此页内地址要用12位表示,剩余20位表示页号。

        物理内存 4GB = 2^20 * 2^12 B

        因此,该系统中用户进程最多有2^20页。相应的,一个进程的页表中,最多会有2^20个页表项,所以一个页表最大需要2^20 * 4B = 2^22B。一个页框(内存)大小为4KB,所以需要2^22/2^12 = 2^10个页框存储该页表。

        而页表的存储是需要连续存储的,因为根据页号查询页表的方法:

        K号页对应的页表项的位置 = 页表起始地址 + K * 4B(页表项长度),所以这就要求页表的存储必须是连续的。

        

        回想一下,当初为什么使用页表,就是要将进程划分为一个个页面可以不用连续的存放在内存中,但是此时页表就需要1024个连续的页框,似乎和当时的目标有点背道而驰了....
          此外,根据局部性原理可知,很多时候,进程在一段时间内只需要访问某几个页面就可以正常运行了。因此也没有必要让整个页面都常驻内存。
          所以,单级页表存在以上两个问题。

        (参考文章:两级页表 - 简书 (jianshu.com))

       

        4.2 两级页表:

        如何解决页表过大需要连续存储的问题呢?这个问题可以参考进程太大需要连续存储的答案。因为页表必须连续存放,所以可以将页表再分页。
         解决方案:可以将长长的页表进行分组,使每个页面中刚好可以放下一个分组(如上面的例子中,页面的大小4KB),每个页表项4B,所以每个页面中可以存放1K个(1024)个页表项,因此每1K个连续的页表项为一组,每组刚好占一个页面,再讲各组离散的放在各个内存块中)。这样就需要为离散的页表再建立一张页表,称为页目录表,或外层页表,或顶层页表。

        32位的逻辑地址空间,页表项大小为4B,页面大小4KB,则页内地址占12位

        将页表分为分为1024个表,每个表中包含1024个页表项,形成二级页表。二级页表结构的逻辑地址结构如下图

       

两级页表如何实现地址转换:

(1) 按照地址结构将逻辑地址拆成三个部分。
(2) 从PCB中读取页目录起始地址,再根据一级页号查页目录表,找到下一级页表在内存中存放位置。
(3) 根据二级页号查表,找到最终想要访问的内存块号。
(4) 结合页内偏移量得到物理地址

下面以一个逻辑地址为例。将逻辑地址(0000000000,0000000001,11111111111)转换为物理地址的过程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java 进阶篇】MySQL多表查询之外连接详解

在MySQL数据库中,多表查询是一种常见且强大的功能,允许您在多个表之间执行联接操作,从而检索、过滤和组合数据。在本篇博客中,我们将深入探讨多表查询的一种类型,即外连接(Outer Join)&#xff…

医疗小程序开发:技术门槛高?

随着移动互联网的普及,医疗行业也逐渐转向线上。医疗小程序开发成为了很多企业和医疗机构关注的焦点。但是,对于一些技术小白来说,可能会觉得医疗小程序开发技术门槛高,无从下手。实际上,使用乔拓云平台进入后台&#…

C理解(一):内存与位操作

本文主要探讨C语言的内存和为操作操作相关知识。 冯诺依曼结构和哈佛结构 冯诺依曼结构:数据和代码放在一起,便于读取和修改,安全性低 哈佛结构是:数据和代码分开存放,安全性高,读取和修麻烦 内存 内存是用来存储全局变量、局…

Prometheus+Grafana监控K8S集群(基于K8S环境部署)

文章目录 一、环境信息二、部署前准备工作三、部署Prometheus监控系统四、部署Node_exporter组件五、部署Kube_state_metrics组件六、部署Grafana可视化平台七、Grafana可视化显示Prometheus收集数据八、Grafana添加监控模板九、拓展 一、环境信息 1、服务器及K8S版本信息&…

Nim游戏

891. Nim游戏 - AcWing题库 全部异或起来&#xff0c;如果不为零&#xff0c;则可以一步使其变为0&#xff1a; 设异或和为x&#xff0c;x的最高位为第k位&#xff0c;令第k位为1的a[i]变为a[i]^x&#xff0c;a[i]^x < a[i]&#xff0c;这样就可以使异或和为0。 如此往复最…

目标检测如何演变:从区域提议和 Haar 级联到零样本技术

目录 一、说明 二、目标检测路线图 2.1 路线图&#xff08;一般&#xff09; 2.2 路线图&#xff08;更传统的方法&#xff09; 2.3 路线图&#xff08;深度学习方法&#xff09; 2.4 对象检测指标的改进 三、传统检测方法 3.1 维奥拉-琼斯探测器 (2001) 3.2 HOG探测器…

el-table实现穿梭功能

第一种 <template><el-row :gutter"20"><el-col :span"10"><!-- 搜索 --><div class"search-bg"><YcSearchInput title"手机号" v-model"search.phone" /><div class"search-s…

EasyX趣味化编程note2,绘制基本图形

创意化编程&#xff0c;让编程更有趣 今天介绍的仍为比较简单的效果&#xff0c;由浅入深来进行学习 介绍每个函数都会附上代码和运行结果&#xff0c;感兴趣的大家可以复制粘贴运行一下看看效果&#xff0c;也可以自己进行改动&#xff0c;非常好玩且加深印象。 上节课的知识…

idea Springboot在线商城系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 在线商城系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有 完整的源代码和数据库&…

机器学习笔记:Huber Loss smooth L1 loss

1 Huber loss 1.1 介绍 Huber Loss是回归问题中的一种损失函数&#xff0c;它结合了均方误差MSE和绝对误差MAE的特点。 Huber Loss在误差较小的时候是平方损失&#xff0c;而在误差较大的时候是线性损失。因此&#xff0c;它在处理有噪声的数据时&#xff0c;尤其是存在离群点…

手机搜狗输入法,输入拼音时如何分割拼音,调出“分词“功能,如何微信或QQ使用发送按钮而不是换行?

背景 有时候打字&#xff0c;输入 “xian” 的时候我们的意图是 “xi’an” &#xff08;西安&#xff09;&#xff0c;或者输入 “yue” 的时候希望是 “yu’e”&#xff08;余额&#xff09; 如何输入这个分隔符 ’ 呢&#xff1f; 设置方法 默认页面如图 希望设置成 点…

家电行业 EDI:Miele EDI 需求分析

Miele是一家创立于1899年的德国公司&#xff0c;以其卓越的工程技术和不懈的创新精神而闻名于世。作为全球领先的家电制造商&#xff0c;Miele的经营范围覆盖了厨房、洗衣和清洁领域&#xff0c;致力于提供高品质、可持续和智能化的家电产品。公司的使命是为全球消费者创造更美…

【Java 进阶篇】深入理解 SQL 聚合函数

在 SQL 数据库中&#xff0c;聚合函数是一组强大的工具&#xff0c;用于处理和分析数据。它们可以帮助您对数据进行统计、计算总和、平均值、最大值、最小值等操作。无论您是数据库开发者、数据分析师还是希望更好地了解 SQL 数据库的用户&#xff0c;了解聚合函数都是非常重要…

CSS详细基础(四)显示模式

本帖开始介绍CSS中更复杂的内容 目录 一.显示模式 1.行内元素 2.块级元素 3.行内块元素 二.背景样式 一.显示模式 顾名思义&#xff0c;在CSS中&#xff0c;元素主要有3种显示模式&#xff1a;行内元素、块级元素、行内块元素~ 所谓块级元素&#xff0c;指的是该元素在…

ChatGPT AIGC 非常实用的AI工具集合大全

实战AI 工具箱 AIGC ChatGPT 职场案例60集, Power BI 商业智能 68集, 数据库Mysql8.0 54集 数据库Oracle21C 142集, Office, Python ,ETL Excel 2021 实操,函数,图表,大屏可视化 案例实战 http://t.csdn.cn/zBytu

GD32工程创建

1.创建空工程 在任意路径下创建空的test文件夹。打开keil5空工程创建空工程 选择对应的芯片型号&#xff1a; 然后把空工程保存到test文件夹下。会自动生成如下文件。 2. 添加组 下载GD32F10X的固件库&#xff1a;在百度里搜索GD32进入官网。 下载下来对应的文件如下&#xff…

MYSQL常用命令

一.数据类型 MySQL中有多种数据类型&#xff0c;每种类型用于存储不同类型的数据。以下是MySQL中常见的数据类型&#xff1a; 数值类型&#xff1a; INT&#xff1a;整数类型&#xff0c;存储范围为-2,147,483,648到2,147,483,647。BIGINT&#xff1a;大整数类型&#xff0c;存…

【蓝桥杯选拔赛真题63】Scratch云朵降雨 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析

目录 scratch云朵降雨 一、题目要求 编程实现 二、案例分析 1、角色分析

AHH HackerHouse @Move大理站完美谢幕

Antalpha HackerHouse Move 大理站于2023年9月23日在面包树举办了Final DemoDay&#xff0c;这也代表着为期21天的 HackerHouse 活动完美谢幕。 自从9月3日开始&#xff0c;整整21天的共居时间里&#xff0c;我们从个体逐渐融汇成小团队&#xff0c;最终成为了一个紧密团结的大…

UI自动化测试 | Jenkins配置优化

前一段时间帮助团队搭建了UI自动化环境&#xff0c;这里将Jenkins环境的一些配置分享给大家。 背景&#xff1a; 团队下半年的目标之一是实现自动化测试&#xff0c;这里要吐槽一下&#xff0c;之前开发的测试平台了&#xff0c;最初的目的是用来做接口自动化测试和性能测试&…