(890条消息) [架构之路-17]:目标系统 - 硬件平台 - ARM CPU架构与系列选型_arm硬件架构_文火冰糖的硅基工坊的博客-CSDN博客
ARM Core内核系统(取指令、解释指令、执行指令)
内存控制子系统 (内存)
外设控制器子系统(IO)
中断控制子系统 (中断)
系统控制子系统:电源、时钟、复位、启动
该架构是我们理解汇编指令和编写裸机程序的基石。
当我们拿到一个新的SOC的datasheet,首先就要根据这个架构,来查看SOC的RAM空间、时钟频率、包括哪些外部设备的控制器,各个外设控制器的操作原理,各个外设对GPIO的引脚复用情况、各个控制器的SFR地址、中断控制器是如何管理众多中断源的等等。
MCU单片机,不仅仅集成了各种外围设备控制器的接口,包括各种高速和低速总线控制器,还在SOC片内包括Flash和SRAM存储器,用于永久性存储代码和数据。
以由高到低的方式来看,ARM处理器大体上可以排序为:Cortex-A57处理器、Cortex-A53处理器、Cortex-A15处理器、Cortex-A12处理器、Cortex-A9处理器、Cortex-A8处理器、Cortex-A7处理器、Cortex-A5处理器、ARM11处理器、ARM9处理器、ARM7处理器。
ARM内核进行运算的核心部件是算术逻辑运算单元-ALU(arithmetic and logic unit)。它对两个操作数进行逻辑或者算术运算。为了提高嵌入式处理器的工作速度,以保证实时性的要求,ARM在处理器中尽可能多地设置了寄存器。ARM处理器共有N个32位寄存器。
cpu执行指令的流程:取指令,分析指令,执行指令,
内存控制单元负责如何让管理指令和数据的地址。
寄存处负责在外存和运算单元的桥梁
堆栈负责程序指令的嵌套
中断控制器负责紧急事件与常规事件的并发与抢占
CPU在运行不同的程序所需的硬件资源是不同,ARM处理器可以为不同程序提供7种不同的硬件资源组合,每一种硬件资源组合叫做一种运行模式。
在不同的模式下,能否访问的CPU内部的硬件资源的范围和权限是不相同的。
USR(用户模式):ARM处理器正常程序执行模式
FIQ(快速中断模式):用于高速数据传输或通道处理
IRQ(中断模式):用于通用的中断处理
SVC(管理模式):操作系统使用的保护模式
ABT(终止模式):当数据或指令预取出错时进入的模式。
SYS(系统模式):运行具有特权的操作系统任务。
UND(未定义指令中止模式):当处理器试图执行未定义指令时进入的模式
现代计算机系统都有用户模式,只为用户程序提供了有限硬件资源的运行模式。
相对于用户模式来说,对硬件资源的使用有某种特权的运行模式叫做特权模式(除了用户模式其他六种运行模式都是特权模式)。
(1)用户模式:
用户模式是用户程序的工作模式,它运行在操作系统的用户态,它没有权限去操作其它硬件资源,只能执行处理自己的数据,也不能切换到其它模式下,要想访问硬件资源或切换到其它模式只能通过软中断或产生异常。
(2)系统模式:
系统模式是特权模式,不受用户模式的限制。用户模式和系统模式共用一套寄存器,操作系统在该模式下可以方便的访问用户模式的寄存器,而且操作系统的一些特权任务可以使用这个模式访问一些受控的资源。
说明:用户模式与系统模式两者使用相同的寄存器,都没有SPSR(Saved Program Statement Register,已保存程序状态寄存器),但系统模式比用户模式有更高的权限,可以访问所有系统资源。
(3)一般中断模式:
一般中断模式也叫普通中断模式,用于处理一般的中断请求,通常在硬件产生中断信号之后自动进入该模式,该模式为特权模式,可以自由访问系统硬件资源。
(4)快速中断模式:
快速中断模式是相对一般中断模式而言的,它是用来处理对时间要求比较紧急的中断请求,主要用于高速数据传输及通道处理中。
(5)管理模式(Supervisor,SVC) :
管理模式是CPU上电后默认模式,因此在该模式下主要用来做系统的初始化,软中断处理也在该模式下。当用户模式下的用户程序请求使用硬件资源时,通过软件中断进入该模式。
说明:系统复位或开机、软中断时进入到SVC模式下。
(6)终止模式:
中止模式用于支持虚拟内存或存储器保护,当用户程序访问非法地址,没有权限读取的内存地址时,会进入该模式,linux下编程时经常出现的segment fault通常都是在该模式下抛出返回的。
(7)未定义模式:
未定义模式用于支持硬件协处理器的软件仿真,CPU在指令的译码阶段不能识别该指令操作时,会进入未定义模式。
除了用户模式和系统模式,其余模式下都有一个私有SPSR保存状态寄存器,用来保存切换到该模式之前的执行状态,之所以用户模式和系统模式没有SPSR是因为,通常CPU大部分时间执行在用户模式下,当产生异常或系统调用时会分别切换进入另外几种模式,保存用户模式下的状态,当切换回原先模式时,直接回复SPSR的值到CPSR就可以了,因此,用户模式和系统模式下不需要SPSR,其详细操作查看下节异常处理。
以上几种模式通过CPSR里的M[4:0]位进行区分,如图3-1所示:
首先,ARM开发板在刚上电或复位后都会首先进入SVC即管理模式,此时、程序计数器R15-PC值会被赋为0x0000 0000;bootloader就是在此模式下,位于0x0000 0000的NOR FLASH或SRAM中装载的,因此、开机或重启后bootloader会被首先执行。
接着,bootloader引导Linux内核,此时、Linux内核一样运行在ARM的SVC即管理模式下;当内核启动完毕、准备进入用户态init进程时,内核将ARM的当前程序状态CPSR寄存器M[4:0]设置为10000、进而用户态程序只能运行在ARM的用户模式。模式系统的,进程的上下文中包含模型信息,并有调度程序负责切换模式,因为调度程序具有超级权限,是工作在SVC模式。
由于ARM用户模式下对资源的访问受限,因此、可以达到保护Linux操作系统内核的目的。
需要强调的是:Linux内核态是从ARM的SVC即管理模式下启动的,但在某些情况下、如:硬件中断、程序异常(被动)或系统调用等情况下进入ARM的其他特权模式,这时仍然可以进入内核态(因为就是可以操作内核了);同样,Linux用户态是从ARM用户模式启动的,但当进入ARM系统模式时、仍然可以操作Linux用户态程序(进入用户态,如init进程的启动过程)。即:Linux内核从ARM的SVC模式下启动,但内核态不仅仅指ARM的SVC模式(还包括可以访问内核空间的所有ARM模式);Linux用户程序从ARM的用户模式启动,但用户态不仅仅指ARM的用户模式。
寄存器分为模式无关的通用寄存器以及模式相关的专有寄存器。
ARM处理器共有N=37个寄存器,但是根据处理器的运行模式,程序能够真正使用的只是其中的18个或者17个。
两种或两种以上运行模式所共享的寄存器叫做基础寄存器。他们是R0~R15和CPSR,其中R0~R7、R15和CPSR为所有运行模式共享;R8~R12为除了快中断模式之外的其他所有运行模式共享;R13和R14为用户模式和系统模式共享,如下图所示:
为了对数据进行保护,ARM为某些运行模式设置了一些只能在该运行模式下使用的私有寄存器,上图中带有后缀的寄存器均为私有寄存器。
ARM规定,当处理器在某种模式运行时,凡是与该模式私有寄存器序号相同的基本寄存器都将被禁用。例如在终止模式下,与该模式私有寄存器R13_abt~R14_abt序号相同的基础寄存器R13和R14就处于禁用状态。为了减少寄存器名称的数量,ARM规定,寄存器名称统一写为R<序号>方式,但是这个名称所对应的实际物理寄存器与处理器当前运行模式相关。也就是说,程序中的一个寄存器名称可能对应着多个物理寄存器,程序中的这个名称究竟指的是哪个物理寄存器,则由系统根据当前运行的模式来决定。
在ARM中,通用寄存器R15固定得作为程序计数器来使用。
为了提高程序的可读性,通常用PC来标识。
在CPU中,一条指令的执行简单的划分为:取指-译码-执行,三个部分 [2]。
PC中存放的是下一条将要“执行”的指令的地址,这里的执行并不是取指-译码-执行中的第三个步骤,而是指的将存放于内存中的指令输送进CPU中“准备执行”,那么第一步就要取指,PC中存放的是从内存中取指所需要的地址。
ARM处理器的字长是32位,则一条汇编指令的长度也是32位,也就是四个字节,而内存中一个地址单元是一个字节,也就是说一条指令要占据4个地址单元。
假设程序顺序执行(一条接一条,没有跳转),假设当前正在CPU中执行的指令A的首地址是0,也就是说指令A的存放位置是内存中的0—3这4个地址单元。
假设指令A后面紧跟着指令B,指令B后面紧跟指令C,如果顺序执行,按理来说pc中存放的地址应该是指令B的首地址,也就是PC=0+4。
但是由于ARM处理器中采用了流水线的技术,假设是3级流水线,那么执行A处于三个步骤中的“执行”时,指令B已经开始进行“译码”,而真正开始“取指”的是指令C。
也就是说,当指令A在运行的时候,PC中存放的地址应该是指令C的地址,也就是说PC=0+8。
通用寄存器R16专门用作程序状态寄存器。
为了提高程序的可读性,程序中也可以称为PSR。
CPSR格式
ARM处理器中有6个PSR,当前程序状态寄存器CPSR是所有运行模式所共享的,而另外5个PSR为模式私有,用来对CPSR进行备份的寄存器叫做SPSR。
由于CPSR中保存的是程序当前运行模式的状态信息,所以当前运行模式发生变化时,为了防止这些信息丢失,ARM对每种异常运行模式都设置了一个与CPSR的格式完全相同的备份寄存器SPSR(Saved Progarm Status Register)。即当处理器进入异常运行模式时,系统会自动把CPSR的当前值转存到SPSR;当从异常模式退出时,再自动把当初保存到SPSR中的状态信息存回CPSR。
由于用户模式和系统模式不属于异常模式,所以这两个模式没有SPSR。
堆栈是计算机存储数据的一种数据结构,SP的作用就是指示当前要出栈或入栈的数据,并在操作执行后自动递增或递减。
计算机中的堆栈主要用来保存临时数据,局部变量和中断/调用子程序程序的返回地址。程序中栈主要是用来存储函数中的局部变量以及保存寄存器参数。
1) 保存现场;
2) 传递参数:汇编代码调用 C 函数时,需传递参数;
3) 保存临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量;
寄存器R14也称为子程序链接寄存器(Subroutine Link Register)或链接寄存器LR。
当执行子程序调用指令BL时,R14会备份R15(程序计数器PC)的内容,以便子程序结束后能使程序正确地返回。
概述:
ARM的RISC体系结构的发展中已经提供了低功耗、小体积、高性能的方案。而为了解决代码长度的问题,ARM体系结构又增加了T变种,开发了一种新的指令体系,这就是Thumb指令集,它是ARM技术的一大特色。
Thumb是ARM体系结构的扩展。它有从标准32位ARM指令集抽出来的36条指令格式,可以重新编成16位的操作码。这能带来很高的代码密度。
支持Thumb的ARM体系结构的处理器状态可以方便的切换、运行到Thumb状态,在该状态下指令集是16位的Thumb指令集。
ARM指令集对比Thumb指令集:
完成相同的操作,Thumb指令通常需要更多的指令,因此在对系统运行时间要求苛刻的应用场合ARM指令集更为适合;
Thumb指令集没有包含进行异常处理时需要的一些指令,因此在异常中断时,还是需要使用ARM指令,这种限制决定了Thumb指令需要和ARM指令配合使用。
ARM处理器的工作状态由程序状态寄存器CPSR的D5位的值控制,ARM指令集和Thumb指令集都设有处理器工作状态切换指令,以供程序在执行过程中对处理器进行状态切换。启动时,处理器默认状态为ARM状态。
Thumb指令与ARM指令的时间效率和空间效率对比:
Thumb代码所需的存储空间为ARM代码的60%~70%;
Thumb代码使用的指令数比ARM代码多30%~40%;
使用32位的存储器,ARM代码比Thumb代码执行效率快约40%;
若使用16位存储器,则Thumb代码比ARM代码快40%~50%;
与ARM代码相比较,使用Thumb代码,存储器的功耗会降低约30%。
若对系统的性能有较高要求,则应使用32位存储系统和ARM指令集;
若对系统的成本及功耗有较高要求,则应使用16位存储系统和Thumb指令集。
当然,若两者结合使用,充分发挥各自的优点,则会取得更好的效果。
1.寄存器寻址;
2.立即寻址;
3.寄存器移位寻址;
4.寄存器间接寻址;
5.基址寻址;
6.多寄存器寻址;
7.堆栈寻址;
8.块拷贝寻址;
9.相对寻址。
ARM是一种32位处理器,即ARM处理器处理的数据通常是以32位二进制位基本单位的。ARM中的一个32位数叫做一个字。在存储器中,ARM的一个基本数据需要占用4个连续存储单元,为了判断哪四个单元为一个字,ARM规定一个字所占用的4个连续存储单元的第一个单元地址的低2位必须是00。
根据字的4字节在4个存储单元中的存储顺序,ARM提供了两种存储方式:小端方式和大端方式。系统默认的是小端方式,即字的低位字节在地址的底端(小端)。
MMU分为两个部分: TLB maintenance 和 address translation
在Linxu OS之前,如uboot,是可以不需要启动MMU内存管理单元的,程序访问的是实际的物理地址,而不是逻辑地址。在Linux OS启动后,需要使用逻辑地址访问物理的空间,如0-1G的逻辑地址空间留给内核,1G-4G是进程空间。
MMU的作用,主要是完成地址的翻译,无论是main-memory地址(DDR地址),还是IO地址(设备device地址),在开启了MMU的系统中,CPU发起的指令读取、数据读写都是虚拟地址,在ARM Core内部,会先经过MMU将该虚拟地址自动转换成物理地址,然后在将物理地址发送到AXI总线上,完成真正的物理内存、物理设备的读写访问。
TLB(Translation Lookaside Buffer)转换检测缓冲区是一个内存管理单元,用于改进逻辑地址到物理地址转换速度的缓存。
TLB是一个小的,逻辑寻址的缓存,其中每一行都保存着一个由单个PTE(Page Table Entry,页表项)组成的块。
如果没有TLB,则每次取数据都需要两次访问内存,即查页表获得物理地址和取数据。
典型的 TLB
容量:8 - 4,096 分页表条目
寻中时间:0.5 - 1 时钟频率周期
不命中代价:10 - 30 时钟频率周期
不命中率: 0.01% - 3%
备注:Cache位于MMU与物理内存之间。
在计算机应用中,常常需要在内存中建立一种特殊工作方式的存储区域,这种存储区域中数据的读/写方式是按先进后出(First In Last Out,FILO)的原则来组织的,这种存储区域就叫做堆栈。
为了指示堆栈的位置,计算机系统都有一个堆栈指针的专用寄存器来存放堆栈的地址:
堆栈按照其生长方式可分为两种:
地址递增式
地址递减式
在系统初始化时,如果把堆栈指针置于较低的地址,当向堆栈存入一个数据时,堆栈的指针会指向高地址移动,即下次再存入数据时,数据的存放地址位于先存入数据上方的这个堆栈叫做地址递增式的堆栈。反之,如果数据的存储方向刚好与地址递增方式的堆栈的方向相反,则这种堆栈就叫做地址递减式堆栈。
(1)什么是FIQ和IRQ
FIQ(快速中断)和IRQ(普通中断)是ARM处理器里的两个处理器模式,ARM总有7种处理模式。两种模式都是用来处理中断的。
(2)FIQ和IRQ的区别
本质上来说两者都是中断,但是FIQ处理的优先级比IRQ更高,FIQ的相应时间也比IRQ更快,简单来说FIQ就是IRQ里的VIP,享有特权。
在ARM中,一般可以将某一个中断设置为FIQ,被设置为FIQ的中断在发生时可以插队,下一个处理的中断就是FIQ,有的甚至可以直接打断当前处理的IRQ,这里分为抢占式和非抢占式。
(3)中断为什么要分为FIQ和IRQ
现在的系统是需要频繁和用户进行交互的,用户的体验很大部分取决于响应时间,试想一下,你点一下鼠标系统要一分钟才响应,你会是怎样的感受。系统是不知道什么时候会发生中断,当有多个中断产生时,系统通常会按照中断发生的先后顺序去处理中断。但是中断之间的紧急程度是不同的,比如现在产生两个中断,一个是后台程序产生的,一个是用户点击了一下鼠标。如果先处理后台程序产生的中断再响应鼠标,用户会感觉系统好卡,响应很慢;其实后台程序慢一点处理也没有什么大不了,用户现在又不着急,这种情况我们就可以先去响应鼠标,把鼠标设置为FIQ,改善用户的体验感。
(4)FIQ比IRQ响应快的原因
FIQ的处理优先级比IRQ更高,甚至可以打断正在执行的IRQ;
FIQ模式有自己独有的寄存器,而IRQ需要和其他模式共用寄存器,在中断处理的保护/恢复现场会更快;
在异常向量表中,FIQ处在最末尾。在异常向量表中IRQ只能保存中断处理程序的首地址,在发生IRQ时需要一次跳转;而FIQ处在最末尾,所以可以直接将FIQ模式下的中断处理程序紧接着存放,这样在处理FIQ时就少一次跳转或进行短跳转,不需要长跳转。
在ARM系统中,所有的外设与内存是统一编址的,没有独立的IO空间。
llxx3.pdf (ustc.edu.cn)
ARM体系架构 - 知乎 (zhihu.com)
ARM架构处理器解析【最全的一篇!】 - 知乎 (zhihu.com)
(1090条消息) 深度学习arm cache系列--一篇就够了_代码改变世界ctw的博客-CSDN博客_arm cache
(1115条消息) [架构之路-22]:目标系统 - 系统软件 - 汇编语言的结构与X86指令系统以及CPU的工作原理、函数调用与堆栈操作_cpu堆栈_文火冰糖的硅基工坊的博客-CSDN博客
汇编语言:ARM中汇编文件和函数的格式【ARM汇编系列--入门篇01】 (ngui.cc)