微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > linux内核中的信号机制--信号处理

linux内核中的信号机制--信号处理

时间:11-22 来源:互联网 点击:

  1. regs->regs->ARM_lr=retcode;//返回地址,当用户态信号处理函数结束时,就会把这个地址作为返回地址
  2. regs->ARM_pc=handler;//信号处理函数
  3. regs->ARM_cpsr=cpsr;
  4. return0;
  5. }

当setup_frame()返回后,一切准备就绪,因此可以从内核态返回了,这样就顺利过渡到用户态的信号处理函数。当这个函数处理结束后,会通过retcode再次进入内核态,现在我们看看retcode是如何处理的,下面的代码选自glibc(2.3.2):

[plain]view plaincopyprint?

  1. #include
  2. /*IfnoSA_RESTORERfunctionwasspecifiedbytheapplicationweuse
  3. oneofthese.Thisavoidstheneedforthekerneltosynthesiseareturn
  4. instructiononthestack,whichwouldinvolveexpensivecacheflushes.*/
  5. ENTRY(__default_sa_restorer)
  6. swiSYS_ify(sigreturn)
  7. #ifdef__NR_rt_sigreturn
  8. ENTRY(__default_rt_sa_restorer)
  9. swiSYS_ify(rt_sigreturn)
  10. #defineSYS_ify(syscall_name)(__NR_##syscall_name)

下面具体看看sys_sigreturn()的定义:

[plain]view plaincopyprint?

  1. asmlinkageintsys_sigreturn(structpt_regs*regs)
  2. {
  3. structsigframe__user*frame;
  4. sigset_tset;
  5. /*Alwaysmakeanypendingrestartedsystemcallsreturn-EINTR*/
  6. current_thread_info()->restart_block.fn=do_no_restart_syscall;
  7. /*
  8. *Sincewestackedthesignalona64-bitboundary,
  9. *thenspshouldbewordalignedhere.Ifits
  10. *not,thentheuseristryingtomesswithus.
  11. */
  12. if(regs->ARM_sp&7)
  13. gotobadframe;
  14. frame=(structsigframe__user*)regs->ARM_sp;
  15. if(!access_ok(VERIFY_READ,frame,sizeof(*frame)))
  16. gotobadframe;
  17. if(__get_user(set.sig[0],&frame->sc.oldmask)
  18. ||(_NSIG_WORDS>1
  19. &&__copy_from_user(&set.sig[1],&frame->extramask,
  20. sizeof(frame->extramask))))
  21. gotobadframe;
  22. sigdelsetmask(&set,~_BLOCKABLE);
  23. spin_lock_irq(¤t->sighand->siglock);
  24. current->blocked=set;
  25. recalc_sigpending();
  26. spin_unlock_irq(¤tt->sighand->siglock);
  27. if(restore_sigcontext(regs,&frame->sc,&frame->aux))
  28. gotobadframe;
  29. /*SendSIGTRAPifweresingle-stepping*/
  30. if(current->ptrace&PT_SINGLESTEP){
  31. ptrace_cancel_bpt(current);
  32. send_sig(SIGTRAP,current,1);
  33. }
  34. returnregs->ARM_r0;
  35. badframe:
  36. force_sig(SIGSEGV,current);
  37. return0;
  38. }

这个函数主要调用restore_sigcontext()根据用户态态堆栈上的sigframe备份还原pt_regs。

[plain]view plaincopyprint?

  1. staticint
  2. restore_sigcontext(structpt_regs*regs,structsigcontext__user*sc,
  3. structaux_sigframe__user*aux)
  4. {
  5. interr=0;
  6. __get_user_error(regs->ARM_r0,&sc->arm_r0,err);
  7. __get_user_error(regs->ARM_r1,&sc->arm_r1,err);
  8. __get_user_error(regs->ARM_r2,&sc->arm_r2,err);
  9. __get_user_error(regs->ARM_r3,&sc->arm_r3,err);
  10. __get_user_error(regs->ARM_r4,&sc->arm_r4,err);
  11. __get_user_error(regs->ARM_r5,&sc->arm_r5,err);
  12. __get_user_error(regs->ARM_r6,&sc->arm_r6,err);
  13. __get_user_error(regs->ARM_r7,&sc->arm_r7,err);
  14. __get_user_error(regs->ARM_r8,&sc->arm_r8,err);
  15. __get_user_error(regs->ARM_r9,&sc->arm_r9,err);
  16. __get_user_error(regs->ARM_r10,&sc->arm_r10,err);
  17. __get_user_error(regs->ARM_fp,&sc->arm_fp,err);
  18. __get_user_error(regs->ARM_ip,&sc->arm_ip,err);
  19. __get_user_error(regs->ARM_sp,&sc->arm_sp,err);
  20. __get_user_error(regs->ARM_lr,&sc->arm_lr,err);
  21. __get_user_error(regs->ARM_pc,&sc->arm_pc,err);
  22. __get_user_error(regs->ARM_cpsr,&sc->arm_cpsr,err);
  23. err|=!valid_user_regs(regs);
  24. #ifdefCONFIG_IWMMXT
  25. if(err==0&&test_thread_flag(TIF_USING_IWMMXT))
  26. err|=restore_iwmmxt_context(&aux->iwmmxt);
  27. #endif
  28. #ifdefCONFIG_VFP
  29. //if(err==0)
  30. //err|=vfp_restore_state(&aux->vfp);
  31. #endif
  32. returnerr;
  33. }

restore_sigcontext()很简单,当它返回后,通过sys_sigreturn()在内核态堆栈建立的pt_regs已经变为调用信号处理函数之前的pt_regs。这样,sys_sigreturn()返回用户态时,就顺利地过渡到处理之前的状态了。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top