arm linux内核中ARM中断实现详解3388.docx

上传人:you****now 文档编号:68882546 上传时间:2022-12-30 格式:DOCX 页数:29 大小:65.04KB
返回 下载 相关 举报
arm linux内核中ARM中断实现详解3388.docx_第1页
第1页 / 共29页
arm linux内核中ARM中断实现详解3388.docx_第2页
第2页 / 共29页
点击查看更多>>
资源描述

《arm linux内核中ARM中断实现详解3388.docx》由会员分享,可在线阅读,更多相关《arm linux内核中ARM中断实现详解3388.docx(29页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、linux-2.6.26内核中ARM中断实现详解(1) 作者:刘洪涛,华清远见嵌入式学院金牌讲师,ARM ATC授权培训讲师。看了一些网络上关于linux中断实现的文章,感觉有一些写的非常好,在这里首先感谢他们的无私付出,然后也想再补充自己对一些问题的理解。先从函数注册引出问题吧。一、中断注册方法在linux内内核中用于申申请中断的函函数是reqquest_irq(),函函数原型在KKernell/irq/managge.c中定定义:int reqquest_irq(uunsignned innt irqq, irqq_handdler_tt handdler, uunsignned loon

2、g irrqflaggs, coonst cchar *devnaame, vvoid *dev_iid)irq是要申请请的硬件中断断号。handlerr是向系统注注册的中断处处理函数,是是一个回调函函数,中断发发生时,系统统调用这个函函数,devv_id参数数将被传递给给它。irqflaggs是中断处处理的属性,若若设置了IRRQF_DIISABLEED (老版版本中的SAA_INTEERRUPTT,本版zhhon已经不不支持了),则则表示中断处处理程序是快快速处理程序序,快速处理理程序被调用用时屏蔽所有有中断,慢速速处理程 序序不屏蔽;若若设置了IRRQF_SHHARED (老版本中中的S

3、A_SSHIRQ),则则表示多个设设备共享中断断,若设置了了IRQF_SAMPLLE_RANNDOM(老老版本中的 SA_SAAMPLE_RANDOOM),表示示对系统熵有有贡献,对系系统获取随机机数有好处。(这这几个flaag是可以通通过或的方式式同时使用的的)dev_id在在中断共享时时会用到,一一般设置为这这个设备的设设备结构体或或者NULLL。devnamee设置中断名名称,在caat /prroc/innterruupts中可可以看到此名名称。requestt_irq()返回0表表示成功,返返回-INVVAL表示中中断号无效或或处理函数指指针为NULLL,返回-EBUSYY表示中断已

4、已经被占用且且不能共享。关于中断注册的的例子,大家家可在内核中中搜索下reequestt_irq。在编写驱动的过过程中,比较较容易产生疑疑惑的地方是是:1、中断向量表表在什么位置置?是如何建建立的? 2、从中中断开始,系系统是怎样执执行到我自己己注册的函数数的? 3、中断号号是如何确定定的?对于硬硬件上有子中中断的中断号号如何确定? 4、中中断共享是怎怎么回事,ddev_idd的作用是?本文以2.6.26内核和和S3C24100处理器为例例,为大家讲讲解这几个问问题。二、异常向量表表的建立在ARM V44及V4T以以后的大部分分处理器中,中中断向量表的的位置可以有有两个位置:一个是0,另另一个

5、是0xxffff00000。可可以通过CPP15协处理理器c1寄存存器中V位(bit113)控制制。V和中断断向量表的对对应关系如下下:V=0 0xx00000000000x00000001C V=11 0xfffff000000xxffff0001Carch/arrm/mm/proc-arm9220.S中.sectioon .ttext.iinit, #allloc, #execiinstr _aarm9200_setuup: orrr r00, r0, #0x22100 .1. .1 .11 .1/bit133=1 中断断向量表基址址为0xFFFFF00000。R0的的值将被付给给CP15

6、的的C1.在linux中中,向量表建建立的函数为为:init/maain.c-starrt_kerrnel()-traap_iniit()void _init trap_init(void) unssignedd longg vecttors = CONFFIG_VEECTORSS_BASEE; meemcpy(voidd *)veectorss, _vvectorrs_staart, _vecttors_eend - _vecctors_startt); meemcpy(voidd *)veectorss + 0xx200, _stuubs_sttart, _stuubs_ennd - _s

7、tubbs_staart); . 在2.6.266内核中COONFIG_VECTOORS_BAASE最初是是在各个平台台的配置文件件中设定的,如如:arch/arrm/connfigs/s3c24100_defcconfigg中CONFIG_VECTOORS_BAASE=0xxffff00000_vectoors_ennd 至 _vecttors_sstart之之间为异常向向量表。位于arch/arm/kkernell/entrry-armmv.S.globl _vecctors_startt_vecctors_startt: sswi SYYS_ERRROR0: b vvectorr_und

8、 + stuubs_offfset /复位异异常: ldr ppc, .LLCvswii + sttubs_ooffsett /未定义指令令异常: b veector_pabt + stuubs_offfset /软软件中断异常常: bb vecttor_daabt + stubss_offsset /数据异异常: b vecctor_aaddrexxcptn + stuubs_offfset /保保留: b vecctor_iirq + stubss_offsset /普通中中断异常: b vvectorr_fiq + stuubs_offfset /快快速中断异常常: .globll _v

9、eectorss_end:_vecctors_end:_stubss_end 至 _sstubs_startt之间是异常常处理的位置置。也位于文文件archh/arm/kerneel/enttry-arrmv.S中中。vecttor_unnd、vecctor_ppabt、vvectorr_irq、vvectorr_fiq都都在它们中间间。stubs_ooffsett值如下:.equ sttubs_ooffsett, _vvectorrs_staart + 0x2000 - _stubss_starrtstubs_ooffsett是如何确定定的呢?(引引用网络上的的一段比较详详细的解释)当汇编器

10、看到BB指令后会把把要跳转的标标签转化为相相对于当前PPC的偏移量量(32MM)写入指令令码。从上面面的代码可以以看到中断向向量表和sttubs都发发生了 代码码搬移,所以以如果中断向向量表中仍然然写成b vvectorr_irq,那那么实际执行行的时候就无无法跳转到搬搬移后的veector_irq处,因因为指令码里里写的是原来来的偏移量,所所以需要把指指令码中的偏偏移量写 成成搬移后的。我我们把搬移前前的中断向量量表中的irrq入口地址址记irq_PC,它在在中断向量表表的偏移量就就是irq_PC-veectorss_starrt, veector_irq在sstubs中中的偏移量是是vec

11、toor_irqq-stubbs_staart,这两两个偏移量在在搬移前后是是不变的。搬搬移后 veectorss_starrt在0xfffff00000处,而而stubss_starrt在0xfffff02200处,所所以搬移后的的vectoor_irqq相对于中断断 向量中的的中断入口地地址的偏移量量就是,2000+vecctor_iirq在sttubs中的的偏移量再减减去中断入口口在向量表中中的偏移量,即即200+ vectoor_irqq-stubbs_staart-irrq_PC+vectoors_sttart = (vecctor_iirq-irrq_PC) + veectorss

12、_starrt+2000-stubbs_staart,对于于括号内的值值实际上就是是中断向量表表中写的veector_irq,减减去irq_PC是由汇汇 编器完成成的,而后面面的 vecctors_startt+200-stubss_starrt就应该是是stubss_offsset,实际际上在enttry-arrmv.S中中也是这样定定义的。三、中断处理过过程 这一节将以S33C24100为例,描述述linuxx-2.6.26内核中中,从中断开开始,中断是是如何一步一一步执行到我我们注册函数数的。 3.1 中断向向量表 arrcharrmkerrneleentry-armv.S_vectoo

13、rs_sttart:swii SYS_ERRORR0bb vvectorr_und + stuubs_offfsetldrr pc, .LCvsswi + stubss_offssetb vectoor_pabbt + sstubs_offseetbb vvectorr_dabtt + sttubs_ooffsettb veector_addreexcptnn + sttubs_ooffsettb veector_irq + stubbs_offfset b vecctor_ffiq + stubss_offsset.globbl _vecttors_eend_vecctors_end:中断发

14、生后,跳跳转到b vvectorr_irq + stuubs_offfset的的位置执行。注注意现在的向向量表的初始始位置是0xxffff00000。 3.2 中断跳跳转的入口位位置 arccharmmkernnelenntry-aarmv.SS.globll _stubss_starrt_stuubs_sttart: /* * Innterruupt diispatccher*/veector_stub irrq, IRRQ_MODDE, 4 IRQ_MMODE在iincluddeasmmptraace.h中中定义:0xx12.longg _irq_usr 0 (UUSR_266 / USS

15、R_32).llong _iirq_innvalidd 1 (FIQ_26 / FIQ_332).longg _irq_invallid 2 (IRRQ_26 / IRQQ_32).loong _irrq_svcc 3 (SVC_26 / SVC_332).longg _irq_invallid 4.long _irq_iinvaliid 55.llong _iirq_innvalidd 6.loong _irrq_invvalid 7.lonng _irqq_invaalid 8.longg _irq_invallid 9.long _irqq_invaalid a.longg _irrq_

16、invvalid b.lonng _iirq_innvalidd c.loong _irq_iinvaliid dd.llong _irq_invallid e.long _irqq_invaalid f上面代码中veector_stub宏宏的定义为: .macro vectoor_stuub, naame, mmode, correectionn=0.aliggn 5vecttor_nname:.iff corrrectiionsub llr, lrr, #ccorrecction.enndif Savve r0, lr_ (parrent PPC) annd spssr_ (pparent

17、t CPSRR)sttmia ssp, rr0, lrr ssave rr0, lrrmrrs lr, spsrrsttr lr, sp, #8 savve spssr Prepaare foor SVCC32 moode. IIRQs rremainn disaabled.mrss r0, cpsreorr r0, r0, #(modde SSVC_MOODE)msr spsr_cxsf, r0 为后面进入入svc模式式做准备 tthe brranch tablee mustt immeediateely foollow this code andd lr, lr, #0x0f 进入入中断前

18、的mmode的后后4位 #deefine USR_MMODE 00x000000010#ddefinee FIQ_MODE 0x0000000111#definne IRQQ_MODEE 0x0000000112#defiine SVVC_MODDE 0x0000000013#deffine AABT_MOODE 0xx000000017#deefine UND_MMODE 00x00000001b#ddefinee SYSTTEM_MOODE 0xx00000001fmov r0, ssplldr lrr, pcc, lr, lsl #2 如果进入中中断前是ussr,则取出出PC+4*0的内

19、容,即即_irqq_usr如果进入入中断前是ssvc,则取取出PC+44*3的内容容,即_iirq_svvcmmovs ppc, lrr 当指指令的目标寄寄存器是PCC,且指令以以S结束,则则它会把 spsr的的值恢复给ccpsr bbranchh to hhandleer in SVC mmode.enddm.globll _sttubs_sstart_sttubs_sstart:/* Innterruupt diispatccher*/vectoor_stuub irqq, IRQQ_MODEE, 4.lonng _iirq_ussr 00 (USRR_26 / USR_32).lonng

20、 _iirq_innvalidd 1 (FIQ_26 / FIQ_332).longg _irrq_invvalid 2 (IRQ_226 / IIRQ_322).long _irqq_svc 3 (SVC_226 / SSVC_322)用“irq, IRQ_MMODE, 4”代替宏vvectorr_stubb中的“naame, mmode, correectionn”,找到了了我们中断处处理的入口位位置为vecctor_iirq(宏里里面的vecctor_name)。 从上面代码码中的注释可可以看出,根根据进入中断断前的工作模模式不同,程程序下一步将将跳转到_iirq_ussr 、或_irq

21、_svc等位位置。我们先先选择_iirq_ussr作为下一一步跟踪的目目标。 3.3 _iirq_ussr的实现 archarmkkernellentrry-armmv.S_irq_uusr:usr_entryy 后面有有解释 kuseer_cmppxchg_checkk#iffdef CCONFIGG_TRACCE_IRQQFLAGSSbll tracce_harrdirqss_off#enddifget_tthreadd_infoo tsk 获取当前前进程的进程程描述符中的的成员变量tthreadd_infoo的地址,并并将该地址保保存到寄存器器tsk等于于r9(在eentry-heade

22、er.S中定定义)#ifdeff CONFFIG_PRREEMPTT/如果定定义了抢占,增增加抢占数值值 lldr r88, tssk, #TTI_PREEEMPT geet preeempt counttaddd r7, r8, #1 increement itstr rr7, ttsk, #TI_PRREEMPTT#eendifirq_hanndler 中断处理理,我们最关关心的地方,33.4节有实实现过程。 #ifddef COONFIG_PREEMMPTldr rr0, ttsk, #TI_PRREEMPTTsstr r88, tssk, #TTI_PREEEMPTteeq r0, r

23、7strnne r0, r0, -r0#enddif#iifdef CONFIIG_TRAACE_IRRQFLAGGSbbl traace_haardirqqs_on#enddifmov whyy, #0b ret_tto_useer 中断断处理完成,返返回中断产生生的位置,33.7节有实实现过程 上面代码中的uusr_enntry是一一个宏,主要要实现了将uusr模式下下的寄存器、中中断返回地址址保存到堆栈栈中。.macro usr_eentrysub sp, ssp, #SS_FRAMME_SIZZE SS_FRAMME_SIZZE的值在aarchaarmkeernelasm-ooffse

24、tts.c 中定义义 DEFIINE(S_FRAMEE_SIZEE, sizzeof(sstructt pt_rregs);实际上等等于72sttmib ssp, rr1 - rr12ldmiia r0, r1 - r3addd r0, sp, #S_PCC heere foor intterlocck avooidanccemmov r44, #-11 str r1, sp savee the reall r0 copieed fromm the excepption stackk WWe aree now readyy to ffill iin thee remaainingg blann

25、ks onn the stackk: r2 - lr_, alreeady ffixed up foor corrrect returrn/resstart rr3 - sspsr_ r4 - orig_r0 (ssee ptt_regss defiinitioon in ptracce.h) Allso, sseparaately save sp_ussr andd lr_uusrsstmia r0, r2 - r4stmddb r0, sp, lr Enablle thee aliggnmentt trapp whille in kerneel moddealignnment_trap r

26、0 CClear FP too markk the firstt stacck fraamezzero_ffp.endm上面的这段代码码主要在填充充结构体ptt_regss ,这里提提到的strruct ppt_reggs,在inncludee/asm/ptracce.h中定定义。此时ssp指向sttruct pt_reegs。 sstructt pt_rregs longg ureggs18;#ddefinee ARM_cpsr uregss16#deffine AARM_pcc ureggs15#deefine ARM_llr ureegs144#ddefinee ARM_sp urreg

27、s113#definne ARMM_ip uuregs12#defiine ARRM_fp uregss11#deffine AARM_r110 ureegs100#ddefinee ARM_r9 urregs99#ddefinee ARM_r8 urregs88#ddefinee ARM_r7 urregs77#ddefinee ARM_r6 urregs66#ddefinee ARM_r5 urregs55#ddefinee ARM_r4 urregs44#ddefinee ARM_r3 urregs33#ddefinee ARM_r2 urregs22#ddefinee ARM_r1 u

28、rregs11#ddefinee ARM_r0 urregs00#ddefinee ARM_ORIG_r0 urregs1173.4 irqq_handdler的实实现过程,archarmkkernellentrry-armmv.S.macrro irqq_handdlergett_irqnnr_preeamblee r5, lr在inncludee/asm/arch-s3c24100/entrry-maccro.s中中定义了宏gget_irrqnr_ppreambble为空操操作,什么都都不做1: gget_irrqnr_aand_baase r00, r6, r5, lr 判判断中断号,通

29、通过R0返回回,3.5节节有实现过程程 movnee r1, sp rooutinee callled wiith r00 = irrq nummber, r1 = strucct pt_regs *adrnee lr, 1bbne asm_ddo_IRQQ 进入中中断处理。 .endm3.5 gett_irqnnr_andd_basee中断号判断断过程,inncludee/asm/arch-s3c24100/entrry-maccro.s.macro get_iirqnr_and_bbase, irqnrr, irqqstat, basee, tmppmmov bbase, #S3C24XX

30、X_VA_IIRQ ttry thhe intterruppt offfset rregistter, ssince it iss therreldr irqsttat, basse, #IINTPNDD teq irqsstat, #0beq 1002fflldr iirqnr, bbase, #INTOOFFSETT 通通过判断INNTOFFSSET寄存器器得到中断位位置 mmov ttmp, #1tst irqsttat, tmp, lsl irqnrrbbne 10001f the nnumberr speccifiedd is nnot a validd irq, so ttry a

31、and woork itt out for ooursellvesmovv irqqnr, #0 startt heree worrk outt whicch irqq (if any) we gootmovs tmp, irqqstat, lsl#16addeeq irrqnr, irqnnr, #116moveqq irqqstat, irqqstat, lsr#16tst irqsstat, #0xfffaaddeq irqnnr, iirqnr, #8movveq iirqstaat, iirqstaat, lssr#8tstt irqqstat, #0xffaaddeq irqnnr

32、, iirqnr, #4movveq iirqstaat, iirqstaat, lssr#4tstt irqqstat, #0x33aaddeq irqnnr, iirqnr, #2movveq iirqstaat, iirqstaat, lssr#2tstt irqqstat, #0x11aaddeq irqnnr, iirqnr, #1 we haave thhe vallue10001:adds irqnnr, iirqnr, #IRQQ_EINTT0 加上上中断号的基基准 数值,得得到最终的中中断号,注意意:此时没有有考虑子中断断的具体情况况,(子中断断的问题后面面会有讲解)。IIR

33、Q_EIINT0在iincludde/asmm/archh- s3cc2410/irqs.h中定义.从这里可以以看出,中断断号的具体值值是有平台相相关的代码决决定的,和硬硬件中断挂起起寄存器中的的中断号是不不等的。 1002: exit here, Z fllag unnset iif IRQQ.endmm3.6 asmm_do_IIRQ实现过过程,arcch/armm/kernnel/irrq.c asmlinkkage vvoid _exceeptionn asm_do_IRRQ(unssignedd int irq, strucct pt_regs *regss)sstructt pt_

34、rregs *old_rregs = set_irq_rregs(rregs);sstructt irq_desc *descc = irrq_dessc + iirq;/根据中断号号找到对应的的irq_ddesc/* Some hardwware ggives randoomly wwrong interrruptss. Ratther* tthan ccrashiing, ddo sommethinng sennsiblee.*/if (irq = NR_IRQS)ddesc = &badd_irq_desc;iirq_ennter();/没做做什么特别的的工作,可以以跳过不看 ddesc_hhandlee_irq(irq, desc);/ 根根据中断号和和desc进进入中断处理理 /* ATT91 sppecifiic worrkarouund */iirq_fiinish(irq);iirq_exxit();sset_irrq_reggs

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 管理文献 > 电力管理

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com