「ARM32」MMU和页表的映射过程详解

news2024/10/6 8:31:17

在ARM32中,MMU主要完成虚拟地址到物理地址的映射,并且能够控制内存的访问权限,而页表是实现上述功能的主要手段。页表又分为一级页表、二级页表,在ARM64中甚至还有三级页表。为了便于理解,本章主要讲述一级页表完成段映射的详细过程,二级页表将在下一章节进行详述,约定下文提到的页表均为一级页表。

1. MMU和页表

1.1 MMU

MMU是一种硬件电路,再直白一点,就是使用与或非门组合而成的数字电路,既然是电路,那么就有输入和输出,输入就是CPU发起的虚拟地址,输出就是最终转换后的物理地址。

CPU根本不知道访问的地址是物理的还是虚拟的,它只访问一个地址,然后从数据线上获取数据。未开启MMU时,CPU的访问地址直接通过地址总线访问到外部内存,此时CPU的访问地址就是物理地址。启用MMU时,CPU的访问地址是虚拟地址,经过MMU转化为物理地址,从而访问外部内存里的数据。

暂且把MMU看成一个黑盒,下图为一个使用虚拟地址寻址的系统框图,CPU发起访问虚拟地址0x00000000来访问内存,在0x00000000被送到内存之前,先经过了MMU做了虚拟地址到物理地址的转换,MMU输出为0xC0000000,然后通过并行总线访问了物理地址为0xC0000000的地址空间。

1.2 页表

页表是一种数据结构,再直白点,基本在32位的ARM处理器中,页表是uint32类型的数组,且数组大小为4K,页表存放在内存当中,页表里存放了虚拟地址与物理地址的对应关系,VA到PA的转换过程其实就是MMU查询和解析页表的过程。

学习直通车:

Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈ke.qq.com/course/4032547?flowToken=1040236

页表在内存中的存储如下图所示,软件在DDR中开辟了16KByte连续的空间用来存储一级页表,也就是定义了一个数组用来存放虚拟地址与物理地址的对应关系,代码实现上大体如下:

uint32 L1Table[4096];

1.2.1 一级描述符

什么是一级描述符,从数学上说,一级页表是一级描述符的集合

L1Table中的每一个元素都描述了虚拟地址到物理地址或二级页表的映射关系,因为这些元素位于一级页表,所以称为一级描述符。

一级描述符的格式如下图所示,本章只介绍和段映射有关的bit,其他bit的含义会在后面的章节再进行介绍:

bit1:0:

00,缺页,虚拟存储空间没有被映射到物理存储空间,因而访问该存储空间将产生缺页异常。

01,该一级描述符中包含了粗粒度的二级页表的物理地址。该粗粒度的二级页表定义了对应的 1MB 的虚拟存储空间的地址映射关系。它可以实现以大页和小页为单位的地址映射。

2. 完成虚拟地址到物理地址的段映射

在ARM32中,以1M为单位进行虚拟地址到物理地址的映射称为段映射,我们已经知道一级页表有4096个描述符,每个描述符描述了1M的虚拟地址到物理地址的映射关系,正好是4G。

2.1 页表基地址寄存器

既然页表里存放了(VA)虚拟地址到(PA)物理地址的对应关系,且页表存放在内存里,在做VA到PA的转换时,MMU需要到页表里去取数据,那么MMU怎么知道页表在内存的什么位置呢?

在ARM32中,协处理器CP15的C2寄存器用来存放一级页表的基地址,但只使用了bit31:14,bit13:bit0并未使用,这就决定了一级页表在内存中一定是16K对齐的(2的14次方等于16K)。C2寄存器的格式如下图所示

2.2 一级描述符所在的物理地址

当CPU发起一次寻址操作时,虚拟地址作为MMU的输入,被MMU内的逻辑门电路进行运算,将C2寄存器的bit31:bit14作为高位,将虚拟地址的bit31:bit20作为低位,将两者拼接,低2位补0,如下图所示,最终找到一级描述符所在的物理地址。

用软件模拟一级描述符的查找过程:

uint32_t GetPTE所在的物理地址(uint32 虚拟地址)
  {
    uint32 页表基地址 = 页表基地址寄存器 & 0xffffc000 ;
    
    //与上0xfffffffc;是因为页表是4字节对齐的
    uint32 PTE所在的物理地址 = (虚拟地址>>18) |  页表基地址  & 0xfffffffc;
    
    return PTE所在的物理地址;
  }

2.3 完成虚拟地址到物理地址的段映射

如上图所示,假设,CPU此刻要读取虚拟地址0x12345678上连续4Byte的数据,ARM32的C2寄存器值为0xC0009000,按照上一节所讲方式进行拼接。

得出一级描述符位于物理地址0xC000848C处,0xC000848C地址存储的是一条段描述符,此描述符映射物理地址0xB00000000~0xb00fffff共1M的物理地址空间,虚拟地址的低20位(0x45678)为段内地址的偏移,虚拟地址0x12345678对应的物理地址是0xB0045678,该物理地址存放的数据为0x57280000,所以CPU读取到的数据为0x57280000

2.4 再补充一张段映射的系统框图

文章最后,根据下图再巩固一下段映射的过程

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

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

相关文章

centos7 安装Mysql详细教程

centos7 弃用了Mysql,默认安装了MariaDB,MariaDB是Mysql一个分支,所以要想在centos上安装Mysql,需要先进行卸载MariaDB,避免冲突 本次教程所用环境: 腾讯云服务器:centos7Mysql5.7 1. 卸载Ma…

dubbo源码实践-protocol层-invoker理解

1概述Invoker官方解释:Invoker 是实体域,它是 Dubbo 的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起 invoke 调用,它有可能是一个本地的实现,也可能是一个…

Python 机器学习最常打交道的 27 款工具包

为了大家能够对人工智能常用的 Python 库有一个初步的了解,以选择能够满足自己需求的库进行学习,对目前较为常见的人工智能库进行简要全面的介绍。 1、Numpy NumPy(Numerical Python)是 Python的一个扩展程序库,支持大量的维度数组与矩阵运算…

Maix Bit(K210)保姆级入门上手教程

Maix Bit(K210)快速上手 这是K210快速上手系列文章,主要内容是,设备连接,环境准备,运行第一个程序 阅读文章前提:python基础,K210是使用Micropython脚本语法的,因此需要一些python…

RocketMQ5.0.0部署与实例

一、Idea调试1.相关配置文件在E:\rocketmq创建conf、logs、store三个文件夹。从RocketMQ distribution部署目录中将broker.conf、logback_namesrv.xml、logback_broker.xml文件复制到conf目录。如下图所示。其中logback_namesrv.xml、logback_broker.xml分别是NameServer、Brok…

纯C语言实现动态爱心(详解,初学者也能看懂)

文章目录✍动态爱心实现💖一段小故事:爱心函数的由来🎈 创建动态爱心的准备(非小白可以跳过)1.爱心字符2.对easyx库里面的基础函数的认识①initgraph函数②settextcolor、settextstyle、setbkmode、outtextxy四种函数③…

PostgresSQL数据库的使用

PostgresSQL数据库的使用 下载安装 数据类型 使用指导 数据库操作 连接控制台 psql -h <实例连接地址> -U <用户名> -p <端口号>参数描述实例连接地址RDS PostgreSQL实例的连接地址&#xff0c;本机可用localhost或者127.0.0.1用户名创建的RDS Postgre…

ES语法扩展

剩余参数 剩余参数本质 // 剩余参数的本质const add(x,y,...args)>{console.log(x,y,args);}add();add(1);add(1,2);add(1,2,3,4,5); 剩余参数的注意事项 箭头函数的参数部分即使只有一个剩余参数&#xff0c;也不能省略圆括号使用剩余参数替代arguments获取实际参数剩余…

4.Isaac Jetson Nano 入门

Isaac Jetson Nano 入门 本节介绍如何在 Jetson Nano 设备上运行 Isaac SDK 示例应用程序。 有关如何开始使用 Nano 的一般说明&#xff0c;请参阅 Jetson Nano 开发工具包入门。 文章目录Isaac Jetson Nano 入门获取 IP 地址在 Jetson Nano 上运行示例应用程序PingOpenCV 边缘…

Pytorch CIFAR10图像分类 EfficientNet v1篇

Pytorch CIFAR10图像分类 EfficientNet v1篇 文章目录Pytorch CIFAR10图像分类 EfficientNet v1篇4. 定义网络&#xff08;EfficientNet&#xff09;EfficientNet介绍EfficientNet性能比较EfficientNet的baselineEfficientNet模型混合缩放方法其他版本的EfficientNet(B1-B7)判断…

错题 3jxn (8253复杂)

A 指示型指令 C 比如 ,跟C语言的return 一样&#xff0c;可以由多条&#xff0c;但是返回的位置都是一个地方 JN NEXT RET NEXT: RET A 可以重复 EQU不可以重复 C 中断向量&#xff1a;中断服务程序的入口地址 向量中断&#xff1a;识别中断你的方法 接口 编程题&#xff…

Redis关键知识点总结

Reference: http://redis.cn用处缓存数据库分布式锁&#xff08;Redission的redlock&#xff0c;自定义的lock等&#xff09;过滤器&#xff08;布隆过滤器/增强的带计数的布隆过滤器/布谷鸟过滤器等&#xff09;大规模的计算辅助&#xff08;bitmap&#xff09;消息订阅/监听 …

PyQt5入门学习(一)【小白入门系列】

PyQt5入门学习 介绍&#xff1a;PyQt5是Python较好的图形库&#xff0c;与C的Qt不同的是PyQt5封装得较为简单&#xff0c;上手也更加的方便。下面话不多说&#xff0c;开始学习PyQt5吧&#xff01; 安装过程 安装方法有两种&#xff0c;一种是下载PyQt5最新源码进行编译安装…

初识Kafka

1.1 定义 Kafka传统定义: Kafka是一个分布式的基于发布/订阅模式的消息队列(MessageQueue&#xff09;&#xff0c;主要应用于大数据实时处理领域。 发布/订阅: 消息的发布者不会将消息直接发送给特定的订阅者&#xff0c;而是将发布的消息分为不同的类别&#xff0c;订阅者只…

[数据结构基础]二叉树——堆的概念、结构、接口函数及经典的Topk问题和堆排序问题

目录 一. 堆的概念及结构 1.1 堆的概念 1.2 堆的结构及在内存中的存储 二. 堆的主要接口函数 2.1 堆初始化函数HeapInit 2.2 堆销毁函数HeapDestroy 2.3 向堆中插入数据函数HeapPush&#xff08;以小堆为例&#xff09; 2.4 删除堆根节点数据函数HeapPop&#xff08;小…

C++ 夺冠!成为 TIOBE 2022 年度编程语言

目录&#xff1a;C夺冠—成为TIOBE2022年度编程语言一、前言二、C 摘得桂冠三、Top 10 编程语言 TIOBE 指数走势&#xff08;2002-2023&#xff09;四、历史排名&#xff08;1987-2023&#xff09;五、编程语言“名人榜”&#xff08;2003-2022&#xff09;六、说明一、前言 2…

vitepress(三):自动生成目录

上一节我们将自己的网站发布到了git pages上&#xff0c;但是现在我们需要每次更新一篇文章就重写一次目录&#xff0c;操作上十分的繁琐和不方便&#xff0c;所以我们需要一个方法去自动生成我们的侧边栏结构&#xff0c;方便我们每次只需要更新我们的项目即可。这里我们要知道…

【每日一题】【LeetCode】【第六天】【Python实现】加一

加一的解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 1这个很好理解&#xff0c;唯一的难点就是个位1导致的进位的问题&#xff0c;可能会只会导致十位1&#xff0c;也有像8999这样产生多次进位的情况。 为了解决进位问题&#xff0c;自己想到了第三天学…

mysql三表查询15个例子带你搞懂它

mysql三表查询30个经典案例创建三个表a、b、c表a中的数据表b中的数据表c中的数据1.查询出学习成绩70分以上的学生姓名与成绩与学科&#xff1b;2.查询姓名以mi结尾的学生姓名及其任课老师姓名&#xff1b;3.选修课名为math的学生学号与姓名;4.选修课号为C4的学生学号&#xff1…

QEMU调试Linux内核环境搭建

一个最小可运行Linux操作系统需要内核镜像bzImage和rootfs&#xff0c;本文整理了其制作、安装过程&#xff0c;调试命令&#xff0c;以及如何添加共享磁盘。编译内核源码从 The Linux Kernel Archives 网站下载内核源码&#xff0c;本文下载的版本为4.14.191&#xff0c;4.14.…