Linux内核异常向量表在哪,ARM64的启动过程之(六):异常向量表的设定

ARM64的启动过程之(六):异常向量表的设定

作者:linuxer 发布于:2015-11-24 18:22

分类:ARMv8A Arch

一、前言

本文主要描述了4.1.10内核初始化过程中如何初始化异常向量表。当然,首先需要准备一些异常的基础知识,这主要在第二章,如果你非常熟悉ARM64的异常,那么可以忽略这个章节。 第三章描述了ARM64上各种形形色色的异常,第四章描述了ARM64上硬件提供的协助,最后一章描述了代码过程。

为了简化,本文对所描述的异常进行了限制:

1、所有的exception level的运行状态都是AArch64,不考虑异常发生在AArch32 excution state的时候

2、不考虑支持security extension,也就是说EL3状态的异常处理也不在本文描述

3、不考虑virtualization的支持,也就是说EL2的异常处理不会在本文描述

一句话总结,本文主要描述EL0和EL1这两个exception level下的异常向量表的设定。

二、 异常(exception)的基础知识

1、什么是异常(exception)?

对于ARM64而言,exception是指cpu的某些异常状态或者一些系统的事件(可能来自外部,也可能来自内部),这些状态或者事件可以导致cpu去执行一些预先设定的,具有更高执行权利的软件(也叫exception handler)。执行exception handler可以进行异常的处理,从而让系统平滑的运行。exception handler执行完毕之后,需要返回发生异常的现场。上面这段话非常的拗口,但是不要紧,当进入细节的时候一切会慢慢清晰起来,下面我们逐一介绍各种异常:中断(interrupt),abort,reset,异常指令……

2、exception level

上一节中,我们在定义异常的时候说道:一旦异常发生,系统(包括硬件和软件)将切换到具有更高执行权利的状态,对于cpu而言,就是exception level了,ARM64最大支持EL0~EL3四个exception level,EL0的execution privilege最低,EL3的execution privilege最高。当发生异常的时候,系统的exception会迁移到更高的exception level或者维持不变,但是绝不会降低。此外,不会有任何的异常会去到EL0。

对比是一个不错的学习方法,我们先看看ARM32的情况。对于ARM32而言,cpu可以处在各种processor mode下,例如User、FIQ、IRQ、Abort、Undefined、System,这些不同的mode又对应两种privilege level,non-privilege(user processor mode)和privilege(其他processor mode)。

来到ARM64,processor mode这个概念已经消失了,取而代之的是exception level,如果没有支持两个security state(但是支持虚拟化),那么ARM64有3个exception level,分别是:EL0(对应user mode的application),EL1(guest OS)和EL2(Hypervisor)。如果支持两个security state(但是不支持虚拟化),ARM64还是有3个exception level,分别是:EL0(对应trusted service),EL1(trusted OS kernel)和EL3(Secure monitor)。如果支持了虚拟化并且同时支持两种security state,那么ARM64的处理器可以处于4种exception level,具体如下(摘自wowo同学的文章里面的图片,^_^):

Linux内核异常向量表在哪,ARM64的启动过程之(六):异常向量表的设定_第1张图片

由于EL3是和安全相关的,目前linux kernel并不涉及这部分的内容,因此本文将不考虑EL3这个exception level。

2、异步异常(asynchronous exception)和同步异常(synchronous exception)

虽然异常各具形态,但是基本可以分成两类,一类是asynchronous exception,另外一类是synchronous exception。

asynchronous exception基本上可以类似大家平常说的中断,它是毫无预警的,丝毫不考虑cpu core感受的外部事件(需要注意的是:外部并不是表示外设,这里的外部是针对cpu core而言,有些中断是来自SOC的其他HW block,例如GIC,这时候,对于processor或者cpu(指soc)而言,这些事件是内部的),这些事件打断了cpu core对当前软件的执行,因此称之interrupt。interrupt或者说asynchronous exception有下面的特点:

(1)异常和CPU执行的指令无关。

(2)返回地址是硬件保存下来并提供给handler,以便进行异常返回现场的处理。这个返回地址并非产生异常时的指令

根据这个定义IRQ、FIQ和SError interrupt属于asynchronous exception。

synchronous exception和asynchronous exception相反,其特点是:

(1)异常的产生是和cpu core执行的指令或者试图执行执行相关

(2)硬件提供给handler的返回地址就是产生异常的那一条指令所在的地址

synchronous exception又可以细分成两个类别,一种我们称之为synchronous abort,例如未定义的指令、data abort、prefetch instruction abort、SP未对齐异常,debug exception等等。还有一种是正常指令执行造成的,包括SVC/HVC/SMC指令,这些指令的使命就是产生异常。

3、precise exception

什么是precise exception呢?现代的cpu设计越来越复杂,各种pipe技术,各种cache技术,分支预测,multi-issue,out-of-order-execution等等,这些都让cpu core执行指令处于一个混沌的状态(主要是指不象sequential cpu 那么清晰),因此,当发生一个exception的时候,需要一个快刀来斩断那些处于各种纠缠中的乱麻一样的各种cpu以及memory的状态。这时候,我们需要选定一条指令,该指令之前的指令(不包括该指令)都已经全部执行完毕,修改了硬件上下文(cpu状态寄存器,各种通用寄存器,系统寄存器等等,memory hierarchy状态)。而该指令之后(包括该指令)的指令都没有执行

你可能感兴趣的:(Linux内核异常向量表在哪)