启动流程分析(一)-vitis工程asm_vectors.S

ARM汇编异常处理代码的流程图解析,按模块分层展示

┌───────────────────────┐
│     向量表入口          │
│ (0x00000000开始)       │
└──────────┬────────────┘
           │
           ▼
┌───────────────────────┐
│ 异常类型判断            │
│ (通过向量表偏移跳转)     │
└──────────┬────────────┘
           │
           ├───────────────────┬─────────────┬────────────────┬────────────────┐
           ▼                   ▼             ▼                ▼                ▼
┌───────────────────┐   ┌───────────┐  ┌───────────┐   ┌──────────────┐ ┌───────────┐
      Reset              Undefined       SVC调用         PrefetchAbort    DataAbort 
    (跳转_boot)             异常处理         处理               处理           处理      
└───────────────────┘   └─────┬─────┘  └─────┬─────┘   └─────┬────────┘ └─────┬─────┘
           │                  │              │               │                │
           ├──────────────────┴──────────────┴───────────────┴────────────────┘
           ▼
┌───────────────────────┐
│   IRQ/FIQ中断处理      │
└──────────┬────────────┘
           │
           ▼
┌───────────────────────┐
│ 公共处理流程            │
├───────────────────────┤
│ 1. 保存现场            │
│   (r0-r3,r12,lr入栈)   │
├───────────────────────┤
│ 2. FPU状态保存         │
│   (如果启用FPU)        │
├───────────────────────┤
│ 3. 调用C处理函数        │
│   (如IRQInterrupt)    │
├───────────────────────┤
│ 4. FPU状态恢复         │
│   (如果启用FPU)        │
├───────────────────────┤
│ 5. 恢复现场            │
│   (寄存器出栈)          │
├───────────────────────┤
│ 6. 异常返回地址调整      │
│   (PC ← LR - 偏移量)   │
└───────────────────────┘

1、向量表定义

.org 0                 ; 设置当前地址为0x0
.text                  ; 进入代码段

.globl _vector_table    ; 声明全局符号
.section .vectors       ; 定义向量表段
_vector_table:          ; 向量表起始标签

作用:定义位于地址0的异常向量表,使用.vectors段存放

2、异常向量入口

B   _boot              ; 0x00: Reset向量,跳转到启动代码
B   Undefined          ; 0x04: 未定义指令异常
B   SVCHandler         ; 0x08: SVC调用
B   PrefetchAbortHandler ; 0x0C: 预取中止
B   DataAbortHandler    ; 0x10: 数据中止
NOP                    ; 0x14: 保留向量(历史地址异常)
B   IRQHandler         ; 0x18: IRQ中断
B   FIQHandler         ; 0x1C: FIQ中断

关键点:每个向量占用4字节,使用B指令跳转(范围限制±32MB)

3、IRQ处理程序

IRQHandler:
stmdb   sp!,{r0-r3,r12,lr}  ; 压栈保存关键寄存器

寄存器保存策略:保存被破坏的调用者保存寄存器(AAPCS标准)

4、FPU状态保存

#if FPU_HARD_FLOAT_ABI_ENABLED
vpush {d0-d7}          ; 保存低128位FPU寄存器
vpush {d16-d31}        ; 保存高128位FPU寄存器
vmrs r1, FPSCR         ; 读取FPU状态控制寄存器
push {r1}              ; 保存FPSCR
vmrs r1, FPEXC         ; 读取FPU异常寄存器
push {r1}              ; 保存FPEXC
#endif

技术要点:VFPv4架构需要保存D0-D31共32个双字寄存器

5、性能分析支持

#ifdef PROFILING
ldr r2, =prof_pc       ; 加载prof_pc的地址
subs r3, lr, #0        ; 复制LR到R3(subs用于设置标志)
str r3, [r2]           ; 存储异常发生时的PC值
#endif

作用:记录异常发生时的程序计数器,用于性能分析

6、中断处理调用

bl  IRQInterrupt       ; 调用C语言中断处理函数

调用约定:使用标准ARM调用约定,参数通过寄存器传递

7、FPU状态恢复

#if FPU_HARD_FLOAT_ABI_ENABLED
pop  {r1}
vmsr FPEXC, r1         ; 恢复FPEXC
pop  {r1}
vmsr FPSCR, r1         ; 恢复FPSCR
vpop {d16-d31}         ; 恢复高128位
vpop {d0-d7}           ; 恢复低128#endif

恢复顺序:严格按照保存的逆序进行

8、现场恢复与返回

ldmia   sp!,{r0-r3,r12,lr} ; 弹出通用寄存器
subs    pc, lr, #4      ; 修正返回地址(IRQ特定)

关键细节:subs pc, lr, #4 将导致:

恢复CPSR

PC ← LR - 4

自动切换回之前的处理器模式

9、SVC指令解析

tst r0, #0x20          ; 检查CPSR的T位(bit5)
ldrneb r0, [lr,#-2]    ; Thumb模式:LR-2获取SWI指令
ldreq r0, [lr,#-4]     ; ARM模式:LR-4获取SWI指令
biceq r0, r0, #0xff000000 ; 清除ARM模式SWI编号的高字节

SWI编号提取:

ARM模式:SWI指令的高24位是编号

Thumb模式:SWI指令的低8位是编号

10、数据中止特殊处理

#ifdef CONFIG_ARM_ERRATA_775420
dsb                   ; 数据同步屏障
#endif
subs    pc, lr, #8    ; 返回触发异常的指令

勘误说明:Cortex-A9 Errata 775420要求在异常入口添加屏障

11、未定义指令处理

ldr r0, =UndefinedExceptionAddr
sub r1, lr, #4        ; LR-4获取异常指令地址
str r1, [r0]          ; 存储到全局变量
bl  UndefinedException ; 调用C处理函数
movs pc, lr           ; 直接返回(不重新执行异常指令)

处理策略:记录异常地址后交给C代码处理,不尝试恢复

12、FIQ快速处理循环

FIQLoop:
bl  FIQInterrupt      ; 可能连续处理多个FIQ

设计特点:允许在FIQ处理中继续响应新的FIQ中断

各异常返回地址修正总结表:

异常类型           LR值     PC修正      指令示例


Reset               -        跳转到_boot   B _boot


IRQ            PC+4      PC = LR - 4    subs pc, lr, #4


FIQ            PC+4       PC = LR - 4    subs pc, lr, #4


Data Abort          PC+8      PC = LR - 8    subs pc, lr, #8


Prefetch Abort      PC+4         PC = LR - 4    subs pc, lr, #4


Undefined          PC+4       PC = LR      movs pc, lr


SWI               PC+4    PC = LR        movs pc, lr


关键设计决策:

最小化中断延迟:通过分层保存(先通用寄存器后FPU)

勘误兼容性:通过条件编译处理芯片特定问题

调试支持:提供PC记录机制

模式透明:自动处理ARM/Thumb模式差异

可扩展性:通过C函数实现具体处理逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值