ARMv8异常向量表初始化
2026/6/6 16:11:43 网站建设 项目流程

异常向量表的初始化过程

异常向量表是异常处理的入口,每个异常等级都有自己独立的异常向量表。异常向量表的初始化是系统启动过程中最重要的步骤之一,直接关系到系统的稳定性和安全性。

1.1 标准ARMv8实现

1.1.1 异常向量表的结构
ARMv8架构的异常向量表包含16个入口,每个入口对应一种异常类型。每个入口的大小为128字节,最多可以包含32条AArch64指令。异常向量表必须对齐到2KB边界,因为VBAR_ELx寄存器的低11位是保留的。
异常向量表的结构如下:

偏移量

异常类型

说明

0x000

Current EL with SP_EL0, Synchronous

当前异常等级,使用SP_EL0,同步异常

0x080

Current EL with SP_EL0, IRQ

当前异常等级,使用SP_EL0,IRQ异常

0x100

Current EL with SP_EL0, FIQ

当前异常等级,使用SP_EL0,FIQ异常

0x180

Current EL with SP_EL0, SError

当前异常等级,使用SP_EL0,SError异常

0x200

Current EL with SP_ELx, Synchronous

当前异常等级,使用SP_ELx,同步异常

0x280

Current EL with SP_ELx, IRQ

当前异常等级,使用SP_ELx,IRQ异常

0x300

Current EL with SP_ELx, FIQ

当前异常等级,使用SP_ELx,FIQ异常

0x380

Current EL with SP_ELx, SError

当前异常等级,使用SP_ELx,SError异常

0x400

Lower EL using AArch64, Synchronous

低异常等级,使用AArch64,同步异常

0x480

Lower EL using AArch64, IRQ

低异常等级,使用AArch64,IRQ异常

0x500

Lower EL using AArch64, FIQ

低异常等级,使用AArch64,FIQ异常

0x580

Lower EL using AArch64, SError

低异常等级,使用AArch64,SError异常

0x600

Lower EL using AArch32, Synchronous

低异常等级,使用AArch32,同步异常

0x680

Lower EL using AArch32, IRQ

低异常等级,使用AArch32,IRQ异常

0x700

Lower EL using AArch32, FIQ

低异常等级,使用AArch32,FIQ异常

0x780

Lower EL using AArch32, SError

低异常等级,使用AArch32,SError异常

1.1.2 EL3异常向量表初始化
EL3的异常向量表是系统中第一个被初始化的异常向量表,由BL1在启动时初始化。
初始化步骤如下:
  1. 定义异常向量表:在汇编代码中定义异常向量表,每个入口包含一条跳转指令,跳转到对应的异常处理函数。
  2. 设置VBAR_EL3寄存器:将异常向量表的基地址写入VBAR_EL3寄存器。
  3. 执行ISB指令:确保所有之前的指令都已经执行完成,异常向量表的修改生效。
代码示例(文件:bl1/aarch64/bl1_entrypoint.S):
/* 定义EL3异常向量表 */ .section .vectors, "ax" .align 11 .global bl1_vectors bl1_vectors: .align 7 b sync_exception_sp_el0 .align 7 b irq_exception_sp_el0 .align 7 b fiq_exception_sp_el0 .align 7 b serror_exception_sp_el0 .align 7 b sync_exception_sp_elx .align 7 b irq_exception_sp_elx .align 7 b fiq_exception_sp_elx .align 7 b serror_exception_sp_elx .align 7 b sync_exception_aarch64 .align 7 b irq_exception_aarch64 .align 7 b fiq_exception_aarch64 .align 7 b serror_exception_aarch64 .align 7 b sync_exception_aarch32 .align 7 b irq_exception_aarch32 .align 7 b fiq_exception_aarch32 .align 7 b serror_exception_aarch32 /* 初始化EL3异常向量表 */ ldr x0, =bl1_vectors msr vbar_el3, x0 isb
1.1.3 SEL1异常向量表初始化
SEL1的异常向量表由TEE操作系统在启动时初始化。初始化步骤与EL3类似:
  1. 定义异常向量表:在TEE的汇编代码中定义异常向量表。
  2. 设置VBAR_EL1寄存器:将异常向量表的基地址写入VBAR_EL1寄存器。
  3. 执行ISB指令:确保异常向量表的修改生效。
代码示例(OP-TEE):
/* 定义SEL1异常向量表 */ .section .vectors, "ax" .align 11 .global tee_vectors tee_vectors: /* 异常向量表入口 */ // ... 省略 /* 初始化SEL1异常向量表 */ ldr x0, =tee_vectors msr vbar_el1, x0 isb
1.1.4 NSEL1异常向量表初始化
NSEL1的异常向量表由Linux内核在启动时初始化。Linux内核的异常向量表定义在arch/arm64/kernel/entry.S文件中,初始化代码在arch/arm64/kernel/traps.c文件中。
代码示例
/* 初始化NSEL1异常向量表 */ void __init trap_init(void) { /* 设置VBAR_EL1寄存器 */ write_sysreg(vectors, vbar_el1); isb(); /* 其他初始化 */ // ... }

2.2 MT8766定制实现

MT8766的异常向量表初始化流程与标准ATF基本一致,但在preloader和Kinibi中做了一些定制化修改。
2.2.1 Preloader中EL3向量表初始化
MT8766的preloader运行在EL3,它会在启动时初始化自己的异常向量表。preloader的异常向量表定义在plat/mediatek/common/aarch64/exception.S文件中。
代码示例
/* 定义preloader的EL3异常向量表 */ .section .vectors, "ax" .align 11 .global preloader_vectors preloader_vectors: .align 7 b sync_exception .align 7 b irq_exception .align 7 b fiq_exception .align 7 b serror_exception /* 其他入口 */ // ... 省略 /* 初始化EL3异常向量表 */ ldr x0, =preloader_vectors msr vbar_el3, x0 isb
2.2.2 Kinibi中SEL1向量表初始化
Kinibi TEE的异常向量表是闭源的,但根据MTK公开的技术文档,其初始化流程与标准TEE基本一致。Kinibi会在启动时设置VBAR_EL1寄存器,指向自己的异常向量表。
2.2.3 与标准实现的差异
MT8766的异常向量表初始化与标准ATF有以下几个关键差异:
  1. 向量表大小不同:标准ATF的异常向量表包含16个入口,而MT8766的preloader只实现了必要的几个入口,以减少代码大小。
  2. 异常处理不同:MT8766的preloader对异常的处理更加简单,大部分异常都会导致系统复位。
  3. 向量表位置不同:标准ATF的异常向量表位于单独的.vectors段,而MT8766的preloader将异常向量表与代码放在同一个段中。

3.3 安全风险与漏洞分析

异常向量表的初始化过程中的漏洞可能导致攻击者篡改异常向量表,控制异常处理流程,从而获取系统的控制权。
3.3.1 常见漏洞类型
  1. 异常向量表未保护:异常向量表所在的内存区域没有被设置为只读,攻击者可以篡改异常向量表的入口地址,控制异常处理流程。
  2. VBAR_ELx寄存器未保护:攻击者可以修改VBAR_ELx寄存器的值,指向自己的恶意异常向量表。
  3. 异常处理函数漏洞:异常处理函数存在输入验证不足、缓冲区溢出等漏洞,允许攻击者提权。
  4. 异常注入攻击:攻击者注入异常,触发异常处理流程,利用异常处理函数中的漏洞。
3.3.2 安全加固建议
为了防止异常向量表初始化过程中的漏洞,建议采取以下安全加固措施:
  1. 写保护异常向量表:将异常向量表所在的内存区域设置为只读,防止被篡改。
  2. 保护VBAR_ELx寄存器:禁止低权限代码修改VBAR_ELx寄存器。
  3. 严格验证异常处理函数的输入:对异常处理函数的输入进行严格的验证,防止缓冲区溢出和指针越界。
  4. 异常向量表完整性校验:定期校验异常向量表的完整性,确保其没有被篡改。
  5. 最小化异常处理函数:异常处理函数只包含必要的代码,减少攻击面。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询