ARM体系结构与编程-第五章

第5章 ARM存储系统

5.1 ARM存储系统概述

存储系统:

  • 包含多种类型的存储器件,如FLASH、ROM、SRAM和SDRAM
  • 通过使用CACHE及WRITE BUFFER技术缩小处理器和存储系统得速度差别
  • 内存管理不见使用内存映射技术实现虚拟空间到物理空间的映射。
  • 引入存储保护机制
  • 引入一些机制保证将I/O操作映射成内存操作后,各种I/O操作能够得到正确的结果

5.2 ARM中用于存储管理的系统控制协处理器CP15

在基于ARM的嵌入式应用系统中,存储系统通常是通过系统控制协处理器CP15完成的。此外,还有一些其他的技术,如在MMU中除了CP15外还将使用页表。

5.2.1 访问CP15寄存器的指令

  • MCR ARM寄存器到协处理器寄存器的数据传送指令

    MCR {<cond>} p15, 0, <Rd>, <CRn>, <CRm> {, <opcode_2>}

    MCR2 p15, 0, <Rd>, <CRn>, <CRm> {, <opcode_2>}

  • MRC 协处理器寄存器到ARM寄存器的数据传送指令

    MRC {<cond>} p15, 0, <Rd>, <CRn>, <CRm> {, <opcode_2>}

    MCR2 p15, 0, <Rd>, <CRn>, <CRm> {, <opcode_2>}

5.2.2 CP15中的寄存器

  1. CP15中的寄存器C0

    存放ARM相关的一些标识符,只读

  2. CP15中的寄存器C1

    控制寄存器,包括:

    • 禁止/使能MMU以及其他的与存储系统相关的功能
    • 配置存储系统以及ARM处理器中的相关部分的工作方式

5.2.3 存储器管理单元 MMU

存储器管理单元工作:

  • 虚拟存储空间到物理存储空间的映射
  • 存储器访问权限的控制
  • 设置虚拟存储空间的缓冲的特性

主要通过页表实现,表的每一行对应于虚拟存储空间的一个页,该行包含了该虚拟内存页对应的物理内存页的地址、该页的方位权限和该页的缓冲特性。这样一行称为一个地址变换条目。

页表存放在内存中,系统通常用一个寄存器来保存页表的基地址。在ARM中CP15的C2用来保存页表的基地址。

从虚拟地址到物理地址的变换过程其实就是查询页表的过程。为提高速度,使用一个小容量快速的快表称为TLB。需要时现在TLB中查找,不存在就到内存页表中查询,并将结果添加到TLB中。

但内存页表内容改变,或使用新的页表时,TLB中内容需要全部清除,ARM中有CP15的C8控制。

MMU中C10控制TLB内容的锁定

MMU可将整个存储空间分为16个域,每个域对应一定的内存区域,具有相同访问控制属性。C3用于控制域相关的属性的配置。

存储访问失效,C5和C6处理这些情况

5.3.2 禁止/使能MMU

CP15的寄存器C1的位[0]控制禁止/使能MMU。0禁止1使能

MRC P15,0,R0,C1,0,0
ORR R0, #01
MCR P15,0,R0,C1,0,0
  1. 使能MMU时存储器访问过程

    ARM处理器请求存储访问时,首先在TLB中查找虚拟地址。如果虚拟地址对应的地址变换条目不在TLB中,CPU从位于内存中的页表中查找对应于该虚拟地址的地址变换条目,并把相应的结果添加到TLB中,若已满,根据一定淘汰算法进行替换。

    得到需要的地址变换条目后,进行:

    • 得到该虚拟地址对应的物理地址
    • 根据条目中的C和B控制位决定是否缓存该内存访问的结果
    • 根据存取权限控制位和域访问控制位确定该内存访问是否被允许。若不被允许,CP15向ARM处理器报告存储访问中止
    • 对于不允许缓存的存储访问,使用第一步得到的物理地址访问内存。对于允许缓存的存储访问,如果cache命中,则忽略物理地址;如果没有命中,则使用第一步得到的物理访问内存,并把该数据读到cache中。
  2. 禁止MMU时存储访问过程

    当禁止MMU时,存储访问规则:

    • 当禁止MMU时,是否支持cache和write buffer由各个具体芯片的设计决定
    • 存储访问不进行权限控制,MMU也不会产生存储访问中止信号
    • 所有的物理地址和虚拟地址相等,即使用平板存储模式。
  3. 禁止/使能MMU时应注意的问题
    • 使能MMU之前,要在内存中建立号页表,同时CP15中的各相关寄存器必须完成初始化
    • 如果使用的不是平板存储模式,在禁止/使能MMU时,虚拟地址和物理地址的对应关系会发生改变,这时应该清除cache中的当前地址变换条目。
    • 如果完成禁止/使能MMU的代码的物理地址和虚拟地址不相同,则禁止/使能MMU时将造成很大麻烦,因此完成禁止/使能MMU的代码的物理地址和虚拟地址最好相同。

5.3.3 MMU中地址变换的过程

ARM支持的存储块大小:

  • 段:大小为1M的存储块
  • 大页:大小为64KB的存储块
  • 小页:大小为4KB的存储块
  • 极小页:大小为1KB的存储块

在MMU中采用下面两级页表实现:

  • 一级页表中包含有以段为单位的地址变换条目以及指向二级页表的指针。一级页表实现的地址映射粒度较大。
  • 二级页表中包含以大页和小页为单位的地址变换条目。其中,一种类型的二级页表好包含有以极小页为单位的地址变换条目

通常,以段为单位的地址变换过程还需要一级页表。而以页为单位的地址变换过程还需要二级页表。

基于一级页表的地址变换过程

基于二级页表的地址变换过程

一级描述符格式、页描述符的格式

5.3.4 MMU中存储访问权限控制

在MMU中,寄存器C1的R、S控制位和页表中地址转换条目中的访问权限控制位联合作用控制存储访问的权限。

5.3.5 MMU中的域

指的是一些段、大页或者小页的集合。ARM最多支持16个域,每个域的访问控制特性由CP15中的寄存器C3中的两位来控制。

5.3.6 关于快表的操作

TLB

当CPU需要访问内存时,先在TLB中查找需要的地址变换条目。如果该条目不存在,CPU从位于内存中的页表中查询,并把相应的结果添加到TLB中。这样,当CPU下一次又需要该地址变换条目时,可以从TLB直接得到,从而地址变换速度大大增加。

  1. 使无效快表的内容
  2. 锁定快表的内容

5.3.7 ARM中的存储访问失效

  • 当MMU检测到存储访问失效时,可以向CPU报告该情况,并将存储访问失效的相关信息保存到寄存器中。这种机制叫MMU失效
  • 外部存储系统也可以像CPU报告存储访问失效。这种机制称为外部存储访问中止。
  1. MMU失效
  2. 外部存储访问失效

5.4 高速缓存存储器和写缓冲区

5.4.1 基本概念

Cache与主存储器之间以块为单位进行数据交换

5.4.2 cache的工作原理和地址映像方法

  1. cache的工作原理

    在cache存储系统中,把cache和主存储器都划分成相同大小的块。主存地址可以由块号B和块内地址W两部分组成,同样,cache的地址也可以由块号b和块内地址w组成。

    当CPU要访问cache时,CPU送来主存地址,放到主存地址寄存器中。通过地址变换部件把主存地址中的块号B变换成cache的块号b,并放到cache地址寄存器中。同时将主存地址中的块地址W直接作为cache的块地址w装入到cache地址寄存器中。

    如果变换成功称为cache命中,就用得到的地址访问cache,否则,产生cache失效信息,并用主存地址访问主存储器。从主存储器读出一个字送往CPU,同时,把包含被访问字在内的一整块都从主存储器读出来,装入到cache中去。如果cache已满,采用某种替换策略把不常用的块调出主存储器中相应的块,一遍存放新调入的块。

  2. cache地址映像和变换方法

    在cache中,地址映像是指把主存地址空间映像到cache地址空间。即把主存中的程序按某种规则装入到cache中,并建立主存地址到cache地址之间的对应关系。

    在进行地址映像和变换时,都是以块为单位进行调度。

    常用的地址映像方式和变换方式包括全相连映像和变换方式、直接映像和变化方式及组相连映像和变换方式。

5.4.3 cache的分类

  1. 统一/独立的数据cache和指令cache
  2. 写通cache和写回cache
  3. 读操作分配cache和写操作分配cache

5.4.4 cache的替换算法

随机替换算法和轮转法

5.4.5 缓冲技术的使用注意事项

在ARM中,I/O操作通常被映射为存储器操作。I/O的输出通过存储器写入操作实现,I/O输入操作通过存储器读取操作实现。这些存储器的I/O空间就不满足cache所要求的上述特性。

将存储器映射的I/O空间设置成uncached是为了有效地防止硬件系统优化时删掉有用的存储访问操作。如果在高级语言中访问存储器映射的I/O空间时,仅仅将存储器映射的I/O空间设置成uncached是不够的。还必须告诉编译器不要在优化时删掉有用的存储访问操作。在C语言中是通过使用关键词volatile声明存储器映射的I/O空间来防止编译器在优化时删掉有用的存储访问操作。

5.4.6 存储系统的一致性问题

  1. 地址映射关系变化造成的数据不一致
  2. 指令cache的数据一致性问题
  3. DMA造成的数据不一致问题

5.4.7 cache内容锁定

将一些关键代码和数据项预取到cache后,设置一定的属性,使发生cache块替换时,这些关键代码和数据所在的块不会被替换。

5.4.8 与cache和写缓冲区相关的编程接口

  1. 寄存器C1中的相关位与写缓冲区操作相关
  2. 寄存器C7用于控制cache和写缓冲区
  3. 寄存器C9是cache内容锁定寄存器

5.5 快速上下文切换技术FCSE

通过修改系统中不同进程的虚拟地址,避免在进行进程间切换时造成的虚拟地址到物理地址的重映射。

5.5.1 快速上下文切换技术原理

如果两个进程占用的虚拟地址空间重叠,系统在这两个进程之间进行切换时,必须进行虚拟地址到物理地址的重映射。而虚拟地址到物理地址重映射涉及到重建MMU中的页表,而cache和TLB中的内容都必须使无效。

快速上下文切换技术,位于CPU和MMU之间,如果两个进程使用同样的虚拟地址空间,则对CPU而言,两个进程使用了同样的虚拟地址空间;快速上下文切换机构对各进程的虚拟地址进行变换,这样系统除了CPU外的部分看到的是经过FCSE机构变换的虚拟地址。这样在进行进程间切换的时候就不需要进行虚拟地址到物理地址的重映射。

在ARM中,4GB的虚拟空间被分成了128个进程空间块,每个32MB。每个进程空间块中可以包含一个进程,该进程可以使用虚拟地址空间0x00000000~0x01ffffff,这个地址范围就是CPU看到的进程的虚拟地址空间。系统128个进程空间块的编号0~127,编号为I的进程空间块中的进程使用的虚拟地址空间为(I X 0x02000000)到(I X 0x02000000+0x01ffffff),这个地址空间是系统除了CPU之外的其他部分看到的该进程所占用的虚拟地址空间。

if(VA[31:25] == 0b0000000) then
MVA = VA | (PID << 25)
else
MVA = VA

其中,PID位当前进程所在的进程控制块的编号,即当前进程的进程标识符。取值为0~127

5.5.2 快速上下文切换技术编程接口

C13用于上下文切换

5.6 与存储系统相关的程序设计指南

5.6.1 地址空间

ARM体系使用单一的平板地址空间,该地址空间的大小为2^32个8位字节。这些字节单元的地址是一个无符号的32位数值,其取值范围为0~2^32-1。也可以看作是2^30个32位的字单元。这些字单元可以被4整除,也就是说地址的低两位为0b00.地址为A的字数据包括地址A、A+1、A+2、A+3 4个字节单元的内容。

5.6.2 存储器格式

big-endian和little-endian格式

高位在高地址,低位在低地址--小端

高位在低地址,低位在高地址--大端

5.6.3 非对齐的存储访问操作

  1. 非对齐的指令预取操作

    要么指令执行的结果不可预知,要么地址值中最低两位(非字对齐)/最低位(非半字对齐)被忽略

  2. 非对齐的数据访问操作
    • 执行的结构不可预知
    • 忽略字单元的低两位的值,即访问地址是字单元;忽略半字单元的最低位,即访问地址为半字单元
    • 忽略字单元地址值中的低两位的值;忽略半字单元地址的最低位的值。由存储系统实现这种“忽略”。即地址值原封不动送到存储系统。

5.6.4 指令预取和字修改代码

当用户读取PC寄存器的值时,返回的是当前指令下面第2条指令的地址。

自修改代码指的是代码在执行过程中可能修改自身。

5.6.5 IMB

IMB在新的指令被保存到主存中后,在该指令被实际执行之前执行,提供可自修改代码在ARM体系中的可靠执行。

5.6.6 存储器映射的I/O空间

在ARM中,I/O操作通常被映射成存储器操作,I/O的输出操作可以通过存储器写入实现;I/O的输入操作可以通过存储器读取操作实现。不能使用cache技术。

原文地址:https://www.cnblogs.com/luoxiao23/p/11386101.html

时间: 2024-10-10 17:23:12

ARM体系结构与编程-第五章的相关文章

ARM体系结构与编程-5

GET通常用于包含定义常量的源文件. 例如:GET 2440addr.inc 用AREA定义一个段,ENTRY用于指定程序的入口点,END用于告诉汇编器源文件已经结束. 例如: AREA init, CODE, READONLY ENTRY ...... END EQU用于定义常量,提醒:在每条ARM指令前必须有空格,但是用EQU定义常量时,必须顶格写,否则编译器报错. LTORG用于声明一个文字池,所谓文字池就是一个数据缓存区. ALIGN伪操作通过调整地址指针,使得当前地址满足一定的对齐方式

【嵌入式Linux+ARM】ARM体系结构与编程(ARM概述)

ARM体系结构与编程 本文章记录一些看<ARM体系结构与编程>这一本书的记录: 个人觉得,学习ARM体系时,不需要死记硬背,只要把某些关键的大致记住,比如ARM寄存器(通用寄存器.PC.LR.SP.CPSR.SPSR).ARM中断处理体系.常用的ARM汇编指令等. 本文基本都是从书上截图,都是一些关键的知识,需要我们时常去复习的. 一.ARM概述 ARM处理器的7种工作模式: ARM处理器寄存器: ARM中PC(R15)寄存器: ARM中CPSR寄存器: ARM异常处理模式--响应过程和返回过

[python核心编程] 第五章练习题

第五章 数字 5-2. 操作符,写一个函数,计算并返回两个数的乘积“整理的时候才看到我把题目看成两个数的和了” 5-3. 标准类型操作符.写一段脚本,输入一个测验成绩,根据下面的标准,输出他的评分成绩(A-F) A:90~100 B:80~89 C:70~79 D:60~69 F:<60 5-4. 取余.判断给定年份是否是闰年.使用下面的公式. 一个闰年后就是指他可以被4整除,但不能被100整除,或者它可以被400整除. [python核心编程] 第五章练习题,布布扣,bubuko.com

ARM体系结构与编程-4

ARM异常中断处理: ARM体系异常中断种类:按中断的处理优先级从高到低依次为:复位.数据访问中止.快速中断请求.外部中断请求.预取指中止.未定义指令.软件中断. ARM体系中的异常中断向量表: 0x0 复位 0x4 未定义指令 0x8 软件中断(SWI) 0x0c 预取指中止 0x10 数据访问中止 0x14 保留 0x18 外部中断请求(IRQ) 0x1c 快速中断请求(FIQ) 各异常中断对应着一定的处理器模式,不同处理器模式下有各自的物理寄存器.如果异常中断处理程序中使用它自己的物理寄存

Python核心编程第五章习题

Python核心编程-第五章-习题 5.1  整形,讲讲Python普通整形与长整形的区别? Python的标准整形类型是最通用的数字类型.在大多数32位机器上,标准整形类型的取值范围是-2**32-2**32 - 1. Python的长整型类型能表达的数值仅仅与你的机器支持的(虚拟)内存大小有关,换句话说,Python能轻松表达很大的整数. 长整型类型是标准整形类型的超集,当程序需要使用比标准整形更大的整型时,可以使用长整型类型,在整型值后面添加L,表示这个为长整型,3.0版本已经统一称为为整

ARM体系结构与编程

ARM处理器的7中运行模式:usr.fiq.irq.svc.abt.und.sys. ARM处理器共37个寄存器:31个通用寄存器(未备份寄存器R0-R7,在所有模式下指的都是同一个物理寄存器:备份寄存器R8-R12,每个寄存器对应两个不同的物理寄存器.对于R13[sp]和R14[lr]来说,每个寄存器对应6个不同的寄存器:程序计数器R15[pc]),6个状态寄存器(当前程序状态寄存器[cpsr]:5个备份状态寄存器[spsr]). ARM体系的异常中断:复位.未定义指令.软件中断.指令预取中止

UNIX 网络编程第五章读后有感

刚看完 UNIX 第五章内容,我想按照自己的方式将自己获得的知识梳理一遍,以便日后查看!先贴上一段简单的 TCP 服务器端代码: 1 #include <sys/socket.h> 2 #include <netinet/in.h> 3 #include <stdio.h> 4 #include <error.h> 5 #include <unistd.h> 6 #include <string.h> 7 #include <s

【嵌入式Linux+ARM】ARM体系结构与编程(ARM汇编指令)

自己的一些简单的总结,也是最常用的ARM汇编指令,之后也会不断的补充完善. 1. 汇编系统预定义的段名 .text    @代码段 .data   @初始化数据段 .bss    @未初始化数据段 需要注意的是,源程序中.bss段应该在.text之前. 2.定义入口点 汇编程序的缺省入口是 start标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点. .text .global _start _start: 3 .word用法 word expression就是在当前位置放一个wo

第四章 基本TCP套接字编程 第五章 TCP客户/服务器程序实例

TCP客户与服务器进程之间发生的重大事件时间表 TCP服务器 socket() --- bind() --- listen() --- accept() --- read() --- write --- read() --- close TCP客户 socket() --- connect() --- write() --- read()  --- close() 套接字函数简介 int socket(int family, int type, int protocol); 指定要用的通信协议类