.section .vectors, "ax", %progbits
.L__vectors_start:
W(b) vector_rst
W(b) vector_und
W(ldr) pc, .L__vectors_start + 0x1000
W(b) vector_pabt
W(b) vector_dabt
W(b) vector_addrexcptn
W(b) vector_irq
W(b) vector_fiq
每种处理方式中相同的部分 // 8个入口
1. 直接定义 2个
vector_rst:
ARM( swi SYS_ERROR0 )
THUMB( svc #0 )
THUMB( nop )
b vector_und
vector_addrexcptn:
b vector_addrexcptn
2. 利用vector_stub宏 5个
irq
dabt
pabt
und
fiq
3. 利用链接脚本 // __vectors_start + 0x1000 的位置是 vector_swi 1个
pc, .L__vectors_start + 0x1000
vector_swi
// 参考 https://blog.csdn.net/u011011827/article/details/115900559 中的 链接布局 关键字 : "__vectors_start"
// 参考 https://blog.csdn.net/u011011827/article/details/117475336 的 关键字 "vectors"
vector_stub
arm-linux-gnueabi-gcc -Wp,-MMD,arch/arm/kernel/.entry-armv.o.d -nostdinc -isystem /home/suws/ok6410/system/tools/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabi/7.4.1/include -I./arch/arm/include -I./arch/arm/include/generated -I./include -I./arch/arm/include/uapi -I./arch/arm/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -D__ASSEMBLY__ -fno-PIE -mabi=aapcs-linux -mfpu=vfp -funwind-tables -marm -Wa,-mno-warn-deprecated -D__LINUX_ARM_ARCH__=6 -march=armv6k -mtune=arm1136j-s -include asm/unified.h -msoft-float
-c -o arch/arm/kernel/entry-armv.o arch/arm/kernel/entry-armv.S
可改为
-E -o arch/arm/kernel/entry-armv.i arch/arm/kernel/entry-armv.S
.macro vector_stub, name, mode, correction=0
.align 5
vector_name:
.if correction
sub lr, lr, #correction
.endif
@
@ Save r0, lr_ @ (parent CPSR) @ stmia sp, {r0, lr} @ save r0, lr mrs lr, spsr str lr, [sp, #8] @ save spsr @ @ Prepare for SVC32 mode. IRQs remain disabled. @ mrs r0, cpsr eor r0, r0, #(mode ^ 0x00000013 | 0) msr spsr_cxsf, r0 @ @ the branch table must immediately follow this code @ and lr, lr, #0x0f // 该指令运行前,lr 中是 spsr 的值 // cpsr 低4位是用来区分 mode // 0000 user // 0001 fiq // 0010 irq // 0011 svc // 0111 abort // 1011 und // 1111 sys mov r0, sp ldr lr, [pc, lr, lsl #2] // lr 中存着 pc + lr*4 // pc 的值 是 vector_stub 下面的第一个 .long xxx 中变量的地址 // 所以 .long 申请的变量值 和 mode的值 一一对应 // __irq_usr 代表 之前 是 user mode , 跳到了 irq mode // __irq_svc 代表 之前 是 svc mode ,跳到了 irq mode // 为什么没有 __irq_dabt , // 因为 linux (通过在其他mode关闭中断,在其他mode不会发生异常?)保证了 中断发生时 当前mode 只存在两种情况 // 1. usr mode 2. svc mode // 通过在其他mode关闭中断 : 所以一般其他mode只是一个过渡阶段,处理具体事务的会是 svc mode // fiq 是个特例, fiq 可以在 dat 模式下发生 movs pc, lr @ branch to handler in SVC mode .type vector_name, %function; .size vector_name, .-vector_name .align 2 @ handler addresses follow this label 1: .endm /* * Interrupt dispatcher */ vector_stub irq, IRQ_MODE, 4 .long __irq_usr @ 0 (USR_26 / USR_32) .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) .long __irq_invalid @ 2 (IRQ_26 / IRQ_32) .long __irq_svc @ 3 (SVC_26 / SVC_32) .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 __dabt_invalid __dabt_svc __dabt_usr --- __fiq_abt __fiq_svc __fiq_usr --- __irq_invalid __irq_svc __irq_usr --- __pabt_invalid __pabt_svc __pabt_usr --- __und_invalid __und_svc __und_usr
上一篇:OK6410A 开发板 (八) 118 linux-5.11 OK6410A arm异常原因及linux应用场景及结果
下一篇:OK6410A 开发板 (八) 117 linux-5.11 OK6410A Prefetch Abort 实例分析
推荐阅读最新更新时间:2024-11-17 03:14
设计资源 培训 开发板 精华推荐
- LTC1261LIS8-4.5 -4V 发生器的典型应用电路,具有电源有效开关电容器稳压逆变器
- 1810300424-王京情-课程设计5
- 【物联网】智能WIFI开关
- LM2576、3A、15V降压型开关稳压器的典型应用电路
- STM32F405RGT6最小系统板
- Tah:兼容 Arduino的BLE平台,可用作信标、微控制器和 HID 设备(含原理图、源码等)
- 具有 1.8V 和 ±5V 输出的 LT3506 降压型开关稳压器的典型应用电路
- 【涂鸦智能】物联网温湿度传感器+541726A
- 使用具有 B 类 EMI 过滤功能的 RP10-123.3SA DC/DC 转换器(单输出)的典型应用
- 使用 ROHM Semiconductor 的 BA90BC0WT 的参考设计