当前位置: 首页 > news >正文

《ARM64体系结构编程与实践》学习笔记(四)

MMU内存管理

1.MMU内存管理(armv8.6手册的D5章节),MMU包含快表TLB,TLB是对页表的部分缓存,页表是存放在内存里面的。

AArch64仅仅支持Long Descriptor的页表格式,AArch32支持两种页表格式Armv7-A Short Descriptor format和Armv7-A(LPAE)Long Descriptor format(默认是short)。AArch64支持3种不同的页大小:4KB,16KB,64KB(Linux使用的是4KB的页大小),大粒度的page size可以减少页表的体积。ARMv8的地址总线位宽通常为48位,最大空间支持256TB,对于实现了LVA扩展的ARMv8可以将位宽扩展到52位。ARMv8虚拟地址是64位的,虚拟地址VA被划分为两个空间,每个空间最大支持256TB,低位的虚拟地址空间位于0x0000_0000_0000_0000到0x0000_FFFF_FFFF_FFFF高位的虚拟地址空间位于0xFFFF_0000_0000_0000到0xFFFF_FFFF_FFFF_FFFF,低位地址空间用作App Space,使用页表TTBR0,高位地址空间用作Kernel Space,使用页表TTBR1,如下图所示,中间的FAULT部分的地址CPU是无法访问的,若访问会报错。

 AArch64采用的是四级页表索引,如下图所示:

AArch64页表的L0~L2页表的页表项格式如下图所示,共有三种情况,bit0为0表示该页表项无效,bit0为1表示有效;bit1为1表示该页表项指示下一级页表的基地址,bit1为0表示该页表项指向一个大块内存空间。(可参考ARMv8手册第D5.3节)

AArch64页表的L3页表的页表项格式如下图所示,不同粒度的页面大小,会有不同位数的输出地址。

高位属性和低位属性的具体字段可以参考ARMv8手册的D5.3.3节,不涉及虚拟化只需参考stage1的部分,如下图:

各个字段具体含义如下:

通常一个TLB entry只能完成一个page的VA到PA的转换,Armv8上利用TLB进行的一个优化,可以利用一个TLB entry来完成多个连续的page的VA到PA的转换,这通过上图中的Contiguous位标示,使用Contiguous bit的条件:页面对应的VA和PA必须是连续的、对于4KB的页面,可以一次转换16个连续的page、对于16KB的页面,可以一次转换32或者128个连续的page、对于64KB的页面,可以一次转换32个连续的page、连续的页面必须有相同的属性、起始地址必须以页面对齐。对于不同粒度的页面大小,48位地址的划分情况如下图所示:

2.共享性与缓存性:缓存性(cacheability)指的是页面是否使能了高速缓存以及高速缓存的范围。通常只有普通内存可以使能高速缓存,通过页表项AttrIndx[2:0]来设置页面的内存属性。另外,还能指定高速缓存是内部共享属性还是外部共享属性。通常处理器内核集成的高速缓存属于内部共享的高速缓存,而通过系统总线集成的高速缓存属于外部共享的高速缓存。共享性指的是在多核处理器系统中某一个内存区域的高速缓存可以被哪些观察者观察到。没有共享性指的是只有本地CPU能观察到,内部共享性只能被具有内部共享属性的高速缓存的CPU观察到,外部共享性通常能被外部共享的观察者(例如系统中所有的CPU、GPU以及DMA等主接口控制器)观察到。页表项属性中使用SH[1:0]字段来表示页面的共享性与缓存性,对于使能了高速缓存的普通内存,可以通过SH[1:0]字段来设置共享属性。但是,对于设备内存和关闭高速缓存的普通内存,处理器会把它们当成外部共享属性来看待,尽管页表项中为SH[1:0]字段设置了共享属性(此时SH[1:0]字段不起作用)。在多核处理器系统中,内部共享性和外部共享性描述了缓存的访问范围。内部共享性指处理器内部多个核心之间共享的缓存(如L1、L2缓存),这些缓存只在同一处理器内部可见,通常访问速度较快,适用于核心间的缓存一致性。外部共享性指多个不同硬件单元(如多个CPU核心、GPU、DMA等)共享的缓存,通常位于处理器外部(如L3缓存),这些缓存通过系统总线对所有设备可见,保证了不同硬件之间的缓存一致性。内部共享性通常具有较低的延迟,而外部共享性涉及的硬件更多,延迟较高。两者的主要区别在于缓存的可见性和访问范围,分别适用于不同层级的硬件和内存访问需求。

3.AArch64执行状态的MMU支持单一阶段的页表转换,也支持虚拟化扩展中两阶段的页表转换。单一阶段的页表转换指把虚拟地址(VA)翻译成物理地址(PA)。两阶段的页表转换包括两个阶段。在阶段1,把虚拟地址翻译成中间物理地址(Intermediate Physical Address,IPA);在阶段2,把IPA翻译成最终PA。

4.在SMP(Symmetric Multi-Processor,对称多处理器)系统中,每个处理器内核内置了MMU和TLB硬件单元。如图110所示,CPU0和CPU1共享物理内存,而页表存储在物理内存中。CPU0和CPU1中的MMU与TLB硬件单元也共享同一份页表。当一个CPU修改了页表项时,需要使用BBM(Break-Before-Make)机制(该机制用于确保在SMP系统中,当一个CPU修改页表项时,其他CPU不会使用过时的TLB缓存数据,可参考ARMv8手册的第D5.11节和K11.5.3节)来保证其他CPU能访问正确和有效的TLB。

5.和页表相关的寄存器:

  1. TCR_EL1(Translation Control Register):用来配置地址空间大小和页面粒度,其常用字段如下:IPS[34:32]:用来配置物理地址的大小,对于48位地址(物理空间256TB),可将该位设置为0b101。如果IPS字段定义的输出地址大于实际物理内存地址,那么CPU会使用实际物理内存,因为MMU输出地址不能大于实际物理地址。如果页表里的输出地址超过了物理内存地址,会触发地址大小缺页异常(address size fault)或者页表转换缺页异常(translation fault);TG0[15:14]和TG1[31:30]:分别用来配置TTBR0_EL1和TTBR1_EL1的页面粒度,可设置为4KB、16KB或64KB,例如将该位置为0b00表示4KB;T0SZ[5:0]和T1SZ[21:16]:分别用来配置TTBR0_EL1和TTBR1_EL1对应页表所能管辖的地址空间的大小,计算公式为2^(64-TxSZ),如果想将其设为48位寻址空间,则将该位的值设置为16即可;SH0、SH1、IRGN0、IRGN1、ORGN0、ORGN1:用来设置TTBR0_EL1和TTBR1_EL1对应内存的相关属性,如共享属性、高速缓存属性(具体参考ARM64体系结构编程与实践P203),上文提及的每个页表项中的SH[1:0]比当前的SH字段优先级更高,当两个字段都设置时,以页表项中的SH[1:0]位对应的共享属性为准,一般情况下两者需保证一致,否则可能出错

  2. SCTLR_EL1(System Control Register):M[0]位用来设置MMU的打开与关闭,即控制第一阶段地址翻译的开关,C[2]位用来设置data cache的打开与关闭,I[12]位用来设置instruction cache的打开与关闭

  3. TTBR0_EL1和TTBR1_EL1:分别指向TTBR0和页表TTBR1的基地址,通常用于EL1/EL0的页表映射

6.ARMv8架构处理器主要提供两种类型的内存属性:普通内存(Normal)和设备内存(Device),普通内存是弱一致性的(weakly ordered),没有其他额外的约束,提供最高的内存访问性能。处理器访问设备内存有很多限制,如不能使用高速缓存等。设备内存是严格按照指令顺序来执行的,是强一致性的。ARMv8架构定义了多种设备内存的属性:

  • Device-nGnRnE:不支持聚合操作,不支持指令重排,不支持提前写应答;
  • Device-nGnRE:不支持聚合操作,不支持指令重排,支持提前写应答;
  • Device-nGRE:不支持聚合操作,支持指令重排,支持提前写应答;
  • Device-GRE:支持聚合操作,支持指令重排,支持提前写应答。

设备内存相关操作:G表示支持聚合操作(聚合是指可以在同一个内存属性的区域里面把多次访问内存的操作合并成一次总线传输,如果一个设备内存标记为nG,那么就会严格按照访问的次数和大小来进行访问而不会进行合并优化);R表示支持指令重排,可以乱序执行;E表示支持提前写应答(即数据到达写缓存就可以进行写应答,如果一个设备内存标记为nG则数据到达外设才能进行写应答)。内存属性并没有存放在页表的页表项中,而是存放在MAIR_ELn寄存器(Memory Attribute Indirection Register)。MAIR_ELn寄存器结构如下,最多可以存储八类不同属性的内存:

页表项中有一个3位的索引值AttrIdx[0:2]来查找MAIR_ELn寄存器。

7.在操作系统启动过程中,从BootLoader/BIOS跳转到操作系统时,MMU(内存管理单元)通常是关闭的,因此处理器直接使用物理地址进行内存访问。关闭MMU意味着不能使用高速缓存优化性能,因为当MMU关闭时,系统无法使用虚拟地址进行内存访问,因此无法进行虚拟地址到物理地址的转换,也就无法正确维护缓存的内容。在系统初始化时,打开MMU并启用数据高速缓存是提高性能的关键,但这需要谨慎操作。因为当MMU打开后,处理器会开始使用虚拟地址进行内存访问,因此必须确保虚拟地址到物理地址的正确映射(如使用恒等映射,即VA=PA,一般映射前后2M空间就可以了),否则可能会导致访问错误或数据不一致,在关闭MMU情况下,处理器访问的地址都是物理地址。当MMU打开时,处理器访问的地址变成了虚拟地址。现代处理器都是多级流水线架构,处理器会提前预取多条指令到流水线中。当打开MMU时,处理器已经提前预取了多条指令,并且这些指令是以物理地址来进行预取的。当打开MMU指令执行完成,处理器的MMU功能生效,那么之前提前预取的指令以虚拟地址来访问,到MMU单元去查找对应的物理地址。因此在打开MMU前后应用isb()指令刷新处理器的指令流水线让CPU重新取指。页表的创建和填充是由操作系统来完成的,但是处理器遍历页表是由处理器的 MMU来完成的。第14章的实验一通过恒等映射创建了四级页表,主要创建过程如下:

  • 在链接脚本中的数据段直接分配4KB大小作为L0级页表的缓存空间,剩下的L1级、L2级、L3级页表在初始化时动态创建,实验中所设计的页表只有第L2级页表(三级页表)可以分配2M的大块内存,所以在创建页表时用了一个小技巧,即在创建L2级页表项时如果虚拟区间的开始地址(addr)、结束地址(next)和物理地址(phys)都与SECTION_SIZE大小(2MB)对齐并且没有设置NO_BLOCK_MAPPINGS标志位,那么直接设置段映射(section mapping)的页表项,不需要映射下一级页表,因为这几个地址都与SECTION_SIZE对齐就说明所需要的内存大于SECTION,直接按照SECTION分配即可,不用再往下细分到4KB,如下图(具体参考ARM64体系结构编程与实践P215):

  • 页表创建完之后设置所要用到的几种内存的内存属性,写入MAIR_EL1寄存器中,并设置页面粒度为4KB,ID_AA64MMFR0_EL1寄存器中含有当前支持的页面粒度信息

  • 而后将L0页表基地址写入TTBR0_EL1中,打开MMU,注意在打开MMU前后使用isb()指令冲刷流水线

建立完页表并打开MMU后,可以正常访问已经建立了VA到PA映射的地址,但如果访问没有建立页表映射的地址则会导致同步异常。

8.ldxr和stxr可以进行原子访问,但是使用时有很多限制,参考ARM®Cortex®-A Series(Programmer’s Guide for ARMv8-A)手册的14.1.4节,如下图所示:

只有在所访问的存储器满足:可内部或外部共享、内部回写、外部回写、读写分配命中、非暂态等条件时才能确保这两个指令可正常使用。当没有打开MMU时,访问normal内存会被当成是访问device 内存,这两个指令无法使用。如果仅仅enable了MMU,而没有设置上述属性(具体设置为:通过SCTLR_EL1寄存器的C位打开data cache、通过TCR_EL1寄存器的SH0、SH1、IRGN0、IRGN1、ORGN0、ORGN1位打开外部共享、内部回写、外部回写等属性),这两个指令也无法正常使用。

9.除了通过MMU自动进行虚拟地址到物理地址的转换外,还可以通过AT指令实现两个地址间的转换。AT指令用法如下图所示:

语法格式为AT <operation>, <Xt>,例如上图中s1e1r表示第一阶段地址转换、EL1、读取操作,X0存放了待转换的虚拟地址值,具体可参考ARMv8手册第D5.2.11节,如果转换成功读取的物理地址和内存相关属性信息会被存放在PAR_EL1寄存器中,该寄存器结构如下图所示:

相关文章:

《ARM64体系结构编程与实践》学习笔记(四)

MMU内存管理 1.MMU内存管理&#xff08;armv8.6手册的D5章节&#xff09;&#xff0c;MMU包含快表TLB&#xff0c;TLB是对页表的部分缓存&#xff0c;页表是存放在内存里面的。 AArch64仅仅支持Long Descriptor的页表格式&#xff0c;AArch32支持两种页表格式Armv7-A Short De…...

01-SDRAM控制器的设计——案例总概述

本教程重点▷▷▷ 存储器简介。 介绍 SDRAM 的工作原理。 详细讲解SDRAM 控制的Verilog 实现方法。 PLL IP和FIFO IP 的调用&#xff0c;计数器设计&#xff0c;按键边沿捕获&#xff0c;数码管控制。 完成SDRAM控制器应用的完整案例。 Signal Tap 调试方法。 准备工作▷…...

京准:NTP卫星时钟服务器对于DeepSeek安全的重要性

京准&#xff1a;NTP卫星时钟服务器对于DeepSeek安全的重要性 京准&#xff1a;NTP卫星时钟服务器对于DeepSeek安全的重要性 在网络安全领域&#xff0c;分布式拒绝服务&#xff08;DDoS&#xff09;攻击一直是企业和网络服务商面临的重大威胁之一。随着攻击技术的不断演化…...

uniapp访问django目录中的图片和视频,2025[最新]中间件访问方式

新建中间件, middleware.py 匹配,以/cover_image/ 开头的图片 匹配以/episode_video/ 开头的视频 imageSrc: http://192.168.110.148:8000/cover_image/12345/1738760890657_mmexport1738154397386.jpg, videoSrc: http://192.168.110.148:8000/episode_video/12345/compres…...

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决 1、报错情况 下载&#xff1a;https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle 用idea打开&#xff0c;启动&#xff1a; 日志有报错&#xff1a; 点右侧m图标&#xff0c;maven有以下报误 &…...

python脚本实现windows电脑内存监控内存清理(类似rammap清空工作集功能)

import ctypes import psutil import time import sys import os from datetime import datetime import pyautogui# 检查管理员权限 def is_admin():try:return ctypes.windll.shell32.IsUserAnAdmin()except:return False# 内存清理核心功能 def cleanup_memory(aggressivene…...

【狂热算法篇】并查集:探秘图论中的 “连通神器”,解锁动态连通性的神秘力量

嘿&#xff0c;朋友们&#xff01;喜欢这个并查集的讲解吗 记得点个关注哦&#xff0c;让我们一起探索算法的奥秘&#xff0c;别忘了一键三连&#xff0c;你的支持是我最大的动力&#xff01; 欢迎拜访&#xff1a;羑悻的小杀马特.-CSDN博客 本篇主题&#xff1a;深度剖析并查…...

SpringBoot中实现动态数据源切换

SpringBoot中实现动态数据源切换 文章目录 SpringBoot中实现动态数据源切换SpringBoot中实现动态数据源切换基础知识1. 什么是数据源&#xff1f;2. 动态数据源切换的概念3. Spring Boot 中的默认数据源配置4. 动态数据源的挑战5. Spring 中的数据源切换方式 设计思路1. 明确应…...

数据结构及排序算法

数据结构 线性结构 ◆线性结构:每个元素最多只有一个出度和一个入度,表现为一条线状。线性表按存储方式分为顺序表和链表。 存储结构: ◆顺序存储:用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素物理上也相邻。 ◆链式存储:存储各数据元素的结点…...

Python基础-元组tuple的学习

在 Python 中&#xff0c;元组&#xff08;tuple&#xff09;是一种不可变的序列类型&#xff0c;允许存储不同类型的元素。元组非常类似于列表&#xff08;list&#xff09;&#xff0c;但与列表不同的是&#xff0c;元组一旦创建&#xff0c;就不能修改其内容。 1 元组的创建…...

【手写公式识别】MEMix: Improving HMER with Diverse Formula Structure Augmentation 论文阅读

发表于&#xff1a;ICME 2024 原文链接&#xff1a;https://ieeexplore.ieee.org/document/10687521 源码&#xff1a;无 Abstract 手写数学表达式识别&#xff08;HMER&#xff09;旨在将数学表达式&#xff08;MEs&#xff09;的图像转换为相应的LaTeX序列。然而&#xff0…...

使用deepseek写一个飞机大战游戏

说明&#xff1a; 安装pygame&#xff1a;在运行代码之前&#xff0c;需要先安装 pygame 库。可以通过以下命令安装&#xff1a; pip install pygame图像文件&#xff1a;需要将玩家、敌人和子弹的图像文件&#xff08;player.png, enemy.png, bullet.png&#xff09;放在与脚本…...

用Kibana实现Elasticsearch索引的增删改查:实战指南

在大数据时代&#xff0c;Elasticsearch&#xff08;简称 ES&#xff09;和 Kibana 作为强大的数据搜索与可视化工具&#xff0c;受到了众多开发者的青睐。Kibana 提供了一个直观的界面&#xff0c;可以方便地对 Elasticsearch 中的数据进行操作。本文将详细介绍如何使用 Kiban…...

C# 封送和远程编程介绍

.NET学习资料 .NET学习资料 .NET学习资料 在 C# 编程领域中&#xff0c;封送&#xff08;Marshaling&#xff09;和远程编程&#xff08;Remote Programming&#xff09;是两个极为重要的概念&#xff0c;它们为开发者提供了与不同环境、不同进程或不同机器上的代码进行交互的…...

MybatisPlus较全常用复杂查询引例(limit、orderby、groupby、having、like...)

MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。以下是 MyBatis-Plus 中常用复杂查询&#xff08;如 LIMIT、ORDER BY、GROUP BY、HAVING、LIKE 等&#xff09;的引例&#xff1a; 1. 环境准备…...

02.07 TCP服务器与客户端的搭建

一.思维导图 二.使用动态协议包实现服务器与客户端 1. 协议包的结构定义 首先&#xff0c;是协议包的结构定义。在两段代码中&#xff0c;pack_t结构体都被用来表示协议包&#xff1a; typedef struct Pack {int size; // 记录整个协议包的实际大小enum Type type; …...

Jenkins数据备份到windows FTP服务器

文章目录 背景1. 安装配置 FileZilla Server&#xff08;Windows&#xff09;1.1 下载并安装 FileZilla Server1.2 配置 FTP 用户和共享目录 2. 安装并配置 FTP 客户端&#xff08;CentOS&#xff09;2.1 在 CentOS 安装 lftp 3. 编写 Jenkins 备份脚本3.1 赋予执行权限3.2 测试…...

【R语言】卡方检验

一、定义 卡方检验是用来检验样本观测次数与理论或总体次数之间差异性的推断性统计方法&#xff0c;其原理是比较观测值与理论值之间的差异。两者之间的差异越小&#xff0c;检验的结果越不容易达到显著水平&#xff1b;反之&#xff0c;检验结果越可能达到显著水平。 二、用…...

ASP.NET Core托管服务

目录 托管服务的异常问题 托管服务中使用DI 托管服务案例&#xff1a;数据的定时导出 场景&#xff0c;代码运行在后台。比如服务器启动的时候在后台预先加载数据到缓存&#xff0c;每天凌晨3点把数据导出到备份数据库&#xff0c;每隔5秒钟在两张表之间同步一次数据。托管服…...

HarmonyOS 5.0应用开发——全局自定义弹出框openCustomDialog

【高心星出品】 文章目录 全局自定义弹出框openCustomDialog案例开发步骤完整代码 全局自定义弹出框openCustomDialog CustomDialog是自定义弹出框&#xff0c;可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹出框…...

如何在C++ QT 程序中集成cef3开源浏览器组件去显示网页?

文章目录 1. **准备工作**1.1 下载CEF31.2 配置Qt项目2. **集成CEF3到Qt窗口**2.1 创建Qt窗口容器2.2 初始化CEF33. **处理CEF3消息循环**4. **处理多进程架构**5. **完整代码示例**`main.cpp`6. **常见问题**6.1 黑屏问题6.2 窗口嵌入失败6.3 多进程调试7.**Github源码参考**8…...

深入讲解MyBatis

1. MyBatis 的背景和优势 背景&#xff1a;在 Java 开发中&#xff0c;传统的 JDBC 操作数据库代码繁琐&#xff0c;需要手动管理数据库连接、编写 SQL 语句、处理结果集等&#xff0c;开发效率低且容易出错。MyBatis 应运而生&#xff0c;它通过将 SQL 语句与 Java 代码分离&a…...

使用matlab 对传递函数分析bode图和阶跃函数

如果已知一个系统的传递函数&#xff0c;想看一下bode图&#xff0c;可以通过simulink 建模&#xff0c;但是simulink运行起来相对比较慢&#xff0c;我一般都是直接通过matlab 的m语言写脚本实现。可以快速的获得结果 如 我们有一个一阶低通传递函数 syswn/(swn) 在matlab中…...

2025牛客寒假算法基础集训营5(补题)

C 小L的位运算 显然&#xff0c;如果两次反置的价格小于等于交换的价格&#xff0c;那么直接全部反置就好了。 反之&#xff0c;由于交换一定低于两次反置&#xff0c;我们尽可能用交换来消去不正确的位置。不正确的位置类型只有00&#xff0c;01&#xff0c;10&#xff0c;11&…...

FaceFusion如何设置公开链接和端口

有时候我们想在局域网内的其他设备上使用 FaceFusion&#xff0c;这时候需要设置公开链接和端口。 当你运行 FaceFusion 的时候&#xff0c;会发现有这样的一段提示&#xff1a; To create a public link, set shareTrue in launch().但是这个提示是错的&#xff0c;如果你查…...

神经网络常见激活函数 6-RReLU函数

文章目录 RReLU函数导函数函数和导函数图像优缺点pytorch中的RReLU函数tensorflow 中的RReLU函数 RReLU 随机修正线性单元&#xff1a;Randomized Leaky ReLU 函数导函数 RReLU函数 R R e L U { x x ≥ 0 a x x < 0 \rm RReLU \left\{ \begin{array}{} x \quad x \ge 0…...

计算机网络面经

文章目录 基础HTTPHTTP报文结构 (注意)RPC和http的区别TCPTCP报文结构(注意)IP基础 HTTP HTTP报文结构 (注意) 请求行:请求方法get/post,url,http版本 请求头:用户标识,请求体长度,类型,cookie 请求体:内容 状态行:状态码,状态消息、(http版本) 响应头:内…...

Qt:常用控件

目录 控件概述 控件体系的发展 按钮类控件 QPushButton QRadioButton QCheckBox QToolButton 显示类控件 QLabel QLCDNumber QProgressBar QCalendarWidget 输入类控件 QLineEdit QTextEdit QComboBox QSpinBox QDateEdit & QTimeEdit QDial QSlider …...

算法设计-找第二大数(C++)

一、问题描述 用于在给定的整数数组中找到 第二大值。 二、详细代码 #include<iostream> #include<limits.h> using namespace std; //初始化最大值为a[0]&#xff0c;次大值为a[1]&#xff0c;遍历一次&#xff0c;每次比较并更新最大值和次大值&#xff0c;最…...

【C++高并发服务器WebServer】-14:Select详解及实现

本文目录 一、BIO模型二、非阻塞NIO忙轮询三、IO多路复用四、Select()多路复用实现 明确一下IO多路复用的概念&#xff1a;IO多路复用能够使得程序同时监听多个文件描述符&#xff08;文件描述符fd对应的是内核读写缓冲区&#xff09;&#xff0c;能够提升程序的性能。 Linux下…...