Linux ARMv7架构通用中断流程(1)

最新更新时间:2021-09-29来源: eefocus关键字:Linux 手机看文章 扫描二维码
随时随地手机看文章

一、ARMv7 Cortex-A系列处理器寄存器组介绍及其功能介绍


1. ARMv7 Cortex-A处理器一般共有37寄存器,其中包括:

 (1) 31个通用寄存器,包括PC(程序计数器)在内,都是32位的寄存器。


  (2) 6个状态寄存器,都是32位的寄存器。



2. ARMv7 Cortex-A系列处理器的模式

        ARMv7 Cortex-A系列处理器共有7种处理器模式分别是:用户模式(User)、快速中断模式(FIQ)、普通中断模式(IRQ)、管理模式(Supervisor SVC)、数据访问中止模式(Abort)、未定义指令中止模式(Undefined)、系统模式(System)。在每一种处理器模式中有一组相应的寄存器。在任意一种寄存器模式下,可见的寄存器包括15个通用寄存器(R0~R14)、程序计数器(PC)、一个或者两个状态寄存器(CPSR、SPSR)。在所有寄存器中,有些是各个模式共用同一个物理寄存器,有些寄存器是各个模式自己拥有独立的物理寄存器。各种模式下的寄存器组如下入所示。

       其中R0~R3主要用于子程序间传递参数,R4~R11主要用于保存局部变量, 但在Thumb程序中,通常智能使用R4~R7来保存局部变量;R12(Intra-Procedure-call scratch register,详细介绍参见"Procedure Call Standard for the ARM Architecture",)用作子程序间的scratch 寄存器,即IP;R13通常用作栈指针,即SP;R14寄存器又被称为连接寄存器,即LR,用于保存子程序以及中断的返回地址;R15用作程序计数器(PC),由于ARM采用流水线机制,PC的值当前正在指令地址加8个字节,即PC指向当前指令的下两条指令地址。CPSR和SPSR都是程序状态寄存器,其中SPSR是用来保存中断前的CPSR中的值,一边在中断返回后恢复处理器状态。


3. CPSR寄存器详解

       所有处理器模式下都可访问当前程序状态寄存器CPSR。CPSR中包含条件码标志、中断禁止位、当前处理器模式以及其他状态和控制信息。在每种异常模式下都有一个对应的程序状态寄存器SPSR。当异常出现时,SPSR用于保存CPSR的状态,以便异常返回后恢复异常发生时的工作状态。


(1)条件码标志


        程序状态寄存器CPSR的最高4位N、Z、C、V是条件码标志。ARM的大多数指令可条件执行,即通过检测这些条件码标志来决定程序指令如何执行。


      各个标志的含义如下:


     N: 在结果有符号的二进制补码的情况下,如果结果为负数,则N=1;如果为非负数,则N=0.


     Z:如果结果为0,则Z=1;如果结果为非零,则Z=0;


     C:其设置分一下几种情况:


           (1)对于加法指令(包括比较指令CMN),如果产生进位,则C=1;否则C=0。


            (2)对于减法指令(包括比较指令CMP),如果产生借位,则C=0;否则C=1。


            (3)对于有移位操作的非法指令,C为移位操作中最后移出位的值。


             (4) 对于其他指令,C通常不变。


     V:对于加减法指令,在操作数和结果是有符号的整数时,如果发生溢出,则V=1;如果无溢出发生,则V=0;对于其他指令,V通常不发生变化。


 (2)控制位的作用在上图中可以看出来。


4. CPSR与CPSR_c的区别

    CPSR有4个8位区域:标志域(F)、状态域(S)、扩展域(X)、控制域(C).


     C控制域屏蔽字节(CPSR[7:0])


     X扩展域屏蔽字节(CPSR[15:8])


     S状态域屏蔽字节(CPSR[23:16])


     F标志域屏蔽字节(CPSR[31:24])


     常用于MRS或MSR指令,用于CPSR的值转移到寄存器或把寄存器的内容加载到CPSR中。如:


     MSR  CPSR_c , #0xd3



二、Linux ARMv7 Cortex-A系列处理器中断向量表处理和代码分析


1.  ARMv7 Cortex-A系列处理器打开关闭irq中断

   ARMv7 Cortex-A系列处理器打开关闭irq中断是通过改变CPSR寄存器的bit7位完成的。


   开启和关闭当前处理器的本地中断,会产生中断信号,但不处理 。


   local_irq_disable()关闭中断指令:cpsid i;


   local_irq_enable()开启中断指令:cpsie i;


   关闭和开启中断,不会产生中断信号。


   disable_irq/enable_irq



2. linux系统为了实现异常处理引入了栈帧的概念

// arch/arm/include/uapi/asm/ptrace.h

/*

* This struct defines the way the registers are stored on the

* stack during a system call. Note that sizeof(struct pt_regs)

* has to be a multiple of 8.

*/

#ifndef __KERNEL__

struct pt_regs {

long uregs[18];

};

#endif /* __KERNEL__ */

 

#define ARM_cpsr uregs[16]

#define ARM_pc uregs[15]

#define ARM_lr uregs[14]

#define ARM_sp uregs[13]

#define ARM_ip uregs[12]

#define ARM_fp uregs[11]

#define ARM_r10 uregs[10]

#define ARM_r9 uregs[9]

#define ARM_r8 uregs[8]

#define ARM_r7 uregs[7]

#define ARM_r6 uregs[6]

#define ARM_r5 uregs[5]

#define ARM_r4 uregs[4]

#define ARM_r3 uregs[3]

#define ARM_r2 uregs[2]

#define ARM_r1 uregs[1]

#define ARM_r0 uregs[0]

#define ARM_ORIG_r0 uregs[17]

 

 

//arch/arm/kernel/asm-offsets.c

DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));

DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));

DEFINE(S_R2, offsetof(struct pt_regs, ARM_r2));

DEFINE(S_R3, offsetof(struct pt_regs, ARM_r3));

DEFINE(S_R4, offsetof(struct pt_regs, ARM_r4));

DEFINE(S_R5, offsetof(struct pt_regs, ARM_r5));

DEFINE(S_R6, offsetof(struct pt_regs, ARM_r6));

DEFINE(S_R7, offsetof(struct pt_regs, ARM_r7));

DEFINE(S_R8, offsetof(struct pt_regs, ARM_r8));

DEFINE(S_R9, offsetof(struct pt_regs, ARM_r9));

DEFINE(S_R10, offsetof(struct pt_regs, ARM_r10));

DEFINE(S_FP, offsetof(struct pt_regs, ARM_fp));

DEFINE(S_IP, offsetof(struct pt_regs, ARM_ip));

DEFINE(S_SP, offsetof(struct pt_regs, ARM_sp));

DEFINE(S_LR, offsetof(struct pt_regs, ARM_lr));

DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));

DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));

DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));

DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));

 

3. ARM异常处理类型和模式

   ARM的各种异常类型和每种异常类型处于的处理器模式,如下表所示:

4. ARM中断处理汇编代码分析(基于LINUX 4.4.49内核分析)

4.1 arm中断处理总入口


//arch/arm/kernel/entry-armv.S

/*

*注释:

* 1)ARM架构异常处理向量表起始地址__vectors_start(定义在arch/arm/kernel/vmlinux.lds).

* 2)ARM架构定义7种异常包括中断、系统调用、缺页异常等,发生异常时处理器会跳转到相应入口。

* 3)异常向量表的起始位置由CP15协处理器的控制寄存器C1的bit13决定:

* v=0,Normal exception vectors, base address 0x00000000. Software can remap this

* base address using the VBAR(CP15 C12寄存器);

* v=1,High exception vectors, base address 0xFFFF0000-0xFFFF001C. This base address

* is never remapped.

* The primary input VINITHI defines the reset value of the V bit.

* VINITHI: Controls the location of the exception vectors at reset:

* 0 = starts exception vectors at address 0x00000000

* 1 = starts exception vectors at address 0xFFFF0000.

* This pin is only sampled during reset of the processor

*/

        .section .vectors, "ax", %progbits

__vectors_start:

        W(b)     vector_rst

        W(b)     vector_und

/*

*系统调用入口点:

* __vectors_start + 0x1000 = __stubs_start(由arch/arm/kernel/vmlinux.lds链接脚本可知)

* 此时PC指向系统调用异常的处理入口:vector_swi用户态通过swi指令产生软中断。因为vector_swi系统

* 调用异常代码在(arch/arm/kernel/entry-common.S),其入口地址与异常向量相隔较远,使用b指令无

* 法跳转过去。b指令只能相对当前PC跳转 +/-32M范围)。

*/

        W(ldr)    pc, __vectors_start + 0x1000

        W(b)      vector_pabt //取指令异常

        W(b)      vector_dabt //数据异常--缺页异常

        W(b)      vector_addrexcptn

        W(b)      vector_irq //irq中断异常

        W(b)      vector_fiq

4.2 以vector_irq为例进行深入分析


 vector_irq是通过vector_stub宏定义的,vector_stub宏定义尤为关键,ARM任何异常都是通过将r0,lr,spsr保存到异常模式的栈中(每种异常模式都有自己的栈,栈的初始化在cpu_init,见下面分析), vector_stub通过vector_name实现其功能。


//arch/arm/kernel/entry-armv.S

/*

*注释:

*当irq发生时,硬件自动完成如下操作:

*1. arm在irq模式下有自己的lr寄存器lr_irq、spsr_irq、sp_irq.

* r14_irq = lr_irq = address pf next instruction to be executed+4;

*2. spsr_irq = cpsr,保存了处理器当前的状态,中断屏蔽位以及各种条件标志位,保存后cpsr会切换到

* irq模式。

*3. cpsr[4 :0] = 0b10010,设置arm为irq模式

*4. cpsr[5] = 0,arm状态执行

*5. cpsr[7] = 1,禁止irq

*6. pc = 0xffff0018(High exception vectors,取决于CP15协处理器的C1寄存器的配置,参看上面的分

* 析), 将pc值设置成异常中断的中断向量地址,即vectot_irq.

*/

/*

* Interrupt dispatcher

*/

    vector_stub irq, IRQ_MODE, 4

 

    .long __irq_usr     @ 0 (USR_26 / USR_32) 从用户态下进入的irq,执行__irq_usr代码

    .long __irq_invalid @ 1 (FIQ_26 / FIQ_32)

    .long __irq_invalid @ 2 (IRQ_26 / IRQ_32)

    .long __irq_svc     @ 3 (SVC_26 / SVC_32) 从内核态下进入的irq,执行__irq_svc代码

    .long __irq_invalid @ 4

    .long __irq_invalid @ 5

    .long __irq_invalid @ 6

    .long __irq_invalid @ 7

    .long __irq_invalid @ 8

    .long __irq_invalid @ 9

    .long __irq_invalid @ a

    .long __irq_invalid @ b

    .long __irq_invalid @ c

    .long __irq_invalid @ d

    .long __irq_invalid @ e

    .long __irq_invalid @ f

sp在不同的模式下有不同寄存器,在cpu_init中进行初始化。


/* arch/arm/kernel/setup.c

* cpu_init - initialise one CPU.

*

* cpu_init sets up the per-CPU stacks.

*/

void notrace cpu_init(void)

{

#ifndef CONFIG_CPU_V7M

        unsigned int cpu = smp_processor_id();

        struct stack *stk = &stacks[cpu];

 

        if (cpu >= NR_CPUS) {

            pr_crit("CPU%u: bad primary CPU numbern", cpu);

            BUG();

        }

        /*

        * This only works on resume and secondary cores. For booting on the

        * boot cpu, smp_prepare_boot_cpu is called after percpu area setup.

        */

        set_my_cpu_offset(per_cpu_offset(cpu));

        cpu_proc_init();

 

        /*

        * Define the placement constraint for the inline asm directive below.

        * In Thumb-2, msr with an immediate value is not allowed.

        */

#ifdef CONFIG_THUMB2_KERNEL //此宏为定义

#define PLC "r"

#else

#define PLC "I" //表示是立即数,其他定义可以查看GCC ARM C语言嵌入汇编语法

#endif

        /*

        * setup stacks for re-entrant exception handlers

        * 修改几种模式下的sp指向struct stack结构体类型变量stacks中定义的各个变量,每种模式下的栈为3个字

        */

        __asm__ (

        "msr cpsr_c, %1nt" //msr cpsr_c,(PSR_F_BIT|PSR_I_BIT|IRQ_MODE)切换为irq模式

        "add r14, %0, %2nt" //r14 = r +offset(struct stack, irq[0])

        "mov sp, r14nt"

        "msr cpsr_c, %3nt" //msr cpsr_c,(PSR_F_BIT|PSR_I_BIT|ABT_MODE)切换为abt模式

        "add r14, %0, %4nt" //r14 = r +offset(struct stack, abt[0])

        "mov sp, r14nt"

        "msr cpsr_c, %5nt" //msr cpsr_c,(PSR_F_BIT|PSR_I_BIT|UND_MODE)切换为und模式

        "add r14, %0, %6nt" //r14 = r +offset(struct stack, und[0])

        "mov sp, r14nt"

        "msr cpsr_c, %7nt" //msr cpsr_c,(PSR_F_BIT|PSR_I_BIT|FIQ_MODE)切换为fiq模式

        "add r14, %0, %8nt" //r14 = r +offset(struct stack, fiq[0])

        "mov sp, r14nt"

        "msr cpsr_c, %9" //msr cpsr_c,(PSR_F_BIT|PSR_I_BIT|FIQ_MODE)切换为svc模式

        :

        : "r" (stk),

[1] [2] [3]
关键字:Linux 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic549372.html

上一篇:ARM cpsr寄存器和spsr寄存器
下一篇:ARM体系架构—ARMv7-A处理器模式及寄存器

推荐阅读

ARM开发——nfs引导启动linux
波特率 和屏幕save //设置完一定要保存之后我们需要配置一下nfs服务器,让他可以适应我们低版本的内核 sudo vi /etc/default/nfs-kernel-server RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog" //让服务器可以支持我们内核之后将linux内核发送过来dnw 40008000 //将内核放到默认启动位置//在主机将我们编译好的内核发送过去bootm 40008000 //这时候我的内核就跑起来了这时候我们就进入了我们的linux系统的,我们现在需要将我们发送的内核解压到分区mount  /etc
发表于 2021-09-27
配置arm-linux虚拟机开发环境
/home路径sudo mv /home/dnw /bin/sudo chmod +x /bin/dnwsudo chmod +s /bin/dnw安装gcc工具链:http://www.veryarm.com/arm-none-linux-gnueabi-gcc安装libncurses库:sudo apt-get install libncurses5-dev如果是64位机器的话,还需要安装32位的库,这样交叉编译链才会正常工作,不然会显示没有这个文件:sudo apt-get install ia32-libs这个在执行make menuconfig时会用到安装库:sudo apt-get install mtd-utils这个在执行
发表于 2021-09-22
配置arm-<font color='red'>linux</font>虚拟机开发环境
ARM协处理器访问指令(Linux学习记录)
什么是协处理器?协处理器用于执行特定的处理任务,如:数学协处理器可以控制数字处理,以减轻处理器的负担。ARM可支持多达16个协处理器,其中CP15是最重要的一个。CP15的作用?系统控制协处理器,CP15提供额外的寄存器,用于配置和控制缓存。MMU,保护系统,时钟模式,以及其他的系统选项,如大或小门的操作。如何访问CP15?通过CP15提供的16组寄存器,来达到访问目的。 协处理器访问:mcr (把通用寄存器的值复制或移动到协处理器中的寄存器中)、mrc(把协处理器中的寄存器的值复制或移动到通用寄存器中)访问例: MCR{cond} P15,<Opcode_1>,<Rd>,<CRn&
发表于 2021-09-22
Ubuntu安装arm-linux-gcc 详细步骤
gcc编译的只能在Linux中使用,要在ARM中使用,还要使用交叉编译工具:arm-linux-gcc1.获取压缩包首先尝试使用命令行安装,结果如下:但是此方法需要翻墙获取(我听别人说的…),一般情况不会成功的。所以在主机上下载 arm-linux-gcc的安装包,通过FTP传输工具发送压缩包到Ubuntu中:发送到 /tmp 路径下,如图:2.解压 压缩包到指定路径然后解压压缩包到根目录,注意这里使用tar命令,根据压缩包的后缀信息看出使用bzip2压缩然后tar命令分包:sudo tar -xjvf arm-linux-gcc-4.6.4-arm-x86_64.tar.bz2 -C /可以查看解压后的路径:3.新建目录,解放
发表于 2021-09-07
Ubuntu安装arm-<font color='red'>linux</font>-gcc 详细步骤
小米加入开源专利社区OIN,免进行Linux专利交叉许可授权
8月30日,小米集团通过其官方微博宣布加入开源专利社区OIN。OIN 首席执行官 Keith Bergelt 称,智能手机、智能设备和IoT技术正在快速推动改善个人协作与沟通关系、增加娱乐选择,并促使家庭更智能化,业务处理更高效。小米是以技术驱动的全球领先创新科技公司,拥有强大的技术研发实力和大量的技术沉淀及知识产权。非常感谢小米加入OIN,并展示其对开源领域协作创新和专利保护的承诺。小米集团副总裁崔宝秋表示,小米致力于为用户提供开放透明值得信赖的小米产品,让全球每个人都能享受科技带来的美好生活。Linux和开源技术是我们致力于开发并集成到小米产品中的关键技术要素。通过加入 OIN,我们展示了自身对创新和开源的不懈承诺,并会继续
发表于 2021-09-01
小米加入开源专利社区OIN,免进行<font color='red'>Linux</font>专利交叉许可授权
ARMV7架构下的普通寄存器和CPSR寄存器及SPSR寄存器
普通寄存器上面是不同工作模式对应的寄存器,其中要重点知道的为sp : stack pointer 用于保存栈顶对应的内存地址,当需要入栈或出栈时,将访问sp对应的内存地址lr:link register 链接寄存器用于保存跳转过程中子程序的返回地址pc:给pc写值,处理器会跳转到所写位置执行位置读pc会读得pc指令的下下一条指令当前程序状态寄存器(CPSR)他的前四位为为条件标记位,并和你的主动更新的意愿有关系N[31]:负的条件标记Z[30]:零的条件标记C[29]:操作进位V[28]:操作溢出低五位为运算模式但是需要特权模式才能去修改他的工作模式T[5]:决定的是用的是ARM指令集还是Thumb指令集A[6]:异常终止的频闭位I
发表于 2021-09-24
<font color='red'>ARMV7</font><font color='red'>架构</font>下的普通寄存器和CPSR寄存器及SPSR寄存器

推荐帖子

TMS320VC5509A DSP学习路线
step1:芯片的数据手册(datasheet) 参考资料:sprs205k_TMS320VC5509AFixed-PointDigitalSignalProcessorDataManual(Rev.K) 此手册为TMS320C5509A定点数字信号处理器的数据手册。本手册分6章,每章的主要内容如下: 第1章介绍芯片的特征参数(片上资源),列出了该芯片上所有的设备资源; 第2章描述了该芯片的内部结构及主要特性,列举了该芯片的引脚排布和各个引脚的功能;
灞波儿奔 DSP 与 ARM 处理器
周计划提交
Beaglone外围电路设计周计划提交
billjing DSP 与 ARM 处理器
gw540 是什么啊 ,
向各位大侠请教,gw540是什么啊一个贴的黑色的东西,干什么用的,我怎么在论坛上找不到他的文档啊,gw540是什么啊,
十一少 PCB设计
500分+现金酬谢 :GPRS拨号获得一个由移动随机分配的内部IP地址后怎么样向数据中心发起TCP或UDP通信请求从而握手成功?
GPRS拨号获得一个由移动随机分配的内部IP地址后怎么样向数据中心发起TCP或UDP通信请求从而握手成功? 只要能拨号成功,分数不是问题,少的可以再加!可以加我qq:284843368500分+现金酬谢:GPRS拨号获得一个由移动随机分配的内部IP地址后怎么样向数据中心发起TCP或UDP通信请求从而握手成功?
belongto 嵌入式系统
【NXP Rapid IoT评测】触摸按键没有反应——I2C死锁解除方法
NXPRapidIoT上用I2C1上挂了很多外设, I2C1:Sensors+Touch:FXOS8700,FXAS21002,MPL3115,ENS210,TSL25711,CCS811(behindI2Cswitch),SX9500 I2C2:afterI2Cswitch(...NTAG_I2C_EN):NT3H2211,A1006,A71 而且在开发过程中不何避免的复位重启RapidIoT,造成了I2C时序混乱,同
dvd1478 RF/无线
各位大虾,求数码相框电路图
本帖最后由jameswangsynnex于2015-3-320:02编辑我是一名业务员,由于专业知识不够,常常与大客户失之交臂,因此下定决心恶补专业知识,请各位大虾不吝指教![:\'(][:\'(] 各位大虾,求数码相框电路图
liaozc 移动便携
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved