Linux异常处理体系结构
arm11处理器裸机的异常与中断处理参考:
另外参考一篇:Linux中断体系结构
在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。V和中断向量表的对应关系如下: [V=0]0x00000000~0x0000001C /[V=1]0xffff0000~0xffff001C 。Linux内核使用0xffff0000。
异常向量的代码很简单,只是一些跳转指令。发生异常时,cpu自动执行这些指令,跳转到更复杂得代码。
地址__vectors_start~__vectors_end间的代码就是异常向量,在arch/arm/kernel/entry-armv.S中定义,这些异常向量会被复制到0xffff0000处。
.globl __vectors_start
__vectors_start:
swi SYS_ERROR0 //复位时,cpu将执行这条指令
b vector_und + stubs_offset //未定义异常时,cpu执行这条指令
ldr pc, .LCvswi + stubs_offset //swi异常
b vector_pabt + stubs_offset //指令预取终止
b vector_dabt + stubs_offset //数据访问终止
b vector_addrexcptn + stubs_offset //没有用到
b vector_irq + stubs_offset //irq异常
b vector_fiq + stubs_offset //fiq异常 .globl __vectors_end
__vectors_end:
“更复杂得代码”在地址__stubs_start~__stubs_end之间,在arch/arm/kernel/entry-armv.S中定义,这些异常向量会被复制到0xffff0200处。
.globl __stubs_start
__stubs_start:
/*
* Interrupt dispatcher
*/
vector_stub irq, IRQ_MODE, .long __irq_usr @ (USR_26 / USR_32)
.long __irq_invalid @ (FIQ_26 / FIQ_32)
.long __irq_invalid @ (IRQ_26 / IRQ_32)
.long __irq_svc @ (SVC_26 / SVC_32)
.long __irq_invalid @
.long __irq_invalid @
.long __irq_invalid @
.long __irq_invalid @
.long __irq_invalid @
.long __irq_invalid @
.long __irq_invalid @ a
.long __irq_invalid @ b
.long __irq_invalid @ c
.long __irq_invalid @ d
.long __irq_invalid @ e
.long __irq_invalid @ f /*
* Data abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/
vector_stub dabt, ABT_MODE, .long __dabt_usr @ (USR_26 / USR_32)
.long __dabt_invalid @ (FIQ_26 / FIQ_32)
.long __dabt_invalid @ (IRQ_26 / IRQ_32)
.long __dabt_svc @ (SVC_26 / SVC_32)
.long __dabt_invalid @
.long __dabt_invalid @
.long __dabt_invalid @
.long __dabt_invalid @
.long __dabt_invalid @
.long __dabt_invalid @
.long __dabt_invalid @ a
.long __dabt_invalid @ b
.long __dabt_invalid @ c
.long __dabt_invalid @ d
.long __dabt_invalid @ e
.long __dabt_invalid @ f /*
* Prefetch abort dispatcher
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
*/
vector_stub pabt, ABT_MODE, .long __pabt_usr @ (USR_26 / USR_32)
.long __pabt_invalid @ (FIQ_26 / FIQ_32)
.long __pabt_invalid @ (IRQ_26 / IRQ_32)
.long __pabt_svc @ (SVC_26 / SVC_32)
.long __pabt_invalid @
.long __pabt_invalid @
.long __pabt_invalid @
.long __pabt_invalid @
.long __pabt_invalid @
.long __pabt_invalid @
.long __pabt_invalid @ a
.long __pabt_invalid @ b
.long __pabt_invalid @ c
.long __pabt_invalid @ d
.long __pabt_invalid @ e
.long __pabt_invalid @ f /*
* Undef instr entry dispatcher
* Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
*/
vector_stub und, UND_MODE .long __und_usr @ (USR_26 / USR_32)
.long __und_invalid @ (FIQ_26 / FIQ_32)
.long __und_invalid @ (IRQ_26 / IRQ_32)
.long __und_svc @ (SVC_26 / SVC_32)
.long __und_invalid @
.long __und_invalid @
.long __und_invalid @
.long __und_invalid @
.long __und_invalid @
.long __und_invalid @
.long __und_invalid @ a
.long __und_invalid @ b
.long __und_invalid @ c
.long __und_invalid @ d
.long __und_invalid @ e
.long __und_invalid @ f .align /*=============================================================================
* Undefined FIQs
*-----------------------------------------------------------------------------
* Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
* MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
* Basically to switch modes, we *HAVE* to clobber one register... brain
* damage alert! I don't think that we can execute any code in here in any
* other mode than FIQ... Ok you can switch to another mode, but you can't
* get out of that mode without clobbering one register.
*/
vector_fiq:
disable_fiq
subs pc, lr, # /*=============================================================================
* Address exception handler
*-----------------------------------------------------------------------------
* These aren't too critical.
* (they're not supposed to happen, and won't happen in 32-bit data mode).
*/ vector_addrexcptn:
b vector_addrexcptn /*
* We group all the following data together to optimise
* for CPUs with separate I & D caches.
*/
.align .LCvswi:
.word vector_swi .globl __stubs_end
__stubs_end:
__stubs_start
关于stubs_offset的值及解析,参考Linux异常体系之stubs_offset
关于__stubs_start~__stubs_end之间的代码解析,参考vector_stub宏解析 。vector_irq、 vector_dabt、vector_pabt、vector_und、vector_fiq都在它们中间。
各种异常的C处理函数分为5类,分布在不同的函数中。
1.中断处理C总入口函数asm_do_IRQ,在linux/arch/arm/kernel/irq.c中。它调用其它文件注册的中断处理函数。
init_IRQ函数被用来初始化中断的处理框架,设置各种中断的默认处理函数。当中断发生时,中断总入口函数asm_do_IRQ就可以调用这些函数坐进一步的处理。
b vector_irq + stubs_offset
-->vector_stub irq, IRQ_MODE,
-->__irq_usr/__irq_svc
-->void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
2.未定义指令处理C总入口函数do_undefinstr,在linux/arch/arm/kernel/traps.c中。
b vector_und + stubs_offset
-->vector_stub und, UND_MODE
-->__und_usr/__und_svc
-->b do_undefinstr
3.与内存访问相关的异常处理C总入口函数do_DataAbort,do_PrefechAbort,在linux/arch/arm/kernel/fault.c中。
4.swi异常处理函数,在在linux/arch/arm/kernel/calls.S中。swi异常的处理函数指针被组织成一个表格;swi指令机器码的为[23:0]用来作为索引,通过不同的“swi index”指令可以调用不同的swi异常处理函数,也称为系统调用,比如sys_open、sys_read、sys_write等。
5.没有使用的异常,linux中没有使用FIQ异常。
Linux异常处理体系结构的更多相关文章
- 字符设备驱动-------Linux异常处理体系结构
裸机中断流程 外部触发 CPU 发生中断, 强制的跳到异常向量处 跳转到具体函数 保存被中断处的现场(各种寄存器的值) 执行中断处理函数,处理具体任务 恢复被中断的现场 Linux处理异常流程 异常发 ...
- Linux内核异常处理体系结构详解(一)【转】
转自:http://www.techbulo.com/1841.html 2015年11月30日 ⁄ 基础知识 ⁄ 共 6653字 ⁄ 字号 小 中 大 ⁄ Linux内核异常处理体系结构详解(一)已 ...
- Linux计时体系结构
[Linux操作系统分析]定时测量——RTC,TSC,PIT,jiffies,计时体系结构,延迟函数 1 基本概念 定时机制连同一些更可见的内核活动(如检查超时)来驱使进程切换. 两种主要的定时测 ...
- linux异常处理:selinux配置错误导致无法重启
点击返回自学Linux集锦 linux异常处理:selinux配置错误导致无法重启 一次linux无法重启异常记录: 当时第一反应就是梳理最近的配置变更,特别是能预知相关的就是selinux配置变更. ...
- 字符设备驱动笔记——中断方式按键驱动之linux异常处理结构(四)
.中断方式获取按键值 单片机: )按键按下 )cup发生中断,跳转到异常向量入口执行 )b 函数 a.保存被中断的现场 b.执行中断处理函数 c.恢复 linux: )trap_init()函数构造异 ...
- Linux驱动之异常处理体系结构简析
异常的概念在单片机中也接触过,它的意思是让CPU可以暂停当前的事情,跳到异常处理程序去执行.以前写单片机裸机程序属于前后台程序,前台指的就是mian函数里的while(1)大循环,后台指的就是产生异常 ...
- linux文件系统体系结构 和 虚拟文件系统(VFS)
图 1. Linux 文件系统组件的体系结构 用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C 库(glibc),它们为文件系统调用(打开.读取.写和关闭)提供用户接口.系统调用接口的 ...
- linux内核体系结构
linux内核第一记 1.linux体系结构 从上图可知,Linux分为:用户空间和内核空间.内核空间和用户空间是程序执行的两种不同的状态,通过系统调用和硬件中断能够完成从用户空间到内核空间的 ...
- Linux中断体系结构
1.中断处理体系结构 Linux内核将所有中断统一编号,使用一个irq_desc结构数组来描述这些中断. 数组声明在/linux/kernel/irq/handle.c中,其中#define NR_I ...
随机推荐
- pom文件jar包缺失问题
一般情况,不在中央仓库的jar包,比如自己的版本,要用的话打入maven私服 在eclipse中引入其他项目(包含jar包),类似于放入了私服,删除工程源文件,会导致别的工程引用此jar包失效
- DOM操作(二)对元素的操作(创建,追加,删除)
1 创建新的 HTML 元素 (节点) var divDom=document.createElement('div'); 2 添加新元素到尾部 element.appendChild(para); ...
- Python使用selenium进行爬虫(一)
JAVA爬虫框架很多,类似JSOUP,WEBLOGIC之类的爬虫框架都十分好用,个人认为爬虫的大致思路就是: 1.挑选需求爬的URL地址,将其放入需求网络爬虫的队列,也可以把爬到的符合一定需求的地址放 ...
- linux系统基本结构-《循序渐进linux》
1.linux控制台 linux系统由桌面控制台(X -Window视窗)和字符控制台组成.字符控制台是linux的核心,默认linux下有6个字符控制台. 字符控制台--〉X-Window下:ctr ...
- 初识AutoCompleteTextView
AutoCompleteTextView自动补全框继承自TextView和EditView,通过一个下拉框的形式可以补全信息. 可以通过setThreshold()方法指定用户输入多少个字符后开始显示 ...
- getuser
Help on function getuser in module getpass: getuser() Get the username from the environment or pa ...
- Writable和Comparable
WritableComparable接口相当于继承了上述两个接口的新接口 : Public interface WritableComparable<T>extends Writable, ...
- Python+selenium之疑难点解决之去除readonly的限制
去除文本框的readonly只读模式的限制 如图所示:去除卡号readonly限制 代码如图所示: js = 'document.getElementById("cardNo"). ...
- Windows系统下查看文件编码类型
这是一个程序员的最基本的技能,原谅我到现在才去了解 以前只知道window操作系统下文件大部分默认编码是ANSI,中文版是GBK编码 如果想要查看或者修改文件编码的话有两种方式 一:用记事本打开文件, ...
- 一点对Promise的理解与总结
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10959411.html,多谢,=.=~ axios用多了就开始疑惑它里面到底是个啥,虽然总被告知 ...