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

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

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

返回后就不复存在了)。而现在必须通过最初的pt_regs上下文返回用户态,为此,在构建临时堆栈环境时,内核会把最初的pt_regs上下文备份到临时堆栈中(位于用户态堆栈),当通过系统调用sys_sigreturn()再次进入内核时,内核从用户态空间还原出原始的pt_regs。最后正常返回。

通过上面的讨论,我们知道在这个迂回的处理过程中,关键在于用户态的临时堆栈环境的建立,这是一个sigframe结构:

[plain]view plaincopyprint?

  1. /*
  2. *Doasignalreturn;undothesignalstack.Thesearealignedto64-bit.
  3. */
  4. structsigframe{
  5. structsigcontextsc;//保存一组寄存器上下文
  6. unsignedlongextramask[_NSIG_WORDS-1];
  7. unsignedlongretcode;//保存返回地址
  8. structaux_sigframeaux__attribute__((aligned(8)));
  9. };
  10. structrt_sigframe{
  11. structsiginfo__user*pinfo;
  12. void__user*puc;
  13. structsiginfoinfo;
  14. structucontextuc;
  15. unsignedlongretcode;
  16. structaux_sigframeaux__attribute__((aligned(8)));
  17. };

其中的sigcontext的作用类似于pt_regs用于保存相关寄存器上下文,原始的pt_regs的相关信息就备份在这里。而整个sigframe结构是通过get_sigframe()函数在进程用户态空间分配的,get_sigframe()定义如下:

[plain]view plaincopyprint?

  1. staticinlinevoid__user*
  2. get_sigframe(structk_sigaction*ka,structpt_regs*regs,intframesize)
  3. {
  4. unsignedlongsp=regs->ARM_sp;
  5. void__user*frame;
  6. /*
  7. *ThisistheX/Opensanctionedsignalstackswitching.
  8. */
  9. if((ka->sa.sa_flags&SA_ONSTACK)&&!sas_ss_flags(sp))
  10. sp=current->sas_ss_sp+current->sas_ss_size;
  11. /*
  12. *ATPCSB01mandates8-bytealignment
  13. */
  14. frame=(void__user*)((sp-framesize)&~7);
  15. /*
  16. *Checkthatwecanactuallywritetothesignalframe.
  17. */
  18. if(!access_ok(VERIFY_WRITE,frame,framesize))
  19. frame=NULL;
  20. returnframe;
  21. }

get_sigframe()通过用户态空间堆栈的sp-sizeof(struct sigframe)在用户态堆栈的顶部分配了一篇存储空间,将来使用完成后,再通过sp+sizeof(struct sigframe)还原。

通过上面的讨论,我们再回到do_signal()中来,如果有用户态的信号处理函数,do_signal()会调用handle_signal(),handle_signal()将调用setup_frame()或者setup_rt_frame()来完成实际的工作,这里我们以setup_frame()为例进行进一步讨论。

[plain]view plaincopyprint?

  1. staticint
  2. setup_frame(intusig,structk_sigaction*ka,sigset_t*set,structpt_regs*regs)
  3. {
  4. //在用户态堆栈上分配一个sigframe结构
  5. structsigframe__user*frame=get_sigframe(ka,regs,sizeof(*frame));
  6. interr=0;
  7. if(!frame)
  8. return1;
  9. //把相关信息从内核态备份到用户态堆栈的sigframe结构中
  10. err|=setup_sigcontext(&frame->sc,&frame->aux,regs,set->sig[0]);
  11. if(_NSIG_WORDS>1){
  12. err|=__copy_to_user(frame->extramask,&set->sig[1],
  13. sizeof(frame->extramask));
  14. }
  15. if(err==0)
  16. err=setup_return(regs,ka,&frame->retcode,frame,usig);
  17. returnerr;
  18. }

setup_return()设置返回地址,其定义如下:

[plain]view plaincopyprint?

  1. staticint
  2. setup_return(structpt_regs*regs,structk_sigaction*ka,
  3. unsignedlong__user*rc,void__user*frame,intusig)
  4. {
  5. unsignedlonghandler=(unsignedlong)ka->sa.sa_handler;
  6. unsignedlongretcode;
  7. intthumb=0;
  8. unsignedlongcpsr=regs->ARM_cpsr&~PSR_f;
  9. /*
  10. *Maybeweneedtodelivera32-bitsignaltoa26-bittask.
  11. */
  12. if(ka->sa.sa_flags&SA_THIRTYTWO)
  13. cpsr=(cpsr&~MODE_MASK)|USR_MODE;
  14. #ifdefCONFIG_ARM_THUMB
  15. if(elf_hwcap&HWCAP_THUMB){
  16. /*
  17. *TheLSBofthehandlerdeterminesifweregoingto
  18. *beusingTHUMBorARMmodeforthissignalhandler.
  19. */
  20. thumb=handler&1;
  21. if(thumb)
  22. cpsr|=PSR_T_BIT;
  23. else
  24. cpsr&=~PSR_T_BIT;
  25. }
  26. #endif
  27. //这里的retcode就是保存手工构造的sigreturn()代码
  28. if(ka->sa.sa_flags&SA_RESTORER){
  29. retcode=(unsignedlong)ka->sa.sa_restorer;
  30. }else{
  31. unsignedintidx=thumb;
  32. if(ka->sa.sa_flags&SA_SIGINFO)
  33. idx+=2;
  34. if(__put_user(sigreturn_codes[idx],rc))
  35. return1;
  36. if(cpsr&MODE32_BIT){
  37. /*
  38. *32-bitcodecanusethenewhigh-page
  39. *signalreturncodesupport.
  40. */
  41. retcode=KERN_SIGRETURN_CODE+(idx<2)+thumb;
  42. }else{
  43. /*
  44. *Ensurethattheinstructioncachesees
  45. *thereturncodewrittenontothestack.
  46. */
  47. flush_icache_range((unsignedlong)rc,
  48. (unsignedlong)(rc+1));
  49. retcode=((unsignedlong)rc)+thumb;
  50. }
  51. }
  52. regs->ARM_r0=usig;
  53. regs->ARM_sp=(unsignedlong)frame;//堆栈
  54. regs->regs->ARM_lr=retcode;//返回地址,当

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

网站地图

Top