文章目录

  • 1、ARM的异常向量表基地址寄存器--VBAR
    • 1.1、armv8 : VBAR寄存器
    • 1.2、armv7 : VBAR寄存器
  • 2、ARM的异常向量表的定义
    • 2.1 armv8 :异常向量表offset的定义
    • 2.2 armv8 : 在linux kernel中异常向量表的实现定义
    • 2.3 armv8 : 在ATF中异常向量表的实现定义
    • 2.4 armv8 : 异常向量表总结和示例:
    • 2.5 armv7 :异常向量表offset的定义
    • 2.6 armv7 : 在linux kernel中异常向量表的实现定义
  • 3、总结:

★★★ 友情链接 : 个人博客导读首页—点击此处 ★★★

1、ARM的异常向量表基地址寄存器–VBAR

1.1、armv8 : VBAR寄存器

1.2、armv7 : VBAR寄存器

2、ARM的异常向量表的定义

2.1 armv8 :异常向量表offset的定义


实际上有四组表,每组表有四个异常入口,分别对应同步异常,IRQ,FIQ和出错异常。

  • 如果发生异常并不会导致exception level切换,并且使用的栈指针是SP_EL0,那么使用第一组异常向量表。
  • 如果发生异常并不会导致exception level切换,并且使用的栈指针是SP_EL1/2/3,那么使用第二组异常向量表。
  • 如果发生异常会导致exception level切换,并且比目的exception level低一级的exception
    level运行在AARCH64模式,那么使用第三组异常向量表。
  • 如果发生异常会导致exception level切换,并且比目的exception level低一级的exception
    level运行在AARCH32模式,那么使用第四组异常向量表。

另外我们还可以看到的一点是,每一个异常入口不再仅仅占用4bytes的空间,而是占用0x80 bytes空间,也就是说,每一个异常入口可以放置多条指令,而不仅仅是一条跳转指令

2.2 armv8 : 在linux kernel中异常向量表的实现定义

我们再来看在linux kernel中定义的异常向量表

 .align  11
ENTRY(vectors)
(1)kernel_ventry    1, sync_invalid         // Synchronous EL1tkernel_ventry    1, irq_invalid          // IRQ EL1tkernel_ventry    1, fiq_invalid          // FIQ EL1tkernel_ventry    1, error_invalid        // Error EL1t
(2)kernel_ventry    1, sync             // Synchronous EL1hkernel_ventry    1, irq              // IRQ EL1hkernel_ventry    1, fiq_invalid          // FIQ EL1hkernel_ventry    1, error_invalid        // Error EL1h
(3)kernel_ventry    0, sync             // Synchronous 64-bit EL0kernel_ventry  0, irq              // IRQ 64-bit EL0kernel_ventry  0, fiq_invalid          // FIQ 64-bit EL0kernel_ventry  0, error_invalid        // Error 64-bit EL0
(4)
#ifdef CONFIG_COMPATkernel_ventry   0, sync_compat, 32      // Synchronous 32-bit EL0kernel_ventry  0, irq_compat, 32       // IRQ 32-bit EL0kernel_ventry  0, fiq_invalid_compat, 32   // FIQ 32-bit EL0kernel_ventry  0, error_invalid_compat, 32 // Error 32-bit EL0
#elsekernel_ventry  0, sync_invalid, 32     // Synchronous 32-bit EL0kernel_ventry  0, irq_invalid, 32      // IRQ 32-bit EL0kernel_ventry  0, fiq_invalid, 32      // FIQ 32-bit EL0kernel_ventry  0, error_invalid, 32        // Error 32-bit EL0
#endif
END(vectors)

第(1)段对应的是第一行向量表、第(2)段对应的是第二行向量表、第(3)段对应的是第三行向量表、第四段对应的是第一行向量表.
带invalid后缀的,都是未实现的。然后我们抽出实现了的部分,仅4行:

kernel_ventry    1, sync             // Synchronous EL1h
kernel_ventry   1, irq              // IRQ EL1h
kernel_ventry   0, sync             // Synchronous 64-bit EL0
kernel_ventry   0, irq              // IRQ 64-bit EL0

他们对应的函数分别是:
el1_sync //在kernel mode中调用svc指令,触发同步异常
el1_irq //在kernel mode中触发了irq异步异常
el0_sync //在user mode中调用svc指令,触发同步异常
el0_irq //在user mode中触发了irq异步异常

2.3 armv8 : 在ATF中异常向量表的实现定义

在ATF的代码中,在不同的阶段有着不同的异常向量表:

  • 在bl1阶段使用bl1_exceptions
  • 在bl2阶段使用bl2_entrypoint
  • 在bl31及其之后使用runtime_exceptions
func bl1_entrypoint
......el3_entrypoint_common                 \_set_endian=1                 \_warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS    \_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU    \_init_memory=1                    \_init_c_runtime=1             \_exception_vectors=bl1_exceptionsfunc bl2_entrypointel3_entrypoint_common                 \_set_endian=0                 \_warm_boot_mailbox=0              \_secondary_cold_boot=0                \_secondary_cpu = 0                \_init_memory=0                    \_init_c_runtime=1             \_exception_vectors=bl2_vectorfunc bl31_entrypoint
......el3_entrypoint_common                 \_set_endian=0                 \_warm_boot_mailbox=0              \_secondary_cold_boot=0                \_init_memory=0                    \_init_c_runtime=1             \_exception_vectors=runtime_exceptions

我们常说的ATF中的向量表,其实就是bl31之后使用runtime_exceptions向量表,下面重点介绍下

(注意 : 带unhandled的都是未实现的)

  • 用于处理EL0产生异常时的entire(对应第一行向量表)
vector_entry sync_exception_sp_el0
b report_unhandled_exception
check_vector_size sync_exception_sp_el0
vector_entry irq_sp_el0
b report_unhandled_interrupt
check_vector_size irq_sp_el0
vector_entry fiq_sp_el0
b report_unhandled_interrupt
check_vector_size fiq_sp_el0
vector_entry serror_sp_el0
b report_unhandled_exception
check_vector_size serror_sp_el0
  • 用于处理当前ELx产生异常时的entire(对应第二行向量表)
vector_entry sync_exception_sp_elx
b report_unhandled_exception
check_vector_size sync_exception_sp_elx
vector_entry irq_sp_elx
b report_unhandled_interrupt
check_vector_size irq_sp_elx
vector_entry fiq_sp_elx
b report_unhandled_interrupt
check_vector_size fiq_sp_elx
vector_entry serror_sp_elx
b report_unhandled_exception
check_vector_size serror_sp_elx
  • 用于处理AArch64指令产生的异常,且发生了EL的迁移的entire(对应第三行向量表)
vector_entry sync_exception_aarch64
handle_sync_exception
check_vector_size sync_exception_aarch64
vector_entry irq_aarch64
handle_interrupt_exception irq_aarch64
check_vector_size irq_aarch64
vector_entry fiq_aarch64
handle_interrupt_exception fiq_aarch64
check_vector_size fiq_aarch64
vector_entry serror_aarch64
b report_unhandled_exception
check_vector_size serror_aarch64
  • 用于处理AArch32指令产生的异常,且发生了EL的迁移的entire(对应第四行向量表)
vector_entry sync_exception_aarch32
handle_sync_exception
check_vector_size sync_exception_aarch32
vector_entry irq_aarch32
handle_interrupt_exception irq_aarch32
check_vector_size irq_aarch32
vector_entry fiq_aarch32
handle_interrupt_exception fiq_aarch32
check_vector_size fiq_aarch32
vector_entry serror_aarch32
b report_unhandled_exception
check_vector_size serror_aarch32

2.4 armv8 : 异常向量表总结和示例:

以异步异常irq为例
(1)、当irq产生,如果该irq被target到了EL3,那么将使用VBAR_EL3寄存器中的基地址.
我们知道armv8有四组异常向量表,对应表格四行。然后再看使用哪组表:
cpu运行在EL0时产生了irq, 切未发生EL级别切换(中断需被target到EL0),使用第一组表,这个条件不会存在.
cpu是在EL3时产生的irq, 未发生EL级别切换,使用第二组表,跳转到VBAR_EL3 + 0x280处,对应的irq_sp_elx函数
cpu运行在aarch64级别,在EL1/EL2时产生的irq,发生了EL级别切换,使用第三组表,跳转到VBAR_EL3 + 0x480处,对应的irq_aarch64函数
cpu运行在aarch32级别,在EL1/EL2时产生的irq,发生了EL级别切换,使用第四组表,跳转到VBAR_EL3 + 0x680处,对应的irq_aarch32函数

(2)、当irq产生,如果该irq被target到了EL1,那么将使用VBAR_EL1寄存器中的基地址.
我们知道armv8有四组异常向量表,对应表格四行。然后再看使用哪组表:
cpu运行在EL0时产生了irq, 切未发生EL级别切换(中断需被target到EL0),使用第一组表,这个条件不会存在.
cpu是在EL1时产生的irq, 未发生EL级别切换,使用第二组表,跳转到VBAR_EL1 + 0x280处,对应的el1_irq函数
cpu运行在aarch64级别,在EL0时产生的irq,发生了EL级别切换,使用第三组表,跳转到VBAR_EL1 + 0x480处,对应的el0_irq函数
cpu运行在aarch32级别,在EL0时产生的irq,发生了EL级别切换,使用第四组表,跳转到VBAR_EL1 + 0x680处,对应的irq_invalid函数,也就是未实现

2.5 armv7 :异常向量表offset的定义


2.6 armv7 : 在linux kernel中异常向量表的实现定义

 .section .stubs, "ax", %progbits
__stubs_start:@ This must be the first word.word   vector_swi.section .vectors, "ax", %progbits
__vectors_start:W(b)    vector_rstW(b)  vector_undW(ldr)    pc, __vectors_start + 0x1000W(b)   vector_pabtW(b) vector_dabtW(b) vector_addrexcptnW(b)   vector_irqW(b)  vector_fiq

3、总结:

1、在armv7下使用的是data abort、prefetch abort、undefined instruction,在armv8下使用的是SError.
2、在linux kernel中,armv7体系下均已实现data abort、prefetch abort、undefined instruction异常处理函数,在linux kernel的armv8体系下,没有实现SError异常处理
3、在linux kernel的armv8体系中,未实现fiq函数
4、
在armv7的向量表offset中,每一个异常入口都是占4 bytes,是这样排的:0x1c 0x18 0x10 0x0c 0x08 0x04
在armv8的向量表offset中,每一个异常入口都是占0x80bytes,是这样排的00 0x80 0x100 0x180 0x200 0x280…
那么我们在linux kernel中定义的向量表,是怎样和上面的offset对应上的?

W(b) vector_irq
W(b)    vector_fiq

5、在armv7中,VBAR是banked的,在linux/tee各有一份拷贝. 在armv7中,没有gic的cpu interface。所以armv7的芯片只能使用gicv2.
在gicv2中,FIQ表示安全中断,给TEE用的,IRQ表示非安全中断,给Linux用的.

  • 当cpu在REE(linux)执行时,来了一个非安全中断(linux中断、IRQ), 那么cpu陷入异常,跳转到 "normal VBAR + irq offset“ 处, 也就是linux irq中断处理函数
  • 当cpu在REE(linux)执行时,来了一个安全中断(tee中断、FIQ),那么cpu陷入异常,跳转到 "normal VBAR + fiq offset“ 处,也就是linux fiq中断处理函数
  • 当cpu在TEE(tee)执行时,来了一个安全中断(TEE中断、FIQ), 那么cpu陷入异常,跳转到 "secure VBAR + fiq offset“ 处, 也就是tee irq中断处理函数
  • 当cpu在TEE(tee)执行时,来了一个非安全中断(linux中断、irq),那么cpu陷入异常,跳转到 "secure VBAR + irq offset“ 处,也就是tee fiq中断处理函数, 在该函数中会主动将cpu切换到linux进行处理.

6、如果在某一时刻,将发送给cpu0的IPI_RESCHEDULE(SGI=2)中断屏蔽了,过了一会再恢复. 这样会对linux系统有影响吗?
内核的中断屏蔽,是将cpu的PSTATE.I置0了。 local_disable_irq后,gic再产生的中断,ARM Core不会去处理,也就不会清除gic寄存器中的中断状态. 等到 local_enable_irq后, 该中断还会再送给ARM Core. 所以这种情况中断不会丢失…
所以在某一时刻屏蔽了IPI_RESCHEDULE,也只是屏蔽,也没有去清gic中相关寄存器。所以等到恢复屏蔽后,应该也不会丢中断

[ARM异常]-linux中(aarch/aarch64)异常向量表介绍相关推荐

  1. java异常类中属于非检测异常的是_下列java语言的常用异常类中,属于检测异常的是()_学小易找答案...

    [单选题]在Word 2010的编辑状态,对当前文档中的文字进行"字数统计"操作,应当使用的菜单是( ) [单选题]客运员领带统一,领带夹夹在衬衣的( )钮扣之间. [单选题]文件 ...

  2. linux的swap与memory,【Linux】Linux中Swap与Memory内存简单介绍

    背景介绍 对于Linux来说,其在服务器市场的使用已经占据了绝对的霸主地位,不可动摇.Linux的各种设计思想和使用也被传承(当然不乏各种黑Linux,而且黑的漂亮).Linux的很多独特的设计,对性 ...

  3. linux应用程序注册表,如何打开 Linux 中 Windows 程序的注册表编辑器

    在我们借助CrossOver这款兼容软件在Linux操作系统中运行Windows应用程序的过程中,有的时候我们可能会遇到有关要求,为Windows应用程序设置注册表项的疑难解答问题的提示,指南或说明. ...

  4. linux的matplotlib中文异常,Linux中matplotlib 中文显示问题解决

    1.下载下载中文 arial unicode ms 字体到 /home 目录 2. 拷贝字体到 usr/share/fonts 下: sudo cp ~/arial\ unicode\ ms.ttf ...

  5. [ATF]-ATF的异常向量表介绍-(irq,fiq,smc,hyc...)

    文章目录 1.同步异常向量表-(smc) 1.1.handle_sync_exception调用smc_handler64处理同步异常 2.异类步异常向量表-(irq,fiq...) 2.1.get_ ...

  6. java 如何忽略异常_java中如何解决异常

    原文 | dzone.com/articles/9-- 作者 | Thorben Janssen 翻译 | geekymv 无论你是初学者还是经验丰富的开发人员,对于你和你的团队来说,提高异常处理的能 ...

  7. linux中mysql8设置不区分表名大小写

    第一种:安装好mysql后,先设置好配置文件,然后在启用mysql 找到linux中mysql配置文件 my.cnf 命令: which mysqld 命令: /usr/sbin/mysqld --v ...

  8. linux中mysql的库、表和字段的字符集指令总结

    一.查看数据库,表,字段编码 1.查看数据库编码 (1)通过show variables查看编码,需要转换数据库,不转换看的是server字符集.字符序. mysql> use test; my ...

  9. Vmware 中Linux中NAT网络异常解决方法

    如果在Vmware Workstation中出现 Bringing up interface eth0: Error: Connection activation failed: Device not ...

最新文章

  1. 你连原理都还没弄明白?快来瞧瞧这份Spring面试小抄
  2. .net源代码已经可以调试
  3. android支持第三方jar包,以及Eclipse如何导入jar包
  4. LIVE555再学习 -- DM368/Hi3516A 交叉编译
  5. 大道至简,仅需4行代码提升多标签分类性能!ICCV21 南大提出Residual Attention
  6. .NET的Math.Round与数学无关。没关系!
  7. 雨巷(A Lane in the Rain)
  8. 计算机系统结构名词解释
  9. A Style-Aware Content Loss for Real-time HD Style Transfer(一个风格转换的风格感知损失)CVPR2018
  10. paypal支付交易数据
  11. Windows OCR推荐
  12. html页面颜色排列,HTML前端页面颜色的四种方法,色号表
  13. 关于ip、pv、uv的概念
  14. 计算机无法启动怎么重装系统,电脑开不开机怎么重装系统教程
  15. 自相关与互相关在matlab中实现
  16. 《Windows CE嵌入式开发入门——基于Xscale架构》第4章 外设控制器
  17. 【stm32】ADC的规则通道和注入通道混合使用
  18. 什么是元组以及元组的作用
  19. 在Magento产品分类页面创建推荐产品(Featured Products)
  20. APP新用户注册、手机号绑定、用户登录验证新方式——一键登录(免密登录)验证方式新趋势

热门文章

  1. 数据中心运维管理社区祝大家新春快乐,虎年大吉!
  2. 上海:加快推进18个新建数据中心项目的建设和投资进度
  3. 成功解决Both binary classification-only and multiclassification-only loss function or metrics specified
  4. DL之DeepLabv2:DeepLab v2算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
  5. Dataset之Handwritten Digits:Handwritten Digits(手写数字图片识别)数据集简介、安装、使用方法之详细攻略
  6. 成功解决ImportError: [joblib] Attempting to do parallel computing without protecting your import on a sy
  7. Crawler:基于BeautifulSoup库+requests库实现爬取2018最新电影《后来的我们》热门短评
  8. pyhanlp 提取关键词、自动摘要
  9. HDFS的读文件、写文件过程
  10. RocketMQ学习笔记(7)----RocketMQ的整体架构