《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寄存器中,该寄存器结构如下图所示:

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

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

相关文章

如何在Vscode中接入Deepseek

一、获取Deepseek APIKEY 首先&#xff0c;登录Deepseek官网的开放平台&#xff1a;DeepSeek 选择API开放平台&#xff0c;然后登录Deepseek后台。 点击左侧菜单栏“API keys”&#xff0c;并创建API key。 需要注意的是&#xff0c;生成API key复制保存到本地&#xff0c;丢失…

Docker 部署 MinIO | 国内阿里镜像

一、导读 Minio 是个基于 Golang 编写的开源对象存储套件&#xff0c;基于Apache License v2.0开源协议&#xff0c;虽然轻量&#xff0c;却拥有着不错的性能。它兼容亚马逊S3云存储服务接口。可以很简单的和其他应用结合使用&#xff0c;例如 NodeJS、Redis、MySQL等。 二、…

DeepSeek-R1 32B Windows+docker本地部署

最近国产大模型DeepSeek兴起&#xff0c;本地部署了一套deepseek同时集成Open WebUI界面,给大家出一期教程。 软件&#xff1a;Ollama、docker、Open WebUI 一、用Ollama下载模型 首先我们需要安装Ollama&#xff0c;它可以在本地运行和管理大模型。 到Ollama官网 https://ol…

TCP服务器与客户端搭建

一、思维导图 二、给代码添加链表 【server.c】 #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <fcntl.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.…

python爬虫--简单登录

1&#xff0c;使用flask框架搭建一个简易网站 后端代码app.py from flask import Flask, render_template, request, redirect, url_for, sessionapp Flask(__name__) app.secret_key 123456789 # 用于加密会话数据# 模拟用户数据库 users {user1: {password: password1}…

ESXi Host Client创建ubuntu虚拟机教程及NVIDIA显卡驱动安装

参考文章 VMware虚拟机显卡直通记录 AIGC 实战&#xff08;环境篇&#xff09; - EXSI 8.0 Debian安装RTX3060显卡驱动 重点介绍 client版本是7.0.3 注意&#xff1a;下图中不要选择BIOS 按照两个链接中的方法进行操作&#xff0c;以及本章节的上面几个图片的配置之后&a…

Maven入门核心知识点总结

Maven 1. POM&#xff08;Project Object Model&#xff09;2. 坐标&#xff08;Coordinates&#xff09;3. 依赖管理&#xff08;Dependency Management&#xff09;4. 常用五个生命周期&#xff08;Life Circle&#xff09;5. Maven 仓库&#xff08;Maven Repository&#x…

测试中的第一性原理:回归本质的质量思维革命

在软件工程领域&#xff0c;测试活动常被惯性思维和经验主义所主导——测试用例库无限膨胀、自动化脚本维护成本居高不下、测试策略与业务目标渐行渐远。要突破这种困境&#xff0c;第一性原理&#xff08;First Principles Thinking&#xff09;提供了独特的解题视角&#xff…

Rust语言进阶之标准输入: stdin用法实例(一百零五)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

SpringBoot速成(七)注册实战P2-P4

1.创建 数据库创建 依赖引入 <!-- mybatis起步依赖--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency> <…

Spring Boot接入Deep Seek的API

1&#xff0c;首先进入deepseek的官网&#xff1a;DeepSeek | 深度求索&#xff0c;单击右上角的API开放平台。 2&#xff0c;单击API keys&#xff0c;创建一个API&#xff0c;创建完成务必复制&#xff01;&#xff01;不然关掉之后会看不看api key&#xff01;&#xff01;&…

【C++学习篇】C++11第二期学习

目录 1. 可变参数模板 1.1 基本语法及原理 1.2 包扩展 1.3empalce系列接⼝ 2. lamba 2.1 lambda的语法表达式 2.2 捕捉列表 2.3 lamba的原理 1. 可变参数模板 1.1 基本语法及原理 1. C11⽀持可变参数模板&#xff0c;也就是说⽀持可变数量参数的函数模板和类模板&…

开放式TCP/IP通信

一、1200和1200之间的开放式TCP/IP通讯 第一步&#xff1a;组态1214CPU&#xff0c;勾选时钟存储器 第二步&#xff1a;防护与安全里面连接机制勾选允许PUT/GET访问 第三步&#xff1a;添加PLC 第四步&#xff1a;点击网络试图&#xff0c;选中网口&#xff0c;把两个PLC连接起…

迁移学习 Transfer Learning

迁移学习&#xff08;Transfer Learning&#xff09;是什么&#xff1f; 迁移学习是一种机器学习方法&#xff0c;它的核心思想是利用已有模型的知识来帮助新的任务或数据集进行学习&#xff0c;从而减少训练数据的需求、加快训练速度&#xff0c;并提升模型性能。 &#x1f…

爬虫技巧汇总

一、UA大列表 USER_AGENT_LIST 是一个包含多个用户代理字符串的列表&#xff0c;用于模拟不同浏览器和设备的请求。以下是一些常见的用户代理字符串&#xff1a; USER_AGENT_LIST [Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; Hot Lingo 2.0),Mozilla…

我们来学人工智能 -- 将Ollama已下载的模型从C盘迁出

题记 未配置OLLAMA_MODELS系统变量导致模型下载到了C盘 迁移步骤 退出ollama 配置OLLAMA_MODELS系统变量 OLLAMA_MODELS&#xff1a;D:\ollama\models 直接将C盘下的models目录剪切到指定目录 检查 cmd命令窗口退出重新打开

Redis 集群原理、主从复制和哨兵模式的详细讲解

引言&#xff1a;本文记录了博主在学习Redis的过程中的原理&#xff0c;了解为什么使用与怎么样使用 Redis 集群&#xff0c;在使用 Redis 集群时出现的主从复制和哨兵模式的相关知识。本文并不涉及Redis安装。 文章目录 一、简单介绍什么是 Redis二、为什么要使用 Redis 集群三…

Java数据结构 | TreeMap 和 TreeSet

TreeMap 和 TreeSet 1. 搜索树1.1 概念1.2 搜索树的查找、插入、删除思路及代码1.2.1 查找1.2.2 插入1.2.3 删除&#xff08;难点&#xff09; 1.3 二叉搜索树的性能分析 2. Map 和 Set2.1 Map 接口2.1.1 Map.Entry<K,V>2.1.2 Map的常用方法 2.2 Set 接口2.2.1 Set 的常用…

智能理解 PPT 内容,快速生成讲解视频

当我们想根据一版 PPT 制作出相对应的解锁视频时&#xff0c;从撰写解锁词&#xff0c;录制音频到剪辑视频&#xff0c;每一个环节都需要投入大量的时间和精力&#xff0c;本方案将依托于阿里云函数计算 FC 和百炼模型服务&#xff0c;实现从 PPT 到视频的全自动转换&#xff0…

小鹅通首页网页开发

一、小鹅通首页开发 二、代码&#xff1a; index.html: <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&…