查看: 834|回复: 0

[经验] 掌握ARM的2种工作状态和7种工作模式,电子工程师必看

[复制链接]
  • TA的每日心情
    无聊
    2018-11-16 10:48
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2020-8-20 09:19:59 | 显示全部楼层 |阅读模式
    分享到:
    一、存储器格式(字对齐):
    ARM体系结构将存储器看做是从零地址开始的字节的线性组合。从零字节到三字节放置第一个存储的字(32位)数据,从第四个字节到第七个字节放置第二个存储的字数据,一次排列。作为32位的微处理器,arm体系结构所支持的最大寻址空间为4GB。

    存储器格式
            1、大端格式:高字节在低地址,低字节在高地址;
            2、小端格式:高字节在高地址,低字节在低地址;
    指令长度:
    Arm微处理器的指令长度是32位的,也可以为16位(thumb状态下)。Arm微处理器中支持字节(8位),半字(16位),字(32位)三种数据类型,其中,字需要4字节对齐,半字需要2字节对齐。
    注:所谓的指令长度是一条完整的指令的长度,而不是单纯的mov这3个字母长度
    二、ARM体系的CPU有两种工作状态


      1、ARM状态:处理器执行32位的字对齐的ARM指令;
           2、Thumb状态:处理器执行16位的、半字对齐的Thumb指令;
    在程序运行的过程中,可以在两种状态之间进行相应的转换。处理器工作状态的转变并不影响处理器的工作模式和相应寄存器中的内容。
    CPU上电处于ARM状态

    三、ARM体系的CPU有以下7种工作模式:


            1、用户模式(Usr):用于正常执行程序;
            2、快速中断模式(FIQ):用于高速数据传输;
            3、外部中断模式(IRQ):用于通常的中断处理;
            4、管理模式(svc):操作系统使用的保护模式;
            5、数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储以及存储保护;
            6、系统模式(sys):运行具有特权的操作系统任务;
            7、未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件;
    Arm的工作模式切换有两种方法:
    被动切换:在arm运行的时候产生一些异常或者中断来自动进行模式切换
    主动切换:通过软件改变,即软件设置寄存器来经行arm的模式切换,应为arm的工作模式都是可以通过相应寄存器的赋值来切换的。
    tips:当处理器运行在用户模式下,某些被保护的系统资源是不能被访问的。

    除用户模式外,其余6种工作模式都属于特权模式;
    特权模式中除了系统模式以外的其余5种模式称为异常模式;
    大多数程序运行于用户模式;
    进入特权模式是为了处理中断、异常、或者访问被保护的系统资源;

    四、寄存器
    ARM有31个通用的32位寄存器,6个程序状态寄存器,共分为7组,有些寄存器是所有工作模式共用的,还有一些寄存器专属于每一种工作模式;
    R13——栈指针寄存器,用于保存堆栈指针;
    R14——程序连接寄存器,当执行BL子程序调用指令时,R14中得到R15的备份,而当发生中断或异常时,R14保存R15的返回值;
    R15——程序计数器;
    快速中断模式有7个备份寄存器R8—R14,这使得进入快速中断模式执行很大部分程序时,甚至不需要保存任何寄存器;
    其它特权模式都含有两个独立的寄存器副本R13、R14,这样可以令每个模式都拥有自己的堆栈指针和连接寄存器;

    五、当前程序状态寄存器(CPSR)
    CPSR中各位意义如下:
    T位:1——CPU处于Thumb状态, 0——CPU处于ARM状态;
    I、F(中断禁止位): 1——禁止中断, 0——中断使能;
    工作模式位:可以改变这些位,进行模式切换;

    六、程序状态保存寄存器(SPSR)
    当切换进入某一个特权模式时,SPSR保存前一个工作模式的CPSR值,这样,当返回前一个工作模式时,可以将SPSR的值恢复到CPSR中;


    Linux用户态程序运行在FIQ,Linux内核运行在Supervisor模式

    七、模式切换
    当异常发生,CPU进入相应的异常模式时,以下工作是由CPU自动完成的:
    1、在异常模式的R14中保存前一工作模式的下一条即将执行的指令地址;
    2、将CPSR的值复制到异常模式的SPSR中;
    3、将CPSR的工作模式设为该异常模式对应的工作模式;
    4、令PC值等于这个异常模式在异常向量表中的地址,即跳转去执行异常向量表中的相应指令;
    从异常工作模式退回到之前的工作模式时,需要由软件来完成以下工作:
    1、将异常模式的R14减去一个适当的值(4或8)后赋给PC寄存器;
    2、将异常模式SPSR的值赋给CPSR;

    早期的ARM核有状态(ARM或Thumb)切换(通过BX等指令修改CPSR寄存器(当前程序状态寄存器,存放条件码标志,中断禁止位,当前处理器模式以及其他状态和控制信息)中T的控制位完成程序状态的切换),现在ARM都只使用Thumb状态了。所以,我们不在讨论状态切换相关。
    一、ARM七种工作模式及其应用场合(Linux操作系统使用了其中USR和SVC模式、出现异常时还可能通过进入其他模式转为Linux内核态)
        在CPSR寄存器中设置M[4:0]位,分别对应如下七种模式(注意:用户模式和系统模式只有对CPSR的读权限,因此、这两种模式下不可以通过直接设置CPSR进入其他模式(SWI汇编指令除外)):
        1.用户模式(USR):用于正常执行程序。在Linux操作系统中,用户空间进程就是在这种模式下运行。CPSR寄存器M[4:0]设置10000。
        2.系统模式(SYS):运行有特权的操作系统任务。CPSR寄存器M[4:0]设置11011。
        这个模式和用户模式共用R15-pc(程序计数器,存放下一条指令所在单元的地址)的值,因此不用ARM强制赋值。
        ARM进入以下几种模式后,都需要给R15-PC寄存器重新赋值、也就是开始执行新的指令。
        3.管理模式(SVC):操作系统使用的保护模式(高权限)。在Linux操作系统中,内核空间在这种模式下运行。CPSR寄存器M[4:0]设置10011。
        当ARM刚上电或复位时、进入该模式,并强制PC从0x0000 0000处取指令;当系统软中断(如系统调用,调用ARM的SWI汇编指令)时、进入该模式,并强制PC从0x0000 0008处取指令——这也是ARM从用户模式主动切入管理模式(Linux从用户态主动进入内核态)的唯一方法。
        当出现异常状况时,Linux还有可能在如下几种ARM模式下运行;如硬件中断、程序问题导致的异常等。
        4.快速中断模式(FIQ):用于高速数据传输。CPSR寄存器M[4:0]设置10001。
        进入该模式后、ARM强制PC从0x0000 001C处取指令。
        5.外部中断模式(IRQ):用于通常的中断处理。CPSR寄存器M[4:0]设置10010。
        进入该模式后、ARM强制PC从0x0000 0018处取指令。
        6.数据访问终止模式(ABT):当数据或指令预取终止时进入该模式,可用于虚拟内存及存储保护。CPSR寄存器M[4:0]设置10111。
        当指令取终止时、进入该模式,并强制PC从0x0000 000C处取指令;当数据取终止时、进入该模式;并强制PC从0x0000 0010处取指令。
        7.未定义指令终止模式(UND):当未定义的指令执行时进入该模式,可用于支持硬件。CPSR寄存器M[4:0]设置11111。
        当程序中出现未定义的指令时、进入该模式,并强制PC从0x0000 0004处取指令。
        在非user模式下的其他6中模式,有SVC,FIQ,IRQ,ABT,UND,SYS 都可以修改CPSR寄存器、从而控制ARM工作模式的切换。
        在Linux操作系统中;当CPU处于特权模式(Linux处于内核态)时,可以随意进入用户态。而当CPU处于用户模式(Linux处于用户态)时,Linux从用户态切换到内核态(ARM从用户模式切换到其他特权模式)只有在系统调用和中断(中断进入IRQ模式,也可以操作内核)两种情况下发生,一般程序一开始都是运行于用户态,当程序需要使用系统资源时,就必须通过调用软中断进入内核态。
        每一种工作模式的R13-SP(堆栈指针寄存器,在堆栈操作中使用)都是独立的。因此,对程序中需要用到的每一种模式都要给SP定义一个堆栈地址。方法是改变状态寄存器(CPSR)内的状态位,使处理器切换到不同的状态,然后给SP赋值。注意:不要切换到User模式进行User模式的堆栈设置,因为进入User模式后就不能再操作CPSR回到别的模式了,可能会对接下去的程序执行造成影响。
        ARM在刚上电或复位后、进入SVC管理模式,并从0x0000 0000开始取指令;bootloader和Linux Kernel都是工作在此模式。

    八、ARM工作模式切换的两种方法
        1.被动切换:是指ARM在当前工作模式下,没有要求模式切换、而被动地进入另外一种模式。在ARM运行的时候产生一些异常(包括软中断)或者中断(硬中断)来进行模式切换。如上边提到的Linux操作系统从用户态到内核态,如硬件中断或程序异常。内核态不会被动切换到用户态。
        2.主动切换:是指ARM在当前工作模式下,通过一些自主操作、主动的要求切换工作模式。ARM通过软件改变,即软件设置寄存器来进行ARM的模式切换,因为ARM的工作模式都是可以通过相应寄存器的赋值来切换的。如上边提到的Linux操作系统从内核态到用户态;这里边有一个比较特殊的情况:Linux用户态可以通过系统调用主要要求切换到内核态。

    九、linux操作系统与ARM工作模式
       首先,arm开发板在刚上电或者复位后,都会首先进入SVC即管理模式,此时、程序计数器R15-PC会被自动赋值为0x0000 0000,bootloader就是在该模式下,位于0x0000 0000 的NOR FLASH或SRAM中装载的,因此,开机或重启后bootloader会被首先执行。
       接着,bootloader引导linux内核,此时,linux内核仍然运行在SVC即管理模式下,当内核启动完毕后,进入用户态init进程时,内核将ARM的当前程序状态CPSR寄存器M[4:0]设置为10000,进而用户态程序只能运行在ARM的用户模式。
       由于ARM用户模式下对资源的访问时受限制的,因此,用户态可以实现对linux操作系统内核保护的目的。
       需要强调的是:Linux内核态是从ARM的SVC即管理模式下启动的,但在某些情况下、如:硬件中断、程序异常(被动)等情况下进入ARM的其他特权模式,这时仍然可以进入内核态(因为就是可以操作内核了);同样,Linux用户态是从ARM用户模式启动的,但当进入ARM系统模式时、仍然可以操作Linux用户态程序(进入用户态,如init进程的启动过程)。
        即:Linux内核从ARM的SVC模式下启动,但内核态不仅仅指ARM的SVC模式(还包括可以访问内核空间的所有ARM模式);Linux用户程序从ARM的用户模式启动,但用户态不仅仅指ARM的用户模式。







    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-18 16:53 , Processed in 0.109761 second(s), 15 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.