亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

中斷——中斷處理程序的進入與退出 (基于3.16-rc4)

2024-06-28 13:25:07
字體:
來源:轉載
供稿:網友
中斷——中斷處理程序的進入與退出 (基于3.16-rc4)

上一篇博文我們分析了中斷描述符表的中斷門初始化過程,并且在interrupt數組中初始化過程中,可以看到每個中斷處理程序都會跳入common_interrupt中。下面我們分析下common_interrupt匯編片段(arch/x86/kernel/entrt_32.S)。

 1     .p2align CONFIG_X86_L1_CACHE_SHIFT 2 common_interrupt: 3     ASM_CLAC 4     addl $-0x80,(%esp)    /* Adjust vector into the [-256,-1] range */ 5     SAVE_ALL 6     TRACE_IRQS_OFF 7     movl %esp,%eax 8     call do_IRQ 9     jmp ret_from_intr10 ENDPROC(common_interrupt)11     CFI_ENDPROC 

第5行SAVE_ALL也是一個匯編片段(宏),用來將當前多個寄存器壓棧,因為在do_IRQ中可能會用到這些寄存器。第8行調用了do_IRQ函數,接下來我們分析do_IRQ函數(arch/x86/kernel/irq.c)。

 1 __visible unsigned int __irq_entry do_IRQ(struct pt_regs *regs) 2 { 3     struct pt_regs *old_regs = set_irq_regs(regs); 4  5     /* high bit used in ret_from_ code  */ 6     unsigned vector = ~regs->orig_ax; 7     unsigned irq; 8  9     irq_enter();10     exit_idle();11 12     irq = __this_cpu_read(vector_irq[vector]);13 14     if (!handle_irq(irq, regs)) {15         ack_APIC_irq();16 17         if (irq != VECTOR_RETRIGGERED) {18             pr_emerg_ratelimited("%s: %d.%d No irq handler for vector (irq %d)/n",19                          __func__, smp_processor_id(),20                          vector, irq);21         } else {22             __this_cpu_write(vector_irq[vector], VECTOR_UNDEFINED);23         }24     }25 26     irq_exit();27 28     set_irq_regs(old_regs);29     return 1;30 }

第12行的vector_irq數組保存了中斷向量號和中斷線號(中斷號)的對應關系,利用__this_cpu_read函數獲得當前中斷向量號所對應的中斷號。第14行中handle_irq函數,使用中斷號irq作為參數,進入該中斷號所對應的中斷服務例程中,下面分析下handle_irq函數(arch/x86/kernel/irq_32.c)。

 1 bool handle_irq(unsigned irq, struct pt_regs *regs) 2 { 3     struct irq_desc *desc; 4     int overflow; 5  6     overflow = check_stack_overflow(); 7  8     desc = irq_to_desc(irq); 9     if (unlikely(!desc))10         return false;11 12     if (user_mode_vm(regs) || !execute_on_irq_stack(overflow, desc, irq)) {13         if (unlikely(overflow))14             print_stack_overflow();15         desc->handle_irq(irq, desc);16     }17 18     return true;19 }

第8行獲取到中斷號irq所對應的struct irq_desc結構體指針,內核使用struct irq_desc類型結構體數組來存放所有的中斷服務例程,中斷號irq作為數組元素下標,如下所示(kernel/irq/irqdesc.c)。

1 struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {2     [0 ... NR_IRQS-1] = {3         .handle_irq    = handle_bad_irq,4         .depth        = 1,5         .lock        = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),6     }7 };

再來看下struct irq_desc結構體(include/linux/irqdesc.h)。

 1 struct irq_desc { 2     struct irq_data        irq_data; 3     unsigned int __percpu    *kstat_irqs; 4     irq_flow_handler_t    handle_irq; 5 #ifdef CONFIG_IRQ_PREFLOW_FASTEOI 6     irq_preflow_handler_t    preflow_handler; 7 #endif 8     struct irqaction    *action;    /* IRQ action list */ 9     unsigned int        status_use_accessors;10     unsigned int        core_internal_state__do_not_mess_with_it;11     unsigned int        depth;        /* nested irq disables */12     unsigned int        wake_depth;    /* nested wake enables */13     unsigned int        irq_count;    /* For detecting broken IRQs */14     unsigned long        last_unhandled;    /* Aging timer for unhandled count */15     unsigned int        irqs_unhandled;16     atomic_t        threads_handled;17     int            threads_handled_last;18     raw_spinlock_t        lock;19     struct cpumask        *percpu_enabled;20 #ifdef CONFIG_SMP21     const struct cpumask    *affinity_hint;22     struct irq_affinity_notify *affinity_notify;23 #ifdef CONFIG_GENERIC_PENDING_IRQ24     cpumask_var_t        pending_mask;25 #endif26 #endif27     unsigned long        threads_oneshot;28     atomic_t        threads_active;29     wait_queue_head_t       wait_for_threads;30 #ifdef CONFIG_PROC_FS31     struct proc_dir_entry    *dir;32 #endif33     int            parent_irq;34     struct module        *owner;35     const char        *name;36 } ____cacheline_internodealigned_in_smp;

真正的中斷處理程序并不直接放在struct irq_desc結構體中,而是存放在struct irq_desc結構體的action成員所指向的struct irqaction結構體中,第8行。下面看下struct irqaction結構體類型(include/linux/interrupt.h)。

 1 struct irqaction { 2     irq_handler_t        handler;           3     void            *dev_id; 4     void __percpu        *percpu_dev_id; 5     struct irqaction    *next; 6     irq_handler_t        thread_fn; 7     struct task_struct    *thread; 8     unsigned int        irq; 9     unsigned int        flags;10     unsigned long        thread_flags;11     unsigned long        thread_mask;12     const char        *name;13     struct proc_dir_entry    *dir;14 } ____cacheline_internodealigned_in_smp;

第1行handler中存放著中斷服務例程。第5行next中存放下一個該類型結構體指針。因為一個中斷號可以對應多個中斷服務例程(中斷線共享),內核將中斷號相同的多個中斷服務例程組織成一個鏈表,掛到以irq號作為下標的irq_desc數組元素中。

回到handle_irq函數中,第8行獲取到irq號所對應的struct irq_desc結構體指針desc,接著第15行執行了desc->handle_irq函數,在該函數中執行irq號的所有中斷服務例程。

在這里,一定要區別清楚IDT表idt_table和irq_desc數組的區別,idt_table中存放的是中斷處理程序,而且這些中斷處理程序的開頭部分代碼都是相同的,都要跳到common_interrupt函數中,進而去尋找中斷服務例程。而irq_desc數組中存放的是中斷服務例程,中斷處理程序最終要通過該數組找到對應的中斷服務例程并執行它。我們在編寫驅動程序時,很多時候需要編寫設備的中斷服務例程,我們將中斷服務例程存放在申請的struct irqaction結構體當中,并將該結構體掛到irq_desc數組的對應鏈表中,當中斷發生后,系統會自動通過IDT--->GDT--->中斷處理程序--->common_interrupt(屬于中斷處理程序)--->do_IRQ--->handle_irq,然后將irq_desc[NR_IRQS]數組中irq號對應的所有中斷服務例程全部執行一遍。

當中斷服務例程執行結束后,就會返回文章最開始的common_interrupt函數中,開始執行第9行,跳入到ret_from_intr函數中(arch/x86/kernel/entry_32.S)。

 1     ALIGN 2     RING0_PTREGS_FRAME 3 ret_from_exception: 4     preempt_stop(CLBR_ANY) 5 ret_from_intr: 6     GET_THREAD_INFO(%ebp) 7 #ifdef CONFIG_VM86 8     movl PT_EFLAGS(%esp), %eax    # mix EFLAGS and CS 9     movb PT_CS(%esp), %al10     andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax11 #else12     /*13      * We can be coming here from child spawned by kernel_thread().14      */15     movl PT_CS(%esp), %eax16     andl $SEGMENT_RPL_MASK, %eax17 #endif18     cmpl $USER_RPL, %eax19     jb resume_kernel        # not returning to v8086 or userspace20 21 ENTRY(resume_userspace)22     LOCKDEP_SYS_EXIT23      DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt24                     # setting need_resched or sigpending25                     # between sampling and the iret26     TRACE_IRQS_OFF27     movl TI_flags(%ebp), %ecx28     andl $_TIF_WORK_MASK, %ecx    # is there any work to be done on29                     # int/exception return?30     jne work_pending31     jmp restore_all32 END(ret_from_exception)

第15行從當前棧中將cs寄存器的值存入eax中,第16行通過掩碼計算,將eax中的DPL字段提取出來再存入eax,第18行比較eax(DPL)和用戶空間權限的大小,如果DPL權限大的話,執行19行,恢復到內核態中,否則恢復到用戶態,21行。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品成人国产在线观看男人呻吟| 91社区国产高清| 国产精品久久久久国产a级| 日韩在线免费视频观看| 久久精品亚洲94久久精品| 亚洲自拍欧美另类| 26uuu久久噜噜噜噜| 国产亚洲成av人片在线观看桃| 美女国内精品自产拍在线播放| 色偷偷91综合久久噜噜| 亚洲欧洲一区二区三区在线观看| 成人免费在线视频网站| 性日韩欧美在线视频| 97碰碰碰免费色视频| 国产一区二区三区视频| 日韩成人av网址| 国产97在线亚洲| 亚洲欧美中文日韩v在线观看| 青青久久av北条麻妃海外网| 91啪国产在线| 九九精品视频在线观看| 欧美极品少妇与黑人| 成人美女av在线直播| 午夜精品久久久久久久99热| 国产亚洲一区精品| 欧美成人sm免费视频| 亚洲精品按摩视频| 成人免费网站在线看| 成人啪啪免费看| 国产精品高潮视频| 亚洲在线www| xvideos亚洲人网站| 一区二区三区视频免费| 日韩电影大全免费观看2023年上| 在线色欧美三级视频| 欧美体内谢she精2性欧美| 日韩欧美国产一区二区| 日韩高清电影好看的电视剧电影| 久久国产精品久久久久久久久久| 欧美亚洲另类在线| 中日韩美女免费视频网址在线观看| 欧美性极品xxxx娇小| 日韩av一卡二卡| 91免费精品国偷自产在线| 日韩专区中文字幕| 精品久久久久久中文字幕大豆网| 欧美做受高潮电影o| 国产精品香蕉在线观看| 国产精品免费一区| 亚洲人成网站777色婷婷| 国产精品一区久久| 中文字幕精品久久| 精品爽片免费看久久| 丰满岳妇乱一区二区三区| 免费成人高清视频| 欧美激情a∨在线视频播放| 亚洲国产高清福利视频| www.99久久热国产日韩欧美.com| 97久久超碰福利国产精品…| 久久视频免费观看| 久久久久久这里只有精品| 国产日韩精品在线观看| 欧美在线视频在线播放完整版免费观看| 国产精品日韩欧美综合| 亚洲一区二区久久久久久| 国产精品久久久久久久久久久不卡| 国产一区二区激情| 成人乱色短篇合集| 久久九九全国免费精品观看| 久久精品国产亚洲精品2020| 精品无人区太爽高潮在线播放| 国产在线拍偷自揄拍精品| 日韩欧亚中文在线| 操日韩av在线电影| xxxx欧美18另类的高清| 亚洲日韩欧美视频一区| 日韩av最新在线观看| 久久福利网址导航| 欧美一区视频在线| 亚洲男人天堂网站| 国产精品自拍偷拍视频| 国产视频一区在线| 日韩av片电影专区| 欧美福利视频在线| 亚洲黄色av女优在线观看| 国产精品第一视频| 欧美激情亚洲激情| 国产精品电影久久久久电影网| 日本高清久久天堂| 亚洲精品免费av| 久久资源免费视频| 色av中文字幕一区| 久久亚洲精品一区二区| 亚洲人成毛片在线播放| 这里只有精品在线播放| 亚洲第一精品夜夜躁人人躁| 日韩欧美综合在线视频| 日韩专区在线观看| 日韩免费观看网站| 成人中文字幕+乱码+中文字幕| 欧美精品在线看| 久操成人在线视频| 欧美成人午夜激情在线| 国产久一一精品| 国产精品久久久久秋霞鲁丝| www国产亚洲精品久久网站| 不卡av电影在线观看| 韩国日本不卡在线| 国产成人精品亚洲精品| 在线观看欧美成人| 亚洲在线免费观看| 国产成人精品在线视频| 亚洲国产精品va在看黑人| 中文字幕欧美精品日韩中文字幕| 国产美女精品免费电影| 538国产精品视频一区二区| 精品国模在线视频| 亚洲美女av在线| 亚洲欧美一区二区激情| 亚洲伊人久久大香线蕉av| 在线视频免费一区二区| 国产精品999| 成人激情视频网| 日韩在线视频二区| 国产成人精品视| 4438全国成人免费| 亚洲福利精品在线| 国产精品美女主播| 成人午夜高潮视频| 丝袜情趣国产精品| 欧美丝袜第一区| 97国产精品久久| 国产精品久久久av| 中文字幕欧美日韩精品| 国产成人aa精品一区在线播放| 成人中文字幕在线观看| 亚洲第一二三四五区| 最近2019中文字幕大全第二页| 国产精品男人爽免费视频1| 日本精品视频在线观看| 欧美性猛交xxxx黑人| 国产精品jvid在线观看蜜臀| 欧美日本国产在线| 日韩高清av一区二区三区| 国产欧美最新羞羞视频在线观看| 亚洲精品乱码久久久久久金桔影视| 国产精品一区二区三区成人| 日韩少妇与小伙激情| 一区二区三区国产视频| 久久免费观看视频| zzjj国产精品一区二区| 91九色精品视频| 久久久久久久久网站| 亚洲国产成人精品一区二区| 国产精品a久久久久久| 92看片淫黄大片欧美看国产片| 美女久久久久久久久久久| 91久久精品美女| 青青草一区二区| 欧美视频13p| 欧美电影在线观看完整版| 久久久久www| 这里只有精品在线播放| 亚洲三级免费看|