linux kernel中的中断处理流程
生活随笔
收集整理的這篇文章主要介紹了
linux kernel中的中断处理流程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- 1、linux kernel arm32的中斷函數處理流程
- (1)、irq_handler宏
- (2)、arch_irq_handler_default 宏
- (3)、調用了asm_do_IRQ
- 2、linux kernel arm64的中斷函數處理流程
- (1)、irq_handler宏 調用handle_arch_irq
- (2)、handle_arch_irq
- (3)、gic_handle_irq()
- (4)、handle_domain_irq()---->__handle_domain_irq()---->generic_handle_irq()---->generic_handle_irq_desc()
★★★ 友情鏈接 : 個人博客導讀首頁—點擊此處 ★★★
1、linux kernel arm32的中斷函數處理流程
我們從irq_handler宏函數看起
(1)、irq_handler宏
注意CONFIG_MULTI_IRQ_HANDLER宏表示"允許每臺機器在運行時指定它自己的IRQ處理程序",當前默認是不開啟的.
所以走else的arch_irq_handler_default邏輯
(2)、arch_irq_handler_default 宏
arch_irq_handler_default 宏 調用了asm_do_IRQ或do_IPI
(arch/arm/include/asr/entry-macro-multi.S) /** Interrupt handling. Preserves r7, r8, r9*/.macro arch_irq_handler_defaultget_irqnr_preamble r6, lr 1: get_irqnr_and_base r0, r2, r6, lrmovne r1, sp@@ routine called with r0 = irq number, r1 = struct pt_regs *@badrne lr, 1bbne asm_do_IRQ#ifdef CONFIG_SMP/** XXX** this macro assumes that irqstat (r2) and base (r6) are* preserved from get_irqnr_and_base above*/ALT_SMP(test_for_ipi r0, r2, r6, lr)ALT_UP_B(9997f)movne r1, spbadrne lr, 1bbne do_IPI #endif 9997:.endm(3)、調用了asm_do_IRQ
asm_do_IRQ()—>handle_IRQ()—>__handle_domain_irq()—>generic_handle_irq()—>調用用戶request_irq注冊的中斷處理函數
void handle_IRQ(unsigned int irq, struct pt_regs *regs) {__handle_domain_irq(NULL, irq, false, regs); } /** asm_do_IRQ is the interface to be used from assembly code.*/ asmlinkage void __exception_irq_entry asm_do_IRQ(unsigned int irq, struct pt_regs *regs) {handle_IRQ(irq, regs); } int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,bool lookup, struct pt_regs *regs) {struct pt_regs *old_regs = set_irq_regs(regs);unsigned int irq = hwirq;int ret = 0;irq_enter();#ifdef CONFIG_IRQ_DOMAINif (lookup)irq = irq_find_mapping(domain, hwirq); #endif/** Some hardware gives randomly wrong interrupts. Rather* than crashing, do something sensible.*/if (unlikely(!irq || irq >= nr_irqs)) {ack_bad_irq(irq);ret = -EINVAL;} else {generic_handle_irq(irq);}irq_exit();set_irq_regs(old_regs);return ret; } (kernel/irq/irqdesc.c) int generic_handle_irq(unsigned int irq) {struct irq_desc *desc = irq_to_desc(irq);if (!desc)return -EINVAL;generic_handle_irq_desc(desc);return 0; } EXPORT_SYMBOL_GPL(generic_handle_irq); (kernel/include/linux/irqdesc.h) static inline void generic_handle_irq_desc(struct irq_desc *desc) {desc->handle_irq(desc); // 這里真正調用到,用戶request_irq注冊的中斷處理函數 }2、linux kernel arm64的中斷函數處理流程
我們依然從irq_handler宏函數看起
(1)、irq_handler宏 調用handle_arch_irq
(arch/arm/kernel/entry.S) /** Interrupt handling.*/.macro irq_handlerldr_l x1, handle_arch_irqmov x0, spirq_stack_entryblr x1irq_stack_exit.endm(2)、handle_arch_irq
handle_arch_irq是在set_handle_irq()設置的handle地址
void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) {if (handle_arch_irq)return;handle_arch_irq = handle_irq; }(3)、gic_handle_irq()
在gic_of_init初始化的時候,將gic_handle_irq()地址賦給了handle_arch_irq
static int __init gic_of_init(struct device_node *node, struct device_node *parent) { ......set_handle_irq(gic_handle_irq); ...... }進入gic中的gic_handle_irq處理函數
在這里會調用handle_domain_irq函數或者handle_IPI函數
(4)、handle_domain_irq()---->__handle_domain_irq()---->generic_handle_irq()---->generic_handle_irq_desc()
int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,bool lookup, struct pt_regs *regs) {struct pt_regs *old_regs = set_irq_regs(regs);unsigned int irq = hwirq;int ret = 0;irq_enter();#ifdef CONFIG_IRQ_DOMAINif (lookup)irq = irq_find_mapping(domain, hwirq); #endif/** Some hardware gives randomly wrong interrupts. Rather* than crashing, do something sensible.*/if (unlikely(!irq || irq >= nr_irqs)) {ack_bad_irq(irq);ret = -EINVAL;} else {generic_handle_irq(irq);}irq_exit();set_irq_regs(old_regs);return ret; } int generic_handle_irq(unsigned int irq) {struct irq_desc *desc = irq_to_desc(irq);if (!desc)return -EINVAL;generic_handle_irq_desc(desc);return 0; } EXPORT_SYMBOL_GPL(generic_handle_irq);static inline void generic_handle_irq_desc(struct irq_desc *desc) {desc->handle_irq(desc); }總結
以上是生活随笔為你收集整理的linux kernel中的中断处理流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux kernel中的栈的介绍
- 下一篇: [trustzone]-ARM Trus